大模型三階段訓練方法(LLaMa Factory) 原創
前言
本章我們將通過 LLaMA-Factory 具體實踐大模型訓練的三個階段,包括:預訓練、監督微調和偏好糾正。
大模型訓練回顧
訓練目標
訓練一個醫療大模型
訓練過程實施
準備訓練框架
??LLaMA Factory?
?是一款開源低代碼大模型微調框架,集成了業界最廣泛使用的微調技術,支持通過Web UI界面零代碼微調大模型,目前已經成為開源社區內最受歡迎的微調框架,GitHub星標超過2萬。
運行環境要求
- ?硬件:
- GPU:推薦使用24GB顯存的顯卡或者更高配置
- 軟件:
- python:3.10
- pytorch:2.1.2 + cuda12.1
- 操作系統:Ubuntu 22.04
推薦選擇DSW官方鏡像:?
?modelscope:1.14.0-pytorch2.1.2-gpu-py310-cu121-ubuntu22.04?
?
下載訓練框架
第一步:登錄ModelScope平臺,啟動PAI-DSW的GPU環境,并進入容器。
第二步:在容器中,通過命令行拉取代碼。
# 拉取代碼
git clone --depth 1 https://github.com/hiyouga/LLaMA-Factory.git
# 進入代碼目錄
cd LLaMA-Factory
# 安裝依賴
pip install -e ".[torch,metrics]"
第三步:檢查環境是否安裝成功。
llamafactory-cli version
正常安裝成功顯示如下:
- 如果安裝不成功,需要根據提示信息進行逐個問題解決。
- 一般情況下,在ModelScope平臺中,一般會出現?
?Keras?
?? 版本不匹配的問題,可以運行??pip install tf-keras?
?解決。
第四步:進行端口映射命令 由于阿里云平臺的端口映射似乎存在問題,這會導致啟動LLaMA Factory的Web界面顯示異常,所以需要手動在命令行運行如下命令:
export GRADIO_SERVER_PORT=7860 GRADIO_ROOT_PATH=/${JUPYTER_NAME}/proxy/7860/
第五步:命令行下運行命令,啟動WebUI界面
llamafactory-cli webui
啟動后,點擊返回信息中的http://0.0.0.0:7860,可以看到Web界面。
準備訓練模型
選擇模型
在開展大模型訓練之前,由于我們不能從零開始訓練一個大模型(時間及資源都不允許!),所以我們需要選擇一個已經訓練好的模型,作為基礎模型進行訓練。
在ModelScope平臺,我們選擇??Qwen2-0.5B?
?模型作為底座模型。
下載模型
第一步:拉取代碼
git clone https://www.modelscope.cn/qwen/Qwen2-0.5B.git
第二步:在??LLaMA-Factory?
?下創建models目錄,方便后續模型都維護在該目錄下。
第三步:移動模型目錄到??LLaMA-Factory?
??的??models?
?目錄下。
LLaMA-Factory/
|-models/
|-Qwen2-0.5B/
驗證模型
第一步:在??LLaMA-Factory?
?的WebUI界面,進行相關配置。
- Model name:?
?Qwen2-0.5B?
? - Model path:?
?models/Qwen2-0.5B?
?
?
?models/Qwen2-0.5B?
?? 對應 ??下載模型?
? 第三步中的路徑。由于Linux系統是大小寫敏感,所以需要特別注意頁面配置路徑與實際路徑大小寫要保持一致。
第二步:切換Tab為 ??Chat?
?? , 點擊 ??Load model?
?按鈕。 模型加載成功后,會顯示如下界面。
如果出現錯誤,可以通過切換到啟動?
?LLaMA Factory?
?的命令行查看日志信息排查問題。
第三步:在Chat的對話框中,輸入簡單信息驗證模型能否使用。
由于當前加載的?
?Qwen2-0.5B?
?是一個基礎模型,所以其對話能力會非常弱,這里我們主要是驗證模型加載的整體流程是否通順。
第1階段:預訓練
?由于大模型的預訓練需要數千個GPU并持續數月的時間,所以一般情況下實際工作中并不會涉及到預訓練,本篇文章我們只做的簡單流程體驗。
準備訓練數據
說明:LLaMa-Factory的Github上有訓練數據格式的詳細說明,請見README_zh。
- 預訓練數據格式:?
?[
?
{"text": "document"},
{"text": "document"}
]? - 數據集樣例:
按照數據集樣例,我們準備如下的自定義預訓練數據集,保存到??data/custom_pt_train_data.json?
?。
[
{"text":"患者在過去的五年中多次出現頭痛癥狀。"},
{"text":"研究表明,適量運動有助于改善心血管健康。"},
{"text":"高血壓患者需定期監測血壓水平。"},
{"text":"糖尿病患者應注意飲食控制和胰島素使用。"},
{"text":"流感疫苗每年接種可以有效預防流感。"},
{"text":"保持良好的睡眠習慣對心理健康至關重要。"},
{"text":"慢性咳嗽可能是肺部疾病的早期征兆。"},
{"text":"定期體檢可以幫助早期發現健康問題。"},
{"text":"心理咨詢對緩解焦慮和抑郁癥狀有效。"},
{"text":"飲食中增加纖維素有助于消化系統健康。"},
{"text":"適量飲水對維持身體正常功能非常重要。"},
{"text":"戒煙可以顯著降低患肺癌的風險。"},
{"text":"高膽固醇水平可能導致心臟病。"},
{"text":"保持健康體重有助于降低多種疾病風險。"},
{"text":"心理健康與身體健康密切相關。"},
{"text":"兒童應定期進行視力和聽力檢查。"},
{"text":"老年人易患骨質疏松癥,需注意補鈣。"},
{"text":"過度飲酒會對肝臟造成嚴重損害。"},
{"text":"心臟病患者應遵循醫生的治療方案。"},
{"text":"良好的飲食習慣可以改善生活質量。"},
{"text":"運動可以幫助減少壓力和焦慮。"},
{"text":"戒煙后,肺部功能會逐漸恢復。"},
{"text":"高血糖可能導致多種并發癥。"},
{"text":"定期鍛煉有助于提高免疫力。"},
{"text":"適量的社交活動可以提高生活滿意度。"},
{"text":"健康的生活習慣可以改善整體健康狀況。"},
{"text":"心理健康教育應引起全社會的重視。"}
]
注冊自定義數據
根據LLaMa-Factory的README,我們需要在??dataset_info.json?
?中按照以下格式注冊自定義的數據集。
- 數據集注冊格式:?
?"數據集名稱": {
?
"file_name": "data.json",
"columns": {
"prompt": "text"
}
}?
我們在??data/dataset_info.json?
?中添加如下數據集:
"custom_pt_train_data": {
"file_name": "custom_pt_train_data.json",
"columns": {
"prompt": "text"
}
}
預覽訓練數據
在 LLaMa-Factory的WebUI界面上,選擇Dataset為 ??custom_pt_train_data?
??,點擊??Preview dataset?
?按鈕,預覽數據集。
配置訓練參數
- Model name:?
?Qwen2-0.5B?
? - Model path:?
?models/Qwen2-0.5B?
? - Finetuning method:?
?full?
? - Stage :?
?Pre-Training?
? - Dataset:?
?custom_pt_train_data?
?? ,??c4_demo?
??,??wikipedia_zh?
? - Output dir:?
?Qwen2_pretrain_output_demo1?
?
參數簡要說明:
- ?
?Finetuning method?
?代表微調的方法:
??full?
?: 完全微調模型的所有參數。
??Freeze?
?:凍結模型的某些層或所有層,僅微調特定的參數。
??LoRA (Low-Rank Adaptation)?
?:在不改變原始模型參數的情況下,通過添加少量的可訓練參數來適應新任務。
- ?
?Stage?
? 代表訓練的階段: - ?
?Pre-Training?
?: 預訓練階段。 - ?
?Supervised Fine-Tuning?
?: 微調階段。 - ?
?Reward Model?
?: 獎勵模型是一個過程,通過構建一個模型來預測給定輸入的獎勵值,通過訓練獎勵模型,可以為后續的強化學習提供一個目標。 - ?
?PPO (Proximal Policy Optimization)?
?: PPO是一種強化學習算法,旨在優化策略(即模型的行為),以最大化預期獎勵。 - ?
?DPO (Direct Preference Optimization)?
?: DPO是一種直接優化偏好的方法,通常用于根據人類反饋直接調整模型的輸出。 - ?
?KTO (Knowledge Transfer Optimization)?
?: KTO指的是知識遷移優化,旨在從一個任務或模型中遷移知識到另一個任務或模型。
啟動訓練
點擊??Preview Command?
??預覽命令行無誤后,點擊??Start?
?即可開啟訓練。
如果啟動訓練失敗,可以通過切換到啟動?
?LLaMA Factory?
?的命令行查看日志信息排查問題。 例如:我首次啟動時報錯如下:
# ConnectionError: Couldn't reach 'pleisto/wikipedia-cn-20230720-filtered' on the Hub (ConnectionError)
這個問題是因為加載wikipedia-cn-20230720-filtered數據集時,由于網絡問題,導致無法加載。因此,本著將訓練流程跑通,我將數據集改為?
?wiki_demo?
?后運行,即可正常訓練。
正常訓練過程:
第2階段:監督微調
準備訓練數據
??SFT?
? 的數據格式有多種,例如:Alpaca格式、OpenAI格式等。
其中Alpaca格式如下:
[
{
"instruction":"human instruction (required)",
"input":"human input (optional)",
"output":"model response (required)",
"system":"system prompt (optional)",
"history":[
["human instruction in the first round (optional)","model response in the first round (optional)"],
["human instruction in the second round (optional)","model response in the second round (optional)"]
]
}
]
根據以上的數據格式,我們在ModelScope的數據集找到中文醫療對話數據-Chinese-medical-dialogue符合上述格式。
# 在data目錄下使用git命令拉取數據集
git clone https://www.modelscope.cn/datasets/xiaofengalg/Chinese-medical-dialogue.git
注冊自定義數據
在??dataset_info.json?
?中添加如下數據集:
"custom_sft_train_data":{
"file_name":"Chinese-medical-dialogue/data/train_0001_of_0001.json",
"columns":{
"prompt":"instruction",
"query":"input",
"response":"output"
}
},
預覽訓練數據
通過??Preview dataset?
?按鈕預覽數據集。
配置訓練參數
- Model name:?
?Qwen2-0.5B?
? - Model path:?
?saves/Qwen2-0.5B/full/Qwen2_pretrain_output_demo1?
? - Finetuning method:?
?full?
? - Stage :?
?Supervised Fine-Tuning?
? - Dataset:?
?custom_sft_train_data?
? - Output dir:?
?Qwen2_sft_output_demo1?
?
配置參數說明:
- ?
?Model path?
?:我們選擇第1階段預訓練模型的輸出目錄。 - ?
?Stage?
??:這一階段,因為我們要進行微調,選擇??Supervised Fine-Tuning?
?。 - ?
?Output dir?
??: 更換一個新的輸出路徑,以便后續開展第3階段訓練,例如:??Qwen2_sft_output_demo1?
?
啟動訓練
點擊??Preview Command?
?預覽命令行
llamafactory-cli train
--stage sft
--do_train True
--model_name_or_path saves/Qwen2-0.5B/full/Qwen2_pretrain_output_demo1
--preprocessing_num_workers 16
--finetuning_type full
--template default
--flash_attn auto
--dataset_dir data
--dataset custom_sft_train_data
--cutoff_len 1024
--learning_rate 5e-05
--num_train_epochs 3.0
--max_samples 100000
--per_device_train_batch_size 2
--gradient_accumulation_steps 8
--lr_scheduler_type cosine
--max_grad_norm 1.0
--logging_steps 5
--save_steps 100
--warmup_steps 0
--optim adamw_torch
--packing False
--report_to none
--output_dir saves/Qwen2-0.5B/full/Qwen2_sft_output_demo1
--bf16 True
--plot_loss True
--ddp_timeout 180000000
--include_num_input_tokens_seen True
補充說明:
- ?
?--logging_steps 5?
?: 每 5 步記錄一次訓練日志。 - ?
?--save_steps 100?
?: 每 100 步保存一次模型檢查點。
這里最好將?
?save_steps?
? 設置大一點,否則訓練過程會生成非常多的訓練日志,導致硬盤空間不足而訓練終止。
命令行確認無誤后,點擊??Start?
?即可開啟訓練。
訓練過程中,記得實時關注資源的消耗情況:
- 顯存:使用?
?watch -n 1 nvidia-smi?
? 實時查看顯存開銷。- 硬盤:使用?
?watch -n 1 df -h /mnt?
? 實施查看/mnt分區的磁盤使用情況。
歷時5小時30分鐘后,模型終于訓練完畢。(大模型的訓練果然是一個燒錢??的過程)
驗證模型
- 在LLaMA Factory的WebUI界面上,切換至?
?Chat?
?界面 - Model path: 輸入剛才訓練模型的輸出目錄,即?
?saves/Qwen2-0.5B/full/Qwen2_sft_output_demo1?
? - 其他配置保持默認不變;
- 點擊?
?Load model?
?,待模型加載成功后,輸入看病相關的信息,測試模型的能力。
第3階段:偏好糾正
準備訓練數據
- 糾正偏好數據格式:?
?[
??按照上述數據格式,我們借助其他的大模型生成20條訓練數據并保存到?
{
"instruction": "human instruction (required)",
"input": "human input (optional)",
"chosen": "chosen answer (required)",
"rejected": "rejected answer (required)"
}
]??data/custom_rlhf_train_data.json?
??。??[
?
{
"instruction":"請提供一種常見的感冒藥。",
"input":"我需要一種能緩解咳嗽的藥。",
"chosen":"感冒藥如對乙酰氨基酚可以緩解癥狀。",
"rejected":"我不知道有什么藥。"
},
{
"instruction":"解釋一下高血壓的危害。",
"input":"高血壓對身體有什么影響?",
"chosen":"高血壓會增加心臟病和中風的風險。",
"rejected":"高血壓沒什么大不了的。"
},
{
"instruction":"推薦一種健康的飲食習慣。",
"input":"我想減肥,應該吃什么?",
"chosen":"建議多吃水果和蔬菜,減少糖分攝入。",
"rejected":"只吃沙拉就可以了。"
},
{
"instruction":"描述糖尿病的癥狀。",
"input":"糖尿病有什么明顯的癥狀?",
"chosen":"常見癥狀包括口渴、頻繁排尿和疲勞。",
"rejected":"沒有什么特別的癥狀。"
},
{
"instruction":"如何預防流感?",
"input":"我應該怎么做才能不得流感?",
"chosen":"接種流感疫苗和勤洗手是有效的預防措施。",
"rejected":"只要不出門就行了。"
},
{
"instruction":"解釋一下心臟病的風險因素。",
"input":"心臟病的危險因素有哪些?",
"chosen":"包括高血壓、高膽固醇和吸煙。",
"rejected":"心臟病與生活方式無關。"
},
{
"instruction":"如何緩解焦慮?",
"input":"我感到很焦慮,有什么建議?",
"chosen":"嘗試深呼吸練習和規律鍛煉。",
"rejected":"焦慮沒什么好擔心的。"
},
{
"instruction":"推薦一些適合老年人的鍛煉方式。",
"input":"老年人適合什么運動?",
"chosen":"散步、游泳和太極都是很好的選擇。",
"rejected":"老年人不需要運動。"
},
{
"instruction":"解釋什么是過敏反應。",
"input":"過敏反應是什么?",
"chosen":"是免疫系統對某些物質的異常反應。",
"rejected":"過敏反應就是感冒。"
},
{
"instruction":"如何保持心理健康?",
"input":"我應該怎么照顧自己的心理健康?",
"chosen":"定期與朋友交流和尋求專業幫助是很重要的。",
"rejected":"心理健康不重要。"
},
{
"instruction":"描述高膽固醇的影響。",
"input":"高膽固醇對身體有什么影響?",
"chosen":"可能導致動脈硬化和心臟病。",
"rejected":"高膽固醇沒什么影響。"
},
{
"instruction":"如何識別抑郁癥?",
"input":"抑郁癥的癥狀有哪些?",
"chosen":"包括持續的悲傷、失去興趣和疲憊感。",
"rejected":"抑郁只是心情不好。"
},
{
"instruction":"建議如何提高免疫力。",
"input":"我想增強免疫力,有什么建議?",
"chosen":"保持均衡飲食、充足睡眠和適量運動。",
"rejected":"吃藥就能提高免疫力。"
},
{
"instruction":"講解什么是癌癥篩查。",
"input":"癌癥篩查是什么?",
"chosen":"是通過檢測早期發現癌癥的過程。",
"rejected":"癌癥篩查沒必要。"
},
{
"instruction":"如何處理壓力?",
"input":"我壓力很大,怎么辦?",
"chosen":"可以嘗試冥想和時間管理技巧。",
"rejected":"壓力是正常的,不必處理。"
},
{
"instruction":"解釋什么是肥胖。",
"input":"肥胖是什么?",
"chosen":"是體重超過健康范圍的狀態,通常由多種因素造成。",
"rejected":"肥胖只是吃得多。"
},
{
"instruction":"如何進行健康檢查?",
"input":"健康檢查包括什么?",
"chosen":"通常包括體檢、血液檢查和必要的影像學檢查。",
"rejected":"健康檢查不重要。"
},
{
"instruction":"推薦一些抗氧化的食物。",
"input":"哪些食物富含抗氧化劑?",
"chosen":"藍莓、堅果和綠茶都是很好的選擇。",
"rejected":"抗氧化食物沒什么特別。"
},
{
"instruction":"解釋什么是慢性病。",
"input":"慢性病是什么?",
"chosen":"是長期存在且通常無法完全治愈的疾病。",
"rejected":"慢性病就是普通病。"
}
]?
注冊自定義數據
在??dataset_info.json?
??中,注冊新添加的??custom_rlhf_train_data.json?
?數據集。
"custom_rlhf_train_data":{
"file_name":"custom_rlhf_train_data.json",
"ranking":true,
"columns":{
"prompt":"instruction",
"query":"input",
"chosen":"chosen",
"rejected":"rejected"
}
},
配置訓練參數
第三階段有兩種訓練方式:??Reward Model?
?? + ??PPO?
?? 和 ??DPO?
?,這兩種方式我們都做一下嘗試。
策略1:??Reward Model?
?? + ??PPO?
?
第一步:先訓練Reward Model
- Finetuning method: 選擇?
?lora?
?? (因為是訓練補丁,所以此處一定要選擇為??lora?
?) - Stage: 選擇?
?Reward Modeling?
? - Dataset: 選擇剛才上傳?
?custom_rlhf_train_data.json?
? - Output dir:設置一個新的輸出目錄,例如:?
?Qwen2_rm_output_demo1?
?
訓練完畢后,會在save下生成一個補丁。
第二步:通過??PPO?
??+第一步訓練時的??Reward Model?
?,具體配置方法為:
- Finetuning method: 選擇?
?lora?
?? (因為是訓練補丁,所以此處一定要選擇為??lora?
?) - Stage: 選擇?
?Supervised Fine-tuning?
? - Dataset: 由于這一過程本質是?
?SFT?
??訓練,所以數據集選擇??custom_sft_train_data.json?
?。 - Reward model: 在?
?RLHF configurations?
??中,設置為第一步訓練的輸出目錄,即??Qwen2_rm_output_demo1?
? - Output dir:設置一個新的輸出目錄,例如:?
?Qwen2_ppo_output_demo1?
?
訓練完畢后,同樣會在save下生成一個補丁。
第三步:將Lora補丁與原始模型合并導出
- 切換到?
?Chat?
?標簽下 - Model path: 選擇第二階段的輸出,即:?
?saves/Qwen2-0.5B/full/Qwen2_sft_output_demo1?
? - Checkpoint path: 選擇上面第二步的輸出,即?
?Qwen2_ppo_output_demo1?
? - 點擊?
?Load model?
?,待模型加載成功后,測試模型 - 切換至?
?Export?
?標簽下 - Export path:設置一個新的路徑,例如?
?Qwen2_final_output_demo1?
? - 點擊?
?Export?
?按鈕
最終,會在LLaMa Factory中,生成導出的目錄文件,該文件即為最終訓練的模型。
策略2:直接使用??DPO?
?訓練
第一步:直接配置??DPO?
?訓練參數
- Finetuning method: 選擇?
?lora?
? - Stage: 選擇?
?DPO?
? - Dataset: 選擇剛才上傳?
?custom_rlhf_train_data.json?
? - Output dir:設置一個新的輸出目錄,例如:?
?Qwen2_dpo_output_demo1?
?
訓練完畢后,會在save下生成一個補丁。
第二步:將Lora補丁與第二階段訓練的模型輸出合并導出。(該步驟與上面策略1的方法類似,此處不再贅述)
至此,經過大模型的三個階段,我們完成了一個醫療大模型的訓練。
附錄
TeleChat-PTD數據集
如果涉及到從零開始訓練大模型的話,預訓練數據集可以參考了解 ??TeleChat-PTD?
? 數據集。
數據集簡介:
- TeleChat-PTD是由電信星辰大模型TeleChat預訓練語料中抽取出的的綜合性大規模中文數據集。
- 數據集地址:https://modelscope.cn/datasets/TeleAI/TeleChat-PTD
- 數據集規模:2.7億
- 數據集類型:純中文文本構成
- 數據集來源:網頁、書籍、官方媒體等
- 數據集大小:原始大小約1TB,壓縮后480G,共189個文件。
數據集特點:
- 該數據集是以?
?JSON Lines?
?? 格式??(.jsonl)?
?存儲的,每一行都是一個獨立的 JSON 對象。 - 每個?
?JSON?
?? 對象包含一個鍵為??"data"?
?? 的字段:??{
?
"data": "文本內容"
}?
數據集內容預覽:
內容小結
- LLaMA-Factory是一個開源的、可自定義的、可擴展的、可部署的、可訓練的大模型訓練平臺。
- LLaMA-Factory的訓練流程分為3個階段:預訓練、監督微調、偏好糾正。
- 訓練過程的大致步驟為:
1.按照LLaMA-Factory官方README文檔的數據格式,準備訓練數據;
2.按照LlaMA-Factory官方README文檔,在的dataset_info.json文件,注冊自定義數據;
3.根據訓練階段配置訓練參數,包括模型名稱、模型路徑、訓練方法、數據集、輸出目錄等;
4.預覽訓練命名無誤后,啟動訓練。
5.如果啟動訓練失敗,可以通過切換到啟動??LLaMA Factory?
?的命令行查看日志信息排查問題。
本文轉載自公眾號一起AI技術 作者:熱情的Dongming
