[# 借助DeepSeek之东风扬帆AI海洋(四):分布式部署](juejin.cn/post/751041…)
什么是微调?
所谓微调,就是对模型进行微微的调整。我举一个例子,我们每个人都接受过九年义务教育和三年高考五年模拟等海量“填鸭式”知识训练。但等到高中毕业以后,就会发现这些天文地理历史政治太过通用,不足以让我们在社会上混饭吃。于是就需要针对某一项技能,进行专业训练。比如有的人学了计算机;有的人学了金融;有的人去了蓝翔,学了挖掘机等等,都是为了应对某项细分工作。
模型微调就是这样,厂商训练出的原始模型是要符合大众化口味的,但对于垂直领域的专业知识,是不可能会的。因此为了让大模型为我所用,我们需要用一些专业数据,比如口腔科的病例数据等等对模型进行二次训练,让模型具备我们想要的能力。口腔科的病例数据再多,可能也就几万份数据,毕竟病人虽多,但重复的病例也多。而模型初始训练时的数据量都是几亿、几十亿、几百亿级别的。因此数据量是微调的“微”的直观体现。
如何微调?
微调通常有三种方式,第一种是模型供应商提供了商业模型的在线微调能力,比如 OpenAI 的 GPT 3.5 等模型就支持在线微调。这种模式是基于商业大模型的微调,因此微调后模型还是商业大模型,我们去使用时依然要按 token 付费。
第二种是云厂商做的一些模型在线部署、微调平台。比如阿里云的 PAI 平台的模型广场功能,就具备模型的部署和训练功能。这种模式我们只需要租用云厂商的 GPU 算力即可。这些模型部署训练功能都是云厂商为了卖卡而推出的增值服务。
第三种就是如果你或你的公司手里有足够的卡,希望完全本地私有化部署和微调,此时就可以使用一些开源方案,部署一个微调平台来进行模型微调。
LLama-factory
LLama-factory 是一款整合了主流的各种高效训练微调技术,适配市场主流开源模型,而形成的一个功能丰富、适配性好的训练框架。LLama-factory 提供了多个高层次抽象的调用接口,包含多阶段训练、推理测试、benchmark 评测、API Server 等,使开发者开箱即用。同时提供了基于 gradio 的网页版工作台,方便初学者迅速上手操作,开发出自己的第一个模型。
实践:微调 DeepSeek-R1:7B
环境准备
实验环境:
模型文件与数据集准备
LLama-factory 支持选择待微调的模型后,自动下载模型,但是我们在 ModelScope 下载模型时,经常会出现文件下载不全或者下载中断的情况,因此 LLama-factory 官方建议自己手动进行下载。下载命令为:
pip install modelscope
modelscope download --model deepseek-ai/DeepSeek-R1-Distill-Qwen-7B --cache_dir /root/ms_cache
模型会下载到 /root/ms_cache/deepseek-ai/DeepSeek-R1-Distill-Qwen-7B/ 目录。
数据集你可以使用如下命令进行下载:
wget https://atp-modelzoo-sh.oss-cn-shanghai.aliyuncs.com/release/llama_factory/data_news_300.zip
下载完成后解压,会得到三个文件,分别是 dataset_info.json、train.json 以及 eval.json。其中 dataset_info.json 是目录文件,LLama-factory 需要通过读取该文件,才能知道有哪些可用的数据集。train.json 是训练数据集,内置了包含 300 组对话样本,是根据新闻分类器的要求准备的,要求有两条:
- 输入为新闻标题,输出为新闻所属的种类,不需要额外解释,但保留思维链的内容;并且在输入的新闻标题前加上“新闻分类:”等类似标签来标明询问目的。
- 新闻种类包括:政治、经济、科技、娱乐、体育、教育、健康、国际、国内、社会。
例如:
[
{
"conversations": [
{
"from": "human",
"value": "新闻分类:给力!中国两次出手,美到手的订单黄了,该国从此只认中国制造!"
},
{
"from": "gpt",
"value": "<think>\n首先,我需要分析给出的新闻标题:“给力!中国两次出手,美到手的订单黄了,该国从此只认中国制造!”\n\n接下来,根据标题内容进行分类。标题中提到了中国两次行动导致美国订单出现问题,并且其他国家开始依赖中国制造,说明这涉及国家之间的经济合作和社会影响。\n\n结合新闻种类,考虑到涉及国际贸易和经济合作,最合适的分类是“经济”。所以,这条新闻应该归类到“经济”类别中。\n</think>\n\n经济"
}
]
}
]
eval.json 是评估数据集,相当于测试用例,LLama-factory 会通过自动执行测试用例来评估训练的效果。
将这三个文件,放到 /root/data 目录下。
编译运行 LLama-factory
由于运行 LLama-factory 需要依赖 pytorch 等一堆 python 包。我不想每次更换服务器环境都重新安装一遍,因此我选择使用 docker 的方式。但是 LLama-factory 官方没有提供编译好的 docker 镜像,所以我们需要将源码下载下来,自行编译成镜像。
源码的下载地址如链接所示:Release v0.9.1: Many Vision Models, Qwen2.5 Coder, Gradient Fix · hiyouga/LLaMA-Factory,下载到服务器后解压。
在代码中有两个特别重要的目录,第一个是 data,里面存放的是官方为我们准备的测试数据集,新手使用这些数据集,特别容易上手。第二个是 docker 文件夹,里面为我们准备了不同架构平台的 Dockerfile,有了 Dockerfile,我们就可以直接将源码编译成镜像。
因为使用的是 NVIDIA 的卡,所以可以在代码的根目录执行如下命令进行编译:
docker build -f ./docker/docker-cuda/Dockerfile \
--build-arg INSTALL_BNB=false \
--build-arg INSTALL_VLLM=false \
--build-arg INSTALL_DEEPSPEED=false \
--build-arg INSTALL_FLASHATTN=false \
--build-arg PIP_INDEX=https://pypi.org/simple \
-t llamafactory:v0.9.1 .
镜像编译完成后,可以执行如下命令,运行镜像:
docker run -dit --gpus=all \
-v /root/ms_cache/deepseek-ai/DeepSeek-R1-Distill-Qwen-7B/:/root/.cache/modelscope/hub/models/DeepSeek-R1-Distill-Qwen-7B \
-v /root/data:/app/modeldata/data \
-v /root/config:/app/config \
-v /root/saves:/app/saves \
-v /root/output:/app/output \
-p 7860:7860 \
-p 8000:8000 \
--name llamafactory \
llamafactory:v0.9.1
7860 端口是 webui 的访问端口,8000 是 API 访问端口。
之后我们进入到 docker 容器内部,执行下面的命令,启动 llama-factory 的 webui。
llamafactory-cli webui
之后在浏览器输入 < 公网 ip>:7860,就可以进入到 WebUI。
WebUI 功能介绍
模型微调的控制台默认语言是英文,可以点击 Language 下拉框改为中文显示。在 Model name 页面可以点击下拉框选择模型,在 Model path 页面可以输入模型的路径。
控制台提供了三种微调方法,分别是 full、freeze 和 lora。
- Full 是全参数微调,意思是把模型所有的权重都放开,用新数据从头到尾训练一遍。这种方法训练效果好,但是所需资源量非常大。
- Freeze 是冻结微调,意思是冻结模型的大部分底层参数,比如前 80% 的层,只训练顶部的几层。这种方法使用的数据量比较少,适合微调简单的任务,比如简单的文本分类等等。
- Lora 中文叫低秩自适应,其原理是不修改原模型参数,而是插入低秩矩阵(理解为轻量级的适配层),只训练这些新增的小参数。优点是超级省资源,且效果很好,解决 Full 微调太耗费资源的问题。但对于用户的要求较高,需要充分理解每个参数的含义和效果。
控制台上,还支持设置 QLoRA 的量化等级等参数。
QLoRA 是 LoRA 的改进版本,Q 的意思是量化。QLoRA 的原理是先把模型进行量化,然后再进行 LoRA 微调。这样的好处在于能进一步节省显存消耗。比如我在一张 16G 的 T4 卡上使用 LoRA 微调 7B 模型,会报显存不足的错误,但如果使用 QLoRA,便可以进行微调。
控制台的四大核心功能,分别是训练(微调)、评估 & 优化、对话和导出。训练包含了我们进行模型微调时的一些步骤,包括数据集的选择、参数的设置等等。参数的设置,需要用户根据微调任务的实际情况自行配置。此外控制台还支持保存训练参数到指定目录。最后点击开始按钮,可以一键开始微调任务。微调结束后产生的检查点文件,也会自动保存。
评估页面会使用评估工具对模型性能进行评估。
对话页面可以直接加载原始模型或者微调过后的模型,之后通过与模型进行对话,来人为地检验模型的效果。
最后一个页面是导出。意思是将对话页面加载的模型输出成模型文件,这里通常有两种使用场景:
- 用户希望把原始模型转换成量化模型。此时可以通过在 chat 页面加载原始模型,然后在导出页面设置导出量化等级来完成。
- 用户希望把微调过后的模型导出。此时就可以通过在 chat 页面加载微调后的模型,然后在导出页面导出。
开始实践
首先加载模型,测试一下原始的 DeepSeek-R1:7B 模型的新闻分类效果。
对话模板选择 DeepSeek3,然后切换到 Chat 页面,点击加载模型。
输入一个 train.json 中的问题,测试一下效果:
可以看到 7B 并没有进行分类。所以接下来我们就进行微调,微调过后再来重新测试。
首先如下图所示,选择数据集,并设置学习率为 5e-6,梯度累积为 2,有利于模型拟合。
之后进行 LoRA 参数设置,我设置 LoRA+ 学习率比例为 16,LoRA+ 被证明是比 LoRA 学习效果更好的算法。在 LoRA 作用模块填 all,意思是将 LoRA 层挂载到模型的所有线性层上,提高拟合效果。
设置完成后,点击开始,就会开始训练。下方会输出训练日志以及进度。