
做这行三四年处理过大大小小几十个微调项目后我越来越体会到一件事大模型落地的难点早就不只是“跑通一个训练脚本”这么简单。真正磨人的是从数据准备、SFT微调、对齐、压缩到评估这一整条流水线。中间随便哪个环节断一下前面几天的功夫可能全白费。最近团队在 CubeStudio 平台上把这条链路完整梳理了一遍用它可以一站式跑完 LLaMA-Factory 的 SFT / Reward / PPO 微调接着做蒸馏、剪枝、量化最后还能直接做安全评估和效度评测。写这篇东西是想把我实际操作中的步骤、参数和踩过的坑都记录下来给正准备上车的朋友一个能直接“抄作业”的参照。这套模板尤其适合两类人一类是公司里要落地私有模型的算法工程师不想每次都在本地环境折腾依赖和GPU调度另一类是对微调有一定了解、但还没系统做过“训练后压缩评估”的进阶选手。接下来我按自己的真实操作顺序来拆每一步都给出可复现的配置和关键参数也把为什么这么做的逻辑讲清楚。1. 内容整体设计与思路拆解1.1 为什么要把微调和压缩评估放在一起先说个亲身体会。以前做项目微调通常在一批服务器上治理好环境跑完量化剪枝又是另一套环境评估还得再开一台机器装依赖。数据、配置、模型权重全部靠人肉搬光版本对齐就能耗掉半天。更麻烦的是微调后的模型往往带了训练框架的特殊标记比如 LoRA adapter如果后续压缩工具不认识这种模型格式你又得先合权重再转格式中间很容易出岔子。CubeStudio 这类的平台化任务模板核心思路就是把这些环节拆成一个个“任务卡片”每个卡片对应一段固定流程底层环境、依赖、脚本全部预置好。你要做的只是填参数、选数据、点运行。这样最大的好处是流程可复现换个人来操作也是同样结果。团队协作的时候别人看你的任务记录就知道你用了什么镜像、什么超参不用再逐条截图解释。另一个关键点是资源管理。训练和评估对 GPU 的需求不同微调阶段要显存大量化评估阶段要 CPU 和内存调优。如果全部手工管理要么高峰期抢卡要么非高峰期卡闲着。平台的任务模板能按阶段申请不同规格的资源比如 SFT 阶段用 8 卡 A100量化阶段用单张 4090成本更可控。1.2 模板里包含的完整闭环我们这次跑通的流程按顺序包含六个环节数据准备与预处理把原始数据集统一成模型训练需要的 JSON 格式做 train / validation 切分。基座模型加载从模型仓库拉取 Qwen、LLaMA 或 Llama 3 系列这类开源权重。三阶段对齐训练先 SFT 做指令微调再用 Reward 模型打分最后 PPO 做强化学习对齐。模型压缩训练完成后做蒸馏、剪枝或量化让模型变小、变快适合线上部署。安全与能力评估通过 OpenCompass 等评测工具跑通用能力和安全指标验证压缩后的模型没有明显能力劣化。产物导出把最终的模型权重和 tokenizer 一起打包供下游服务使用。每个环节都对应 CubeStudio 里的一个模板。你不需要自己写胶水代码模板之间可以串联前一个环节的输出自动作为后一个环节的输入。这就是“一站式”的意义不是把脚本堆在一起而是把依赖关系和工作流固化了。2. 环境准备与模板选型2.1 工作台配置镜像、数据和算力选择第一次进 CubeStudio 工作台别急着跑任务。先把三件事确认好。第一个是镜像。平台一般会预置 PyTorch CUDA 的基础镜像但微调时最好直接用带 LLaMA-Factory 的镜像省去安装依赖的时间。我们用的是cubestudio/llama-factory:latest里面对 transformers、peft、deepspeed 的版本都做了验证不会再出现ImportError: cannot import name AutoModel from transformers这种低级问题。如果自己装建议锁版本transformers4.36,4.40、peft0.7.0、torch2.1.0这几个版本组合在 LLaMA-Factory 里测试得最充分。第二个是数据集。模板默认支持 json 和 jsonl 格式。指令微调的数据要先整理成统一字段conversations里面是{from: human / gpt, value: ...}的序列。如果是从 alpaca 格式转过来的字段名一般是instruction、output需要一次预处理换成conversations。平台的任务模板首页通常带“数据集预览”功能能看到条数和前几条内容这一步能做简单的文本格式检查发现对话对不齐就直接改不要等训练跑起来才报错。第三个是算力。SFT 阶段我们用的 8 卡 A10080Gbatch size 每卡 4总 batch 32。如果只是做 LoRA 微调一个 7B 模型单卡 4090 也能跑只是速度慢些。PPO 阶段因为要同时跑四个模型Actor、Reward、Critic、Reference显存开销比 SFT 大不少建议至少 4 卡 A100否则很容易 OOM。量化评估阶段用 CPU 也能跑但推理速度会明显慢还是建议留一块 GPU。2.2 任务模板的创建和串联逻辑在 CubeStudio 里一个“项目”下面可以建多个“任务”。任务之间用“产物”关联。比如 SFT 任务的输出是模型 checkpoint这个 checkpoint 会自动挂到产物列表里后续的 Reward 任务新建时就能直接选它作为初始模型。一个小技巧命名要按阶段统一打前缀。我们习惯这样01-sft-7b-lora02-reward-7b03-ppo-7b-lora04-distill-7b-to-3b05-prune-30pct06-quantize-int407-eval-safe这样做的好处是任务列表里按名称排序就是完整流程后面找日志、对产物都非常清楚。尤其是多人协作时光看日志记录里的任务名就能快速定位问题出在哪一环。模板里有几个默认参数要改掉不能直接点“开始”就跑model_name_or_path要填具体的模型名比如Qwen/Qwen2.5-7B-Instruct默认可能是空占位符。dataset_dir指向你的数据集路径。output_dir建议填成./runs/{task_name}后面找产物方便。finetuning_typelora我们常用、full或freeze。满参数微调对显存要求极高7B 全参微调没有 48G 以上的卡基本不要想。2.3 不同模板的适用场景和选型标准每个模板不是独立的玩具它背后对应一种业界主流方案SFT 模板底层调llamafactory-cli train指定stage: sft。适合快速把模型调成服从指令的风格。Reward 模板训练一个打分模型输入是“提示词回答”输出一个标量分数。这个分数用来指导 PPO。PPO 模板基于 Actor、Reward、Critic 做强化学习让模型在保留原有能力的同时更倾向于输出高分回答。蒸馏模板一般用 KL 散度或特征对齐方式利用大模型Teacher的 soft label 来训练小模型Student。剪枝模板按权重重要性或结构稀疏度去除不重要的通道能显著降低推理显存。量化模板把 FP16 权重转成 INT8 或 INT4配合 GPTQ / AWQ / GGUF。量化后体积减少一半以上推理速度提升明显但会有一定精度损失。选型标准我一般这么掂量如果时间紧、资源少只做 SFT 量化就够用如果要做高质量对齐就补上 Reward PPO如果追求极致推理性能就上蒸馏 剪枝 量化三层组合。压缩手段不建议一上来全上先单测量化看精度下降能不能接受再考虑要不要加蒸馏。3. 核心实操LLaMA-Factory 微调三件套 SFT / Reward / PPO3.1 SFT 指令微调参数配置和训练日志解读我用的模板配置如下关键项以 7B LoRA 为例model_name_or_path: Qwen/Qwen2.5-7B-Instruct dataset_dir: ./data/sft_data.json stage: sft finetuning_type: lora lora_rank: 32 lora_alpha: 64 learning_rate: 2e-5 num_train_epochs: 3 per_device_train_batch_size: 4 gradient_accumulation_steps: 4 max_length: 2048前三个 epoch 之后我通常会再用 0.5 个 epoch 在 validation 集上跑一次观察 loss 是否反弹。这里有件事值得特别留意LoRA 的训练会冻结原始权重只更新 adapter 部分。所以训练完的产物是 adapter 文件不是完整模型。如果后面直接拿去量化量化工具会一脸懵——它们只认识完整权重。因此 SFT 结束后必须先做一步“合并 adapter 到 base model”。在 LLaMA-Factory 里是这样的命令llamafactory-cli export \ --model_name_or_path Qwen/Qwen2.5-7B-Instruct \ --adapter_name_or_path ./runs/01-sft-lora \ --export_dir ./models/07b-sft-merged \ --export_size 5 \ --export_legacy_format false这一步不要在训练模板里做因为训练模板重活是训练合并是轻量操作。CubeStudio 支持自定义命令可以写一个 shell 脚本作为新任务。我建议单独建一个“sft-merge”任务不然训练完成后临时又去改输入输出很容易出错。训练日志里重点看两个指标loss 是否稳定下降valid loss 是否早停。还有一个容易被忽略的点gradient_accumulation_steps和per_device_train_batch_size的乘积决定了全局 batch size这个值不要太大也不要太小经验值在 32 到 64 之间比较稳妥。太大收敛慢太小容易震荡。3.2 Reward 模型训练构建偏好数据的两个要点Reward 模型本质是从人类偏好中学习“什么答案更好”。CubeStudio 的 Reward 模板底层用的是 LLaMA-Factory 的stage: rm。训练数据格式是{ instruction: 如何缓解焦虑, input: , output: [答案A, 答案B], prefer: 1 }这里prefer表示哪一个回答更好注意下标从 0 开始所以prefer: 1代表答案B更好。训练时模板会自动把两个回答拼在一起用同一个模型分别算出得分用 pairwise loss 拉大好坏差距。实操中有两个坑第一偏好数据里的“好”和“坏”要拉开差距。如果只是“一个比较详细”和“另一个稍微不够详细”Reward 模型学不到东西。最好让坏回答像是“网上随便复制的一段话”好回答是“结构清晰、有步骤、讲证据”。这样模型才能学到实质差异。第二Reward 模型不能和 SFT 模型用同一个 LoRA 权重初始化。因为训练目标完全不同Reward 模型最后学到的分数分布和语言建模分布不是一回事。所以新建任务时基座模型依然用Qwen/Qwen2.5-7B-Instructadapter 为空。训练完成后导出奖励模型也别忘了合并 LoRA。合并后可以写一个简单脚本验证随便输入几个提示词看看好回答、坏回答得分是否拉开。如果分数只差零点几说明数据质量有问题先回去清洗数据而不是继续调参。3.3 PPO 强化学习稳定训练的七个实操建议PPO 模板是三者中最“娇气”的。我踩过的坑如果能堆起来相当于一个小型故障手册。这里的建议给到按优先级排列训练步数不要贪多。建议先跑 1000 步观察而不是一上来 10000 步。PPO 的 loss 波动天然比 SFT 大如果 1000 步内 reward 均值持续下降说明 reward 模型本身有问题先回头看数据。clip 参数不要乱动。ppo_max_token_len和clip_ratio保持默认即可。很多同学喜欢调大 clip 范围结果策略更新太猛模型直接崩掉。参考模型必须冻结。模板里默认 freeze reference model一定不要把它设成可训练否则 PPO 很快会失去目标。学习率调小。PPO 的 actor 学习率一般设在1e-6到3e-6之间比 SFT 小一个数量级。调大容易产生奖励 hack模型输出一些看似高分但语义不通的内容。Critic 模型约束。有的模板里 Critic 和 Actor 共享参数这样还不如分开。如果显存够建议把 Critic 模型单独初始化保证价值网络可以独立学习。监控 KL 散度。每一步更新后actor 和 reference 输出的 KL 散度要在某个范围内。如果 KL 涨得过快说明策略偏离初始模型太远生成的文本容易退化。始终保留 SFT 的 checkpoint。PPO 训练意外中断时最好是回到 SFT 的 merged 模型重新启动不要从半路崩溃的 actor 继续否则灾难已经种下后面只是显性化。一次稳定的 PPO 跑完后对比 SFT 模型你会看到同样的提示词下输出更“克制”了不再长篇大论堆砌无意义内容而且明显更符合人类偏好。这才是强化学习该有的样子。3.4 三阶段之间的产物衔接三阶段跑完之后你会有三个关键产物SFT merged 权重、Reward merged 权重、PPO actor merged 权重。这里有个实际选择最终部署时到底用哪个绝大多数场景下PPO 后的模型效果最好但如果你的业务强调稳定性和可控性SFT 模型往往更可靠。Reward 模型一般不直接参与对话它只用于给回答排序或在 PPO 内作为信号源。所以最终部署一般选 PPO如果有或 SFT 模型。产物衔接要特别注意路径一致性。CubeStudio 里新建任务时输入模型下拉框里可能同时出现多个产物选错一个后面全错。我们总结了命名规范后这种情况少了很多但还是会在启动前再核对一下任务描述里填的模型路径。4. 模型瘦身实战蒸馏、剪枝和量化4.1 知识蒸馏从 7B 压到 3B 的实操记录我们遇到一个真实场景模型要从 7B 压缩到 3B以适配边缘推理卡。直接用 3B 基座做 SFT 效果一般于是用了蒸馏方案——7B 的 PPO 模型当 Teacher3B 基座当 Student目标是最小化两者输出的 KL 散度。CubeStudio 的蒸馏模板参数大概是这样teacher_model: ./models/07b-ppo-merged student_model: Qwen/Qwen2.5-3B temperature: 4 alpha: 0.5 loss_type: kl温度参数temperature设 4是做蒸馏时常用的软化概率分布设置。学生的学习目标包含两部分一是硬标签真实答案的交叉熵二是软标签Teacher 输出的概率分布的 KL 散度。alpha控制这两者的权重我们试了 0.3 太小、0.7 太大0.5 比较均衡。蒸馏后的小模型在大部分测试集上能保留教师模型九成的能力。但有一点必须注意如果 Teacher 本身有偏见蒸馏会把偏见也复制到 Student 上。所以蒸馏之前尽量确保 Teacher 通过安全评估避免偏见被放大。实操中还有个小技巧蒸馏时不要用最高温度的 teacher 输出因为温度太高会稀释太厉害。一般试 4 或 6分别跑一个小样本实验对比 Student 在验证集上的 loss 和指标再选最优。4.2 剪枝结构化剪枝比非结构化更实用剪枝模板解决的是“模型里很多参数其实权重很小、没什么用”的问题。我们用的是结构化剪枝直接剪掉输出通道维度上不重要的部分。模板参数pruning_method: magnitude pruning_ratio: 0.3 target_module: all_linearpruning_ratio表示剪掉百分之三十的通道。这个值建议从 0.2 开始试每次加 0.1然后跑评估看掉点速度。7B 模型剪 20% 通常掉点不大剪 50% 就可能出现胡言乱语。剪枝后必须接一个微调恢复阶段俗称“蒸馏式恢复”。直接用剪枝模型在线推理效果往往不太理想因为权重稀疏度和数据分布发生了变化。我们之后会在一个小的指令数据集上再做 1 个 epoch 的 LoRA 微调把能力拉回来一些。如果没有这个恢复步骤剪枝收益会被精度损失抵消。剪枝和量化的先后顺序也有讲究。我的建议是先剪枝再量化。剪枝会改变权重分布而量化对这种分布变化很敏感。如果先量化再剪枝量化误差和剪枝误差会叠加效果更差。两人都以“先做影响小的操作”为原则我们亲测结果是这个顺序比反着来精度平均高 3 到 5 个百分点。4.3 量化INT4 / INT8 的选择与精度评估量化是压缩环节里最立竿见影的。一个 7B FP16 模型占 14GB 显存量化成 INT8 占 7GBINT4 占 4GB 左右。CubeStudio 的量化模板可以选 GPTQ、AWQ、GGUF 三种方案。我的经验GPTQ适合 NVIDIA GPU 上的推理精度损失在 INT4 下比较可控。它对校准数据比较依赖校准集不要用训练集用单独的样本。AWQ它根据激活感知选出重要权重通道做高精度保留所以 INT4 下效果往往比 GPTQ 更稳一点尤其适合 7B 以下模型。GGUF主要给 llama.cpp 这类 CPU 推理框架使用。如果你要部署到纯 CPU 环境或本地方便工具选它。量化命令模板以 GPTQ INT4 为例quant_method: gptq bits: 4 group_size: 128 desc_act: true calibration_dataset: ./data/calib_samples.jsonlgroup_size是量化分组的大小越小精度越高但会带来更长的编码时间和更大的模型文件。desc_act表示按激活值排序来重排通道对 INT4 精度有帮助但会增加一点推理开销。量化后的模型一定要跑一遍评估。很多同学看到“体积减少一半”直接上线结果线上连续掉点投诉不断。我建议量化评价至少包含三个测试集通用指令集、领域任务集、安全测试集。这个组合能同时观察能力保留和安全性。4.4 压缩组合拳的顺序如果项目对模型体积和速度有极致要求可以按“蒸馏 - 剪枝 - 量化的恢复微调 - 最终量化”的顺序来。为什么这个顺序合理蒸馏已经缩小了规模剪枝再进一步去除冗余最后量化进一步压体积。每一步都建立在上一步更干净的模型基础上。还要注意一点剪枝和量化后的模型如果要做安全评估评估结果不能直接和原模型对比。因为压缩后模型的能力分布变了安全评估的阈值要适当调整。我们的做法是优先保证安全指标不劣化超过 2%若超过回到量化校准集或剪枝比例上找原因。5. 安全评估与上线检查5.1 用 OpenCompass 跑通用能力评测微调和压缩做完不能直接拍脑袋说“效果不错”。要用标准评测集验证。CubeStudio 的评估模板集成了 OpenCompass支持 MMLU、CMMLU、GSM8K、HumanEval 等主流基准。我的操作流程分两层第一层快速摸底。选三个有代表性的测试集MMLU综合知识、GSM8K数学推理、HumanEval代码。跑一次大概二十分钟作为压缩前后的横向对比。eval_dataset: mmlu, gsm8k, humaneval eval_batch_size: 8第二层深度评估。对业务相关领域单独测试。比如做法律垂直模型就跑法律问答集做金融模型就跑金融指令集。OpenCompass 模板里可以自定义eval_dataset路径直接指向我们自己的测试 JSON 文件。评测结果会输出每个测试集上的准确率、困惑度等指标。我最看重的是“压缩前后掉点幅度”。比如量化后 MMLU 从 72% 掉到 70%这个是正常范围如果从 72% 掉到 60%说明量化参数需要调整或者校准数据集和业务数据分布差异太大。5.2 安全评估不仅要看“违不违规”更要看“边缘试探”合规底线是所有模型上线前的硬检查。安全评估模板一般用规则 模型两种方式结合规则匹配一些明显违规词和意图模式模型则用一个安全判别模型对输出做分类。实际操作中光用“安全分类为安全/不安全”这种粗粒度不够。我们通常自定义几类风险提示词比如诱导模型输出危险操作步骤要求模型扮演某种不合适的角色用反问语气诱导模型透露底层隐私信息这些输入跑一遍记录模型的响应是否被直接阻止或是否给出合理拒绝。安全评估报告会生成一个“拒绝率”和“不安全命中率”。一个容易被忽略的细节安全评估不仅要测正常输入还要测“对抗性输入”。比如把提示词用大小写混写、同音字替换、emoji 插入等方式变形看模型是否还能正确拒绝。我们实测发现很多模型在正常讨论时很安全但提高编码度之后就开始松口。所以评估模板里我建议要加“jailbreak”测试集哪怕只有二十条也能暴露出不少问题。5.3 上线前的最终检查清单在把模型推到真实环境前我会逐项核对模型完整性和版本号从产物列表中确认是最终 PPO 模型还是 SFT 模型别拿错版本。Tokenizer 一致性微调阶段有没有加新词新词必须在最终权重里保留。上下文长度限制训练最大长度是多少线上输入如果超长服务端要做好截断或提示。温度参数评估时用的温度和线上推理温度要一致否则指标对不上。量化校准集信息如果量化有用校准集这个数据集要留存方便复现或调整。评测结果存档把评测配置、结果、日志一起归档到项目里方便下次复盘。6. 常见问题与排查技巧实录6.1 任务启动即失败先查三件事当你点“运行”后几秒就失败经验上九成是这三件事之一第一模型路径不对。确认你选的model_name_or_path在平台里真的存在。不要在本地想当然写./models/qwen要先在产列表中复制路径。第二数据集格式不符。模板检查到 JSON 格式缺失instruction或output字段时会直接报错。用模板自带的数据预览功能上传后先看前几条。第三GPU 资源超限。检查任务申请的资源是否超过套餐额度。有时候同一个项目里并发任务太多导致 GPU 配额抢不到。看任务状态的错误信息如果是CUDA out of memory则是显存不足如果是Quota exceeded则是资源配额问题。6.2 训练中断与断点恢复训练中途断网或任务被中断心态容易崩但其实有救。CubeStudio 任务支持断点续训前提是要开启save_strategy: steps和save_on_train_end: true。在 SFT 和 PPO 任务模板里都建议开。如果模板没有自动检查点也可以自己写任务命令deepspeed --include localhost:0,1,2,3 --master_port 9901 \ src/train_bash.py \ --stage sft \ --model_name_or_path ... \ --checkpoint_dir ./runs/01-sft-lora \ # 从断点继续 ...其余参数不变这个重训逻辑很实用。不过要注意PPO 任务的断点续训偶尔会出现 reward 跳变我们遇到好几次从断点续跑后 reward 均值暴跌最后方案就是从头跑。所以 PPO 任务如果中途断了超过 2 个小时干脆直接从头开始更省心。6.3 量化后模型效果跳水量化后掉点太多先不要怀疑模型优先检查这几个方向校准数据太少。GPTQ 校准一般至少需要 128 条太少会低估权重的分布。desc_act是否开启。INT4 下不开desc_act有些矩阵精度会明显下降尤其是一些特征范围特别大的层。是否有模型结构兼容问题。量化后的模型加载时要用对应的量化版片段。用普通的AutoModelForCausalLM直接加载 GGUF 是加载不了的必须配合对应推理框架。还有一个常用技巧量化后进行“感知量化训练”。这里不是重新训练而是在模型上跑一段 10 到 20 分钟的小学习率微调来修复量化带来的分布漂移。模板里如果有post_quantize_ft选项可以试试。6.4 PPO 训练不收敛时的排查路径PPO 不收敛先画三张图actor loss、critic loss、reward mean。判断依据reward mean 一路向下先怀疑 reward 模型质量回去查偏好数据。reward mean 上升到某一值后突然崩溃往往是 KL 惩罚太大导致策略剧烈变化把kl_coef调小一点。critic loss 持续振荡且不下降说明 critic 网络学习困难检查学习率设置或者把 Critic 模型换成更浅的层数。另一个隐蔽问题是 reward 模型和 actor 之间出现了“奖励黑客”。比如 reward 模型对过短的回答给高分PPO 就会诱导模型输出越来越短最后变成“贪一个字”。所以监控输出长度的分布也很重要。6.5 文件命名和路径的隐藏坑模板默认会生成一堆日志和输出命名里若带了空格、中文或特殊符号在后续不同模板间传参时经常会出问题。我的建议是全程用英文小写下划线命令比如qwen2.5_7b_sft_lora_r32_ep3。常见的一个隐藏坑合并 adapter 后的模型目录里还会包含原来的adapter_model.bin或adapter_config.json。如果把它直接交给量化模板量化工具可能识别成了 LoRA 权重导致后面的产物完全不对。解决办法是合并且导出后就把旧 adapter 文件清掉只保留 merged 版的config.json、tokenizer*和.bin文件。7. 一点个人体会现在团队的新项目默认都在 CubeStudio 上跑这个全链路流程。它确实把“想清楚再动手”变成了一种强制习惯因为每一步的参数和产物都被记录复盘时非常省事。如果一开始经验不够建议每一步跑完后都把我上面提到的检查点过一遍不要连着把六个环节一次全跑完否则哪一步错了排查成本会大到你怀疑人生。最后再分享一个小技巧所有模板里都允许自定义启动命令不要怕修改参数。遇到模板没覆盖的场景把它当成一个普通脚本容器写自己的命令执行。比如我常在这里面跑llamafactory-cli export合并 LoRA或是用 Python 脚本做自定义数据清洗都不需要新开环境。算下来从零到获得一个经过微调、对齐、压缩并通过评估的模型我们目前最快能做到两天内交付。省下来的时间都用在打磨数据和思考业务要求上了——这才是做模型该花时间的地方。