大語言模型的訓練和佈署需要大量的計算資源和時間。為了提高效率,Parameter Efficient Fine-Tuning (PEFT) 和 LoRA 等技術被廣泛應用於模型微調階段,以減少訓練所需的計算量和記憶體。這些技術的核心概念是僅微調模型的一小部分引數,同時凍結大部分預訓練模型的權重,從而顯著降低訓練成本。此外,量化技術可以進一步壓縮模型大小和加速推論速度,使得在資源受限的環境下佈署大語言模型成為可能。文章中提供的程式碼範例展示瞭如何使用這些技術進行模型的訓練和推論,並詳細說明瞭相關引數的設定方法。對於進階應用,文章還介紹了監督式微調、強化學習與人類回饋(RLHF)以及近端策略最佳化(PPO)等技術,並討論瞭如何應用這些技術來提升模型的效能和控制模型的輸出。
模型微調與推論的高效技術
在大語言模型的訓練過程中,如何有效地進行模型微調和推論是一個重要的技術挑戰。本章節將探討使用 Parameter Efficient Fine-Tuning (PEFT) 和 LoRA(Low-Rank Adaptation)技術來最佳化模型的訓練過程,並介紹如何進行模型的推論和評估。
設定量化組態與模型載入
首先,我們需要設定模型的量化組態並載入預訓練模型。以下程式碼展示瞭如何使用 BitsAndBytesConfig 設定 4 位元量化,並載入預訓練的語言模型。
from transformers import AutoModelForCausalLM, BitsAndBytesConfig
# 設定量化組態
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_use_double_quant=True,
bnb_4bit_compute_dtype=torch.bfloat16
)
# 載入預訓練模型
model_id = "your_model_id"
model = AutoModelForCausalLM.from_pretrained(
model_id,
quantization_config=bnb_config,
use_cache=False,
device_map="auto",
)
model = prepare_model_for_kbit_training(model)
內容解密:
- 量化組態設定:透過
BitsAndBytesConfig設定 4 位元量化,採用nf4型別並啟用雙重量化,以降低記憶體使用量並加速運算。 - 模型載入:使用
AutoModelForCausalLM.from_pretrained方法載入預訓練模型,並套用設定的量化組態。 prepare_model_for_kbit_training:進一步最佳化模型以適應量化訓練。
設定 PEFT 與 LoRA 組態
接下來,我們需要設定 PEFT 和 LoRA 的組態,以實作高效的模型微調。
from peft import LoraConfig, get_peft_model
# 設定 LoRA 組態
peft_config = LoraConfig(
r=8,
lora_alpha=16,
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM",
)
# 將預訓練模型轉換為 PEFT 模型
model = get_peft_model(model, peft_config)
內容解密:
- LoRA 組態:設定 LoRA 的引數,包括秩 (
r)、縮放因子 (lora_alpha) 和 dropout 率 (lora_dropout)。 get_peft_model:將預訓練模型轉換為 PEFT 模型,以實作高效的模型微調。
設定訓練引數與初始化 Trainer
from transformers import TrainingArguments, AutoTokenizer
from trl import SFTTrainer
# 設定訓練引數
args = TrainingArguments(
output_dir="llama2-7b-chat-samsum",
num_train_epochs=2,
per_device_train_batch_size=4,
gradient_accumulation_steps=2,
logging_steps=4,
save_strategy="epoch",
learning_rate=2e-4,
optim="paged_adamw_32bit",
bf16=True,
fp16=False,
tf32=True,
max_grad_norm=0.3,
warmup_ratio=0.03,
lr_scheduler_type="constant",
disable_tqdm=False,
)
# 初始化 Trainer
trainer = SFTTrainer(
model=model,
train_dataset=train_dataset,
peft_config=peft_config,
max_seq_length=1024,
tokenizer=tokenizer,
packing=True,
formatting_func=prompt_formatter,
args=args,
)
內容解密:
- 訓練引數設定:設定訓練的相關引數,包括 epoch 數、batch size、學習率等。
SFTTrainer初始化:初始化監督式微調訓練器,傳入模型、資料集、PEFT 組態和訓練引數。
開始模型微調
# 開始微調模型
trainer.train()
內容解密:
- 模型微調:呼叫
train方法開始模型的微調過程。
儲存 LoRA 層
# 儲存 LoRA 層
trainer.save_model()
內容解密:
- 儲存 LoRA 層:將微調後的 LoRA 層儲存起來,以便後續使用。
載入微調後的模型進行推論
from peft import AutoPeftModelForCausalLM
# 載入微調後的模型
model_folder = "llama2-7b-chat-samsum"
model = AutoPeftModelForCausalLM.from_pretrained(
model_folder,
low_cpu_mem_usage=True,
torch_dtype=torch.float16,
load_in_4bit=True,
device_map='auto'
)
tokenizer = AutoTokenizer.from_pretrained(model_folder)
內容解密:
- 載入微調後的模型:使用
AutoPeftModelForCausalLM.from_pretrained方法載入微調後的模型和 LoRA 層。
透過以上步驟,我們成功地完成了大語言模型的微調和推論任務。這些技術和方法可以有效地提高模型的效能和效率,為自然語言處理任務提供更好的支援。
大語言模型的進階技術:監督式微調與 RLHF
監督式微調(SFT)技術詳解
監督式微調是提升大語言模型(LLM)效能的重要技術。透過在特定任務或領域的資料集上進行微調,可以顯著改善模型的表現。
微調實作範例
以下程式碼展示如何使用 LoRA(Low-Rank Adaptation)技術對大語言模型進行微調:
# 設定模型的 LoRA 組態
config = LoraConfig(
task_type=TaskType.CAUSAL_LM,
r=8,
lora_alpha=32,
target_modules=["q_proj", "v_proj"],
lora_dropout=0.05,
bias="none"
)
# 建立模型並套用 LoRA
model = get_peft_model(model, config)
model.print_trainable_parameters()
內容解密:
LoraConfig用於設定 LoRA 的引數,包括任務型別、秩(rank)和其他相關模組。get_peft_model將原始模型與 LoRA 組態結合,生成可微調的模型。print_trainable_parameters用於顯示模型中可訓練的引數數量。
微調後的模型效能驗證
使用微調後的模型進行摘要生成的範例如下:
# 構建輸入提示
prompt = f"""### Instruction:
You are a helpful, respectful and honest assistant. \
Your task is to summarize the following dialogue. \
Your answer should be based on the provided dialogue only.
### Dialogue:
{sample['document']}
### Summary:
"""
# 生成摘要
input_ids = tokenizer(prompt, return_tensors="pt").input_ids.cuda()
outputs = model.generate(input_ids=input_ids, max_new_tokens=50, temperature=0.7)
print('Output:\n', tokenizer.batch_decode(outputs.detach().cpu().numpy(), skip_special_tokens=True)[0][len(prompt):])
內容解密:
- 使用特定的提示格式引導模型生成摘要。
generate方法控制生成文字的長度和多樣性。- 輸出結果與真實摘要進行比較,以評估模型的表現。
微調的記憶體需求分析
| Token 長度 | 記憶體需求 | |
-|
-| | 128 tokens | 1.3 gB | | 256 tokens | 2.6 gB | | 512 tokens | 5.2 gB |
圖表翻譯:
此表格顯示不同 Token 長度對記憶體需求的影響。隨著 Token 長度的增加,記憶體需求顯著上升。
SFT 的型別與應用
任務微調(Task Tuning):針對特定任務(如問答或摘要)進行微調。
- 使用特定任務的資料集,如 CoQA 或 Samsum。
領域微調(Domain Tuning):針對特定領域(如法律或醫療)進行微調。
- 使用特定領域的資料集,如 Legal 或 Healthcare。
RLHF 技術詳解
RLHF(Reinforcement Learning from Human Feedback)是一種利用人類反饋來微調預訓練語言模型的技術,旨在改善模型的行為並控制輸出結果。
RLHF 的運作階段
- 預訓練語言模型:使用大量文字資料進行初始訓練。
- 互動式提示:人類 AI 訓練者建立互動式提示,引導模型的回應。
圖表翻譯:
RLHF 的階段圖示說明瞭整個流程,包括預訓練、互動式提示和獎勵模型訓練等關鍵步驟。
進階技術:大語言模型的強化學習與獎勵模型實作
強化學習與人類回饋(RLHF)
強化學習與人類回饋(RLHF)是一種透過結合人類評估與強化學習技術來微調大語言模型(LLM)的方法,旨在提高模型的輸出品質、安全性和適用性。RLHF的核心流程包括以下步驟:
- 資料收集:收集人類生成的提示(prompts)與對應的模型輸出。
- 模型回應排序:由AI訓練人員根據流暢度、相關性和適當性等標準對模型回應進行排名,作為強化學習的獎勵訊號。
- 強化學習:利用排序後的回應作為獎勵,對語言模型進行強化學習,更新模型引數以最大化生成理想輸出的機率。
- 微調:在強化學習後,使用新生成的訓練資料(包含人類提示和模型回應)對語言模型進行微調。
- 評估與迭代:評估微調後的模型表現,如有需要,重複RLHF流程以達到預期效果。
RLHF的優點
- 可控輸出:RLHF允許開發者引導語言模型的回應,確保其遵循特定準則,減少不良輸出。
- 倫理考量:透過納入人類回饋,RLHF有助於減少偏見、有害內容和冒犯性語言,使語言模型更具倫理責任感。
- 客製化:開發者可利用互動式提示,為特定應用和領域量身定做語言模型,產生更有價值和專業的輸出。
RLHF的挑戰與考量
訓練資料品質:人類回饋的品質和多樣性對語言模型的行為至關重要。確保高品質的回饋是有效RLHF的關鍵。
偏見緩解:雖然RLHF旨在減少偏見,但仍需注意人類回饋中的潛在偏見。應努力確保在訓練過程中考慮多樣化的觀點。
- 多元回饋小組:組成由不同背景和觀點的成員組成的評估團隊,以減少單一觀點對模型訓練的影響。
- 盲評估:實施盲評估技術,使評估者無法辨別生成文字的來源(人類或LLM),從而減少根據來源的偏見。
- 主動學習:採用主動學習技術,讓模型識別模糊案例並請求人類專家澄清,集中人力於模型最不確定的領域,避免已明確案例的偏見放大。
最佳化獎勵函式:設計能夠準確捕捉所需模型行為的獎勵函式具有挑戰性,需要仔細考慮。
- 塑造獎勵:設計獎勵函式時,不僅採用簡單的二元分類別(好/壞),還應包含中間品質或相關性層級,提供模型更細緻的回饋。例如,使用三或五點評分機制進行回饋評分。
- 校準獎勵:仔細校準獎勵,以避免意外後果。例如,過度強調事實準確性可能會抑制創意,而僅關注流暢度可能導致無意義的輸出。因此,應捕捉生成輸出的不同導向,如事實準確性、連貫性、完整性等。
- 人機協同訓練:採用人機協同訓練方法,讓專家審查模型的輸出並動態調整獎勵函式,從而根據實際表現持續改進和調整獎勵系統。
獎勵模型實作
RLHF是一種廣泛使用的技術,用於根據人類使用者的回饋微調大語言模型(LLM)。在RLHF中,LLM的權重更新由使用者對模型生成結果提供的獎勵或回饋驅動。為瞭解決取得人類回饋耗時且昂貴的問題,可以訓練另一個稱為獎勵模型的模型來作為人類回饋的代理。
獎勵模型的目標
獎勵模型的主要目標是評估模型的回應與人類偏好的吻合程度。獎勵模型輸入一個(提示-回應)對,並輸出一個獎勵分數。這可以被表述為一個迴歸或分類別任務。建立有效的獎勵模型需要高品質的資料,因為對於不同的人來說,什麼是好的或壞的可能有所不同,這使得對映到一個標量值具有挑戰性。
建立獎勵模型的資料集
一種建立用於訓練獎勵模型的資料集的方法是要求標註者比較兩個回應,並決定哪一個更好,如圖7-5所示。這種資料集被稱為比較資料集,其中每個記錄由一個提示、被選中的回應和被拒絕的回應組成。
圖表翻譯: 此圖示展示了比較資料集的結構,其中包含一個提示、被選中的回應和被拒絕的回應,用於訓練獎勵模型。
獎勵模型的訓練
在訓練獎勵模型時,比較資料集應該採用(提示、被選中的回應、被拒絕的回應)的格式,其中較好的選項排在前面。這種順序對於設計損失函式至關重要。任何能夠處理可變長度文字輸入並輸出標量值的模型都可以用於此任務。通常,使用監督式微調(SFT)模型,並移除最後的嵌入層,在最後一層新增一個單一神經元以輸出標量值。圖7-6展示了訓練獎勵模型的過程。
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
title 大語言模型高效微調與推論技術
package "LLM 高效微調技術" {
package "引數高效微調" {
component [PEFT] as peft
component [LoRA] as lora
component [量化技術] as quant
}
package "模型訓練" {
component [模型選擇] as select
component [超參數調優] as tune
component [交叉驗證] as cv
}
package "評估部署" {
component [模型評估] as eval
component [模型部署] as deploy
component [監控維護] as monitor
}
}
collect --> clean : 原始資料
clean --> feature : 乾淨資料
feature --> select : 特徵向量
select --> tune : 基礎模型
tune --> cv : 最佳參數
cv --> eval : 訓練模型
eval --> deploy : 驗證模型
deploy --> monitor : 生產模型
note right of feature
特徵工程包含:
- 特徵選擇
- 特徵轉換
- 降維處理
end note
note right of eval
評估指標:
- 準確率/召回率
- F1 Score
- AUC-ROC
end note
@enduml圖表翻譯: 此圖示展示了訓練獎勵模型的過程,包括使用監督式微調模型、移除最後嵌入層、新增單一神經元以輸出標量值。
進階大語言模型技術:近端策略最佳化(PPO)訓練與實作
獎勵模型的訓練與控制評論生成
在前面的章節中,我們探討了大語言模型的基礎技術。本章節將深入介紹如何利用近端策略最佳化(Proximal Policy Optimization, PPO)演算法對GPT-2模型進行微調,以生成正向的Yelp評論。
獎勵模型的訓練過程
獎勵模型的訓練涉及每個訓練週期中的兩次傳遞。在第一次傳遞中,將提示和選定的回應輸入獎勵模型,產生輸出 $R_{chosen}$。在第二次傳遞中,使用相同的提示和被拒絕的回應,產生輸出 $R_{rejected}$。損失函式的設計目標是最大化選定回應分數與被拒絕回應分數之間的差距。
控制評論生成
在本文中,我們使用Yelp極性資料集對GPT2(小型)進行微調,以生成正向評論。我們不是從頭開始訓練模型,而是提供真實評論的開頭,並讓模型生成正向的延續內容。
%load_ext autoreload
%autoreload 2
%pip install transformers trl wandb
import torch
from tqdm import tqdm
import pandas as pd
tqdm.pandas()
from transformers import pipeline, AutoTokenizer
from datasets import load_dataset
from trl import PPOTrainer, PPOConfig, AutoModelForCausalLMWithValueHead
from trl.core import LengthSampler
環境設定與引陣列態
ppo_config = PPOConfig(
model_name="gpt2",
learning_rate=1.41e-5,
log_with="wandb",
)
sentiment_kwargs = {
"return_all_scores": True,
"function_to_apply": "none",
"batch_size": 16
}
內容解密:
PPOConfig 組態:定義了PPO訓練過程中的關鍵引數,包括模型名稱、學習率和日誌記錄方式。
model_name: 指定基礎語言模型的名稱,這裡使用的是gpt2模型。learning_rate: 設定PPO訓練過程中的學習率。log_with: 指定訓練進度的日誌記錄方式,這裡使用的是wandb(Weights & Biases)。
情感分析引數:定義了情感分析過程中的引數。
return_all_scores: 布林值,指示是否傳回所有情感分數。function_to_apply: 指定要應用於情感分數的函式,這裡設定為none,表示不應用任何函式。batch_size: 設定情感分析的批次大小。
載入資料集與資料預處理
Yelp極性資料集是一個用於二元情感分類別的大型資料集,包含56萬條高度極化的Yelp評論用於訓練,3.8萬條評論用於測試。
def build_dataset(config, dataset_name="yelp_polarity", min_text_length=2, max_text_length=8):
"""
為訓練建立資料集。
"""
# 載入資料集並進行過濾
dataset = load_dataset(dataset_name)
# 資料過濾與處理邏輯
內容解密:
build_dataset函式用於建立訓練所需的資料集。- 函式接受組態、資料集名稱、以及文字長度的最小和最大值作為引數。
- 資料集的載入和過濾邏輯需要根據具體需求進行自定義。
Weights & Biases(W&B)設定
import wandb
wandb.init()
內容解密:
- 初始化W&B,用於監控訓練過程。