1. 大模型LLM-微調(diào)經(jīng)驗(yàn)分享&總結(jié)

        共 9476字,需瀏覽 19分鐘

         ·

        2023-10-14 20:06

        作者:劉聰NLP

        鏈接:https://zhuanlan.zhihu.com/p/620885226

        寫在前面

        大型語言模型橫行,之前非常焦慮,現(xiàn)在全面擁抱。目前也有很多開源項(xiàng)目進(jìn)行大模型微調(diào)等,筆者也做了一陣子大模型了,特此來介紹一下ChatGLM-6B模型微調(diào)經(jīng)驗(yàn),并匯總了一下目前開源項(xiàng)目&數(shù)據(jù)。筆者與很多人微調(diào)結(jié)論不同,本人在采用單指令上進(jìn)行模型微調(diào),發(fā)現(xiàn)模型微調(diào)之后,「并沒有出現(xiàn)災(zāi)難性遺忘現(xiàn)象」。
        項(xiàng)目地址:https://github.com/liucongg/ChatGLM-Finetuning

        ChatGLM-6B模型微調(diào)

        模型越大對顯卡的要求越高,目前主流對大模型進(jìn)行微調(diào)方法有三種:Freeze方法、P-Tuning方法和Lora方法。筆者也通過這三種方法,在信息抽取任務(wù)上,對ChatGLM-6B大模型進(jìn)行模型微調(diào)。為了防止大模型的數(shù)據(jù)泄露,采用一個(gè)領(lǐng)域比賽數(shù)據(jù)集-汽車工業(yè)故障模式關(guān)系抽取(https://www.datafountain.cn/competitions/584),隨機(jī)抽取50條作為測試集。
        詳細(xì)代碼見上面的GitHub鏈接,并且也被ChatGLM官方收錄。

        Freeze方法

        Freeze方法,即參數(shù)凍結(jié),對原始模型部分參數(shù)進(jìn)行凍結(jié)操作,僅訓(xùn)練部分參數(shù),以達(dá)到在單卡或不進(jìn)行TP或PP操作,就可以對大模型進(jìn)行訓(xùn)練。
        微調(diào)代碼,見finetuning_freeze.py,核心部分如下:
           
           
        for name, param in model.named_parameters():
        if not any(nd in name for nd in ["layers.27", "layers.26", "layers.25", "layers.24", "layers.23"]):
        param.requires_grad = False
        針對模型不同層進(jìn)行修改,可以自行修改。訓(xùn)練代碼均采用DeepSpeed進(jìn)行訓(xùn)練,可設(shè)置參數(shù)包含train_path、model_dir、num_train_epochs、train_batch_size、gradient_accumulation_steps、output_dir、prompt_text等,可根據(jù)自己的任務(wù)配置。
           
           
        CUDA_VISIBLE_DEVICES=0 deepspeed finetuning_freeze.py --num_train_epochs 5 --train_batch_size 2
        三元組抽取的推理代碼,見predict_freeze.py,其他任務(wù)可以根據(jù)自己的評價(jià)標(biāo)準(zhǔn)進(jìn)行推理預(yù)測。

        PT方法

        PT方法,即P-Tuning方法,參考ChatGLM官方代碼(https://github.com/THUDM/ChatGLM-6B/blob/main/ptuning/README.md) ,是一種針對于大模型的soft-prompt方法。
        • P-Tuning(https://arxiv.org/abs/2103.10385),僅對大模型的Embedding加入新的參數(shù)。
        • P-Tuning-V2(https://arxiv.org/abs/2110.07602),將大模型的Embedding和每一層前都加上新的參數(shù)。
        微調(diào)代碼,見finetuning_pt.py,核心部分如下:
           
           
        config = ChatGLMConfig.from_pretrained(args.model_dir)
        config.pre_seq_len = args.pre_seq_len
        config.prefix_projection = args.prefix_projection

        model = ChatGLMForConditionalGeneration.from_pretrained(args.model_dir, config=config)

        for name, param in model.named_parameters():
        if not any(nd in name for nd in ["prefix_encoder"]):
        param.requires_grad = False
        當(dāng)prefix_projection為True時(shí),為P-Tuning-V2方法,在大模型的Embedding和每一層前都加上新的參數(shù);為False時(shí),為P-Tuning方法,僅在大模型的Embedding上新的參數(shù)。
        可設(shè)置參數(shù)包含train_path、model_dir、num_train_epochs、train_batch_size、gradient_accumulation_steps、output_dir、prompt_text、pre_seq_len、prompt_text等, 可根據(jù)自己的任務(wù)配置。
           
           
        CUDA_VISIBLE_DEVICES=0 deepspeed finetuning_pt.py --num_train_epochs 5 --train_batch_size 2 --pre_seq_len 16
        三元組抽取的推理代碼,見predict_pt.py,其他任務(wù)可以根據(jù)自己的評價(jià)標(biāo)準(zhǔn)進(jìn)行推理預(yù)測。

        Lora方法

        Lora方法,即在大型語言模型上對指定參數(shù)增加額外的低秩矩陣,并在模型訓(xùn)練過程中,僅訓(xùn)練而外增加的參數(shù)。當(dāng)“秩值”遠(yuǎn)小于原始參數(shù)維度時(shí),新增的低秩矩陣參數(shù)量很小,達(dá)到僅訓(xùn)練很小的參數(shù),就能獲取較好的結(jié)果。
        • Lora論文:https://arxiv.org/abs/2106.09685
        • 官方代碼:https://github.com/microsoft/LoRA
        • HuggingFace封裝的peft庫:https://github.com/huggingface/peft
        微調(diào)代碼,見finetuning_lora.py,核心部分如下:
           
           
        model = ChatGLMForConditionalGeneration.from_pretrained(args.model_dir)
        config = LoraConfig(r=args.lora_r,
        lora_alpha=32,
        target_modules=["query_key_value"],
        lora_dropout=0.1,
        bias="none",
        task_type="CAUSAL_LM",
        inference_mode=False,
        )

        model = get_peft_model(model, config)
        可設(shè)置參數(shù)包含train_path、model_dir、num_train_epochs、train_batch_size、gradient_accumulation_steps、output_dir、prompt_text、lora_r等,可根據(jù)自己的任務(wù)配置。
           
           
        CUDA_VISIBLE_DEVICES=0 deepspeed finetuning_lora.py --num_train_epochs 5 --train_batch_size 2 --lora_r 8
        三元組抽取的推理代碼,見predict_lora.py,其他任務(wù)可以根據(jù)自己的評價(jià)標(biāo)準(zhǔn)進(jìn)行推理預(yù)測。
        注意:對于結(jié)果需要保持一致的任務(wù)(即關(guān)掉dropout,解碼關(guān)掉do_sample),需要保存模型的adapter_config.json文件中,inference_mode參數(shù)修改成false,并將模型執(zhí)行model.eval()操作。主要原因是chatglm模型代碼中,沒有采用Conv1D函數(shù)。

        三元組抽取實(shí)驗(yàn)結(jié)果

        • 模型訓(xùn)練時(shí),最大長度為768,Batch大小為2,訓(xùn)練輪數(shù)為5,fp16訓(xùn)練,采用DeepSpeed的Zero-1訓(xùn)練;
        • PT為官方的P-Tuning V2訓(xùn)練方法,PT-Only-Embedding表示僅對Embedding進(jìn)行soft-prompt,F(xiàn)reeze僅訓(xùn)練模型后五層參數(shù),Lora采用低秩矩陣方法訓(xùn)練,秩為8;
        • 由于之前訓(xùn)練PT在48G-A40顯卡上會(huì)出現(xiàn)OOM,因此之前進(jìn)行PT實(shí)驗(yàn)時(shí)對模型開啟了gradient_checkpointing_enable,使得模型顯存占用變小,但訓(xùn)練時(shí)長增加。
        • 訓(xùn)練示例:
           
           
        prompt_text:你現(xiàn)在是一個(gè)信息抽取模型,請你幫我抽取出關(guān)系內(nèi)容為\"性能故障\", \"部件故障\", \"組成\"和 \"檢測工具\(yùn)"的相關(guān)三元組,三元組內(nèi)部用\"_\"連接,三元組之間用\\n分割。文本:
        輸入:故障現(xiàn)象:發(fā)動(dòng)機(jī)水溫高,風(fēng)扇始終是低速轉(zhuǎn)動(dòng),高速檔不工作,開空調(diào)尤其如此。
        輸出:發(fā)動(dòng)機(jī)_部件故障_水溫高\(yùn)n風(fēng)扇_部件故障_低速轉(zhuǎn)動(dòng)
        時(shí)間換空間,可用很好的解決顯卡的資源問題,簡單玩玩還可以,如果想要模型達(dá)到最優(yōu)效果或可用快速看到效果,還不如租張A100卡,快速實(shí)驗(yàn),推理階段再用自己的小破卡。
        筆者找到一家新的算力平臺(tái)-攬睿星舟,單張A100僅要6.4元/小時(shí),我翻了一圈,算是便宜的了(反正比AutoDL便宜一點(diǎn),便宜一點(diǎn)是一點(diǎn)吧)。
        下面實(shí)驗(yàn)結(jié)果均是在租的80G-A100上進(jìn)行的實(shí)驗(yàn),與Github里用的A40的實(shí)驗(yàn)結(jié)果會(huì)有些差異,主要在訓(xùn)練時(shí)長(純訓(xùn)練速度,剔除模型保存的時(shí)間)。說實(shí)話,真的要訓(xùn)練一個(gè)大模型,多個(gè)A100是必不可少的,可以減少很多模型并行的操作,效果上也更好把控一些。
        微調(diào)方法
        PT-Only-Embedding
        PT
        Freeze
        Lora





        顯卡占用
        37G
        56G
        24G
        39G
        總參數(shù)
        6.259B
        7.211B
        6.255B
        6.259B
        可訓(xùn)練參數(shù)占比
        0.0586%
        13.26%
        16.10%
        0.0586%
        訓(xùn)練耗時(shí)
        20min
        52min
        46min
        25min
        測試結(jié)果F1
        0.0
        0.6283
        0.5675
        0.5359
        結(jié)果分析:
        • 效果為PT>Freeze>Lora>PT-Only-Embedding;
        • 速度為PT-Only-Embedding>Lora>Freeze>PT;
        • PT-Only-Embedding效果很不理想,發(fā)現(xiàn)在訓(xùn)練時(shí),最后的loss僅能收斂到2.幾,而其他機(jī)制可以收斂到0.幾。分析原因?yàn)?,輸出?nèi)容形式與原有語言模型任務(wù)相差很大,僅增加額外Embedding參數(shù),不足以改變復(fù)雜的下游任務(wù);
        • PT方法占用顯存更大,因?yàn)橐苍黾恿撕芏喽鈪?shù);
        • 測試耗時(shí),采用float16進(jìn)行模型推理,由于其他方法均增加了額外參數(shù),因此其他方法的推理耗時(shí)會(huì)比Freeze方法要高。當(dāng)然由于是生成模型,所以生成的長度也會(huì)影響耗時(shí);
        • 模型在指定任務(wù)上微調(diào)之后,并沒有喪失原有能力,例如生成“幫我寫個(gè)快排算法”,依然可以生成-快排代碼;
        • 由于大模型微調(diào)都采用大量instruction進(jìn)行模型訓(xùn)練,僅采用單一的指令進(jìn)行微調(diào)時(shí),對原來其他的指令影響不大,因此并沒導(dǎo)致原來模型的能力喪失;
        • 上面測試僅代表個(gè)人測試結(jié)果。
        很多同學(xué)在微調(diào)后出現(xiàn)了災(zāi)難性遺忘現(xiàn)象,但我這邊并沒有出現(xiàn),對“翻譯任務(wù)”、“代碼任務(wù)”、“問答任務(wù)”進(jìn)行測試,采用freeze模型,可以用test_forgetting.py進(jìn)行測試,具體測試效果如下:
        • 翻譯任務(wù)
        • 代碼任務(wù)
        • 問答任務(wù)
        后面會(huì)把生成任務(wù)、分類任務(wù)做完,請持續(xù)關(guān)注Github,會(huì)定期更新。(太忙了,會(huì)抓緊時(shí)間更新,并且官方代碼也在持續(xù)更新,如遇到代碼代碼調(diào)不通的情況,請及時(shí)聯(lián)系我,我在github也給出了我的代碼版本和模型版本)

        中文開源大模型&項(xiàng)目

        雖然出來很多大模型,但Open的&中文可直接使用的并不多,下面對中文開源大模型、數(shù)據(jù)集和項(xiàng)目進(jìn)行一下匯總。

        中文開源大模型

        直接可微調(diào),無需指令增量訓(xùn)練:
        • ChatGLM-6B:https://huggingface.co/THUDM/chatglm-6b
        • ChatYuan-large-v2:https://huggingface.co/ClueAI/ChatYuan-large-v2
        原始模型多語言or英文,需要中文指令數(shù)據(jù)集增量訓(xùn)練:
        • BloomZ:https://huggingface.co/bigscience/bloomz
        • LLama:https://github.com/facebookresearch/llama
        • Flan-T5:https://huggingface.co/google/flan-t5-xxl
        • OPT:https://huggingface.co/facebook/opt-66b

        中文開源指令數(shù)據(jù)

        下面中文指令集,大多數(shù)從Alpaca翻譯而來,請看下面項(xiàng)目中data目錄。目前通過ChatGPT或者GPT4作為廉價(jià)標(biāo)注工為自己的數(shù)據(jù)進(jìn)行數(shù)據(jù)標(biāo)注一個(gè)不錯(cuò)的思路。
        • [1]:https://github.com/LC1332/Chinese-alpaca-lora
        • [2]:https://github.com/hikariming/alpaca_chinese_dataset
        • [3]:https://github.com/carbonz0/alpaca-chinese-dataset
        • [4]:https://github.com/Instruction-Tuning-with-GPT-4/GPT-4-LLM
        • [5]:https://github.com/LianjiaTech/BELLE
        • [6]:https://huggingface.co/datasets/JosephusCheung/GuanacoDataset

        開源項(xiàng)目

        總結(jié)下面較火的開源項(xiàng)目:
        • BELLE:https://github.com/LianjiaTech/BELLE
        • ChatGLM:https://github.com/THUDM/ChatGLM-6B
        • Luotuo-Chinese-LLM:https://github.com/LC1332/Luotuo-Chinese-LLM
        • stanford_alpaca:https://github.com/tatsu-lab/stanford_alpaca

        總結(jié)

        目前各大廠的大模型陸陸續(xù)續(xù)放出,堪稱百家爭鳴!個(gè)人玩家也是全面擁抱,想盡一切辦法來訓(xùn)練微調(diào)大模型。只愿大家以后可以實(shí)現(xiàn)“大模型”自由。愿再無“model-as-a-service”。

        END

        推薦閱讀

        瀏覽 1060
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評論
        圖片
        表情
        推薦
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
          
          

            1. 国产日韩理论片 | 亚洲乱亚洲乱妇19p | 啊灬啊别停灬用力啊岳一剧情介绍 | 成人第一页| 男人日女人b |