从零开始亲手微调一个7B的小模型,听起来很硬核,但实际操作中处处是坑。这篇文章是一份完整的实战记录,从环境配置到数据准备,再到跑通流程和验证效果,一步步拆解分析,帮助你在做大模型微调时少走弯路。
微调目的
在接触提示词工程和RAG之后,发现真实业务场景里最核心的需求是让模型真正“学懂”企业内部知识。因此,这次选择模型微调,目标非常明确:将企业内部数据喂给模型,让它学会输出专业、准确的内容。
具体来说,本项目的微调对象是我负责的ERP销售系统。我把系统里的专业术语、操作流程、常见问题整理成结构化数据,用于微调训练。最终目标是让这个小模型在对话时能准确回答出与ERP销售系统相关的各类问题,提升企业内部知识库的问答能力。
【首次】环境安装——各版本不冲突才是关键
1、基础软件及包安装
PyTorch、CUDA、Python等基础软件的安装教程网上很多,这里不再重复。但有一个关键点必须强调:版本冲突问题。
例如,这次微调我原本打算用量化训练,结果发现PyTorch和CUDA版本不兼容,量化直接跑不起来,最后只能改用LoRA,GPU显存还直接撑爆了。这个问题后面会详细展开。综合建议是:先确认好自己的GPU型号和显存,再选择对应版本,这直接影响后续的参数配置和训练稳定性。
2、LLaMA-Factory安装
第一步,在虚拟环境中执行安装命令:
pip install -e ".[torch,metrics]"
依赖装完后,用 llamafactory-cli version 验证安装是否成功。
再用 which llamafactory-cli 确认一下,这个工具被安装在了conda创建的虚拟环境目录里。
3、训练的模型下载
模型可以从ModelScope下载。这里选择的是Qwen2.5-7B-Instruct模型,该模型在中文理解与生成任务上表现优异,适合企业级微调。
下载到本地的默认路径大概是这样:C:UsersXXX.cachemodelscopehubmodelsQwenQwen2___5-7B-Instruct
4、对应LLaMA-Factory-main下载
源码项目放在:D:ai_projectsLLaMA-Factory-mainLLaMA-Factory-mainsrc
数据集准备
1、数据集要求
数据集采用指令性的JSON格式。这里有个经验——让模型在生成的时候就把格式搞定,别指望后续人工去补。下面这几点不注意,后面补起来非常痛苦。
一个容易出问题的地方:每条数据之间必须用逗号隔开。当初有395条数据,少了一个逗号,结果排查了大半天。
[
{
"instruction":"根据下表,将每个句子分类为定义、事实或观点。",
"input":"|句子|n|--------|n|水果是一种通常甜味且含有种子的食物类别。|n|苹果是一种水果。|n|苹果是口感最好的水果。|",
"output":"|句子|分类|n|--------|-----|n|水果是一种通常甜味且含有种子的食物类别。|定义|n|苹果是一种水果。|事实|n|苹果是口感最好的水果。|观点|"
},
{
"instruction":"生成与电动汽车相关的适当关键词。",
"input":"",
"output":"电动汽车、电池技术、可持续交通、充电技术、零排放、绿色能源、智能交通、续航能力、电驱动、电动汽车市场、电池回收、电池续航、充电桩、节能减排、无尾气排放、节能汽车、低碳交通。"
}
]
格式对了,后续在微调页面才能正常预览数据集。
另外,数据量的选择也有讲究。这次用的是3060 12GB显卡,AI建议准备500个问题,一轮训练效果比较理想。大家可以根据自己配置问一下AI,看看需要多少数据。
2、数据集——问答对准备
(1)大模型生成
这里有个实操经验:直接把整个操作手册丢给大模型去生成问题,效果很差。更好的做法是把操作手册按章节拆分,一个章节一个章节地让AI去生成。这样生成的问题更有针对性,质量更高。
提示词可以参考类似这样:
#任务:帮我仔细阅读附件操作手册,帮我生成微调训练的40条数据,数据格式可直接用于微调训练,目的是小模型学习我的操作手册。
#要求:切勿瞎编乱造,生成的微调数据,只能来源于我的附件操作手册;
#格式及样例:
{
"instruction":"根据下表,将每个句子分类为定义、事实或观点。",
"input":"|句子|n|--------|n|水果是一种通常甜味且含有种子的食物类别。|n|苹果是一种水果。|n|苹果是口感最好的水果。|",
"output":"|句子|分类|n|--------|-----|n|水果是一种通常甜味且含有种子的食物类别。|定义|n|苹果是一种水果。|事实|n|苹果是口感最好的水果。|观点|"
},
{
"instruction":"生成与电动汽车相关的适当关键词。",
"input":"",
"output":"电动汽车、电池技术、可持续交通、充电技术、零排放、绿色能源、智能交通、续航能力、电驱动、电动汽车市场、电池回收、电池续航、充电桩、节能减排、无尾气排放、节能汽车、低碳交通。"
}
(2)人工生成问题
AI生成数据后,还是要手工过一遍。通常会删除少量虚构内容、补充必要的知识点。高质量数据输入,才会有高质量输出。后期还计划多次测试,看看哪种数据组合效果更优。
3、数据集提前配置
数据集文件命名为 business_qa.json,放入LLaMA-Factory的data目录下。具体路径参考:D:ai_projectsLLaMA-Factory-mainLLaMA-Factory-maindata
然后需要修改同一个目录下的 dataset_info.json 文件,添加自定义数据集配置:
"business_qa":{
"file_name":"business_qa.json",
"formatting":"alpaca",
"columns":{
"prompt":"instruction",
"query":"input",
"response":"output"
}
}
【每次使用】打开虚拟环境及微调页面
1、打开微调页面
#1、打开虚拟环境
conda activate lf
#2、进入项目目录,目的后续加载训练数据
cd /d D:ai_projectsLLaMA-Factory-mainLLaMA-Factory-main
#3、打开微调页面
llamafactory-cli webui
2、模型选择
用ModelScope先把模型下载到本地,然后填本地路径加载,速度会快很多。
3、数据集加载与预览
在WebUI中选择刚才配置好的数据集,确认预览里数据加载正常。
4、微调参数设置
这次使用的参数如下:
- 学习率:2e-4
- 训练轮数:5
- 验证比例:0.1
- 量化等级:4
- 微调方法:LoRA
当然,这些参数不是死的,得根据自己的GPU、数据量和实际效果来微调。建议先小批量测试,再逐步调整。
实际微调记录
1、第一次微调——财务数据集,8月22日
(1)数据集:395条数据
(2)微调参数
学习率:2e-4
训练轮数:5
验证比例:0.1
量化等级:原本设了4,最后改成none——原因就是前面提到的PyTorch与CUDA版本冲突,暂时没解决。
微调方法:LoRA
(3)微调过程与踩坑记录
报错1:
importlib.metadata.PackageNotFoundError: No package metadata was found for
The 'bitsandbytes>=0.39.0' distribution was not found and is required by this application.
To fix: run `pip install bitsandbytes>=0.39.0`.
解决办法:强行卸载并重装bitsandbytes,用指定版本的wheel文件。
pip uninstall -y bitsandbytes
pip cache purge
pip install https://github.com/jllllll/bitsandbytes-windows-webui/releases/download/wheels/bitsandbytes-0.41.1-py3-none-win_amd64.whl
报错2:
ModuleNotFoundError: Could not import module 'validate_bnb_backend_a vailability'.
Are this object's requirements defined correctly?
核心问题在于bitsandbytes无法正确检测CUDA环境,导致微调启动失败。
分析:系统环境变量指向的是CUDA 11.8,但实际安装的PyTorch却是CUDA 12.1版本。这不匹配就炸了。
python -c "import torch; print(torch.version.cuda)"
# 输出12.1
# 解决方案:要么重装匹配的PyTorch(如2.0.1+cu118),要么不用量化。
个人选择:因为重装代价太大,直接禁用了量化,改用普通LoRA微调。代价是显存需求从8GB左右飙升到14GB+,RTX 3060的12GB显存直接拉满,但通过调整batch size和梯度累积仍能勉强运行。
微调过程
[INFO|2025-08-22 16:19:04] llamafactory.train.callbacks:143 >>{'loss':4.3177, 'learning_rate':1.9940e-04, 'epoch':0.22, 'throughput':17.82}
{'loss':4.3177, 'grad_norm':5.115846157073975, 'learning_rate':0.00019940356672322037, 'epoch':0.22, 'num_input_tokens_seen':5520, 'train_runtime':309.7212, 'train_tokens_per_second':17.822}
微调结果:损失曲线很漂亮,从最初的4.3一路降到0.5左右,耗时大约1小时多点。对于第一次跑的人来说,这个结果算很不错了,说明数据集质量和参数选择基本合理。
