LLM微调经验分享

admin 2023年7月15日17:50:45评论300 views字数 2460阅读8分12秒阅读模式

原文链接:

https://twitter.com/xinqiu_bot/status/1679786303716749312

(1/15)在经历了无数次踩坑后,来分享一些针对私有数据进行finetune的经验吧。这里默认使用的8xA100-40G进行训练,框架是DeepSpeed。

(2/15)目前很多教程主要以SFT为主,大部分都是参考Stanford Alpaca的方式来进行微调LLaMA系模型,主要是在构建指令上。这里通过指令直接finetune实际上是模型的全量finetune,计算成本会比较大,因此如果想减少训练且不希望影响到基座模型的效果推荐还是lora。

(3/15)在使用Transformers需要注意版本,很多教程都是使用hf格式的LLaMA模型进行微调,即使用decapoda-research/llama-7b-hf这个转化好的库,但是这里tokenizer_config.json里有一些问题需要进行调整。老版本是先加载tokenizer.model,新版本是加载config,老版本的transfomers中config有问题。

(4/15)tokenizer的问题会影响finetune后的效果,模型容易在finetune后都是输出乱码。因此需要提前确认训练的transformers版本以及相关配置是否正确。另外在配置上,需要手动设置padding_token,可以和eos_token保持一致较好。

(5/15)以alpaca 52k进行finetune,train_batch_size=64的情况下,建议内存需要有300GB,这里使用的是zero3的相关trainer配置,max_seq_len=512,如果想增加seq最大长度,会更耗显存,只能通过减少batch的方式来操作。

(6/15)40G的显卡训练对于较大参数的LLM训练比较够呛,这时候如果想利用较大的batch,可以使用 accumulate_grad_batches 这种方式进行梯度累积,通过这种方式来达到资源少但提高batch_size。同时显存较小的情况下可以使用DeepSpeed的ZeRO-Offload将一些工作放到CPU和Memory中,节省显存。

(7/15)不同模型对显存的诉求是不同的,比如Bloomz-6b1,虽然是6b的模型,但是实际训练时相比llama-7b更消耗显存,原因可能是bloom的词表较大,如果是中英文使用场景,可以使用剪裁后的YeungNLP/bloomz-6b4-zh进行相关训练。 

https://huggingface.co/YeungNLP/bloomz-6b4-zh

LLM微调经验分享

(8/15)在推理方面,如果想图方便使用多个模型,可以将这些模型都转成hf格式,使用统一的代码进行加载模型和tokenizer。要注意的是,llama模型自身是不带stream流式输出的,和chatglm不同。如果很想使用流式输出,可以参考这个issue中的方法进行改造即可实现流式llama输出。 

https://github.com/huggingface/transformers/issues/22710

LLM微调经验分享

(9/15)对于大部分本质还是Transformers的LLM,想要优化训练速度可以使用FlashAttention,使用起来也较为简单且通用。但也有设备限制,推荐在A100上使用,加速效果与batch_size以及模型参数量相关,batch越大,加速效果越大。

https://github.com/HazyResearch/flash-attention

LLM微调经验分享

(10/15)另一种是使用QLoRA,但是在测试时,DeepSpeed多卡场景下ZeRO3目前不支持QLoRA,只能进行单卡训练,在真正上手以后才明白为什么论文里大部分都是介绍单卡能跑更多参数的模型,在多卡上目前只能使用ZeRO1。从Repo里看目前也有多卡跑的方法,但多卡上仍然存在一些问题。 

https://github.com/artidoro/qlora

LLM微调经验分享

(11/15)对于不使用Lora的finetune,其实是full finetune,如果使用单一内容SFT指令进行训练,反而容易劣化大模型。这里还和模型有关,在llama上finetune泛化能力会稍微好点,在ChatGLM-6B上使用alpaca sft容易导致模型只学到指令格式,在回答内容上没有变好。

(12/15)对于通用的模型微调,确实使用具有多样性的SFT指令能带来模型的效果提升。对于私有数据,如果光使用SFT,效果并没有很好,这里的一些推测是,对于7B模型来说,还无法理解SFT中的指令知识,因此直接微调很难提升效果,需要先使用预训练的方式让模型做知识扩充。

(13/15)当完成continue pretrain后再利用SFT进行微调,确实会让模型学会如何按照指令风格进行回答。原生llama在中文上效果不好,某种程度上也是因为中文词表较少,很多词会被模型认为是unk,因此很难微调好模型。这里可以进行中文词表扩充,或者使用已经预训练好的基座模型。 https://github.com/ymcui/Chinese-LLaMA-Alpaca

LLM微调经验分享

(14/15) 预训练大部分只需要跑一个epoch,甚至半个epoch,SFT finetune一般是3个epoch,较小的数据集可以通过更多epoch想办法让模型过拟合,这种使用场景主要是对模型进行认知上的训练。不建议每次训练都让模型过拟合。对于lora之后的预训练和finetune,都需要先将lora权重和基座权重合并后再操作。

(15/15)大模型的训练还是有不少坑,每一次的训练都有点像开盲盒,要清晰的知道训练目标再去做事,如果场景是想利用大模型的推理能力,直接使用更大参数的模型+Few Shot Learning来解决问题即可,微调仍然是投入成本大但效果很难估计的工作。

原文始发于微信公众号(我不是Hacker):LLM微调经验分享

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年7月15日17:50:45
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   LLM微调经验分享https://cn-sec.com/archives/1878549.html

发表评论

匿名网友 填写信息