在深度學習領域,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資料集上的訓練結果

epochsteplossgrad_normlearning_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):這是最簡單的量化技術。它計算向量的最大絕對值,並根據該值計算量化因子。

量化的優點

量化有幾個優點:

  • 減少模型大小:透過降低引數精確度,模型大小大大減少,這使得模型更容易佈署在資源有限的裝置上。
  • 提高推理速度:量化可以加速模型的推理速度,因為低精確度運算通常比高精確度運算更快。

實作量化

要實作量化,可以使用以下步驟:

  1. 計算量化因子:計算向量的最大絕對值,並根據該值計算量化因子。
  2. 量化向量:使用量化因子將向量乘以一個值,以確保最大值為127(int8的最大可能值)。
  3. 去量化:如果需要,可以透過將量化向量乘以量化因子的逆來還原原始向量。但是,這個過程會導致一些資訊損失。

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 和量化等技術將持續最佳化,在平衡模型效能和效率方面扮演更關鍵的角色。對於追求高效能且資源敏感的應用場景,建議優先探索並應用這些技術,以最大化模型效益。