用標註資料微調 LLM
用研究自己的標籤,通過 SFT、DPO、獎勵模型或過程獎勵模型訓練 LLM,在留出條目上給每個模型打分,併發布到 Hub。
v2.14.0 新增
本教程在 Potato 研究收集到的答案上訓練四種語言模型。llm-sft 訓練器在書面答案或修正後的智慧體軌跡上微調 LLM,llm-dpo 在成對選擇上調優 LLM,reward-model 在比較結果上擬合標量獎勵模型,prm-reward 在步驟評分上擬合過程獎勵模型。本頁面向已經在 Potato 中收集偏好或軌跡資料的團隊,他們想用這些標籤得到第一個模型,而不必把資料匯出到單獨的訓練指令碼。每一節都會指出產生資料的方案,給出能通過 Potato 驗證器的配置,列出值得調整的參數,並說明留出得分衡量什麼,以及預測是否會作為預標籤送回給標註者。模型訓練概覽介紹訓練頁面,訓練你的第一個模型則用一個不需要 GPU 的分類器走完整個迴圈。
按標註方案劃分的訓練器
本頁的每個訓練器每次執行只從一個標註方案學習,訓練頁面只為訓練器能夠學習的方案提供該訓練器。下表列出每個訓練器所學習的方案:
| 訓練器 | 方案 | 模型學到什麼 | 留出主指標 | 是否展示給標註者 |
|---|---|---|---|---|
llm-sft | text | 寫出標註者所寫的答案 | token F1 | 是,生成的答案會填入文本框 |
llm-sft | trajectory_edit | 把智慧體的步驟改寫成修正後的步驟 | closer_to_correction | 否,只儲存和打分 |
llm-dpo | binary 模式的 pairwise | 偏好標註者選擇的回覆 | 準確率,不計平局 | 是,被偏好回覆的卡片處於選中狀態 |
llm-dpo | trajectory_edit | 偏好修正後的步驟而非原始步驟 | closer_to_correction | 否,只儲存和打分 |
reward-model | pairwise(binary 和 scale)、ranking、bws | 每條回覆的得分 | 準確率、方向準確率、Kendall's tau 或最佳-最差準確率 | 是,作為方案自己的答案 |
prm-reward | process_reward | 對每個步驟給出正確、中性或錯誤的評分 | step_macro_f1 | 通過“AI pre-label steps”按鈕提供 |
開始之前
Potato 的訓練 extra 會為這四個訓練器安裝 PyTorch、Transformers 和 PEFT:
pip install "potato-annotation[train-llm]"
pip install "potato-annotation[train-text]"第一個 extra 覆蓋 llm-sft 和 llm-dpo,第二個覆蓋 reward-model 和 prm-reward。pip install "potato-annotation[train]" 一次安裝全部訓練 extra。缺少所需包的訓練器會在訓練頁面上列為“not installed”,並附上安裝這些包的命令。
每個訓練器在 train 劃分少於 20 個條目時都拒絕擬合(即 min_instances 參數)。預設劃分把 70% 的已標註條目放進 train,15% 放進 val,15% 放進 test,因此第一次執行之前要準備約 30 個已標註條目。val 和 test 條目留在訓練之外,用來給模型打分。
llm-sft 和 llm-dpo 從 Qwen/Qwen2.5-0.5B-Instruct 起步,reward-model 從 distilbert/distilroberta-base 起步,prm-reward 從 answerdotai/ModernBERT-base 起步。LLM 訓練器設計為在 GPU 上執行。執行 Potato 的機器沒有 GPU 時,遠端訓練會通過 ssh 把執行傳送到 GPU 伺服器,或傳送到 SLURM 叢集。
收集偏好和改寫的研究
第一個配置針對每條客服提示提出兩個問題。標註者從兩條回覆中選出更好的一條,並寫出標註者希望助手給出的答案。選擇用於訓練 llm-dpo 和 reward-model,書面答案用於訓練 llm-sft。data/answers.jsonl 的每一行包含一條提示和兩條回覆:
{"id": "q001", "prompt": "How do I reset my router to factory settings?", "responses": ["Hold the reset button on the back for 10 seconds until the lights blink, then wait two minutes for the router to restart.", "Routers can be reset. Check the manual."]}該配置把提示顯示為條目的文本,把兩條回覆顯示為卡片 A 和 B:
annotation_task_name: "Support answers: preferences and rewrites"
task_dir: .
data_files:
- data/answers.jsonl
item_properties:
id_key: id
text_key: prompt
output_annotation_dir: annotation_output
user_config:
allow_all_users: true
annotation_schemes:
- annotation_type: pairwise
name: preferred
description: "Which response answers the question better?"
mode: binary
items_key: responses
allow_tie: true
tie_label: "No preference"
- annotation_type: text
name: rewrite
description: "Write the answer you would want the assistant to give."
multiline: true
rows: 4
model_training:
enabled: true
writeback:
schemas: [preferred]
min_confidence: 0.7text_key: prompt 有兩重作用,因為提示既是標註者閱讀的內容,也是 llm-sft 放在問題之後的內容。items_key: responses 指明成對卡片所來自的列表,順序與資料中一致,因此 A 是第一條回覆。writeback.schemas 只列出 preferred,所以標註者看到的是模型的選擇,而不是生成的改寫。預標籤會錨定標註者,因此要等 llm-sft 執行的留出得分足以支援展示模型的文本之後,再把 rewrite 加進列表。min_confidence: 0.7 讓模型把握較小的預測不出現在頁面上,同時仍然儲存這些預測。啟動伺服器之前,先用 Potato 的驗證器檢查配置:
python -m potato.validate_cli config.yaml --strict啟動 Potato,至少標註 30 條提示,然後以管理員身份開啟 /admin/training。下面的執行也可以通過 API 啟動,把配置中的 admin_api_key 放在 $KEY 裡。
用 llm-sft 做監督微調
llm-sft 把每個已標註條目變成一個訓練樣本。提示是方案的 description(標註者看到的問題)加上條目的文本,目標是標註者寫下的答案。損失只覆蓋答案的 token,因此模型學的是作答,而不是複述提示。預設訓練 LoRA 介面卡,而不是訓練全部權重。
在訓練頁面上選擇 llm-sft 和 rewrite 方案,然後點選 Train now,或者通過 API 啟動同樣的執行:
curl -X POST -H "X-API-Key: $KEY" -H "Content-Type: application/json" \
http://localhost:8000/admin/training/api/runs \
-d '{"trainer": "llm-sft", "schemas": ["rewrite"], "params": {"max_new_tokens": 256}}'大多數執行只改動下表中的參數:
| 參數 | 預設值 | 含義 |
|---|---|---|
model_name | Qwen/Qwen2.5-0.5B-Instruct | Hugging Face Hub 上的因果語言模型,或本地目錄。 |
lora | true | false 訓練全部權重,需要數倍的記憶體。{quantize: 4bit} 以 4 位載入基礎模型(見 QLoRA)。 |
max_length | 1024 | 每個樣本的 token 數。過長的提示會丟失開頭的 token,答案則保留。 |
max_new_tokens | 256 | 模型生成的最長答案。 |
instruction | 方案的 description | 放在每個條目文本之前的文字。 |
system_prompt | 無 | 為帶聊天模板的模型提供的系統訊息。 |
gradient_checkpointing | false | 節省啟用記憶體,代價是多用約三分之一的時間。 |
learning_rate | 使用 LoRA 時 2e-4,不使用時 1e-5 |
執行會保留 val 損失最低的檢查點。由於執行是在 val 上選定檢查點的,留出得分取自 test。得分是 token F1,即生成答案與書面答案之間不計順序的詞重疊,精確匹配則與該得分一併報告。Token F1 會給詞對但位置錯的答案記分,因此要把兩個指標放在一起看。
模型會為每個 val 和 test 條目貪心地生成一個答案。設定 writeback.include_unlabeled: true 後,模型還會回答沒有人標註過的條目。預測的置信度是模型對其所生成 token 的平均機率,模型稽核佇列按這個置信度排序。把 rewrite 放進 writeback.schemas 後,標註者開啟條目時,生成的答案會填入文本框。
自由文本不太適合每個條目由多位標註者回答。aggregation 設定通過逐詞比較答案,把多個答案合併成一個,而兩個書面答案很少逐詞相同。對於 text 方案上的 llm-sft,每個條目只安排一位撰寫者,可以避免逐詞比較。
用 llm-dpo 做偏好調優
直接偏好最佳化(DPO)訓練 LLM 提高被偏好回覆相對於另一條回覆的似然,並以起始模型的凍結參考副本為基準。llm-dpo 從每個回答為 A 或 B 的條目構建一個樣本。提示是條目的 prompt 欄位,或條目所具有的 question、instruction、query、input 和 context 中的第一個。回答為平局選項的條目會被排除,因為平局並不表明哪條回覆更好。
選擇 llm-dpo 和 preferred 方案,或者傳送與上面相同的請求,只是改為 "trainer": "llm-dpo" 和 "schemas": ["preferred"]。使用預設的 LoRA 介面卡時,參考模型就是關閉介面卡的同一個模型,因此記憶體裡不需要第二份副本。lora: false 訓練全部權重,並保留一份凍結副本作為參考,凍結副本會使記憶體翻倍。
| 參數 | 預設值 | 含義 |
|---|---|---|
model_name | Qwen/Qwen2.5-0.5B-Instruct | 因果語言模型。 |
beta | 0.1 | 模型可以偏離參考多遠。取值越低,模型可以偏離得越遠。 |
epochs | 2 | |
learning_rate | 使用 LoRA 時 5e-5,不使用時 5e-7 | |
max_length | 1024 | 每條提示和回覆的 token 數。 |
instruction | 無 | 放在每個條目提示之前的文字。 |
執行會保留 val 上 DPO 損失最低的檢查點,執行日誌會報告模型在 val 上有多大比例偏好標註者的選擇。留出得分是 test 上的準確率,針對未回答為平局的條目,宏 F1 與準確率並列報告。預測是訓練後的模型所偏好的回覆,該偏好的機率作為置信度。作為預標籤,標註者開啟條目時,被偏好回覆的卡片處於選中狀態。方案設定了 randomize_order 時,選中狀態會跟隨該回復,出現在標註者看到該回復的位置。儲存下來的介面卡同樣是一個策略,用 PEFT 載入後可以生成文本。關於如何收集偏好資料本身的背景,見收集 RLHF 與偏好資料和成對比較。
用 reward-model 訓練獎勵模型
獎勵模型把一條回覆對映為一個數,可用於 RLHF、best-of-n 取樣,或為新輸出排序。reward-model 訓練一個只有一個輸出的 transformer,使標註者偏好的回覆得分更高。損失是 Bradley–Terry 損失,即 -log sigmoid(r_winner - r_loser),也就是 InstructGPT 的獎勵建模損失。上面的 preferred 方案不改動配置就能訓練 reward-model。每種比較型方案提供不同的訓練訊號:
| 方案 | 訓練訊號 | 留出主指標 |
|---|---|---|
pairwise,binary | 被選中的回覆勝過另一條。平局被跳過。 | 準確率 |
pairwise,scale | 滑塊偏向的一側獲勝,權重取決於滑塊偏離的程度。中點被跳過。 | 方向準確率 |
ranking | 整個順序,使用 Plackett-Luce 損失,或設定 ranking_loss: pairs 時使用順序中的每一對。 | Kendall's tau |
bws | 最佳條目勝過元組中的每個其他條目,其他每個條目都勝過最差條目。 | 最佳-最差準確率 |
條目有提示欄位時,每個獎勵都是針對給定提示的回覆。排序的選項是方案的標籤,每個選項都在給定條目文本的條件下打分。伺服器根據 bws_config 構建 BWS 元組,因此用伺服器自己的資料啟動的執行自帶元組,資料檔案不需要再提供元組。
| 參數 | 預設值 | 含義 |
|---|---|---|
model_name | distilbert/distilroberta-base | 編碼器,或帶 lora 的 LLM。 |
ranking_loss | plackett_luce | 只用於 ranking 方案:plackett_luce 或 pairs。 |
max_length | 512 | 每個被打分文本的 token 數,提示和回覆合計。 |
learning_rate | 2e-5,使用 LoRA 時 2e-4 |
預測回答的是方案自己的問題,因此這些預測像其他任何方案的預測一樣被打分和回寫。二選一的預標籤是被選中的卡片,量表的預標籤是滑塊位置,排序的預標籤是列表順序,BWS 的預標籤是被選中的最佳和最差項。每個預測還會儲存該預測所依據的 rewards。只有獎勵之間的差值才有意義。成對比較與最佳-最差標度比較了收集資料時各種比較型格式。
收集步驟評分和修正的研究
第二個配置處理智慧體軌跡。標註者給軌跡的每一步評分,然後修正錯誤的步驟。步驟評分用於訓練 prm-reward,修正用於訓練 llm-sft 或 llm-dpo。data/traces.jsonl 的每一行包含任務、智慧體的步驟和最終答案:
{"id": "traj_001", "task_description": "Find the current weather in San Francisco and report the temperature.", "steps": [{"thought": "I should look up the current weather.", "action": "web_search(queyr='San Francisco weather')"}, {"thought": "Open the first result.", "action": "open_url(results[0])"}, {"thought": "Read the temperature from the page.", "action": "extract_text('.temp')"}], "final_answer": "It is sunny."}訓練器按順序從條目的 task_description、task 或 text 欄位讀取任務:
annotation_task_name: "Agent traces: step ratings and corrections"
task_dir: .
data_files:
- data/traces.jsonl
item_properties:
id_key: id
text_key: task_description
output_annotation_dir: annotation_output
user_config:
allow_all_users: true
annotation_schemes:
- annotation_type: process_reward
name: step_quality
description: "Rate each step of the agent's trace"
steps_key: steps
step_text_key: action
mode: per_step
allow_neutral: true
ai_prelabel: true
- annotation_type: trajectory_edit
name: corrected_trace
description: "Fix the wrong steps, then correct the final answer"
steps_key: steps
step_text_key: action
editable_fields: [action]
show_diff: true
edit_final_answer: true
final_answer_key: final_answer
model_training:
enabled: true
writeback:
schemas: [step_quality]
include_unlabeled: truemode: per_step 加 allow_neutral: true 給出 prm-reward 所學習的三種評分。ai_prelabel: true 在方案上放一個“AI pre-label steps”按鈕,訓練得到的評分通過該按鈕出現。writeback.schemas 只指明 step_quality。把 corrected_trace 列在那裡會使伺服器無法啟動,驗證器會給出原因:
model_training.writeback.schemas names 'corrected_trace', a trajectory_edit scheme, which has no prelabel display: its predictions are stored and scored but annotators would never see them. Leave it out of writeback.schemas.用 llm-sft 和 llm-dpo 修復軌跡
trajectory_edit 的答案是一對軌跡,即智慧體的原始步驟和標註者修正之後的步驟。SFT/DPO 的軌跡編輯介紹編輯器,軌跡編輯博文介紹這些軌跡對如何變成訓練資料。兩個訓練器都會排除沒有人編輯過的軌跡。
llm-sft以任務和原始步驟作為提示,以修正後的步驟作為目標,因此模型學會修復軌跡。每一步寫成Step N加上該步驟的各欄位(action: ...、thought: ...),方案設定了final_answer_key時,最終答案跟在最後一步之後。llm-dpo以任務作為提示,以修正後的步驟作為被偏好的回覆,以原始步驟作為另一條回覆。預測說明模型偏好修正(A)還是原始版本(B),並且只針對有修正的留出軌跡作出。
兩種執行都把 closer_to_correction 作為留出得分報告。對 llm-dpo,該得分是模型偏好修正的留出軌跡所佔的比例。對 llm-sft,該得分是按 token F1 衡量,所寫步驟比起原始版本更接近修正版本的軌跡所佔的比例,針對修正版本的 token_f1 與該得分並列報告。
trajectory_edit 執行的預測會被儲存和打分,標註者看不到這些預測。編輯器總是從智慧體的原始軌跡開始,所以頁面沒有地方展示預測的改寫。請從執行頁面,或從執行目錄中的 artifacts/predictions.jsonl 讀取這些預測。
用 prm-reward 給步驟評分
過程獎勵模型對軌跡的各個步驟打分,而不只是對最終答案打分,做法見 PRM800K。prm-reward 把整條軌跡作為一個輸入送入 transformer 編碼器,即任務後接 Step 1、Step 2 等。編碼器在每個步驟的最後一個 token 處學習三類評分,因此每個評分都是在能看到該步驟之前各步驟的情況下作出的。沒有人評分的步驟不計入損失。預設模型 answerdotai/ModernBERT-base 是因其 8,192 個 token 的上下文而選定的。
| 參數 | 預設值 | 含義 |
|---|---|---|
model_name | answerdotai/ModernBERT-base | 帶快速分詞器的編碼器。 |
max_length | 1024 | 每條軌跡的 token 數。 |
epochs | 6 | |
batch_size | 8 | 每步的軌跡數。 |
learning_rate | 5e-5,使用 LoRA 時 3e-4 |
長軌跡會丟失最後的步驟。超過 max_length 個 token 的軌跡從末尾截斷,截斷點之後的步驟既不參與訓練,也不被評分。執行日誌會統計丟失的步驟數。當 max_length 超過模型所能容納的長度時,執行會把 max_length 降到模型的上限並給出警告,大多數 BERT 類編碼器的上限是 512 個 token。執行日誌報告有步驟丟失時,請調高 max_length,並選擇上下文能容納更長軌跡的模型。
留出得分是 step_macro_f1,即所有已評分步驟上三類評分的宏 F1。大多數軌跡中的大多數步驟是正確的,所以準確率會美化一個從不說“錯誤”的模型。執行還會報告 step_accuracy 和 first_error_accuracy,後者是模型的第一個錯誤步驟恰好是標註者的第一個錯誤步驟的軌跡所佔的比例。
預測會為每個能放進 max_length 的步驟評分,每個評分的機率作為該評分的置信度,最不確定的步驟的置信度作為該軌跡的置信度。方案列在 writeback.schemas 中並且設定了 ai_prelabel: true 時,“AI pre-label steps”按鈕會提供訓練得到的評分供標註者核對。對於已有訓練評分的條目,不會呼叫 ai_support 下配置的 LLM 評判器。過程獎勵標註介紹該方案,過程獎勵模型指南介紹資料。
用 QLoRA 裝下更大的模型
QLoRA 以 4 位載入基礎模型的權重,並在其上訓練 LoRA 介面卡。llm-sft、llm-dpo、hf-text-classification、vlm-sft 和 reward-model 接受 lora: {quantize: 4bit},prm-reward 會在載入模型之前拒絕該設定。請根據每次 transformer 執行在結束時記錄的“Peak GPU memory”一行來規劃記憶體。配置參考的 QLoRA 一節說明基礎權重如何載入以及 8 位選項。
把下面這個塊加進上面的配置,即可把 QLoRA 設為 llm-sft 的預設設定:
model_training:
enabled: true
trainer_params:
llm-sft:
model_name: Qwen/Qwen2.5-7B-Instruct
lora: {quantize: 4bit}
gradient_checkpointing: trueQLoRA 需要 CUDA GPU,以及與該機器的 CUDA 匹配的 bitsandbytes 構建,用 pip install bitsandbytes 安裝。沒有可用的 GPU 或構建時,執行會在載入模型之前於驗證階段停下。
把執行釋出到 Hugging Face Hub
模型位於 Potato 伺服器上的成功執行,在執行頁面上有 Publish to the Hugging Face Hub。推送會上傳模型,以及根據該執行寫成的 README.md 模型卡,其中包含訓練器、基礎模型和介面卡、方案和標籤、劃分大小、留出得分及其衡量物件,以及執行和 bundle 的 id。LoRA 執行只儲存了介面卡,因此 Hub 倉庫裡放的是介面卡,模型卡會指明要把介面卡載入到哪個基礎模型上。
令牌不會出現在瀏覽器中。在 Hugging Face 設定中建立寫入令牌,並在啟動 Potato 之前把令牌放進伺服器的環境:
export HF_TOKEN=hf_your_write_token
potato start config.yaml表單會指明環境變數(預設為 HF_TOKEN),要求輸入兩次倉庫名,並預設勾選 Private。釋出到 Hugging Face Hub列出會上傳的檔案、推送前的檢查,以及模型卡上的許可證。通過 API 進行同樣的推送:
curl -X POST -H "X-API-Key: $KEY" -H "Content-Type: application/json" \
http://localhost:8000/admin/training/api/runs/RUN_ID/push-to-hub \
-d '{"repo_id": "your-org/support-dpo", "confirm_repo_id": "your-org/support-dpo", "private": true, "licence": "apache-2.0"}'該路由返回 201 和提交資訊。留在遠端主機上且設定了 fetch_artifacts: false 的模型無法從 Potato 伺服器推送,執行頁面會說明模型在哪裡。要從已釋出的模型繼續進入主動學習迴圈,請接著看迴圈中的模型。
延伸閱讀
- 模型訓練配置:每個
model_training鍵、留出得分、回寫和路由。 - 訓練器:全部 38 個訓練器,按任務分組。
- 遠端訓練:通過 ssh 連線的 GPU 伺服器、SLURM 叢集和輪詢智慧體。
- 智慧體軌跡標註:在 Potato 中收集軌跡資料。
- 上游參考小節:
llm-sft、llm-dpo、智慧體軌跡、prm-reward、reward-model、QLoRA和 Hub 釋出。
參考文獻
- Dettmers, T., Pagnoni, A., Holtzman, A., and Zettlemoyer, L. (2023). QLoRA: Efficient Finetuning of Quantized LLMs. arXiv:2305.14314. arxiv.org/abs/2305.14314
- Hu, E. J., Shen, Y., Wallis, P., Allen-Zhu, Z., Li, Y., Wang, S., Wang, L., and Chen, W. (2021). LoRA: Low-Rank Adaptation of Large Language Models. arXiv:2106.09685. arxiv.org/abs/2106.09685
- Lightman, H., Kosaraju, V., Burda, Y., Edwards, H., Baker, B., Lee, T., Leike, J., Schulman, J., Sutskever, I., and Cobbe, K. (2023). Let's Verify Step by Step. arXiv:2305.20050. arxiv.org/abs/2305.20050
- Ouyang, L., Wu, J., Jiang, X., Almeida, D., Wainwright, C. L., Mishkin, P., Zhang, C., Agarwal, S., Slama, K., Ray, A., Schulman, J., Hilton, J., Kelton, F., Miller, L., Simens, M., Askell, A., Welinder, P., Christiano, P., Leike, J., and Lowe, R. (2022). Training Language Models to Follow Instructions with Human Feedback. arXiv:2203.02155. arxiv.org/abs/2203.02155
- Rafailov, R., Sharma, A., Mitchell, E., Ermon, S., Manning, C. D., and Finn, C. (2023). Direct Preference Optimization: Your Language Model is Secretly a Reward Model. arXiv:2305.18290. arxiv.org/abs/2305.18290