LLM 这两周带来的震撼和惊喜,确实让人应接不暇。GPT-4 的发布已经把大家的想象力拉到了一个新高度,而本周密集落地的 LLM 应用,更是让那些想象一步步变成现实。今天就来拆解一套完整的 ChatGPT 训练方案,全程可实操,希望给正在探索的小伙伴一些硬核参考。
过去两周,LLM 相关的开源社区涌现了不少亮眼工作,其中让我印象最深的是 Stanford 基于 LLaMA 的 Alpaca,以及随后出现的 LoRA 版本 Alpaca-LoRA。原因很简单——成本。Alpaca 宣称只用不到 600 美元(包括构建数据集),就能让 LLaMA 7B 达到接近 text-da vinci-003 的效果。而 Alpaca-LoRA 更进一步,让一块消费级显卡就能在几小时内完成 7B 模型的微调。
下面这张表是社区成员实测可以跑通的硬件规格和耗时:
根据实测数据,微调 7B 模型只需要 8–10 GB 显存。这意味着在 Google Colab 上完成训练也完全可行。既然门槛已经降到这个程度,那就直接动手吧。
为什么要训练自己的 ChatGPT?
理由其实很直白:
- 个人层面,这事儿本身就非常酷。
- 让模型能讲自己熟悉的语言。
- 让模型帮忙写注释、补测试代码。
- 把产品文档喂给模型,让它去回答用户的基础问题。
- 还有更多场景等待挖掘。
计划
要训练自己的 Chat 模型,理论上需要以下几步:
第一步:准备数据集
微调的目标通常分两种:一种是像 Alpaca 那样,收集 input/output 生成 prompt 进行训练,让模型完成特定任务;另一种是语言填充,直接收集文本让模型学习补全。以第一种为例——假设目标是让模型讲中文,最简单的办法是用其他 LLM(比如 text-da vinci-003)把现有的数据集(比如 Alpaca)翻译成中文。这个思路在开源社区已经有人实现了。
第二步:训练并应用 LoRA
在准备好的数据集上直接微调。
第三步:合并模型(可选)
将 LoRA 权重与基座模型合并,可以加速推理,也为后续量化做准备。
第四步:量化(可选)
量化能进一步加速推理、降低显存占用,这方面已经有现成的开源工具可以直接用。
实践
先挑软柿子捏——目标就从“让模型讲中文”开始。数据集用的是 Luotuo 作者翻译的 Alpaca 中文版,训练代码主要来自 Alpaca-LoRA。
准备
先克隆 Alpaca-LoRA 代码库:
git clone git@github.com:tloen/alpaca-lora.git
下载中文数据集:
wget https://github.com/LC1332/Chinese-alpaca-lora/blob/main/data/trans_chinese_alpaca_data.json
创建虚拟环境并安装依赖(注意根据 CUDA 版本调整):
conda create -n alpaca python=3.9
conda activate alpaca
cd alpaca-lora
pip install -r requirements.txt
训练
单卡选手直接执行:
python finetune.py \
--base_model 'decapoda-research/llama-7b-hf' \
--data_path '/path/to/trans_chinese_alpaca_data.json' \
--output_dir './lora-alpaca-zh'
双卡选手需要多几步:
WORLD_SIZE=2 CUDA_VISIBLE_DEVICES=0,1 torchrun \
--nproc_per_node=2 --master_port=1234 finetune.py \
--base_model 'decapoda-research/llama-7b-hf' \
--data_path '/path/to/trans_chinese_alpaca_data.json' \
--output_dir './lora-alpaca-zh'
在我的环境(2× RTX 3090 Ti 24GB)下,需要额外调小 --micro_batch_size 2 避免 OOM。其他推荐参数:--num_epochs 2。
训练过程比较稳定,用 nvitop 可以实时观察显存和 GPU 利用率:
下面是训练时模型收敛的情况,差不多 2 个 epoch 就收敛得不错了:
推理
单卡选手直接执行:
python generate.py \
--base_model "decapoda-research/llama-7b-hf" \
--lora_weights './lora-alpaca-zh' \
--load_8bit
双卡选手稍微麻烦点——目前还不支持双卡推理,需要手动修改 generate.py,在第 47 行添加相应代码(见下图)。
然后执行上面的命令即可。如果推理运行在服务器上,希望从其他终端访问,给 launch 方法加上 server_name="0.0.0.0" 参数就行。打开浏览器,就能看到成果了。
加速推理
Alpaca-LoRA 提供了 export_hf_checkpoint.py 等脚本来合并模型。合并后的模型可以用 llama.cpp 等工具获得更好的推理性能。
测试
最后来对比一下原生 Alpaca 和自己微调的 Alpaca,看看模型到底有没有学会讲中文。
Good Examples
Bad Examples
可以看到模型确实在讲中文,也能根据中文指令和输入完成一些任务。但由于 LLaMA 本身的训练数据大部分是英文,加上 Alpaca 数据集翻译后的质量有限,某些场景下效果不如原生 Alpaca。这也再次印证了高质量数据对 LLM 的重要性。
总结
作为一个分布式系统方向的工程师,微调 LLM 的过程中遇到了不少坑,也收获了很多乐趣。虽然 LLaMA 7B 展现的能力还比较有限,但开源社区后续的进展很值得期待。接下来计划尝试针对特定场景微调 LLM,比如让模型教我做饭,感兴趣的朋友可以保持关注。
