### [AI / ML領域相關學習筆記入口頁面](https://hackmd.io/@YungHuiHsu/BySsb5dfp) ### [Deeplearning.ai GenAI/LLM系列課程筆記](https://learn.deeplearning.ai/) #### [Large Language Models with Semantic Search。大型語言模型與語義搜索 ](https://hackmd.io/@YungHuiHsu/rku-vjhZT) #### [Finetuning Large Language Models。微調大型語言模型](https://hackmd.io/@YungHuiHsu/HJ6AT8XG6) - [為何要微調(Why finetune)](https://hackmd.io/@YungHuiHsu/HJ6AT8XG6) - [微調的適用範圍(Where finetuning fits in)](https://hackmd.io/@YungHuiHsu/Bkfyyh7zp) - [指令調整(Instruction-tuning)](https://hackmd.io/@YungHuiHsu/B18Hg2XMa) - [資料準備(Data preparation)](https://hackmd.io/@YungHuiHsu/ByR-G24GT) - [訓練過程(Training process)](https://hackmd.io/@YungHuiHsu/rJP6F2Vf6) - [評估與迭代(Evaluation and iteration)](https://hackmd.io/@YungHuiHsu/ryfM524Ga) - [考量與開始(Considerations on getting started now)](https://hackmd.io/@YungHuiHsu/r1KGob8fT) --- # Finetuning Large Language Models ## [資料準備(Data preparation)](https://learn.deeplearning.ai/finetuning-large-language-models/lesson/5/data-preparation) ### 課程概要 * 準備訓練資料非常重要。高品質、多樣化和真實的訓練資料會比大量資料更有效 * 訓練資料需要預處理:將指令和回覆連接、添加提示模板、分詞(tokenize)、填充(padding)和截斷(truncation)。使用適合模型的分詞器非常重要 * 分詞將文本轉換為代表文字的數字。填充使輸入等長,截斷控制最大長度。都需要同時使用 * 可以對一個資料集批量分詞、填充和截斷。然後分割資料集為訓練集和測試集 * Hugging Face提供了一些興趣資料集可供訓練,如Taylor Swift和BTS ### 訓練資料的品質What kind of data? - 更好的訓練資料 - 高品質資料:給模型高品質輸入會得到高品質輸出,避免產生無意義的內容。 - 多樣化資料:涵蓋使用案例的各個面向,避免模型只學會重複固定模式。 - 真實資料:真實世界的資料含有更多樣式,不像生成資料會有固定模式。 - 更糟的訓練資料 - 低品質資料:會使模型學習並產生垃圾內容 - 單一樣式資料:模型只會學會重複單一模式,無法適應多樣化輸入 - 生成資料:已含固定模式,無法學習新的語言結構 - 資料量的影響 - 更多資料:通常能提升機器學習模型的表現 - 較少資料:大型語言模型(LLM)已從大量網路資料中預訓練,所以訓練資料量的影響較小 - 重點在資料品質,量較少但品質好的資料效果常比大量但品質差的資料來得好 ### 需要哪些種類的資料?(What kind of data?) ![](https://hackmd.io/_uploads/r1Sg1TVzT.png =300x) #### Better :::success 在特定任務的微調時,高品質資料是最重要的,要小心地進行資料清理與標註 否則==丟給模型垃圾、生出來的也是垃圾== ::: - Higher Quality - ==高品質的資料==是微調的首要條件。如果提供低質量的輸入,模型可能會模仿這些輸入並給出不良的輸出。因此,提供高質量的資料非常重要。 - Diversity - **多樣性**在資料中也很重要。如果所有的輸入和輸出都是相同的,模型可能會開始記憶它們,這可能不是你想要的。 - Real - 使用**真實資料**比生成資料更有效。生成的資料具有某些固有的模式,而真實的資料對於寫作任務特別有幫助。 - More - 在大多數機器學習應用中,擁有**更多的資料**比少量的資料更重要。但由於預訓練已從大量網絡資料中學到知識,所以更多的資料對模型有幫助,但不如前三者重要。 #### Worse - Lower Quality - **低質量的資料**可能會導致模型的輸出品質下降。如果提供垃圾輸入,模型可能會模仿這些輸入。 - Homogeneity - **同質性**意味著資料中的樣本都非常相似,這可能會導致模型過度擬合。 - Generated - **生成的資料**具有某些固有的模式,這可能不如真實的資料有效。有些服務試圖檢測某些內容是否是生成的,因為生成的資料中存在可以檢測的模式。 - Less - **較少的資料**可能不足以讓模型學到足夠的模式和知識。但由於預訓練已從大量網絡資料中學到知識,所以更多的資料對模型有幫助,但不如質量重要。 ### 準備資料的步驟(Steps to prepare your data) ![](https://hackmd.io/_uploads/BJfMJ6EMT.png =300x) #### 1. Collect instruction-response pairs - **收集指令響應對**: 例如,問答對或其他形式的輸入和輸出對。 #### 2. Concatenate pairs (add prompt template, if applicable) - **連接這些對**:將指令和響應連接在一起。如果適用的話,還可以添加提示模板, #### 3. Tokenize: Pad, Truncate - **分詞**:這是將文本資料轉換為代表每個文本片段的數字的過程。 - **Pad**:由於模型需要固定大小的輸入,因此需要對輸入進行填充,使其達到所需的長度。 - **Truncate**:如果輸入超過模型可以處理的最大長度,則需要對其進行截斷。 #### 4. Split into train/test - **分割成訓練/測試集**:一旦資料準備好,您需要將其分割成訓練集和測試集。在這個例子中,測試集大小被設定為資料的10%。 ### 將你的資料分詞(Tokenizing your data) ![](https://hackmd.io/_uploads/By_DgTEMa.png =400x) 將文本資料轉換為代表每個文本片段的數字的過程 分詞不一定是按單詞進行的,它是基於常見字符出現的頻率。例如,"ING" token 是分詞器中非常常見的,因為它出現在每個現在分詞中,如 "finetuning" 和 "tokenizing"。 #### 不同分詞器(There are multiple popular tokenizers) 有多種流行的分詞器,有些分詞器專為特定的模型而設計,而其他分詞器則可能適用於多種模型 - 使用與模型相關的分詞器(Use the tokenizer associated with your model) - 每個模型在訓練時都使用了特定的分詞器。如果您給模型提供了錯誤的分詞器,它會感到困惑,因為它期望不同的數字代表不同的字母組和不同的單詞 - HuggingFace的AutoTokenizer可以自動找到正確的分詞器,只需指定模型即可 ### Padding和Truncation 補充 - 為何要做Padding和truncation? - 固定輸入大小 - 神經網絡需要固定大小的輸入。但自然語言文本的長度是可變的,因此我們需要一種方法來確保每個輸入序列的長度都是相同的。 - 效率 - 當處理成批的資料時,為了使計算更加高效,我們需要確保每批資料中的所有序列都有相同的長度。 - 模型容量 - 轉換器模型(Transformer)通常有一個最大輸入長度的限制,超過這個長度的序列需要被截斷。 - 主要的Padding和truncation方法: - Padding: * 後置填充(Post-padding) * 在序列的末尾添加填充token,直到達到所需的長度 * 適用情境:例如對電影評論做情感分析時,通常評論的開頭通常包含了主要的情感資訊 * 前置填充(Pre-padding) * 在序列的開頭添加填充token,直到達到所需的長度 * 適用情境:例如語音助理,通常需要理解用戶的最後一句話來給出回應 - Truncation: * 後置截斷(Post-truncation) * 刪除序列的末尾部分,直到達到所需的長度。 * 適用情境:例如新聞報導的重點通常都在前面 * 前置截斷(Pre-truncation) * 刪除序列的開頭部分,直到達到所需的長度 * 適用情境:例如想看文章的結論 ## Lab for Data preparation 程式範例都是呼叫高階API,知道背後的原理跟使用情境比較重要,實際動手體驗詳見[04_Data_preparation_lab_student](https://learn.deeplearning.ai/finetuning-large-language-models/lesson/5/data-preparation) - Tokenizing text 將文本資料轉換為代表每個文本片段的數字的過程。例如,文本"hi, how are you?"可以被分詞為一系列的數字,每個數字都代表文本中的一個特定部分 - Tokenize multiple texts at once 將多個文本輸入進行分詞的過程。例如,可以將文本列表["hi, how are you?", "I'm good", "yes"]一次性輸入分詞器,得到每個文本的分詞結果 - Padding and truncation 於模型需要固定大小的輸入,因此可能需要對輸入進行填充或截斷 * Padding * 將輸入填充到所需的長度,例如,將"yes"填充為與"hi, how are you?"相同的長度 * Truncation * 如果輸入超過模型可以處理的最大長度,則需要對其進行截斷 - Prepare instruction dataset - Tokenize a single example ```python= # Set a default maximum length for the sequences max_length = 2048 # Adjust the max_length based on the actual length of the tokenized input. # It ensures that the max_length is not unnecessarily long if the actual sequence is shorter than 2048. max_length = min( tokenized_inputs["input_ids"].shape[1], max_length, ) # Tokenize the input text # - return_tensors: specifies the type of tensors to be returned, in this case, numpy arrays # - truncation: ensures that the tokenized sequence will be truncated if it exceeds the max_length # - max_length: specifies the maximum length for the tokenized sequence tokenized_inputs = tokenizer( text, return_tensors="np", truncation=True, max_length=max_length ) # Retrieve the tokenized input IDs from the tokenized inputs tokenized_inputs["input_ids"] # array([[ 4118, 19782, 27, ...}}) ``` - Tokenize the instruction dataset 對整個指令資料集進行分詞的過程。這涉及將每個示例連接在一起,然後對其進行分詞,並根據需要進行填充和截斷 - 自定義tokenize函式 `def tokenize_function` ```python= def tokenize_function(examples): if "question" in examples and "answer" in examples: text = examples["question"][0] + examples["answer"][0] elif "input" in examples and "output" in examples: text = examples["input"][0] + examples["output"][0] else: text = examples["text"][0] tokenizer.pad_token = tokenizer.eos_token tokenized_inputs = tokenizer( text, return_tensors="np", padding=True, ) max_length = min( tokenized_inputs["input_ids"].shape[1], 2048 ) tokenizer.truncation_side = "left" tokenized_inputs = tokenizer( text, return_tensors="np", truncation=True, max_length=max_length ) return tokenized_inputs ``` - 將剛剛自訂的tokenize函式應用/映射(map)在整個資料集上 - `map`方法,會遍歷資料集中的每一個元素,並對每一個元素調用指定的函數 ```python= finetuning_dataset_loaded = datasets.load_dataset("json", data_files=filename, split="train") pd.DataFrame(finetuning_dataset_loaded) ``` - 檢視tokenized前的finetuning資料集 ![](https://hackmd.io/_uploads/HyQhdlHGT.png) ```python= tokenized_dataset = finetuning_dataset_loaded.map( tokenize_function, batched=True, batch_size=1, drop_last_batch=True ) pd.DataFrame(tokenized_dataset) ``` - 檢視tokenized的finetuning資料集 ![](https://hackmd.io/_uploads/H166ueBfa.png) - 切分訓練與測試資料集 Prepare test/train splits ```python= split_dataset = tokenized_dataset.train_test_split(test_size=0.1, shuffle=True, seed=123) print(split_dataset) # DatasetDict({ train: Dataset({ features: ['question', 'answer', 'input_ids', 'attention_mask', 'labels'], num_rows: 1260 }) test: Dataset({ features: ['question', 'answer', 'input_ids', 'attention_mask', 'labels'], num_rows: 140 })}) ``` --- ## 補充資料 ### NLP text Text Preprocessing ### [2019.01。mlwhiz.com。ing Series: Part 1 - Text Preprocessing Methods for Deep Learning](mlwhiz.com) ![](https://hackmd.io/_uploads/r1xjmYRNMT.png) ### Tokenization #### [HuggingFace tokenizer tutorial](https://huggingface.co/learn/nlp-course/chapter6/1) #### [2020.01。Cathal Horan。Tokenizers: How machines read](https://blog.floydhub.com/tokenization-nlp/) ![](https://hackmd.io/_uploads/r16xwAEfT.png =400x) ![](https://hackmd.io/_uploads/B1PzvREzp.png =400x) ![](https://hackmd.io/_uploads/rypzDR4Ma.png =400x) ![](https://hackmd.io/_uploads/H1ZVDA4Ga.png =400x) #### [2022.09。https://vaclavkosar.com/。kenization in Machine Learning Explained](https://vaclavkosar.com/ml/Tokenization-in-Machine-Learning-Explained) ![](https://hackmd.io/_uploads/Bk_pw0EMp.png) #### [2023.08。nghuyong。知乎。大模型基础组件 - Tokenizer](https://zhuanlan.zhihu.com/p/651430181) #### [2023.08。Amal Menzli。MLOps Blog。Tokenization in NLP: Types, Challenges, Examples, Tools](https://neptune.ai/blog/tokenization-in-nlp) #### [2023.10。解读大模型(LLM)的token](https://cloud.tencent.com/developer/article/2336073) ![](https://hackmd.io/_uploads/H1djoA4MT.png) ![](https://hackmd.io/_uploads/rJ_piC4Mp.png)