自我認知微調
我們期望微調後的大模型是專屬於我們自己的。比如詢問大模型是誰或由誰訓練的,大模型應當回覆是由我們訓練的。可以使用自我認知微調來實現這一點。自我認知微調與之前實踐過的全參微調和LoRA微調並沒有本質上的區別,我們既可以使用任意的微調方式來實現自我認知微調。區別在於,自我認知微調需要使用專門製作的自我認知資料集,並且往往需要混合一部分通用領域/垂直領域的資料集。混合資料集的原因是為了儘可能防止模型在進行自我認知學習的過程中遺忘掉之前的知識。
在進行以下步驟之前,請先根據全參微調或LoRA微調配置好環境。
編寫自我認知微調指令碼
以下是一個使用LoRA進行自我認知微調的指令碼:
nproc_per_node=8
CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 \
NPROC_PER_NODE=$nproc_per_node \
MASTER_PORT=29500 \
swift sft \
--model_type qwen1half-14b-chat \
--model_id_or_path /yldm0226/models/Qwen1.5-14B-Chat \
--model_revision master \
--sft_type lora \
--tuner_backend swift \
--template_type qwen \
--dtype AUTO \
--output_dir /yldm0226/llm_sft_output \
--ddp_backend nccl \
--custom_train_dataset_path /yldm0226/data/8-DISC-Med-SFT_released.jsonl \
--train_dataset_sample 1000 \
--num_train_epochs 3 \
--max_length 4096 \
--check_dataset_strategy warning \
--lora_rank 8 \
--lora_alpha 32 \
--lora_dropout_p 0.05 \
--lora_target_modules ALL \
--gradient_checkpointing true \
--batch_size 1 \
--weight_decay 0.01 \
--learning_rate 1e-5 \
--max_grad_norm 0.5 \
--warmup_ratio 0.4 \
--eval_steps 10 \
--save_steps 10 \
--save_total_limit 2 \
--logging_steps 5 \
--self_cognition_sample 500 \
--model_name 扁倉 BianCang \
--model_author 齊魯工業大學\(山東省科學院\)電腦科學與技術學部自然語言處理與認知計算研究組 QLU-NLP Research Group
該指令碼中的大部分引數已經在全參微調或LoRA微調介紹過了,此處我們只看與自我認知微調相關的幾個引數:
model_name
:模型的名字,第一個引數是模型中文名,第二個引數是模型英文名,兩個引數用一個空格分隔。
model_author
:模型的作者,第一個引數是模型作者中文名,第二個引數是模型作者英文名,兩個引數用一個空格分隔。
self_cognition_sample
:自我認知資料集的取樣數,這個引數代表著我們將從SWIFT提供的自我認知資料集中抽取多少條資料用於自我認知微調。設定合理的自我認知資料集取樣數是很重要的,這能夠使模型在儘可能保留原有知識的前提下進行自我認知的學習。因此,在實際訓練時,我們需要根據情況調整訓練資料量與自我認知資料量之間的比例。此外,根據我的實踐經驗,如果你使用的是LoRA的微調方式,在進行完知識訓練後,又想單獨進行自我認知微調,這是不推薦的,這大機率會使模型出現災難性遺忘的問題。我推薦的方式是:對訓練資料集和自我認知資料集進行合理的混合配比,然後進行全參或LoRA微調。
lora_target_modules
:根據SWIFT官方的實踐經驗,自我認知訓練涉及到知識編輯,他們建議對mlp加lora_target_modules。你可以透過指定--lora_target_modules為all,以在所有的linear層(包括qkvo以及mlp)加lora。這通常是效果最好的。如果你使用的是全參微調的方式,忽略該引數。
測試自我認知微調的效果
分別測試自我認知微調前的模型和自我認知微調後的模型對下面這兩個問題的回覆:
- 你是誰?
- 你是由誰開發的?
自我認知微調前的效果
使用以下命令啟動CLI推理:
CUDA_VISIBLE_DEVICES=0 swift infer --model_type qwen1half-14b-chat --model_id_or_path /yldm0226/models/Qwen1.5-14B-Chat
以下是模型的回覆:
<<< 你是誰?
我是通義千問,是阿里雲研發的AI助手,專注於提供資訊、解答問題和進行多輪對話。我在這裡是為了幫助使用者,有什麼可以幫到你的?
<<< 你是由誰開發的?
我是由阿里巴巴集團自主研發的。
自我認知微調後的效果
在訓練結束後,我們可以在日誌輸出中看到以下資訊:
[INFO:swift] last_model_checkpoint: /yldm0226/llm_sft_output/qwen1half-14b-chat/v22-20240308-092709/checkpoint-282
[INFO:swift] best_model_checkpoint: /yldm0226/llm_sft_output/qwen1half-14b-chat/v22-20240308-092709/checkpoint-280
可以知道驗證效果最好的模型檢查點位於/yldm0226/llm_sft_output/qwen1half-14b-chat/v22-20240308-092709/checkpoint-280
。
由於我們使用的是LoRA的微調方法,所以在推理前要先將LoRA增量權重與原大模型的權重進行合併:
CUDA_VISIBLE_DEVICES=0 swift export --model_cache_dir /yldm0226/models/Qwen1.5-14B-Chat\
--ckpt_dir '/yldm0226/llm_sft_output/qwen1half-14b-chat/v22-20240308-092709/checkpoint-280' --merge_lora true
其中,ckpt_dir
是LoRA增量權重的存放路徑,model_cache_dir
是原大模型權重的存放路徑。
權重合並後,可以看到以下資訊:
[INFO:swift] Saving merged weights...
[INFO:swift] Successfully merged LoRA and saved in /yldm0226/llm_sft_output/qwen1half-14b-chat/v22-20240308-092709/checkpoint-280-merged.
[INFO:swift] End time of running main: 2024-03-08 10:27:08.848387
可以在/yldm0226/llm_sft_output/qwen1half-14b-chat/v22-20240308-092709/checkpoint-280-merged路徑下找到合併後的權重。
接下來使用以下命令啟動CLI推理:
CUDA_VISIBLE_DEVICES=0 swift infer --model_type qwen1half-14b-chat --ckpt_dir /yldm0226/llm_sft_output/qwen1half-14b-chat/v22-20240308-092709/checkpoint-280-merged
以下是模型的回覆:
<<< 你是誰?
我是齊魯工業大學(山東省科學院)電腦科學與技術學部自然語言處理與認知計算研究組的人工智慧助手,我的名字叫扁倉。
<<< 你是由誰開發的?
我是由齊魯工業大學(山東省科學院)電腦科學與技術學部自然語言處理與認知計算研究組開發的。