
在动手写之前先把话说在前面如果你是从“微调一下模型能跑就行”这个阶段过来的那这篇内容大概率能帮你少走很多弯路。大模型上线前真正的链路远不止 SFT 一步——微调完了要评估评估完了可能还要做 Reward Model、走 PPO 对齐接着为了省显存你得量化为了提速你要剪枝甚至还得把大模型蒸馏成小模型最后还要做安全评估、上推理服务。这一套流程在传统模式下是各种脚本、各种环境、各种显卡集群拼出来的任何一个环节掉链子整个排期就崩了。CubeStudio 这类的平台任务模板解决的问题就是把这些分散的步骤编排成一条可复用的流水线。底层微调靠 LLaMA-Factory 这类成熟开源框架蒸馏、剪枝、量化、评估、部署则作为独立任务挂在同一个工作流里。这篇文章我会从“为什么需要一站式”“每个环节怎么落地”“踩过哪些坑”三个层面把大模型从微调到量化剪枝的完整实操流程拆开讲透。下面直接进入正题。1. 一站式全链路模型上线前为什么要跑这一整套很多人对大模型开发的认知还停留在“数据丢进去LoRA 拉一拉loss 降了就算完事”。但真到了业务侧你会发现微调只是起点。一个模型想要从“能对话”变成“能上线”中间必须经历能力对齐、尺寸压缩、性能验证三个大阶段这三个阶段之间还有强依赖关系顺序错了后面的成本会成倍增加。先说最核心的两个问题为什么要做对齐为什么要做压缩。对齐指的是让模型的输出符合人类的偏好和指令要求。SFT 只能教会模型“模仿正确答案”但它不知道什么样的回答是更好的。Reward Model 负责给回答打分PPO 再根据这个分数去调整策略模型让模型在探索中逐渐学会“好的回答长什么样”。这个过程直接决定了模型在真实场景中的可用度省不得。至于压缩是因为大模型在业务落地时算力和显存都是硬约束。一个 7B 模型用 FP16 跑显存占用接近 15GB如果再算上 KV Cache 和上下文窗口个人电脑和普通服务器根本扛不住。量化到 INT4显存能降到 4GB 级别推理速度反而更快。剪枝则是把不重要的参数或结构砍掉让模型更轻量。蒸馏干脆用一个小的学生模型去模仿大模型的行为追求的是“用更小的体积换接近大模型的能力”。我在实际操作中的体会是这几个阶段必须在同一个体系里跑否则问题会出现在衔接处。举个很典型的例子你在本地用 A 框架做了量化量化之后的模型要评估发现格式不兼容又得写转换脚本转换完丢给推理框架发现动态量化参数不对推理结果和量化前差异巨大想回退找原因发现原始微调产物丢了。这种“每个环节单独能跑但连起来就是不通”的状态才是真实的工程常态。CubeStudio 的思路是先把每个环节封装成模板模板之间通过任务依赖关系串联上一个任务的产物作为下一个任务的输入。微调完直接触发量化量化完直接触发评估评估结果自动回传到总览页面。人在中间不需要频繁切环境、改路径排错成本直线下降。这条链路还有一个容易被忽略的地方资源管理。微调阶段通常要独占 GPU量化阶段显存需求小但 CPU 计算密集评估阶段则是“GPU 推理 CPU 跑指标”混合负载。传统脚本模式下你得自己手动分配机器高峰期抢显卡低峰期又闲置。平台模板会把资源请求写进任务定义里调度器按阶段自动排队、释放整个流程的资源利用率会好看很多。2. 微调与对齐阶段LLaMA-Factory 任务模板的落地细节微调和对齐是整个链路的起点也是变量最多的环节。LLaMA-Factory 在这个领域使用率很高因为它把 SFT、Reward Model、PPO、DPO 等训练模式全部收进了一套 CLI 和 WebUI 里数据格式标准化做得扎实。在 CubeStudio 上做微调本质上是把 LLaMA-Factory 的训练命令包装成任务模板然后通过平台注入数据集、超参数和计算资源。2.1 数据格式怎么排模板才不会报错我见过太多“训练脚本爆了报错信息看不懂”的情况十有八九是数据格式出了问题。LLaMA-Factory 默认支持 Alpaca 格式和 ShareGPT 格式两者字段结构不一样别混用。Alpaca 格式每条数据包含三个字段instruction指令、input输入、output输出。其中input是可选的如果指令本身已经完整input可以留空。比如“写一首关于春天的诗”instruction就是这句话input为空如果指令是“根据以下素材写一首诗”素材放在inputinstruction是“写一首诗”。我把字段结构列出来字段是否必填说明instruction必填任务指令模型需要理解和执行的请求input选填指令所需的附加上下文或素材output必填期望模型生成的答案system选填系统提示词用于设定角色或约束ShareGPT 格式则是对话级数据最外层是一个数组每个元素包含conversations字段内部是from角色和value内容交替的消息序列from只能取值human或gpt。这种格式适合对话类任务比如客服、角色扮演。在模板里创建微调任务时一定要先确认数据集格式和 base model 的 tokenizer 兼容性。我有个习惯先抽 50 条数据在本地写好校验脚本检查字段完整性和角色是否交替正确再上传平台。宁可先花十分钟校验也不要等任务跑了两小时之后才发现数据有问题。Reward Model 的数据格式和 SFT 完全不同。它需要成对的回答一条数据包含instruction、chosen好的回答和rejected差的回答。注意chosen和rejected必须是针对同一个指令的两个不同回答否则 Reward Model 学不到“好坏对比”的信号。实战中还需要控制两个回答的长度差异如果chosen总是比rejected长很多模型可能会学会“越长越好”而不是“质量越好”这是一个非常隐蔽的偏置。2.2 SFT 实操LoRA 参数怎么定全参微调怎么选SFT 分为全参微调和参数高效微调两大类。全参微调效果好但显存开销大得惊人光优化器状态就要吃掉好几倍模型参数量的显存没有多卡并行支撑基本跑不动。参数高效微调里最常用的是 LoRA原理是冻结原模型权重只在 attention 层的线性投影旁插入低秩矩阵。在 LLaMA-Factory 里用 LoRA核心参数有这么几个lora_rank秩、lora_alpha缩放系数、lora_dropout丢弃率。我的经验值是lora_rank从 8 到 16 起步lora_alpha通常设成lora_rank的两倍也就是 16 到 32lora_dropout默认 0.05。秩太小表达能力不够秩太大微调的特性和全参微调逐渐接近显存优势会被削弱。一个 7B 模型配 12GB 左右显卡lora_rank16基本够用。训练超参方面有几个参数之间的关系值得展开说说。第一个是per_device_train_batch_size和gradient_accumulation_steps两者相乘才是真正的全局 batch size。显存不够时千万不要死磕 batch size把per_device_train_batch_size降到 1然后用gradient_accumulation_steps加大累积步数效果是一样的只是训练时间变长。第二个是学习率LoRA 微调通常用 1e-4 到 2e-4 之间全参微调则可以降到 1e-5 到 5e-5。学习率设太大会导致灾难性遗忘模型可能连原本会的能力都丢了。我在模板里习惯加一个关键参数max_length也就是输入和输出的拼接长度上限。这个问题非常容易被忽视。7B 模型的原生最大长度可能是 4096但直接拉满会让显存瞬间翻倍。实际业务中指令场景超过 2048 的都不多模板里把max_length设为 2048 或 3072可以节省大量显存并加快训练。注意max_length会影响模型对长上下文的感知能力如果业务真的依赖长文档再临时调高也不迟。2.3 Reward Model 与 PPO对齐操作中最难驾驭的一环如果说 SFT 是“教会模型说话”那 Reward Model 和 PPO 就是“教模型说好话”。整个过程分三步先训练 Reward Model再用 Reward Model 的分数作为反馈通过 PPO 算法优化策略模型。Reward Model 训练数据格式上面已经说了重点是训练目标的设定。LLaMA-Factory 的 Reward Model 训练基于 pairwise ranking loss模型对chosen的打分要高于rejected。如果数据里这两者的差异非常细微模型就会在学习中摇摆。我的做法是给每条数据加一个margin字段表示期望的分数差距这样 Loss 函数会更早收敛。数据清洗时也注意chosen和rejected不要出现明显的错别字或格式混乱否则 Reward Model 会学到“错别字是差回答”的偏置。PPO 阶段是重头戏涉及四个模型策略模型也就是你微调后的那个模型、参考模型冻结的初始模型用来计算 KL 散度、Reward Model打分模型、Critic Model价值模型。这四个模型加起来显存开销非常大。如果用的是 7B 模型四份模型参数 优化器状态30GB 显存起步。模板里建议开启平台的多卡并行选项否则很容易 OOM。PPO 的超参数里最敏感的是 KL 惩罚系数一般用kl_coef表示初始值我习惯设在 0.02 到 0.1 之间。它的作用是限制策略模型和参考模型的偏离程度防止模型为了拿高分而输出一些“奖励漏洞”式的回答。如果训练过程中response_len突然暴增或者回答变得极其冗长大概率是 KL 惩罚太弱。另一个参数是clip_range默认 0.2控制策略更新的步长太大容易训练不稳太小又收敛太慢。每次跑完 PPO我都会把 Reward 分数变化曲线拉出来看一眼正常情况是稳步上升、最后震荡收敛。如果曲线剧烈抖动优先检查 KL 系数和学习率。说句真心话PPO 阶段是整个链路里最难调的哪怕参数都设对了数据质量稍差就会让 Reward Model 变成“瞎打分”。我建议在模板里先跑一个极小的实验比如 100 条训练数据、1 个 epoch验证 Reward Model 打分的区分度确认没问题再上全量数据。这个习惯帮我省掉了好几次全量训练失败的痛苦。3. 压缩阶段蒸馏、剪枝、量化如何按顺序搭流水线微调和齐搞定了模型在业务侧还是太重。这时候就轮到压缩三件套上场蒸馏、剪枝、量化。这三个环节有明确的先后依赖关系顺序弄反会直接拉低最终效果。3.1 知识蒸馏大模型教小模型先做再剪知识蒸馏的核心思路是用一个大而强的模型Teacher去教一个小模型Student学习让 Student 的输出行为逼近 Teacher。为什么蒸馏要排在最前面因为模型的“知识”在压缩过程中会逐渐丢失如果先把模型剪了或量化了再做蒸馏时 Teacher 本身就不够强教学效果自然打折。反过来先蒸馏再剪枝后面的压缩环节造成的损失还能再用一次短周期的恢复训练来弥补。蒸馏的落地关键有两个。第一是数据选择蒸馏数据不需要标注但需要覆盖目标业务场景的分布。直接用业务侧的指令数据或通用语料都行。第二是损失函数设计常见的做法是让 Student 的 logits 分布去匹配 Teacher 的 logits 分布用 KL 散度做损失温度参数temperature控制分布的平滑程度。温度越高分布越平滑Student 越容易学到 Teacher 的“风格”而不是“死记硬背”。我的经验是温度先设 2.0 到 4.0 之间效果不好再微调。具体到模板配置上distill 任务通常要指定 Teacher 模型路径、Student 模型路径、蒸馏数据集、温度、KL 损失权重、CE 损失权重。KL 损失权重太高Student 会过度模仿 Teacher 的错误行为太低又学不到风格。我一般让 KL 权重和 CE 权重对半分跑几个小实验再定。蒸馏完成后Student 的精度可能只比 Teacher 低 1% 到 3%但参数量往往只有 Teacher 的 1/3 甚至更小这个“性价比”在工程上是值得的。3.2 模型剪枝结构化与非结构化怎么取舍剪枝分两种路线非结构化剪枝和结构化剪枝。非结构化剪枝是把权重矩阵里绝对值较小的单个参数置零这种方式压缩率高但会导致权重矩阵变成稀疏结构很难在 GPU 上获得实际加速效果通常需要配合专用推理库或硬件。结构化剪枝则是直接把某些整行、整列甚至整个通道删掉比如在 Transformer 里剪掉部分注意力头或前馈网络的隐藏单元。它的优点是对推理框架友好模型结构变小了显存和计算量都实实在在地降下来但精度损失通常比非结构化严重。实操中大多数业务场景选择结构化剪枝的变体或者先用 SparseGPT 这类算法做非结构化剪枝再配合量化减小存储体积。模板里跑剪枝任务时有几个关键参数需要留意。sparsity稀疏率表示要剪掉的比例7B 模型我建议从 0.1 到 0.2 起步一味追求 0.5 以上的稀疏率模型基本就废了。calibration dataset校准数据集必须和下游任务分布接近它的作用是让剪枝算法在保留权重时优先保留对下游任务更重要的权重。剪枝完一定要接一个短周期的恢复训练学习率调低比如 1e-5 左右跑上几百步把损失的精度补回来。恢复训练这一步很多人会漏掉但漏掉之后模型的 PPL困惑度很可能飙升 20% 以上。平台上的剪枝模板一般会把剪枝和恢复训练打包成一个复合任务中间自动生成一个“剪枝中间产物”的 checkpoint方便你对比剪枝前后的效果。我在跑完剪枝后一定会先拿几个固定的评测 prompt 跑一轮人工检查看看语义理解有没有明显劣化再决定是否继续往下走。3.3 量化INT8 还是 INT4校准集决定了你的下限量化是把模型权重从 FP16 压缩到更低比特比如 INT8、INT4从而减少显存占用和推理延迟。量化分成训练后量化PTQ和量化感知训练QAT两类。PTQ 直接对训练好的模型做转换速度最快适合 7B 以下的中小模型QAT 在训练过程中就模拟量化误差精度保持更好但训练成本高常用于大模型或精度敏感的场景。实际模板配置里最常用的是 GPTQ 和 AWQ 这类基于校准集的 PTQ 方法。它们都会用到校准数据集。校准集的长度不需要很长但覆盖面必须广我一般从验证集中按类别各抽取 128 到 256 条作为校准集。这里有个关键教训绝对不要拿训练集做校准集否则模型在量化后会对训练数据过拟合泛化能力变差。校准集最好独立于训练集和实际业务分布相近。INT8 和 INT4 的取舍也很现实。INT8 精度损失小但显存降幅有限INT4 能把 7B 模型压到 4GB 显存内个人电脑都能跑但词元生成的吞吐量会受一定影响。业务侧如果对生成质量敏感先从 INT8 开始跑评估确认 PPL 变化在可接受范围内再尝试 INT4。模板里我通常还会开启per-group quantization和act-order这类选项它们能在几乎不增加延时的前提下显著提升低比特量化精度。量化的最后一个坑是“量化后还要不要做恢复训练”。如果你的量化方法是 PTQ那建议量化后再跑一遍轻量级 SFT用几百条高质量指令数据把模型输出拉回正常轨道。这一步叫“量化感知恢复”能有效缓解量化带来的分布偏移。很多平台上叫 “QAT 微调”或 “recovering fine-tune”本质就是 quantization-aware 的轻量训练。4. 评估与开放部署用 OpenCompass 验收模型再发布服务模型经过压缩之后能力到底还剩多少不是靠拍脑袋感觉而是要跑一套标准化的评测。OpenCompass 是目前比较成熟的开源评测体系支持从语言理解、知识问答、代码生成、数学推理等维度全方位评估模型。在 CubeStudio 模板里评估任务通常分为能力评测和安全评测两大类。4.1 能力评估跑起来从指标解读到评测集选择能力评估的第一步是选定评测集。通用模型可以直接用 OpenCompass 预置的 C-Eval、MMLU、GSM8K 等数据集。业务侧则建议上传自定义评测集格式一般是 prompt ground truth 的结构化数据。配置评测任务时注意生成阶段的参数temperature设为 0 或接近 0保证评测结果可复现max_tokens要根据任务设置合理的上限太短会截断正确回答太长会浪费推理时间。评估结果出来后不要只盯着准确率一个指标。生成类任务还要看 BLEU、ROUGE代码类任务要看 passk数学类任务要看最终答案匹配率。OpenCompass 的输出文件一般是分类汇总的 JSON 或 Markdown 表格我习惯把不同阶段的评估结果整理在一张对比表里作为判断每个压缩环节损失的依据。评估维度评测集示例关键指标环节对比重点通用能力C-Eval、MMLUaccuracySFT 前后能力变化指令遵循IFEvalprompt 级准确率对齐阶段提升幅度数学推理GSM8K答案正确率剪枝、量化后的下降幅度代码生成HumanEvalpassk蒸馏后能力保留程度这里还要强调一个经验评估任务必须在量化、剪枝后立刻跑不要等全部压缩完了再统一评估。因为一旦发现某个环节导致指标明显下跌回溯定位的代价会小得多。平台模板支持定义评估任务依赖串在压缩任务之后产物一生成就自动触发评估这个设计我用了很久非常顺手。4.2 安全评估与红队测试上线前不能跳过的关卡安全评估做的是“内容安全、指令遵循边界、输出合规性”这类维度属于工程化评测不涉及具体政策口径。它通常包含两套打法自动化红队测试和人工抽检。红队测试是指用一组对抗性 prompt 去打模型看模型会不会被诱导生成越界内容、会不会泄露系统提示词、会不会做出超出权限的操作。这些 prompt 样本在很多公开对抗性数据集中都能找到平台模板里一般也内置了预设红队词库。自动化评估之外人工抽检是必须的。机器只能判断“文本是否命中违规词库”但很难理解上下文语义。我习惯从评估结果里随机抽取 100 条生成结果逐条看内容质量、语气是否自然、有没有答非所问。这个环节别省很多模型在指标上表现完美实际用起来却驴唇不对马嘴只能靠人眼发现。安全评估的另一个重点是指令注入检测。比如在用户输入里夹带“忽略之前所有指令”这类提法看模型是否会被带偏。这里要给模型加一层系统提示词约束同时在推理服务层面做输入检查。不要指望模型本身完全免疫注入工程上靠的是“模型 规则引擎”双重防护。我在模板里会同时开一个Safety Defensive任务它对用户输入做一轮脱敏和风险标记再和后端模型服务串起来。4.3 部署与推理跑通 vLLM开放 OpenAI 兼容接口评估通过之后模型就该上推理服务了。目前业内最通用的方案是 vLLM它用 PagedAttention 管理 KV Cache吞吐量比原生 Transformers 推理高很多。部署模板里需要指定模型路径、量化方式AutoAWQ 或 GPTQ、张量并行大小、最大序列长度、GPU 显存利用率。显存利用率这个参数值得说一说它控制 vLLM 预分配多少显存给 KV Cache。设太低并发能力上不去设太高留给模型权重的空间不足会出现 OOM。7B INT4 模型我通常设 0.85 到 0.9先跑一轮压测看稳定情况再微调。部署完成后平台一般会生成一个 OpenAI 兼容的 API 地址方便下游应用直接调用。这一步的意义在于把模型服务和业务解耦上层应用不需要关心底层跑的是什么模型、用什么推理框架只要发 HTTP 请求拿响应就行。我在实际项目里经常把部署服务再接入一个评估模板用真实服务的输入输出跑一次评测确保“部署后的模型”和“离线评测的模型”行为一致。这是很多人容易忽略的vLLM 的采样参数和离线评测时的生成参数如果不一致最终效果会有细微差别上线前必须对齐。5. 常见问题与排查技巧实录流水线越完整遇坑的机会就越多。下面这些问题是实战中出现频率最高的整理成速查表可能对大家帮助更大。现象可能原因排查方法训练一开始就报 shape 不匹配SFT 数据格式混用Alpaca 和 ShareGPT 混淆检查数据顶层结构和字段名显存 OOMper_device_train_batch_size 过大降到 1梯度累积补偿Reward 分数不升反降chosen/rejected 数据对过于相似增加 margin 或清洗数据PPO 训练崩溃loss 出现 NaNKL 系数过小策略更新过猛调大 kl_coef降低学习率剪枝后困惑度飙升没做恢复训练或稀疏率过高降低稀疏率接短周期 SFT量化后回答内容严重错误校准集选用了训练集换独立验证集重新校准vLLM 并发一高就 OOM显存利用率设太高调低 gpu_memory_utilization部署 API 输出和离线评测差异大采样参数不一致统一 temperature/max_tokens有几个排查经验值得单独展开。第一个是关于“CUDA OOM 但显存看起来够用”的情况。这个极大概率是碎片化导致的。多个任务在同一个 GPU 上交替运行后显存碎片会越来越严重明明总剩余显存充足大块连续显存就是申请不到。解决方法是模板里显式声明独占 GPU或者定时清理残留进程。平台如果支持内存池配置优先开启。第二个是“LoRA 训练完忘了合并权重”的尴尬。训练完的 adapter 如果直接拿去量化或部署会导致推理结果完全不对。你需要在微调任务后紧接着跑一个 merge 任务把 LoRA 权重和 base model 权重合并产出完整的模型 checkpoint再给后续的蒸馏、剪枝、量化任务使用。这个顺序在模板里要固定下来不然你会被各种诡异报错折磨到怀疑人生。第三个是“多卡训练时参数不一致”的问题。LLaMA-Factory 在 DeepSpeed 或 FSDP 模式下有些超参数是全局配置有些则是每卡配置。如果你修改了learning_rate但没同步到所有 worker会出现训练 loss 曲线震荡的情况。模板化之后这些参数会统一注入到所有卡上手动改的时候就要格外小心最好把参数定义集中在一个 manifest 文件里不要散落在不同脚本中。第四个是我个人印象最深的“量化后的模型没做恢复训练就上了评估结果 PPL 高了 30%白白浪费了三天排期”。这种损失在模板里是可以预测的。我的建议是每一步压缩之后都自动触发一次“快速恢复训练 回归评测”的复合任务把损失控制在最小。宁可每层多花几小时也不要等整条链路跑完了才发现某个环节把模型搞坏了。6. 我把这条链路拆开重跑一遍之后的变化如果要让我给这条全链路排个优先级我的排序是数据质量 参数配置 模型结构。很多时候你觉得是量化参数没调好实际是微调阶段的训练数据出了偏置你觉得是 PPO 没收敛实际是 Reward Model 训练数据质量不够。模板化的好处在于当全流程变得可复现时你才有精力去排查“到底哪个阶段的输出开始偏离”。我个人后来习惯的做法是把评估任务从“最终验收”提前到“阶段卡点”。每完成一个环节就自动跑一轮轻量评测比如 200 条种子数据几分钟就能出结果。这样任何一个环节的劣化都会立刻暴露而不是等到最后统一评才发现问题。CubeStudio 这个平台的任务模板本质上做的就是这个事把整个生命周期变成一条可追溯、可回滚、可对比的流水线。对我这种既要抠算法细节、又要管工程交付的人来说这个思路比一个个孤立的实验脚本要可靠得多。如果你也要搭这么一套链路我的建议是从微调模板入手先跑通一版最小的端到端流程再逐步叠加蒸馏、剪枝、评估任务。不要一开始就上全量模型和全量数据用 7B 模型跑通流程验证各个环节的输出格式和依赖关系再切换到真正的目标模型。这套流程我踩过的坑上面基本都提到了剩下的就是你自己在跑数据时积累体感。模板是死的但调参和理解数据的过程永远是活的。