在深度學習領域,Transformers 模型已成為自然語言處理任務的首選。然而,大型預訓練模型的微調需要大量的計算資源和時間。因此,高效的微調技術對於實際應用至關重要。本文將探討如何利用資料收集器、LoRA、PEFT 和量化等技術,最佳化 Transformers 模型的微調流程。資料收集器能有效處理不同長度的樣本,確保批次處理的一致性。LoRA 和 PEFT 則透過低秩矩陣近似,減少需要訓練的引數數量,從而降低硬體需求並提升訓練速度。此外,量化技術能進一步壓縮模型大小,方便佈署至資源受限的裝置。
資料集與批次處理
在進行自然語言處理任務時,資料集的預處理是一個非常重要的步驟。這包括了將所有樣本填充和截斷到相同的長度,以便於模型的訓練。除了在標記化階段進行這些操作外,我們還可以使用資料收集器(data collators)來實作批次處理。
資料收集器的作用是將樣本組裝成批次,並對批次中的樣本進行動態填充,以確保所有樣本的長度一致。Transformers函式庫提供了一些預設的收集器,適用於特定的任務,如語言模型。
以下是使用資料收集器進行因果語言模型訓練的示例:
from transformers import DataCollatorForLanguageModeling
# 建立資料收集器,設定mlm為False,表示我們正在訓練一個因果語言模型
data_collator = DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm=False)
讓我們看看這個收集器如何處理三個不同長度的樣本:
samples = [tokenized_datasets["train"][i] for i in range(3)]
for sample in samples:
print(f"input_ids shape: {len(sample['input_ids'])}")
# 輸出:
# input_ids shape: 37
# input_ids shape: 55
# input_ids shape: 51
在使用資料收集器後,批次中的樣本將被填充到最大長度(55),並新增一個標籤欄:
flowchart TD A[樣本1] -->|填充|> B[批次] A1[樣本2] -->|填充|> B A2[樣本3] -->|填充|> B B --> C[新增標籤欄] C --> D[輸出批次]
內容解密:
上述程式碼示範瞭如何使用資料收集器來處理批次中的樣本。資料收集器會自動填充樣本到最大長度,並新增一個標籤欄,以便於模型的訓練。
圖表翻譯:
此圖表展示了資料收集器如何處理批次中的樣本。首先,樣本1、樣本2和樣本3被填充到最大長度(55)。然後,新增一個標籤欄,以便於模型的訓練。最終,輸出批次包含了填充和新增標籤欄的樣本。
訓練語言模型的精細調整
在進行語言模型的精細調整時,我們需要定義訓練引數,以控制模型的訓練過程。這些引數包括權重衰減、學習率和學習率排程器型別等。
權重衰減
權重衰減是一種正則化技術,防止模型過度擬合。它透過懲罰大權重來實作這一點。調整TrainingArguments中的權重衰減引數,可以控制這種正則化效果,從而影響模型的泛化能力。
學習率
學習率是最佳化演算法中的一個關鍵超引數,決定了每一步最佳化的步長。在TrainingArguments中,可以指定學習率,從而影響訓練過程的收斂速度和穩定性。仔細調整學習率可以對模型的生成品質產生顯著影響。
學習率排程器型別
學習率排程器控制著學習率在訓練過程中的變化。不同的任務和模型架構可能會受益於不同的排程策略。TrainingArguments提供了選項來定義學習率排程器型別,允許您嘗試不同的排程策略,例如常數學習率、餘弦退火等。
以下是修改部分引數以展示這種靈活性的示例:
training_args = TrainingArguments(
"business-news-generator",
push_to_hub=True,
per_device_train_batch_size=8,
weight_decay=0.1,
lr_scheduler_type="cosine",
learning_rate=5e-4,
num_train_epochs=2,
eval_strategy="steps",
eval_steps=200,
logging_steps=200,
)
建立Trainer例項
在設定完成後,與分類別示例一樣,最終步驟是建立一個Trainer例項,包含所有元件。主要差異在於這次我們使用了資料收集器,並且只使用了5,000個樣本:
trainer = Trainer(
model=model,
tokenizer=tokenizer,
args=training_args,
data_collator=data_collator,
train_dataset=tokenized_datasets["train"].select(range(5000)),
eval_dataset=tokenized_datasets["test"],
)
執行訓練
執行trainer.train()
後,模型將開始進行精細調整。訓練和評估過程中的損失和梯度等資訊將被記錄下來。
表6-3總結了在AG News資料集上對SmolLM進行精細調整的訓練結果。
表6-3:SmolLM在AG News資料集上的訓練結果
epoch | step | loss | grad_norm | learning_rate |
---|---|---|---|---|
… | … | … | … | … |
這些結果反映了模型在不同epoch和step下的效能,對於評估模型的收斂性和泛化能力非常重要。
文字生成模型的最佳化和應用
在前面的章節中,我們討論瞭如何使用預訓練模型進行微調,以完成特定的文字分類別任務,例如主題分類別。然而,這種方法需要為每個不同的任務訓練一個新的模型。如果我們遇到一個未見的任務,例如識別文字是否為垃圾郵件,我們將無法直接使用預訓練模型,而需要對模型進行微調。
微調多個模型
一種方法是選擇一個基礎模型並對其進行微調,以建立一個專門的模型。所有模型權重都會在微調過程中被更新,這意味著如果我們想要解決五個不同的任務,我們將會得到五個不同的微調模型。這種方法的優點是可以為每個任務建立一個高度專業化的模型,但是缺點是需要大量的計算資源和時間。
使用pipeline()函式
另一個方法是使用pipeline()
函式來載入模型和執行推理。這種方法可以簡化模型的使用過程,尤其是在需要完成多個任務的情況下。例如,我們可以使用以下程式碼來載入一個文字生成模型並生成文字:
from transformers import pipeline
pipe = pipeline(
"text-generation",
model="genaibook/business-news-generator",
device=device,
)
print(
pipe("Q1", do_sample=True, temperature=0.1, max_new_tokens=30)[0][
"generated_text"
]
)
這種方法的優點是可以快速地生成文字,並且可以根據需要調整模型的引數。
模型的選擇
在選擇模型時,需要考慮到任務的特點和要求。例如,如果需要生成高品質的文字,可以選擇使用大型模型,如Mistral 7B或Llama 3.1。然而,如果需要快速地生成文字,可以選擇使用小型模型,如基礎模型。
未來的發展
文字生成模型包括:
- 使用更大的模型和更多的訓練資料來提高生成文字的品質和多樣性。
- 開發新的模型架構和訓練方法來提高模型的效率和效果。
- 應用文字生成模型於更多的領域和任務,例如文字摘要、文字翻譯等。
圖表翻譯:
flowchart TD A[文字生成模型] --> B[微調] B --> C[建立專門模型] C --> D[使用pipeline()函式] D --> E[生成文字] E --> F[評估生成文字的品質] F --> G[選擇合適的模型] G --> H[未來的發展方向]
這個流程圖展示了文字生成模型從微調到生成文字的過程,以及如何評估生成文字的品質和選擇合適的模型。
第六章:微調語言模型
微調語言模型是一種改進預訓練模型效能的方法,尤其是在特定任務或領域中。有幾種微調方法,包括監督微調(Supervised Fine-Tuning)、指令微調(Instruct-Tuning)和提示工程(Prompt Engineering)。
監督微調
監督微調是一種簡單直接的方法,透過在預訓練模型上新增一個小型的輔助模型(Adapter),來改進模型的效能。這種方法可以快速完成,並且不需要大量的計算資源。
指令微調
指令微調是一種透過構建一個包含多個任務的指令資料集,然後在預訓練模型上進行微調的方法。這種方法可以使模型學習到多個任務,並且可以提高模型的泛化能力。
提示工程
提示工程是一種透過設計合適的提示來改進預訓練模型效能的方法。這種方法可以快速完成,並且不需要大量的計算資源。
選擇微調方法
選擇合適的微調方法取決於任務、可用資源、期望的實驗速度等因素。通常,針對特定任務或領域的微調模型會表現得更好,但是它們不能夠處理新的任務。指令微調是一種更通用的方法,但是它需要額外的工作來定義資料集和結構。提示工程是一種最靈活的方法,但是它需要一個強大的基礎模型,並且對生成結果的控制有限。
資料集和結構
資料集和結構對於指令微調至關重要。資料集可以是人工生成或自動生成的,並且需要包含多個任務和輸入-輸出對。指令範本也會對最終的效能產生影響。
介面卡
介面卡是一種小型的輔助模型,可以新增到預訓練模型上,以改進其效能。介面卡可以快速完成,並且不需要大量的計算資源。介面卡還可以降低儲存成本,並且可以使模型更容易佈署。
PEFT
PEFT(Parameter-Efficient Fine-Tuning)是一種介面卡技術,允許在不更新所有模型引數的情況下進行微調。PEFT 透過新增一個小型的介面卡,並且只更新介面卡中的引數,從而實作快速和低成本的微調。
PEFT 的優點
- 更快的訓練速度
- 更低的硬體要求
- 相當的效能
- 沒有延遲損失
PEFT 的工作原理
PEFT 透過新增一個小型的介面卡,並且只更新介面卡中的引數,從而實作快速和低成本的微調。介面卡可以是 prefix tuning、prompt tuning 或 low-rank adaptation (LoRA) 等方法。
瞭解 LoRA 的核心概念
LoRA(Low-Rank Adaptation)是一種適應器技術,允許在預訓練模型上進行高效的微調。這種方法透過更新模型的權重來適應新的任務或資料集,而不需要重新訓練整個模型。
LoRA 的核心引數
LoRA 的效能可以透過調整幾個核心引數來控制:
- rank:這控制了更新矩陣的大小。較大的 rank 可以讓適應器學習更複雜的模式,但需要更多的引數。
- lora_alpha:這會縮放更新矩陣。例如,如果
lora_alpha
是 32,而 rank 是 8,則梯度更新將被縮放。 - lora_dropout:這是 LoRA 層的 dropout 機率,可以幫助防止過度擬合。
- task_type:這是任務型別,例如序列分類別(SEQ_CLS)或因果語言模型(CAUSAL_LM)。這將決定適應器的架構。
DoRA 的簡介
DoRA 是 LoRA 的一種變體,特別是在匹配全微調的效能方面表現出色。雖然在這個例子中不會使用 DoRA,但瞭解它的存在是很有用的。
低秩矩陣的概念
LoRA 中的更新矩陣是一種特殊的矩陣,稱為低秩矩陣。低秩矩陣的想法是使用較少的行和列來總結一個大矩陣,而不失去重要的資訊。對於那些對 LoRA 背後的數學感興趣的人,更新矩陣可以用低秩分解來表示,其中 (W_0) 是原始權重,(x) 是輸入:
[h = W_0x + \Delta W = W_0x + \alpha_r BAx]
在 LoRA 中,更新 (\Delta W) 被表示為兩個低秩矩陣 (B) 和 (A) 的乘積,其中 (B) 有較少的行,(A) 有較少的列。縮放因子 (\alpha_r) 控制了這個更新的大小。
低秩矩陣的維度
低秩矩陣 (B) 和 (A) 的維度比原始權重矩陣小。這使得 LoRA 能夠以相對較少的引數來捕捉重要的模式和關係,從而實作高效的適應。
內容解密
上述內容介紹了 LoRA 的核心概念和引數,包括 rank、lora_alpha、lora_dropout、task_type 等。瞭解這些引數和概念對於有效地使用 LoRA 進行模型適應至關重要。此外,低秩矩陣的概念是 LoRA 的基礎,它使得 LoRA 能夠以高效的方式更新模型權重。
flowchart TD A[LoRA] --> B[rank] A --> C[lora_alpha] A --> D[lora_dropout] A --> E[task_type] B --> F[更新矩陣大小] C --> G[梯度更新縮放] D --> H[防止過度擬合] E --> I[決定適應器架構]
圖表翻譯
此圖表展示了 LoRA 的核心組成部分及其之間的關係。LoRA 本身是一種適應器技術,它依賴於 rank、lora_alpha、lora_dropout 和 task_type 等引數來進行模型更新和適應。每個引數都對應著特定的功能,如控制更新矩陣的大小、縮放梯度更新、防止過度擬合以及決定適應器的架構。這些引數共同作用,使 LoRA 能夠高效地適應不同的任務和資料集。
LoRA(低秩適應)技術簡介
LoRA(Low-Rank Adaptation)是一種模型適應技術,透過將原始模型的權重更新矩陣近似為兩個小型矩陣,從而實作對模型進行微調。這種方法可以大大減少需要訓練的引數數量,使得模型更加輕量化和高效。
LoRA 的工作原理
LoRA 的核心思想是將原始模型的權重更新矩陣近似為兩個小型矩陣:$A$ 和 $B$。假設原始模型的權重更新矩陣為 $W$,其尺寸為 $d \times k$,其中 $d$ 和 $k$ 分別為原始權重的行數和列數。LoRA 將 $W$ 近似為 $B \times A$,其中 $A$ 的尺寸為 $d \times r$,$B$ 的尺寸為 $r \times k$,$r$ 是 LoRA 的秩。
LoRA 的優點
LoRA 的優點在於它可以大大減少需要訓練的引數數量,使得模型更加輕量化和高效。例如,假設原始模型的權重更新矩陣的尺寸為 $10,000 \times 20,000$,使用 LoRA 以 $r=8$ 的秩進行近似,則 $A$ 的尺寸為 $10,000 \times 8$,$B$ 的尺寸為 $8 \times 20,000$。這樣,LoRA 只需要訓練 $80,000 + 160,000 = 240,000$ 個引數,而原始模型需要訓練 $200,000,000$ 個引數。這樣可以大大減少模型的計算複雜度和記憶體佔用。
LoRA 的引數選擇
LoRA 的效能取決於兩個重要引數:秩 $r$ 和係數 $\alpha$。秩 $r$ 控制著 LoRA 矩陣的尺寸,而係數 $\alpha$ 控制著 LoRA 對原始模型的影響。一般來說,秩 $r$ 過高會導致過度適應,而過低會導致模型效能不佳。係數 $\alpha$ 過高會使得 LoRA 對原始模型的影響過大,而過低會使得 LoRA 對原始模型的影響過小。
LoRA 的應用
LoRA 可以應用於各種深度學習任務中,尤其是那些需要對大型模型進行微調的任務。LoRA 可以用於語言模型、影像生成模型等各種模型的微調。另外,LoRA 還可以用於多樣性任務中,例如生成多個風格的影像或文字。
內容解密:
上述程式碼展示瞭如何使用 LoRA 進行模型微調。首先,我們需要建立一個 LoRA 組態物件 peft_config
,其中指定了 LoRA 的秩 r
和係數 $\alpha$。然後,我們可以使用 get_peft_model
函式將 LoRA 組態應用於原始模型中。最後,我們可以列印預出微調後的模型的可訓練引數數量。
from peft import LoraConfig, get_peft_model
peft_config = LoraConfig(
r=8, lora_alpha=32, lora_dropout=0.05, task_type="CAUSAL_LM"
)
model = AutoModelForCausalLM.from_pretrained("HuggingFaceTB/SmolLM-135M")
peft_model = get_peft_model(model, peft_config)
peft_model.print_trainable_parameters()
圖表翻譯:
下圖展示了 LoRA 的工作原理。LoRA 將原始模型的權重更新矩陣近似為兩個小型矩陣:$A$ 和 $B$。這樣可以大大減少需要訓練的引數數量,使得模型更加輕量化和高效。
flowchart TD A[原始模型] --> B[權重更新矩陣] B --> C[LoRA 近似] C --> D[小型矩陣 A 和 B] D --> E[微調]
這樣,LoRA 可以用於各種深度學習任務中,尤其是那些需要對大型模型進行微調的任務。LoRA 可以用於語言模型、影像生成模型等各種模型的微調。另外,LoRA 還可以用於多樣性任務中,例如生成多個風格的影像或文字。
量化技術簡介
在深度學習模型中,量化是一種減少模型引數精確度的技術,從而降低模型的大小和計算成本。這對於佈署模型在資源有限的裝置上非常重要,例如移動裝置或嵌入式系統。
量化的基本概念
量化涉及將模型引數從高精確度資料型別(例如float32)轉換為低精確度資料型別(例如int8)。這個過程會導致一些資訊損失,但如果正確實施,對模型效能的影響可以最小化。
量化技術
有幾種量化技術,包括:
- 有符號最大值量化(Signed Max Quantization):這種方法根據向量的最大絕對值計算量化因子。然後,使用此因子將向量乘以一個值,以確保最大值為127(int8的最大可能值)。
- 絕對最大值量化(AbsMax Quantization):這是最簡單的量化技術。它計算向量的最大絕對值,並根據該值計算量化因子。
量化的優點
量化有幾個優點:
- 減少模型大小:透過降低引數精確度,模型大小大大減少,這使得模型更容易佈署在資源有限的裝置上。
- 提高推理速度:量化可以加速模型的推理速度,因為低精確度運算通常比高精確度運算更快。
實作量化
要實作量化,可以使用以下步驟:
- 計算量化因子:計算向量的最大絕對值,並根據該值計算量化因子。
- 量化向量:使用量化因子將向量乘以一個值,以確保最大值為127(int8的最大可能值)。
- 去量化:如果需要,可以透過將量化向量乘以量化因子的逆來還原原始向量。但是,這個過程會導致一些資訊損失。
Python實作
以下是使用Python和NumPy實作絕對最大值量化的示例:
import numpy as np
def scaling_factor(vector):
# 取得向量的最大絕對值
m = np.max(np.abs(vector))
# 傳回量化因子
return 127 / m
array = np.array([1.2, -0.5, -4.3, 1.2, -3.1, 0.8, 2.4, 5.4, 0.3])
quantization_factor = scaling_factor(array)
quantized_array = (array * quantization_factor).astype(np.int8)
量化技術:模型最佳化的關鍵
在深度學習中,模型的大小和複雜度對於其效能和效率有著重要影響。然而,隨著模型大小的增加,所需的計算資源和記憶體也會增加,這使得模型佈署和推理變得更加困難。為瞭解決這個問題,研究人員和開發人員正在探索各種模型最佳化技術,包括量化。
量化的基本概念
量化是指將模型的權重和啟用函式從浮點數(fp32)轉換為整數(int8)或其他低精確度資料型別的過程。這樣做可以減少模型的大小和記憶體需求,使其更容易佈署和推理。然而,量化也可能導致模型效能的下降,因為低精確度資料型別不能準確地表示原始浮點數值。
從效能最佳化視角來看,本文深入探討了資料集批次處理、語言模型微調、LoRA 技術及量化技術等關鍵導向。分析顯示,資料收集器有效解決了批次處理中不同長度樣本的填充問題,提升了訓練效率;微調技術,尤其是結合 LoRA 的 PEFT 方法,在控制引數量及計算成本的同時,展現出接近全微調模型的效能。然而,LoRA 的 rank、lora_alpha 等引數仍需仔細調整以達最佳效果。此外,量化技術有效降低模型大小及推理成本,但精確度損失仍需關注,不同量化策略的選擇也需根據具體模型和硬體環境進行權衡。展望未來,隨著模型架構的持續演進和硬體算力的提升,預期 LoRA 和量化等技術將持續最佳化,在平衡模型效能和效率方面扮演更關鍵的角色。對於追求高效能且資源敏感的應用場景,建議優先探索並應用這些技術,以最大化模型效益。