??每周跟蹤AI熱點新聞動向和震撼發展 想要探索生成式人工智能的前沿進展嗎?訂閱我們的簡報,深入解析最新的技術突破、實際應用案例和未來的趨勢。與全球數同行一同,從行業內部的深度分析和實用指南中受益。不要錯過這個機會,成為AI領域的領跑者。點擊訂閱,與未來同行! 訂閱:https://rengongzhineng.io/
Prefix Tuning 是當前最酷的參數高效微調(PEFT)方法之一,它可以在無需重新訓練整個大模型的前提下對大語言模型(LLM)進行任務適配。為了理解它的工作原理,我們先了解下背景:傳統微調需要更新模型的所有參數,成本高、計算密集。隨后出現了 Prompting(提示學習),通過巧妙設計輸入引導模型輸出;Instruction Tuning(指令微調)進一步提升模型對任務指令的理解能力。再后來,LoRA(低秩適配)通過在網絡中插入可訓練的低秩矩陣實現任務適配,大大減少了可訓練參數。
而 Prefix Tuning 則是另一種思路:它不會更改模型本體參數,也不插入額外矩陣,而是學習一小組“前綴向量”,將它們添加到每一層 Transformer 的輸入中。這種方法輕巧快速,非常適合在 Google Colab 這樣資源受限的環境中實踐。
在這篇博客中,我們將一步步地在 Google Colab 上,使用 Hugging Face Transformers 和 peft
庫完成 Prefix Tuning 的演示。
第一步:安裝運行環境
!pip install transformers peft datasets accelerate bitsandbytes
使用的庫包括:
-
transformers
: 加載基礎模型 -
peft
: 實現 Prefix Tuning -
datasets
: 加載示例數據集 -
accelerate
和bitsandbytes
: 優化訓練性能
第二步:加載預訓練模型和分詞器
from transformers import AutoModelForCausalLM, AutoTokenizer
from peft import get_peft_model, PrefixTuningConfig, TaskTypemodel_name = "gpt2"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(model_name)
這里我們使用 GPT-2 作為演示模型,也可以替換為其他因果語言模型。
第三步:配置 Prefix Tuning
peft_config = PrefixTuningConfig(task_type=TaskType.CAUSAL_LM,inference_mode=False,num_virtual_tokens=10
)model = get_peft_model(model, peft_config)
model.print_trainable_parameters()
上述配置在每層 Transformer 中加入了 10 個可學習的虛擬前綴 token,我們將對它們進行微調。
第四步:加載并預處理 Yelp 數據集樣本
from datasets import load_datasetdataset = load_dataset("yelp_review_full", cache_dir="/tmp/hf-datasets")
dataset = dataset.shuffle(seed=42).select(range(1000))def preprocess(example):tokens = tokenizer(example["text"], truncation=True, padding="max_length", max_length=128)return {"input_ids": tokens["input_ids"], "attention_mask": tokens["attention_mask"]}dataset = dataset.map(preprocess, batched=True)
第五步:使用 Prefix Tuning 訓練模型
from transformers import TrainingArguments, Trainertraining_args = TrainingArguments(output_dir="./prefix_model",per_device_train_batch_size=4,num_train_epochs=1,logging_dir="./logs",logging_steps=10
)trainer = Trainer(model=model,args=training_args,train_dataset=dataset
)trainer.train()
第六步:保存并加載 Prefix Adapter
model.save_pretrained("prefix_yelp")
之后加載方法如下:
from peft import PeftModelbase_model = AutoModelForCausalLM.from_pretrained("gpt2")
prefix_model = PeftModel.from_pretrained(base_model, "prefix_yelp")
第七步:推理測試
訓練完成后,我們可以使用調優后的模型進行生成測試。
input_text = "This restaurant was absolutely amazing!"
inputs = tokenizer(input_text, return_tensors="pt")output = prefix_model.generate(**inputs, max_new_tokens=50)
generated_text = tokenizer.decode(output[0], skip_special_tokens=True)
print("\nGenerated Output:")
print(generated_text)
示例輸出
這是在訓練 3 個 epoch 并使用 20 個虛擬 token 后的輸出示例:
This restaurant was absolutely amazing!, a the the the the the the the the the the the the the the the the the the the the the the the the the the the the the a., and the way. , and the was
雖然模型初步模仿了 Yelp 評論的風格,但輸出仍重復性強、連貫性不足。為獲得更好效果,可增加訓練數據、延長訓練周期,或使用更強的基礎模型(如 gpt2-medium
)。
完整代碼
以下是經過改進的完整代碼(包含更大前綴尺寸和更多訓練輪次):
# 安裝依賴
!pip install -U fsspec==2023.9.2
!pip install transformers peft datasets accelerate bitsandbytes# 加載模型與分詞器
from transformers import AutoModelForCausalLM, AutoTokenizer
from peft import get_peft_model, PrefixTuningConfig, TaskTypemodel_name = "gpt2"
tokenizer = AutoTokenizer.from_pretrained(model_name)
tokenizer.pad_token = tokenizer.eos_token
model = AutoModelForCausalLM.from_pretrained(model_name)
model.config.pad_token_id = tokenizer.pad_token_id# 配置 Prefix Tuning
peft_config = PrefixTuningConfig(task_type=TaskType.CAUSAL_LM,inference_mode=False,num_virtual_tokens=20 # 使用更多虛擬 token
)
model = get_peft_model(model, peft_config)
model.print_trainable_parameters()# 加載和預處理數據集
from datasets import load_dataset
try:dataset = load_dataset("yelp_review_full", split="train[:1000]")
except:dataset = load_dataset("yelp_review_full")dataset = dataset["train"].select(range(1000))def preprocess(examples):tokenized = tokenizer(examples["text"], truncation=True, padding="max_length", max_length=128)tokenized["labels"] = [[-100 if mask == 0 else token for token, mask in zip(input_ids, attention_mask)]for input_ids, attention_mask in zip(tokenized["input_ids"], tokenized["attention_mask"])]return tokenizeddataset = dataset.map(preprocess, batched=True, remove_columns=["text", "label"])# 配置訓練參數
from transformers import TrainingArguments, Trainer
training_args = TrainingArguments(output_dir="./prefix_model",per_device_train_batch_size=4,num_train_epochs=3, # 增加輪次logging_dir="./logs",logging_steps=10,report_to="none"
)trainer = Trainer(model=model,args=training_args,train_dataset=dataset
)trainer.train()# 保存和加載前綴
model.save_pretrained("prefix_yelp")
from peft import PeftModel
base_model = AutoModelForCausalLM.from_pretrained("gpt2")
prefix_model = PeftModel.from_pretrained(base_model, "prefix_yelp")# 推理
input_text = "This restaurant was absolutely amazing!"
inputs = tokenizer(input_text, return_tensors="pt")
output = prefix_model.generate(**inputs, max_new_tokens=50)
print(tokenizer.decode(output[0], skip_special_tokens=True))
不同微調技術如何選擇?
方法 | 特點 | 適合場景 |
---|---|---|
Prompting | 零樣本/少樣本,無需訓練 | 快速實驗、通用模型調用 |
Instruction Tuning | 統一風格指導多個任務 | 多任務模型,提示兼容性強 |
Full Fine-Tuning | 全模型更新,效果最好但成本高 | 數據量大、計算資源充足場景 |
LoRA | 插入低秩矩陣,性能和效率平衡 | 中等規模適配任務、部署靈活 |
Prefix Tuning | 訓練前綴向量,模塊化且輕量 | 多任務共享底模、小規模快速適配 |
真實應用案例
-
客服機器人:為不同產品線訓練不同前綴,提高回答準確性
-
法律/醫學摘要:為專業領域調優風格和術語的理解
-
多語種翻譯:為不同語言對訓練前綴,重用同一個基礎模型
-
角色對話代理:通過前綴改變語氣(如正式、幽默、親切)
-
SaaS 多租戶服務:不同客戶使用不同前綴,但共用主模型架構
總結
Prefix Tuning 是一種靈活且資源友好的方法,適合:
-
有多個任務/用戶但希望復用基礎大模型的情況
-
算力有限,但希望實現快速個性化的場景
-
構建模塊化、可熱切換行為的 LLM 服務
建議從小任務入手測試,嘗試不同 prefix 長度與訓練輪次,并結合任務類型進行微調策略選擇。
如果你想將此教程發布到 Colab、Hugging Face 或本地部署,歡迎繼續交流!