把 LLaMA Factory 和 Qwen 2.5 放在一起用是最近几个微调项目里我最顺手的组合。从环境搭建、数据准备到 LoRA 训练、权重合并、线上部署整条链路用 LLaMA Factory 一步走通不用自己去碰数据加载、模板拼接、断点恢复这些容易翻车的角落。这篇文章就是一份按步骤可以直接照做的手册我会把每个关键参数为什么这么设、每步容易踩的坑都摆出来。适合已经跑通基础推理、但还不太熟悉微调的读者也适合想快速验证一个小模型效果的团队参考。先说清楚一个认知微调的目的从来不是“让模型从零学会中文”而是“在它已有的能力基础上注入你的语料风格、知识边界和任务规范”。Qwen 2.5 本身已经具备很强的中文底子我们要做的只是塑形。如果用对了工具和方法一块 24G 的消费级显卡也能训练出可用的行业模型如果姿势不对哪怕给了 A100也会被各种隐性细节卡到怀疑人生。1. 这套组合能带来什么思路先说透1.1 LLaMA Factory 不是模型而是一整套训练封装很多刚接触微调的同学第一反应是写 Trainer 脚本。写多了之后你会发现真正耗时间的根本不是网络结构而是数据格式、对话模板、训练参数管理、LoRA 合并、推理兼容这些重复劳动。LLaMA Factory 把这些东西全部收敛到了一个入口用配置文件描述一次微调该怎么做底层自动对接 Transformers、PEFT、Datasets 这些生态库。你只需要关心业务数据和评估结果不再需要维护一堆版本混乱的胶水代码。我最早用 LLaMA Factory 就是冲着它的 WebUI 去的。在页面里选好模型、勾上数据集、填几个参数点一下就能开训确实对新手友好。后来的版本把 CLI 和 YAML 配置也做得越来越顺手同一个配置文件丢进 Git一个项目跑完复现成本几乎为零。所以这篇文章后面会同时讲 WebUI 和 YAML 两种跑法你可以根据自己的习惯来选。有一个观点我想放在最前面微调框架的上限取决于你对训练机制的理解程度。LLaMA Factory 简化了操作但没有替代思考。你仍然需要明白 LoRA 和全参微调的区别、学习率为什么不能无脑调大、数据格式为什么错了模型就开始胡言乱语。后面每一节我都会解释背后的“为什么”而不是只给你一串能跑的命令。1.2 Qwen 2.5 为什么值得选Qwen 2.5 是开源中文模型里非常能打的系列。从 0.5B 到 72B每个规格都有 Base 和 Instruct 两个版本。0.5B 能跑在资源很受限的边缘设备上7B 到 14B 是大多数团队微调的首选范围32B 以上就需要多卡或者更大显存。中文指令理解、结构化输出、代码能力都不差作为垂直领域微调的底子综合素质很均衡。我非常推荐优先选 Instruct 版。Instruct 版在预训练之外还做了指令对齐微调样本量少的时候效果会明显更稳因为你只是在它已经学会“怎么听话”的基础上补充业务规则。Base 版不是不能用但它要求你有足够多的高质量数据去重塑对话风格通常只有数据团队比较成熟的项目才适合一上来就动 Base。具体到微调方式Qwen 2.5 官方生态里LLaMA Factory 是被高频验证过的工具之一模型名、模板、数据集映射都已经内置好了。这意味着你不需要自己去配对 ChatML 格式不需要在代码里手写|im_start|这些特殊 token框架会按模板自动处理。1.3 模型规格和显存预算怎么匹配我做选型时只看一件事我的 GPU 到底能不能装下。显存不够再好的模型也跑不起来。这里给你一张基于常见实践估算的表注意它不是绝对值因为显存消耗受序列长度、batch size、是否开启梯度检查点影响很大。模型规格微调方式显存预估适合场景0.5B / 1.5B全参2 ~ 6 GB玩具项目、极简单一任务7BLoRA / QLoRA8 ~ 16 GB单卡开发、客服、知识库问答14BQLoRA12 ~ 20 GB中等业务需要更强综合能力32BQLoRA24 GB 以上高要求场景建议多卡如果你的设备只有普通家用显卡也没关系。QLoRA 是非常成熟的方案把基座量化到 4bit 再加载训练时就只更新低秩矩阵显存占用能压到全参微调的四分之一甚至更低。用一个不严谨但好懂的类比全参微调相当于把整家公司所有员工重新培训一遍LoRA 相当于只给几个关键岗位的老师傅发一个“业务插件”成本低、上线快效果往往也不差。2. 环境准备与依赖安装起步不踩坑2.1 先确认硬件和驱动第一步不是装软件是先看清机器。在终端里跑一句 nvidia-smi看一下显卡型号、显存大小和驱动支持的 CUDA 版本。很多人后面报错“CUDA out of memory”或者“torch not compiled with CUDA”八成是 PyTorch 和驱动版本不匹配而不是代码写错了。我建议 Python 版本选 3.10别追新也别守旧。越新的 Python 版本一些科学计算库的预编译轮子覆盖往往越慢。用 conda 建独立环境是最省心的做法避免把系统 Python 弄乱。如果你在 Windows 上跑训练我仍然建议用 WSL2 或者 Docker。Windows 原生的 PyTorch 也能用但遇到 flash-attn 这种要编译的库时原生环境里排错成本很高遇到一次就会老老实实换回 WSL。2.2 安装 PyTorch 和 LLaMA Factory以 CUDA 11.8 或 12.1 为例安装 PyTorch 的命令长这样conda create -n llama-factory python3.10 -y conda activate llama-factory pip install torch2.4.0 torchvision0.19.0 torchaudio2.4.0 --index-url https://download.pytorch.org/whl/cu121装完先验证一下 PyTorch 能不能正常调用 GPUpython -c import torch; print(torch.cuda.is_available(), torch.cuda.device_count())如果输出 True 且能看到显卡数量再安装 LLaMA Factorypip install llama-factory装完执行llamafactory-cli version能正常输出版本号就说明装好了。如果遇到“unrecognized model”这类问题通常不是你的操作问题而是安装的版本太老、模型映射表里没有 Qwen 2.5。解决办法就是把 LLaMA Factory 升级到最新版或者直接源码安装git clone https://github.com/hiyouga/LLaMA-Factory.git cd LLaMA-Factory pip install -e .源码安装的好处是方便改内部代码缺点是需要自己拉代码和依赖。大多数用户只做微调直接 pip 安装足够了。2.3 下载模型与启动 WebUI国内网络环境下载 Hugging Face 模型经常不稳定建议优先用镜像或者 ModelScope。对于 ModelScope你可以这样下载 7B Instruct 模型pip install modelscope modelscope download --model Qwen/Qwen2.5-7B-Instruct --local_dir ./models/Qwen2.5-7B-Instruct如果坚持从 Hugging Face 下载可以临时设置镜像export HF_ENDPOINThttps://hf-mirror.com下载完成之后启动 WebUIllamafactory-cli webui浏览器打开http://localhost:8000看到界面后先在“模型名称”下拉框里找找有没有 Qwen2.5-7B-Instruct。能找到说明版本和数据映射都正常找不到先升级工具本身不要盲目怀疑模型路径写错。3. 数据准备微调效果的地基3.1 选对数据格式Alpaca 还是 ShareGPTLLaMA Factory 里最常用的数据格式是 alpaca 和 sharegpt。Alpaca 格式适合纯指令任务结构非常简单[ { instruction: 把这句话翻译成中文, input: Long time no see., output: 好久不见。 } ]如果涉及多轮对话、需要保留 system prompt或者需要模拟真实客服场景里的上下文状态就优先用 sharegpt 格式。它的 conversations 数组天然支持多轮还能单独指定 system[ { system: 你是一个耐心细致的银行客服助手。, conversations: [ { from: human, value: 我昨天申请的大额转账还没到账。 }, { from: gpt, value: 您好我帮您查一下。请确认这笔转账是在几点提交的 } ] } ]数据格式的错误往往是隐性的。有时候训练不报错loss 也在下降但模型生成出来的内容前言不搭后语就是因为模板和数据集格式不匹配。我的建议是先不用急着把所有数据都做成多轮如果业务场景的单轮问答居多alpaca 完全够用反而更容易控制变量。3.2 数据质量与数据量怎么平衡第一次做微调的人最容易犯的错是到处收集几十万条数据结果模型学会了噪音。垂直场景的 LoRA 微调500 到 2000 条高质量样本通常就能看到显著效果。关键指标不是数量而是这几点每条样本的任务意图清晰明确输入覆盖面足够广包含用户真实表达里的口语、噪声、同义改写输出风格稳定、内容准确过滤掉重复和高相似样本独立留出验证集验证集绝不要和训练集重叠。如果业务里本来就有真实对话日志先做一轮清洗。把包含敏感信息、乱码、太长太短的都筛掉。还要特别注意不要只收集模型大概率能答对的样本。如果训练集里全是标准问法验证集分数会很好看一上线遇到用户改个说法模型就完全不会了。数据覆盖度比数据量重要得多。3.3 数据集怎么注册到 LLaMA FactoryLLaMA Factory 不会自动扫描你自己新增的 JSON 文件需要先在 data/dataset_info.json 里注册。这个文件是数据集索引注册之后 WebUI 的数据集列表里才会出现你的数据。一个最简单的注册条目长这样my_bank_sft: { file_name: my_bank_sft.json, formatting: sharegpt, columns: { system: system, conversations: conversations } }把 JSON 文件放进 data 目录注册完成后保存回到 WebUI 刷新数据集列表。如果能勾选到my_bank_sft说明注册成功。看不到的话优先检查 dataset_info.json 是否合法尤其是逗号和括号。这里想提醒一下不同版本的 dataset_info.json 字段兼容性会有变化如果遇到 schema 报错直接去查官方 README 里对应版本的数据集注册说明别硬试。4. 微调实操WebUI 和 YAML 两套跑法4.1 核心训练参数到底是什么意思微调界面上参数很多但真正核心的就那么几个。我把常用的参数和推荐范围整理成了一张表后面再逐个解释。参数推荐范围一句话理解finetuning_typelora / qlora训练方式QLoRA 更省显存learning_rate1e-5 ~ 5e-5权重更新的步长num_train_epochs3 ~ 5数据过几遍lora_rank8 ~ 64注入低秩矩阵的复杂度lora_alpha16 ~ 128矩阵增量缩放系数cutoff_len1024 ~ 4096输入序列最大截断长度per_device_train_batch_size1 / 2 / 4每张卡每次喂几条样本gradient_accumulation_steps4 ~ 16攒多少步再更新一次learning_rate 是首选要调参数。LoRA 只更新一小部分参数所以学习率不用像全参微调那样保守但设得太高也会让模型在震荡中丢失已有能力。我的经验是从 5e-5 起步loss 不稳定就降到 2e-5再不行就 1e-5。lora_rank 可以理解为“业务插件的大小”rank 越大插件越复杂能记住的内容越多但也越容易过拟合。数据只有几百条时rank 8 到 16 就很好数据量大、任务复杂时再上 32 或 64。lora_alpha 则控制这个插件的音量一般保持 alpha 是 rank 的 1 到 2 倍比较稳妥比如 rank 32alpha 用 64。cutoff_len 很关键不只是防 OOM。有些业务场景的输入非常长比如客服对话带历史记录如果截断太短模型根本看不到用户上下文loss 再低也没用。建议先统计训练集中 token 长度的分布再设 cutoff_len。4.2 WebUI 配置与训练全流程WebUI 是探索参数最方便的工具。我的操作顺序是在“模型名称”里选择 Qwen2.5-7B-Instruct并填好模型路径。检查模板是否自动识别为 qwen。没有自动识别就手动选。在“数据集”里勾选你在 dataset_info.json 注册的 my_bank_sft。训练方式选 lora如果显存紧张就选 qlora并打开 4bit 量化。设置输出目录建议用带项目名的路径比如 output/qwen25-bank-lora。把 cutoff_len 设为业务需要的长度学习率设为 5e-5epoch 设为 3 到 5。点击“开始”观察终端或者页面上的日志。训练开始后不要盯着屏幕发呆重点看两个东西显存占用和 loss 曲线。显存接近上限时考虑减小 batch sizeloss 如果完全不降先停掉排查数据格式和模板不要硬等到训练结束。首次跑通全链路时建议只留几百条数据、epoch 设 1先把流程走通再上全量数据。4.3 用 YAML 配置固化训练流程WebUI 适合探索但一旦参数确定我强烈建议固化成 YAML 文件。这样跨机器复现、团队协作、Git 追踪都会清晰很多。一个基础配置大致长这样model_name_or_path: /data/models/Qwen2.5-7B-Instruct template: qwen stage: sft finetuning_type: lora dataset: my_bank_sft cutoff_len: 2048 learning_rate: 5e-5 num_train_epochs: 3.0 per_device_train_batch_size: 2 gradient_accumulation_steps: 8 lora_rank: 32 lora_alpha: 64 warmup_ratio: 0.1 lr_scheduler_type: cosine optim: adamw_torch logging_steps: 10 save_steps: 100 output_dir: output/qwen25-bank-lora然后在命令行执行llamafactory-cli train qwen25_bank_sft.yaml这套配置跑起来后你在代码评审里可以把 YAML 当配置变更来 review而不是甩给别人一屏静态文档。注意 YAML 字段名可能随着工具版本微调遇到参数不识别直接看版本对应的配置说明。5. 评估、合并与部署让模型真正被用起来5.1 训练完先做生成测试不要只看 Loss训练结束后先不要急着导出部署。把 WebUI 切换到 Chat 页签加载训练输出目录里的模型输入几条验证集里的问题看模型生成的回答是否符合预期。重点检查三个方面格式是否稳定、语气是否统一、是否出现胡编乱造。只看 loss 很容易被骗因为 loss 低只能说明模型在训练集上拟合得好不能证明它在没见过的输入上表现好。如果业务里有明确的标准答案可以准备一个评测集统计准确率或者关键字段命中率。生成式任务不需要硬套 BLEU我甚至建议少用 BLEU 作为主要指标因为它不适合衡量中文开放式回答的质量。相对务实的做法是把评测集里的输出全部记录下来人工抽样打标看正确率。5.2 合并 LoRA 权重并导出完整模型LoRA 训练出来的产物是一组低秩增量矩阵不是完整的模型权重。要部署到普通推理框架必须先把增量和 Qwen 2.5 基座合并。合并命令如下llamafactory-cli export \ --model_name_or_path /data/models/Qwen2.5-7B-Instruct \ --adapter_name_or_path output/qwen25-bank-lora \ --template qwen \ --finetuning_type lora \ --export_dir output/qwen25-bank-merged导出时有一个常见大坑基础模型路径必须和训练时完全一致模板也不能换。如果你训练时用的是 Instruct 版导出时却误填成 Base 版张量和词表都对不上模型直接废掉。导出成功后output/qwen25-bank-merged 就是一个标准 Hugging Face 格式的完整模型目录可以直接被加载。5.3 vLLM 和 Ollama 部署路线导出完成后最简单的部署方式是用 vLLM 起一个 OpenAI 兼容的服务。当前版本推荐用 serve 命令vllm serve output/qwen25-bank-merged \ --served-model-name qwen25-bank \ --tensor-parallel-size 1 \ --port 8001起来之后业务代码可以直接用 OpenAI SDK 指向这个地址迁移成本非常低。如果你的部署场景是资源受限的边缘设备或者想本地跑 CPU 推理可以把合并后的模型转成 GGUF再用 Ollama 加载。但千万不要一上来就 GGUF性能瓶颈跑的这段路没必要重复走。6. 常见问题与排查技巧实录6.1 显存不足与 OOM这是新手遇到最多的问题。解决顺序建议从便宜的开始试调小 per_device_train_batch_size降低 cutoff_len先看训练数据里的最长 token 数别在无关长文本上浪费显存打开 gradient_checkpointing从 lora 换成 qlora启用 4bit 量化再不行就换小一号模型。如果 batch size 已经降到 1甚至序列长度也降下来了还是 OOM下一步要考虑你的业务数据里是不是存在异常长的文本。先清洗数据比硬调训练参数更划算。这里有一个很容易被忽略的点LLaMA Factory 会在训练日志里打印显存占用峰值跑完一步可以瞄一眼不要等到满屏报错才发现。6.2 Loss 完全不降、NaN 或者梯度爆炸loss 不降的原因通常很直接数据格式错了、模板选错了、学习率太高。排查顺序我建议按下面来用 python -m json.tool 校验数据 JSON确认结构合法确认 template 选的是 qwen而不是其他模型的模板把 learning_rate 降到 2e-5 再试看日志里有没有 NaN有就立刻停关闭 fp16或者换成 bf16。bf16 在大多数现代 GPU 上确实比 fp16 更稳定数值动态范围更大。如果硬件支持直接用 bf16 能省掉很多诡异问题。6.3 中文乱码和模板 token 重复中文乱码里最典型的一种是模型输出了|im_start|这种特殊 token 字符串。出现这个的原因多半是你在数据里手动写了这些标记而 LLaMA Factory 的模板又会自动再拼一次于是模型学到的是“双份分隔符”。我的建议非常明确数据里永远不要手写 BOS、EOS、|im_start|这类 token。它应该是框架和模板自动处理的事情。你要是手动加了轻则多出奇怪字符重则模型生成逻辑彻底乱掉。6.4 合并后效果反而变差了有一种情况很让人生气训练时对话效果不错导出合并之后反而变差。常见原因有四个Adapter 路径填错了加载了旧实验的 LoRA导出时模板和训练时不一致训练时用的 Instruct 版导出时误用 Base 版lora_alpha 设置太大增量矩阵被过度放大。最后一条尤其隐蔽。alpha/rank 比例最好保持在 1 到 2 之间如果你设了 rank 8 但 alpha 128模型输出往往带着很大的随机幻觉。遇到合并后变差先不要怀疑模型坏了把这四个原因按顺序检查一遍。6.5 模型下载慢和找不到模型模型权重动辄十几个 GB直接用在线下载很容易失败。我的建议是用 ModelScope 下载 Qwen 2.5 系列然后通过本地路径传给 LLaMA Factory。不要反复在命令里写模型 ID 走远程拉取本地路径一次设好后面训练、导出、部署全都用这个目录既快又准。如果非要用 Hugging Face 生态记得把 HF_ENDPOINT 指向镜像别硬碰超时。7. 我的工作流与个人建议我现在做微调项目有一个固定动作先在 data 目录里放一个小验证集用几百条数据把全链路跑通确认能训练、能导出、能对话然后再去清洗全量数据。这套流程帮我挡掉了大量无意义的返工。很多问题如果发生在全量训练后排查成本是小时级别的但发生在小数据冒烟测试阶段可能十分钟就定位了。训练配置我一定会纳入 Git 管理数据集版本我也会用独立目录配合简单规则标记清楚。训练日志、loss 截图、评测结果这些材料每次实验都归档一份。这看起来琐碎实际上非常救命。过了两周你翻回来看如果没有这些记录你根本说不清楚当时这个效果好的模型到底是哪次训练跑出来的。最后再说一个我非常坚持的判断微调项目里数据质量永远是第一优先级参数调优只能锦上添花。如果你发现 loss 也降了生成结果表面也对但一上线就是不行先回头审查数据而不是急着把 learning_rate 改成什么天顶星数值。数据里的噪音、重复、问答不同构才是绝大多数“微调没有效果”的真凶。这一条值得所有在这个领域里摸索的人认真对待。
阅读完成 · 觉得有帮助?