一站式大模型微调与压缩评测流水线实操指南
做 LLM 项目有一个绕不开的体验刚在 LLaMA-Factory 里把 7B 模型做完 SFT正要开心转头就发现后面还有一堆活。reward model 要单独训PPO 要对齐得再配一套环境模型大了要蒸馏、剪枝、量化最后还得拉 OpenCompass 去跑 MMLU、C-Eval一个流程串下来光装环境、改数据格式就能耗掉一周。我最近把这条链路整体搬到了 CubeStudio 上用平台自带的大模型任务模板把微调、对齐、蒸馏、剪枝、量化、安全评估和评测全部串在一个工作区里完成。这篇文章就把完整实操过程、关键参数和踩过的坑记录下来适合正在做大模型微调、也想把压缩和评估一起落地的同学可以直接对照着抄。1. 为什么需要一站式大模型任务流水线1.1 传统自建流程的三座大山第一座大山是工具链割裂。微调用 LLaMA-Factory训练 reward model 又需要一套 RLHF 脚本蒸馏往往要自己改 forward、写 KL loss剪枝要借助 LLM-Pruner 或 SparseGPT量化又跳到 GPTQ、AWQ 的工具仓库评测再来一套 OpenCompass。每个工具的环境依赖还不一样有的要 torch 2.0有的要 transformers 4.35有的只兼容 CUDA 11.8凑在一起经常是把这个环境装好了那个又在 import 阶段崩掉。我见过不少人最后是在不同的机器上分别跑完每个环节再人工把产物拷到一起。第二座大山是数据格式不统一。同样是指令数据LLaMA-Factory 里就有 alpaca 格式、sharegpt 格式、rlhf 格式三种reward model 要 chosen 和 rejected 成对的数据蒸馏阶段希望拿到 teacher 的 logits 作为软标签量化阶段又需要专门的 calibration 校准集。这些格式互相转换看起来是小活实际改起来字段错位、prompt 拼接顺序错误、聊天模板不一致问题层出不穷而且往往是训练跑了一半才发现。第三座大山是评测反馈闭环缺失。微调完一个模型大家习惯先写几个 prompt 试一下觉得“好像变聪明了”真要用数据说话就得去 OpenCompass 跑整套基准。评测配置、生成参数、推理后端版本稍有不同跑出来的分数就不可复现。模型经过蒸馏、剪枝、量化之后每一步的指标变化需要积累历史记录散落在各种本地目录里的实验根本没法形成有效的对比链路。1.2 CubeStudio 任务模板的设计思路CubeStudio 的思路其实很朴素把每一步反复要做的操作封装成任务模板。模板内部把容器镜像、依赖版本、常用参数入口都固定好用户只需要提供模型路径、数据集和几个关键超参平台负责拉起任务跑完写入模型仓库记录日志、指标和产物。对使用者来说面向的不再是一堆散落的 GitHub 仓库而是“微调任务”“蒸馏任务”“量化任务”“评测任务”这些逻辑清晰的操作单元。这种设计让整个流程从“拼装代码”变成了“串联任务”。微调完的模型路径可以直接作为蒸馏任务的输入蒸馏产物继续接剪枝、量化最后统一送进安全评估和 OpenCompass 评测。每一步的中间产物、训练参数、评测分数平台都会留痕出问题能回溯实验清晰度比手动管理高了不止一个数量级。我自己的体感是模板化之后流程损耗从“天”降到“小时”而且踩过的坑还能沉淀成团队共享的经验。2. 微调任务模板实操SFT、reward、PPO 三段式2.1 先把三个角色分清楚SFT 不是全部LLaMA-Factory 里常被一起提起的 SFT、reward、PPO本质是三个不同的任务角色。SFT也就是监督微调目标是让模型学会“用户问什么就怎么答”输入是指令和回答对输出是模型自身的续写能力。它解决的是模型“能对话”的问题但是否符合人的偏好比如回答更详细、更礼貌、更安全SFT 阶段并不擅长。reward model 则是学习人类偏好的排序模型。给它一对回答它要判断哪个更好训练数据是 chosen 和 rejected 的成对比较。它不直接生成内容而是给候选回答打分分数的差值表意模型理解的偏好差距。PPO 则是真正利用 reward 去更新策略的阶段。actor 模型在这个阶段生成回答reward model 在线打分再用强化学习目标去调整 actor 的参数。这个组合拳的意义在于让模型不再只是“看过正确答案”而是为了获得更高奖励主动朝着人类更满意的方向生成。三者配合能显著提升对话体验但很多人在 SFT 做完就停住了实际效果距离完整对齐流程差了不少。2.2 数据格式与关键参数在 LLaMA-Factory 模板里这三个阶段的数据格式各不相同。SFT 最常见的是 alpaca 格式长这样{ instruction: 请解释一下什么是梯度消失, input: , output: 梯度消失是指在深层神经网络反向传播过程中靠近输入层的梯度趋近于零... }这里要注意input不能随便删掉即使为空也要保持字段完整否则数据校验会报错。reward 阶段则使用偏好对格式结构上是{ system: 你是一个乐于助人的助手。, human: 如何快速学习 Python, chosen: 可以从基础语法、数据结构、常用库三个层面入手..., rejected: Python 很难学不建议自学。 }PPO 阶段通常复用 reward model 训练用的偏好数据集同时需要额外提供一条好的参考回答作为初始生成参照我习惯把数据集拆成两部分一部分构造 reward 打分一部分走 PPO 训练中的 actor 采样和 critic 评分。训练参数上三个阶段的推荐区间差异很大列一张表比较好阶段stage 参数learning_ratenum_train_epochs典型显存需求7B LoRASFTsft2e-43约 18G~24GReward Modelrm1e-51约 20G~26GPPOppo1e-61约 30G~40G需 actor critic reward表中显存是在 batch size 为 4、max_length 1024、LoRA rank 16 条件下的经验值如果你的序列长度推到 2048显存会显著上涨。reward model 的学习率一定不能跟着 SFT 用 2e-4排序任务对步长敏感太大会直接打穿已经学好的语义表示。2.3 实操步骤与两个关键细节在 CubeStudio 里跑 LLaMA-Factory 微调操作路径比较固定。第一步把数据集上传到平台的对象存储或者数据集管理模块格式转成目标模板要求的 JSON。第二步创建任务选择 LLaMA-Factory 模板指定基座模型我用的是 Qwen2-7B数据集选择刚上传的指令数据。第三步展开高级参数把 LoRA 开关打开lora_rank设 16lora_alpha设 32target_modules填q_proj,v_proj,k_proj,o_proj,gate_proj,down_proj,up_proj。第四步提交任务等日志输出 loss 收敛曲线。第一个容易忽略的细节是reward model 训练时数据里不能混进 SFT 指令格式。很多人在 reward 阶段直接复用 SFT 的 JSON结果模板把output字段读成了 chosen把input字段读成了 rejected跑出来 reward 曲线基本不收敛。第二个细节是 LoRA 合并时机。我的习惯是先合并 LoRA 权重再送去评测而不是守着 adapter 文件做预测。原因很简单PPO 阶段内部会动态融合 adapter而 OpenCompass 评测框架不一定支持动态挂载合并后是标准权重后续所有环节兼容性最好。PPO 阶段还有一个隐蔽坑reward model 和 actor 必须使用同一个 tokenizer。如果 actor 基座是 Qwen2-7Breward model 训练时也用了同一个 base那没问题但如果中途换了模型家族reward 打分会出现系统性偏差表现为奖励曲线稳步上升但生成质量毫无变化。遇到这种情况第一反应不是加训练步数而是检查 tokenizer 是否一致。3. 蒸馏、剪枝、量化压缩任务模板实操3.1 三种压缩手段的本质差别大模型微调完成之后往往面临部署成本问题。蒸馏、剪枝、量化是三个方向完全不同的压缩手段很多人混为一谈实际上选择逻辑差别很大。蒸馏是改变模型结构让一个小模型去模仿大模型的输出分布。它的本质是知识转移学生模型的参数量可以远小于教师模型比如用 Qwen2-1.5B 学 Qwen2-7B 的行为。蒸馏不改变学生模型的推理机制部署时直接使用小模型即可。它适合要显著缩小模型体积、又希望尽量保留教师模型能力的场景。剪枝是保留模型结构删掉多余的权重或通道。非结构化剪枝会把权重矩阵中的小数值直接置零产生稀疏矩阵但要在特定推理框架下才能获得加速结构化剪枝则删除整行整列的神经元和通道模型体积变小但精度损失控制难度更大。量化则是把连续浮点映射到离散整数上最常见的是把 FP16 权重转成 INT8、INT4模型结构不变参数量没变但每个参数的存储位数变少了显存占用和推理带宽都大幅下降。选型建议其实很直接如果只是想把 FP16 模型塞进相同显存容量、部署成本敏感的线上服务优先做量化如果要从 7B 级别跨到 3B、1.5B 级别走蒸馏如果要配合特定的稀疏计算库追求极致推理提速再考虑剪枝。三者完全不冲突常见组合是“先蒸馏、再剪枝、最后量化”。3.2 蒸馏任务模板实操最小的模型学大模型蒸馏任务的模板通常需要指定两个模型teacher 和 student。我这次组的是 teacher 用上一章训练的 Qwen2-7B SFT 版本student 用 Qwen2-1.5B。蒸馏的损失函数一般由硬标签的交叉熵和软标签的 KL 散度组成公式大致是loss alpha * CE(student_output, hard_label) (1 - alpha) * KL(softmax(teacher_logits / T), softmax(student_logits / T)) * T^2温度 T 是知识蒸馏里最核心的超参。T 越高教师输出的概率分布越平滑越能体现类别之间的暗知识T 太低就退化成普通监督学习。我实际试验过T2 是比较稳妥的起点alpha 取 0.5 会让硬标签和软标签的贡献均衡。实际操作里还要注意T^2这个缩放项因为 logits 被温度放大了KL loss 的梯度量级会变化忘记乘回去会导致训练不稳定。数据准备也不能随便拿原始预训练语料硬灌。蒸馏数据要尽量贴近业务场景同时覆盖足够的多样性我一般取 5000 到 10000 条混合 SFT 指令数据和通用问答数据。student 模型迭代速度比 teacher 快一个 epoch 内就能看到 loss 明显下降但这里最大的坑是词表对齐。如果 teacher 和 student 不来自同一模型家族embedding 维度可能不同、tokenizer 切词结果也对不上模板会用映射或小规模扩展词表的方式处理。遇到报错KeyError: token id先查词表是否一致不要盲目加训练步数。3.3 剪枝任务模板实操删冗余之前先校准剪枝模板在 CubeStudio 里通常以 LLM-Pruner 和 SparseGPT 为底座。传统剪枝思路是在训练后对权重做敏感性分析把对损失影响最小的参数置零。以 LLM-Pruner 为例流程分四步计算各层权重敏感性、用校准数据做少量反向传播求梯度、按敏感度排序剪掉低敏感度通道或权重、最后用少量数据做恢复微调。校准集是剪枝流程里非常关键的部分。它的规模不需要大几百条代表性样本就够但分布必须贴近真实推理输入。如果校准集都是新闻类文本剪完之后业务里的代码问答场景掉点会非常明显。模板默认会给一个通用校准集我会在创建任务时把自己的业务样本导入进去。稀疏度 sparsity 的选择需要做梯度试探。我一般会一次性跑 0.1、0.2、0.3、0.4 四档对比模型困惑度和下游指标。Qwen2-7B 上我实测的情况是稀疏度 0.2 时困惑度上涨不到 1%语义基本无损0.3 时开始能感受到生成流畅度下降推到 0.4 以上就出现断层式劣化会出现句式崩塌和重复输出。所以剪枝的默认建议是 0.2 起步别一上来就贪高稀疏度。剪枝完成后模板会重新导出模型权重部分算子会变成稀疏格式如果后续还要接全精度推理框架可能需要转换成标准稠密模型再导出一次。3.4 量化任务模板实操AWQ 是性价比最高的选择量化模板提供的选择通常有 GPTQ、AWQ、以及部分 INT8 方案。GPTQ 是一种基于二阶信息的逐层量化算法它在量化每一层时利用 Hessian 矩阵近似误差校准数据会对最终精度影响明显。AWQ 则是基于激活感知的量化关注权重中哪些通道对激活值影响更大量化时对这些重要通道做保护精度通常更好而且不需要像 GPTQ 那样做复杂的逆矩阵运算速度快、更稳。在 CubeStudio 操作时选择量化模板后会要求填模型路径、量化位宽INT4 或 INT8、group size 和 act order。group size 我几乎固定用 128这是精度和加速的平衡点group size 降到 32 能稍好一些但推理加速收益下降act order 建议打开虽然会略微降低编解码速度但能明显减少量化误差。实测数据我很认可 AWQ 的一个表现Qwen2-7B 在 INT4 量化后 MMLU 通常还能保留 98% 到 99%显存占用直接掉了约 75%推理吞吐提升明显。这个精度损失在大多数业务场景里完全可以接受。量化还有一个常被忽略的后续动作把量化的权重接入 vLLM 或 TGI 这类推理引擎时模型配置里的quantization_config要能正确读出。模板产出的目录里会有config.json和量化分片权重我遇到过一次用 transformers 直接加载时提示找不到量化模块的情况解决办法是确认trust_remote_codeTrue已设置并将模型加载库版本对齐到量化工具要求的大版本。3.5 压缩模板之间的联动顺序蒸馏、剪枝、量化不是只能选一个我建议的完整顺序是先蒸馏出小模型再在小模型上做剪枝最后做量化。顺序背后有明确的工程理由。量化对误差的容忍度最低必须放在最后否则先量化再剪枝会导致误差叠加爆炸。剪枝会引入稀疏结构如果放在量化之后很多量化算子不支持稀疏格式部署阶段直接报错。蒸馏和剪枝的顺序偶尔可以交换但先蒸馏再剪枝有一个额外的好处学生模型的参数量更小剪枝时的敏感性分析耗时降低且稀疏化的目标更容易达成。我在一次实验里把 7B 蒸馏到 1.5B再对 1.5B 做 0.2 稀疏度剪枝最后 AWQ INT4 量化最终模型只有原 7B 的十分之一左右体积推理速度和显存占用完全达到线上要求。当然遇到精度掉点明显时可以只保留“蒸馏量化”剪枝这步直接省略往往也能拿到满意结果。4. 安全评估与 OpenCompass 评测模板4.1 安全评估模板不只是跑一个分数大模型上线前安全评估是我始终不会跳过的一环。CubeStudio 的安全评估模板会预置一批攻击样本和探测集覆盖几个典型维度包括对抗性输入下的鲁棒性、prompt 注入的防御能力、隐私泄露风险、敏感话题的拒答率、幻觉检测。模板会自动调用模型推理把每一类样本的输出与安全基线做对比最终产出一份多维度的安全评分报告。使用门槛不高创建任务时选择安全评估模板指定模型路径模板就会自动加载测试集并并发执行推理。我的习惯是至少跑两轮一轮用原始模型一轮用对齐后的模型对比看微调和 PPO 是否真的降低了风险。安全评估的数据集规模通常不会太小轻则几百条重则上千条按并发度 8 跑一个 7B 模型大概半小时到一小时出头。如果中途任务失败绝大多数情况是某条样本拼接后超过了模型的 max_length把截断参数往上调一档就能解决。安全评估报告要重点看两个数整体通过率和分维度通过率。整体通过率反映平均表现但如果某个别维度低于 90%还是要回到数据层面处理比如补充更多对抗样本再做一轮 SFT或者调整 reward 偏好数据让模型学会更有策略地拒绝。安全评估和 OpenCompass 评测要配合着看千万不要因为安全分数提升就忽略通用能力下降的风险。4.2 OpenCompass 评测模板微调效果用数据说话OpenCompass 是目前最常用的大模型评测框架之一CubeStudio 也内置了它的任务模板。模板会要求指定模型路径、推理后端和评测数据集常用的基准组合是 MMLU、C-Eval、GSM8K、BBH 这几个。MMLU 覆盖 STEM、人文、社科等 57 个学科用来测世界知识C-Eval 是国内的中文知识基准本地化场景很合适GSM8K 是数学应用题集测推理能力BBH 则是 23 个有挑战性的 task测复杂指令理解。模板里的配置主要分两块模型推理配置和数据集评测配置。模型推理配置包括 batch size、max token、max length我用默认值的时候遇到过评测耗时爆炸后来会把 batch 提到 16max token 限制在 2048整体时间能缩短一半以上。数据集评测配置里少样本示例数量要为所有模型保持一致这是评测公平性的底线。跑完 OpenCompass 之后输出会以表格形式汇总各数据集准确率一目了然。我习惯把微调前、SFT 后、PPO 后、蒸馏后、量化后的结果全放在同一张表里一眼就能看出哪个环节掉点、掉在哪类任务上。比如 7B 微调后 C-Eval 上涨但 GSM8K 掉了说明指令数据对推理类任务覆盖不足回去补充数学题数据比盲目调参更有效。4.3 评测公平性是数据有效的前提OpenCompass 评测最怕自欺欺人。不同模型之间如果生成参数不一致分数根本没有可比性。我给自己定了几条硬规则所有模型的 temperature 固定为 0不做随机采样max_token 保持一致短输出模型不会因为生成太短被判错长输出模型也不会因为超长被截断少样本示例放完全相同的几条推理框架版本固定不在评测中途升级。这些规则写进任务模板之后任何人都能复跑实验对比结论才成立。另外一点很容易被忽略蒸馏后的小模型和 7B 教师模型做对比时绝对分数差异是正常的关键看趋势。小模型在 MMLU 上低 5 到 8 分可以接受只要 GSM8K 和 BBH 的推理能力差距控制在 3 分内说明蒸馏把核心推理链路保留得不错。如果只是死盯 MMLU 掉分就否定小模型可能会误砍掉一个部署成本极低的产物。5. 一条完整流水线串联示例5.1 从基座到量化模型的完整依赖链单独讲模板只是理解工具真正有价值的是把整个流程串起来。我以 Qwen2-7B 为例跑过一条完整链路基座 Qwen2-7B 先走 LLaMA-Factory 的 SFT 模板用客服指令数据做垂直微调接着用偏好对数据训练 reward model走 rm 模板再用 SFT 模型和 reward model 跑 PPO 对齐模板。对齐后的 7B 作为 teacher蒸馏出 Qwen2-1.5B小模型继续做 0.2 稀疏度剪枝再走 AWQ INT4 量化。最后把 7B 对齐版、1.5B 蒸馏版、1.5B 剪枝量化版三个产物统一送入安全评估和 OpenCompass完成效果对比。这条链路在 CubeStudio 里实现时核心是任务依赖的可视化。创建任务时除了填写模型路径还能声明依赖的上游任务。平台会沿着依赖关系自动调度上一个任务跑完下一个任务自动拉起。我不用每天去盯任务状态打开工作区看依赖图上的高亮节点就知道当前到哪一步了。中途某个模板失败也只需要单独重跑那一个节点下游任务会在上游完成后重新触发。5.2 数据流如何保持干净串联多个模板时最容易出问题的不是模型路径而是数据格式。我会在平台的数据集管理里为每条数据打上标签SFT 指令集、RM 偏好集、蒸馏混合集、量化校准集。每个任务模板只接受对应标签的数据集避免不同格式混用导致解析错误。蒸馏和量化阶段千万不能拿 SFT 原始数据当校准集校准集要选择分布更接近真实推理场景的语料。模板之间的产物命名也需要约定。我开始时随意命名结果任务一多已经分不清哪个是剪枝后、哪个是量化前。后来统一成模型家族-参数量-阶段-版本的格式比如qwen2-7b-sft-v1、qwen2-1.5b-distill-v2、qwen2-1.5b-pruned-int4。平台任务只要按这个规则生成产物路径下游任务引用时一目了然排查问题能节省大量时间。5.3 一次完整实验的指标变化这条链路的实测结果很有参考价值下表是我在 Qwen2 系列上跑出的一组数据仅供参考模型MMLUC-EvalGSM8K平均显存占用GQwen2-7B base70.568.972.1约 16.0Qwen2-7B SFT71.270.869.5约 16.0Qwen2-7B PPO70.870.170.2约 16.0Qwen2-1.5B distill65.464.868.3约 4.0Qwen2-1.5B prunedint464.663.566.9约 1.2从数据里能读出两件事。第一SFT 对知识类指标提升有限但对业务场景回答质量提升很大所以不要单看跑分否定微调第二从 7B 到 1.5B 蒸馏再加剪枝量化总损失只有不到 6 个点换来显存从 16G 降到 1.2G这个性价比在多数推理服务里都是很划算的买卖。6. 常见问题与排查技巧实录实际操作中会遇到不少问题我整理了一张速查表覆盖这段时间在 CubeStudio 各模板里最常撞上的坑现象可能原因解决办法CUDA out of memorybatch size 过大、max_length 过长把 batch size 降到 2 或 4max_length 从 2048 降到 1024RM 训练 loss 不降数据里混入了 SFT 的 instruction 字段检查 reward 数据是否严格为 chosen/rejected 成对结构PPO 奖励曲线上升但不生成actor 与 reward 的 tokenizer 不一致统一基座或重新训练 reward model蒸馏 loss 有值但生成崩坏teacher 与 student 词表不一致导致映射错位查 embedding 维度扩展词表或换同家族模型剪枝后困惑度暴涨稀疏度设太高换回 0.2 以内或增加恢复微调步数AWQ 量化模型加载报非法内存访问group size 或 act order 配置和推理库不匹配重导 config对齐 transformers 和量化库版本OpenCompass 分数比预期低很多生成参数不一致或 max_token 太小固定 temperature 为 0max_token 统一调到 2048安全评估任务中途失败样本过长触发截断提高 max_length按并发度 8 控制压力平台依赖任务没有自动触发上游产物路径声明错误回到依赖配置里核对模型路径的字符串完全一致这里面最值得说的是剪枝和量化叠加时的问题。剪枝会产生稀疏权重而很多量化算子并不支持稀疏输入所以我建议的串联顺序始终是“先剪枝再量化”量化之后再任何一步依赖结构处理的优化都不要做。如果一定要在量化之后做模型压缩实际意义已经不大反而会引入连续误差。基于这套流程我还想专门提醒一下评价预期管理。微调、对齐、压缩的每一步都会带来指标波动不要因为某个阶段掉了一个点就疯狂调参。先看整体链路中掉点是否集中在一个任务类型上再看是否因为数据或配置问题导致最后再决定要不要动训练超参。很多时候重新整理数据集比盲调 learning rate 有效得多。最后分享一个实际体会落地到具体项目我现在的默认组合是“SFT 蒸馏 AWQ 量化”剪枝只在有明确稀疏加速需求时才启用。PPO 虽然效果好但 reward 数据质量完全决定天花板如果没有一批高质量的偏好数据强行上 PPO 反而会让模型变得保守。每一个模板单独拿出来都不神秘但把它们按正确的顺序组织成流水线才是真正能把大模型从实验带到生产环境的功夫。CubeStudio 这类平台帮我省掉的是环境维护和脚本拼装的时间让我能把精力放在数据、评测和体验优化这些真正影响结果的事情上。
上一篇/下一篇内容由系统自动关联
返回资讯列表 →