
简介面向大模型算法工程师、深度学习研究者与AI应用开发者这份191页实操指南系统串联DeepSeek模型训练、微调与蒸馏全流程重点对比自监督预训练、Prompt-Dropout微调及蒸馏模型稀疏化三大核心技术路径可帮助读者建立从数据准备到工程部署的完整方法论。压缩包大小11.32MB内含单个PDF文件支持目录章节跳转与左侧书签快速定位查阅起来非常便捷。内容共46个大章节仅从前20个章节即可看出不仅涵盖预训练数据体系构建、对比样本构造、损失函数定制、数据清洗算法、分词器词表扩展、超参数调优、分布式训练架构、梯度监控与checkpoint管理等工程基础还深入拆解了Prompt Dropout原理、适配改造、模板设计与概率选择策略以及微调任务类型与Prompt范式的匹配方法。目前已有122人浏览学习适合作为大模型训练与微调方向的中高级技术参考。1. 从API调用到本地复现DeepSeek全流程真正难的是这三道闸门很多人把DeepSeek的API用到顺手就误以为自己已经懂了大模型训练。等到真正需要私有化部署、模型微调、或者把模型压到单卡能跑时才发现日常的API调用只是把黑匣子又包了一层。这份以DeepSeek为主线的全流程指南核心不是教你“怎么发请求”而是把一条完整的链路摊开自监督预训练解决模型有没有知识Prompt-Dropout微调解决模型听不听得懂人话蒸馏与稀疏化解决模型能不能在有限显存里真正跑起来。适合三类人需要本地部署的工程师、想复现训练技巧的研究者以及刚接手模型、连训练日志都看不懂的团队负责人。读完这条链路你会清楚地知道每一步的输入、输出、代价和翻车点在哪里。2. 自监督预训练的成本与收敛判断先搞清楚它和微调隔着多少账再决定要不要碰2.1 同样叫“训练”自监督预训练和微调的目标完全不同自监督预训练顾名思义不需要人工标注。它的学习信号来自文本本身——给模型一段话遮住后面内容让它预测下一个token。DeepSeek这一代模型在预训练阶段吃的就是千万级tokens的无标注语料模型从这些语料里吸收语言规律、世界知识和推理底色。这个阶段的loss降到多少、算力烧了多少决定后续所有工作的起点。微调则完全不同它是把已经预训练好的模型拿到一批高质量标注数据上再走一遍。数据量少一个量级但每条数据都是“问题理想回答”的配对甚至带上人工打分或推理过程。这个阶段模型学的是表达格式、任务边界和用户的真实意图。如果你把微调比作“让一个已经有知识的人学会开会说话”那预训练就是“把一个人从小学养到大学毕业”两者的数据、算力和耗时完全不在一个量级。这也是标题里“对比”两个字的意义所在。很多人拿到DeepSeek模型后第一反应是“从头预训练一个行业版”但看到账单就退缩了。实际上对绝大多数团队来说自监督预训练的正确用法是“续训”而不是“从零训练”在DeepSeek公开权重的基础上用行业语料继续做自监督让模型补齐垂直领域知识。这样既能利用已有权重的通用能力又不用承担从零开始那股烧钱无底洞。另外一点要记住自监督预训练的loss曲线和微调的loss曲线没有可比性。预训练loss受语料质量、批次大小、上下文长度影响极大同样是跑一万步语料里重复内容多loss会极低但不代表模型更强。判断训练有没有生效不能只看曲线末端还要看外部验证集的表现。2.2 续训场景下最实用的自监督训练骨架参数怎么定、断点怎么留不管是从零预训练还是在已有权重上续训训练循环的基本结构是一样的。这里给出一段可以直接改着用的“续训”最小骨架采用Hugging Face Trainer实现适合单机多卡或单卡低显存环境# continuous_pretrain.py from transformers import ( AutoModelForCausalLM, AutoTokenizer, Trainer, TrainingArguments, DataCollatorForLanguageModeling, ) from datasets import load_dataset model_dir ./deepseek-base # 已有的 DeepSeek 权重目录 data_files industry_corpus.jsonl # 未标注的行业文本每行一段完整文本 tokenizer AutoTokenizer.from_pretrained(model_dir) model AutoModelForCausalLM.from_pretrained(model_dir) def tokenize_fn(example): # 自监督阶段只截断不做 paddingpad 交给 DataCollator out tokenizer( example[text], truncationTrue, max_length2048, ) out[labels] out[input_ids].copy() # 每个位置都要预测所以标签就是自身 return out dataset load_dataset(json, data_filesdata_files, splittrain) dataset dataset.map(tokenize_fn, remove_columnsdataset.column_names) training_args TrainingArguments( output_dir./ckpt, per_device_train_batch_size1, # 显存不够时就把 batch 压到最小 gradient_accumulation_steps8, # 用累加凑等效 batch size learning_rate5e-5, warmup_steps200, lr_scheduler_typecosine, logging_steps10, save_steps500, # 每 500 步存一次断点 save_total_limit5, fp16True, # 老显卡用 fp16新卡建议 bf16 gradient_checkpointingTrue, # 用计算换显存 max_steps5000, ) trainer Trainer( modelmodel, argstraining_args, train_datasetdataset, tokenizertokenizer, data_collatorDataCollatorForLanguageModeling(tokenizer, mlmFalse), ) trainer.train()这段代码里最容易被忽略的是per_device_train_batch_size1加gradient_accumulation_steps8的组合。自监督训练的成本瓶颈几乎都在显存与其开大batch然后OOM不如压到单卡batch1用梯度累积获得等效batch8的效果。这是因为语言模型的梯度噪声可以通过累积平滑但batch翻倍并不带来线性收益反而在显存不足时强行开大batch会导致换入换出训练速度断崖式下跌。学习率方面续训场景我建议从2e-5到5e-5之间起步比从零预训练的常见学习率低一个量级。原因是已有权重已经很稳定学习率过大会把学到的通用特征冲掉出现“灾难性遗忘”。warmup_steps200是为了让训练初期学习率从零爬升避免对损失面造成过大冲击。在语料侧max_length2048是多数场景下的平衡点。DeepSeek的窗口远大于此但自监督阶段追求的是“让模型见足够多的干净文本”而不是让每一条样本都顶满上下文。如果你的显存允许把max_length提到4096会更好如果显存只有24G2048更稳妥。2.3 三个判断信号自监督预训练到底算不算“练完”了自监督训练跑起来后最难回答的问题是“什么时候可以停”。我一般不看绝对loss而是盯三个信号。第一个信号是验证集困惑度是否进入平台期。把一部分语料留出来不参与训练每500步用这批语料算perplexity。如果连续5次评估降幅低于5%基本说明模型已经从这份语料里榨不出新知识了继续训练只是在记住数据。第二个信号是loss曲线的斜率变化。注意观察每1000步的下降幅度如果从“每千步降0.2”变成“每千步降0.01”那么再加训练步数也只是浪费算力。第三个信号最关键拿一段行业文本让模型续写人工判断写出来的内容是否真的符合领域常识。loss只是一个数字续写质量才是预训练效果的直接体感。这里有一个常见的判断陷阱语料里重复内容一多loss会漂亮地一路向下但验证集表现却纹丝不动甚至变差。这是因为模型记住了重复片段而不是学到可泛化的规律。所以语料去重不只是数据清洗的仪式感它是预训练阶段最前置、最能避免翻车的一道闸门。日常做法是对语料做minhash全局去重至少要把完全相同的段落剔除有条件的话再做一次n-gram重叠过滤。如果预算实在有限我的建议是别碰自监督续训直接跳到下一章的Prompt-Dropout微调。理由很现实几千条微调数据就能改变模型的行为风格但几千条无标注文本几乎不可能改变模型的知识底座。自监督续训的真正门槛不是代码而是语料规模和清洗工程。3. Prompt-Dropout微调的机制与落法把“指令模板过拟合”治掉的一条可行实现3.1 Prompt-Dropout不是“丢弃权重”而是随机遮住输入提示的一部分常规dropout是在神经网络层之间随机丢弃一部分神经元输出用来防止过拟合。Prompt-Dropout做的事情完全不同它发生在输入侧在微调训练时随机遮住prompt里的一部分token让模型不能过度依赖某个固定说法。为什么会需要这个操作做过指令微调的人都有体验用一批模板化的“问题-答案”对微调之后模型在训练集那种问法下表现惊艳换个同义问法输出质量立刻垮掉。原因是模型把过多的注意力分配给了prompt的“表面形式”——标点、连接词、常见句式——而不是真正理解问题里的实体和意图。Prompt-Dropout的思路很直接训练时故意把prompt里的一部分token遮掉让模型学会“哪怕这句话少了个词、换了个说法我也得给出同样的回答”。它的价值在于把“对措辞的敏感性”作为训练目标显式压下去而不是等上线后被用户五花八门的问法打脸。对DeepSeek这类对话模型来说这个操作几乎可以无痛接入SFT流程尤其适合业务方希望“模型听得懂用户含糊提问”的场景。注意Prompt-Dropout不是对关键信息做随机删除。比如用户明确说“不要输出英文”这里“不要”是核心约束不能被drop。实现上要控制比例并且在语义关键点上做保护。3.2 直接在训练循环里加Prompt-Dropout可嵌入的PyTorch实现下面这段实现可以直接嵌入现有的微调训练循环。它做的事情是对prompt段按比例随机遮住token但保留序列长度不变用attention_mask把被遮位置的注意力清零# prompt_dropout.py import torch def apply_prompt_dropout( input_ids, # [batch, seq_len] attention_mask, # [batch, seq_len] target_len: int, # response 部分的长度 p: float 0.15, # prompt 被丢弃的 token 比例 pad_token_id: int 0, training: bool True, ): 随机丢弃 prompt 段部分 token保留位置与序列长度不变。 关键点丢弃不是删 token而是把 attention_mask 对应位置置 0 并把 input_ids 换成 pad_token_id避免影响 Embedding 统计。 if not training or p 0: return input_ids, attention_mask batch_size, seq_len input_ids.shape prompt_len seq_len - target_len if prompt_len 2: return input_ids, attention_mask # 只在 prompt 段生成随机掩码 rand torch.rand(batch_size, prompt_len, deviceinput_ids.device) drop_mask rand p # [batch, prompt_len] # 把 attention_mask 中对应位置从 1 改成 0 dropped drop_mask.to(attention_mask.dtype) * -1 attention_mask[:, :prompt_len] ( attention_mask[:, :prompt_len] dropped ) # 被丢弃的位置替换成 pad token pad_tensor torch.full_like( input_ids[:, :prompt_len], pad_token_id ) input_ids[:, :prompt_len] torch.where( drop_mask, pad_tensor, input_ids[:, :prompt_len], ) return input_ids, attention_mask调用方式如下input_ids, attention_mask apply_prompt_dropout( input_idsinput_ids, attention_maskattention_mask, target_lenresponse_len, p0.15, pad_token_idtokenizer.pad_token_id, trainingmodel.training, ) outputs model( input_idsinput_ids, attention_maskattention_mask, labelslabels, )这段代码里最需要理解的是“为什么要换成pad而不是直接删token”。如果你直接把被选中的token从序列里删掉那么后面的所有token位置都会前移位置编码和训练目标全部错位而大模型的训练依赖绝对位置信息一旦错位模型看到的东西就变了形。用一个pad占位符保持位置不动再用attention_mask把它屏蔽掉既达到了“让模型注意不到这个词”的效果又不会破坏序列结构。另一个容易忽略的细节是attention_mask[:, :prompt_len] attention_mask[:, :prompt_len] dropped。如果原始attention_mask里已经有padding位置为0那么这里的“mask被丢弃”操作需要确保不会把本来就为0的位置再减成-1。实际使用时建议先记录原始padding位置或者保证prompt段内没有padding再加入这个函数。3.3 三个参数怎么定drop比例、作用段、mask策略参数推荐值说明踩坑点drop比例 p0.1 ~ 0.2每100个prompt token里遮掉10到20个超过0.3会把关键否定词和数字遮掉模型学成“选择性失聪”作用段只作用于prompt不作用于response让模型在预测答案时不被残缺上下文带偏若对response也做drop标签语义会被破坏loss直接失真位置保持用padmask绝不删除token保持位置编码对齐直接删token会让位置编码错位生成结果出现重复或截断保护关键词训练前把“不要”“必须”“数字”等位置加入保护名单避免关键约束被丢弃不做保护时模型会漏掉用户的核心限制条件具体的比例选择还和你的数据性质有关。如果业务prompt本身很短比如只有10到20个token那么0.15的比例意味着只遮1到3个词效果很有限可以把比例提到0.2如果prompt很长达到几百个token模型对其中冗余描述过度依赖0.15的比例已经足够。另外一个常见做法是把Prompt-Dropout和对抗样本混合使用。也就是在训练数据里人为改几个同义词、换一种句式同时叠加Prompt-Dropout让模型从两个维度摆脱对模板的依赖。这比我单独开大drop比例效果更好因为同义词改写保留了语义而drop是删除信息两者互补。从工程节奏上看Prompt-Dropout应该放在普通SFT稳定跑通之后再作为“增强项”叠加。如果基础SFT还没跑顺加这个只会让排查难度翻倍。先保证普通微调效果达标再开Prompt-Dropout对比一组实验用验证集确认它确实带来了提升再全量应用。4. 从模型蒸馏到稀疏化一条把DeepSeek压缩到可部署的链路4.1 知识蒸馏的先决条件白盒拿logits黑盒只能拿文本知识蒸馏的本质是让一个小模型学生模仿一个大模型教师的行为。根据你手里掌握教师模型的程度蒸馏分两条路。白盒蒸馏要求你能拿到教师的logits。也就是说教师模型必须在你本地能够加载、前向传播最好是和DeepSeek同源的开放权重模型。学生在训练时不仅学习教师给出的标准答案还要学习教师在每个token上的概率分布。这个分布里保留了“哪些候选词虽然没被选中、但也接近正确”的信息这是普通硬标签训练学不到的。画个粗糙的比喻硬标签告诉你答案是A软标签告诉你A最像、B和C也有点像于是学生学到的就不是死记硬背而是一种判断倾向。黑盒蒸馏则是教师完全不开放只能通过API调用拿到生成文本。学生只能拿“问题教师输出”当作训练数据学不到概率分布中的那层软信息。这条路的实际代价往往被低估为凑足够的训练样本每一条都要调用一次API还要自己清洗、去重、过滤错误输出算下来可能比直接买API还贵。所以我的原则很简单教师权重能本地加载就绝不用黑盒蒸馏。这里插一句图像检测领域的“yolo蒸馏”常用feature map对齐来迁移中间层特征而大模型蒸馏更常见的是直接在logits层面做分布匹配。两者思路同源但操作对象不同别把CV蒸馏那套特征对齐函数直接搬过来用。4.2 蒸馏目标怎么算温度T、软标签比例alpha、以及shift logits的细节下面这段代码是在训练循环里做白盒蒸馏的最小核心片段。关键点在于“只在目标token位置上计算KL散度”# distill_step.py import torch import torch.nn.functional as F def distill_loss(student_logits, teacher_logits, labels, T4.0, alpha0.7): student_logits / teacher_logits: [batch, seq_len, vocab] labels: [batch, seq_len]非目标位置必须为 -100 # shift 一次让第 i 步的 logits 对齐第 i1 个 token shift_s student_logits[..., :-1, :].contiguous() shift_t teacher_logits[..., :-1, :].contiguous() shift_labels labels[..., 1:].contiguous() # 找出真正需要计算 loss 的位置 loss_mask shift_labels ! -100 # [batch, seq_len-1] # 只在有效位置取 logits s_logits shift_s[loss_mask] t_logits shift_t[loss_mask] hard_labels shift_labels[loss_mask] # 软标签 KL 散度温度 T 放大分布乘 T^2 恢复梯度尺度 log_probs_s F.log_softmax(s_logits / T, dim-1) probs_t F.softmax(t_logits / T, dim-1) kl_loss F.kl_div(log_probs_s, probs_t, reductionbatchmean) * (T ** 2) # 硬标签 CE让学生至少不错过标准答案 ce_loss F.cross_entropy(s_logits, hard_labels) return alpha * kl_loss (1 - alpha) * ce_loss这个片段里有几个参数直接影响蒸馏效果。温度T控制软标签的“软化程度”。T1时教师分布就是原始概率往往已经被模型训练得过于自信学生学到的是几乎确定的那几个词把T提高到4左右原本概率只有0.05的词会被放大学生能从中看到更多候选信息这对小模型的泛化非常关键。但T也不能无限大过高的T会把分布磨平成均匀噪音学生反而学不到倾向性。实践中2到8之间都常见我习惯从4起步。alpha控制软标签和硬标签的配比。alpha0.7表示70%的loss来自软标签30%来自硬标签。如果完全用软标签alpha1学生可能永远学不会给出标准答案格式如果alpha太小又丢了软标签的价值。蒸馏前期可以把alpha调高一些后期逐渐降低类似课程学习的思路。最后是shift logits的细节。大模型的训练标签天然错位一位第i步的logits预测的是第i1个token。如果忘记shift模型学到的是“看到自己现在的位置去预测当前token”推理时就会产生严重的前后矛盾。这个坑在普通SFT里同样存在但蒸馏时教师和学生的logits都要对齐漏掉shift会直接让KL散度算在一堆错位上loss看起来在降模型其实什么都没学会。4.3 蒸馏之后的稀疏化剪枝、量化和部署的先后顺序蒸馏只能缩小模型的参数量不能自动减少单参数占用的体积。要让模型真正在单卡甚至边缘设备上跑起来还得过稀疏化这一关。稀疏化这个词在DeepSeek语境下通常包含两类手段一类是结构化剪枝直接裁掉不重要的attention头或FFN维度另一类是量化把FP16权重压缩成FP8或INT4整数表示。方案适用场景精度变化部署收益主要风险结构化剪枝参数量过大、推理延迟高中低减少显存和计算量收益最直接剪错头会让特定能力永久丢失FP8量化数据中心GPU推理低显存减半吞吐提升明显对分布极端权重敏感需要校准INT4量化边缘设备、Jetson Orin等中显存大幅下降但算子兼容性受限容易在长上下文场景输出乱码量化感知训练QAT精度要求高、量化后掉点明显低量化后仍保持较好精度训练成本高流程更长流程上的关键判断是先蒸馏再剪枝最后量化这个顺序通常最稳。先蒸馏把模型做小小模型的冗余结构更少剪枝时不容易误伤关键能力剪枝完成后模型结构已经固定再做量化校准避免“量化后才想到剪枝”导致二次精度损失。如果目标是部署到Jetson Orin这类边缘设备那么INT4量化几乎不可避免。此时建议在蒸馏阶段就刻意把温度降低因为边缘设备上的推理往往使用贪心解码或少采样学生模型如果学的是过平滑的分布实际生成时会显得呆板。蒸馏阶段T取2到3INT4量化后再配合一小段任务数据的QAT是保证生成质量的经验做法。4.4 一个可复用的本地推理部署命令vLLM启动加量化蒸馏加稀疏化之后的模型最终要跑成服务才算数。以vLLM为例导出后的模型目录如果已经做过FP8量化可以用下面这种方式启动python -m vllm.entrypoints.openai.api_server \ --model ./deepseek-distill-sparse \ --dtype auto \ --max-model-len 8192 \ --gpu-memory-utilization 0.85 \ --quantization fp8 \ --port 8000这条命令里的参数解释一下。--model指向蒸馏剪枝后的模型目录而不是原始权重目录--dtype auto让vLLM根据权重类型自动选择精度--max-model-len 8192把上下文长度限制在8K避免显存被长序列一次性占满--gpu-memory-utilization 0.85表示允许vLLM使用85%的显存剩下的留给KV cache之外的运行开销。--quantization fp8要和模型实际量化格式一致不一致时vLLM会报格式错误这里不是随便填的。在生产环境里这个启动命令通常还要配合并发参数和超时参数。但核心思路是模型侧把体积压下来推理侧把显存余量控制住两者结合才能稳定提供在线服务。5. 训练微调蒸馏的排障手册五个“现象→原因→解决”的血泪记录5.1 训练loss一路下降但生成的文本开始无限重复现象加了Prompt-Dropout后训练loss正常下降但用模型生成几句回答发现它会反复重复第一句话甚至输出开头的“好的好的好的”。原因这是典型的“位置对齐被破坏”。最常见的是在实现时把被drop的token直接删掉了导致目标token的位置整体前移模型学习到的输入-输出对应关系是错位的。另一个可能是labels没有同步处理drop掉的token位置依然参与了loss计算模型被逼着根据pad token预测下一个词只能靠重复来“蒙混过关”。解决回到实现里确认三点。第一drop时用padattention_mask绝不删除token第二labels里把被mask的位置和padding位置全部置为-100第三训练结束后用同样的分词器跑一次无drop的推理确认推理路径不会经过那条被mask的旁路。5.2 蒸馏loss降得很好但学生模型分数比教师低了20%现象白盒蒸馏训练平稳KL散度稳定下降但学生模型在业务验证集上的准确率、ROUGE或人工评分明显低于教师模型。原因温度T和alpha的配合出了问题。T太低时教师分布的软信息没有充分展露学生只学到了最自信的答案alpha过高时学生被软标签拖住硬标签的标准答案学不到位推理时倾向于输出模棱两可的内容。解决把T从4开始先固定alpha0.7跑一组再固定T4把alpha调成0.5、0.7、0.9各跑一组。观察验证集上hard accuracy的变化选择提升最大的组合。如果所有组合都掉点明显检查教师logits是否和labels对齐shift方向错了KL散度就是在学垃圾信息。5.3 剪枝后吞吐提升很大但输出内容出现乱码和语法崩溃现象对蒸馏后的模型做结构化剪枝跑通后推理速度确实快了但生成的句子偶尔会出现中文混英文、词序颠倒、甚至毫无意义的字符。原因剪枝裁掉了一些自认为“不重要的”attention头但这些头可能负责长距离依赖尤其负责中英文切换时的语法约束。稀疏化不是只算权重范数还要考虑结构的功能冗余只看量级剪枝等于蒙着眼睛给模型做手术。解决剪枝前先对模型做一次“敏感度分析”。逐个头做ablation——把某个头置零看业务验证集掉多少点。把掉点最少的头列入可剪名单再结合权重范数筛选。剪枝后的前几步训练一定要开很小的学习率1e-5量级让模型有时间重新分配注意力。5.4 蒸馏已经完成了再做INT4量化后长上下文输出反复崩断现象模型在纯FP16下能稳定生成800字长文INT4量化后生成到400字左右开始重复、中断或者丢信息。原因INT4量化对权重中的异常值非常敏感。长上下文生成时KV cache也会累积量化误差越往后误差越大最终突破了模型保持连贯的底线。解决首先给量化流程加入校准集校准数据要覆盖足够多的长文本、特殊字符和业务术语不能随便拿几句话糊弄。其次如果INT4不可接受退到FP8通常能换回大部分稳定性。还有一种更稳的组合对attention和ffn层分别做不同位宽量化关键层保留FP8非关键层用INT4。5.5 黑盒蒸馏的API账单比直接买API还高训练数据却还是不够现象想通过调用DeepSeek在线API批量生成蒸馏数据跑了一晚上账单金额远超预期清洗后能用的训练样本还不到一半。原因黑盒蒸馏的本质是用推理成本换训练数据。每次调用都按tokens计费生成一条长回答成本极高加上采样需要温度和多样性经常需要重复生成多遍才能筛出达标样本成本自然指数上升。解决能用本地权重做白盒蒸馏就不要碰黑盒。实在只能黑盒时先确定“我要从教师身上提取什么能力”把生成问题写成选择题或短答形式控制输出长度同时打开API的缓存命中机制让相同前缀的问题复用结果避免为同一类问题反复付费。6. 全流程结束后怎么验收一套业务对齐的评估模板而不是只看基准分数蒸馏模型上线前我最常看到的现象是训练loss漂亮、基准测试分数也不差一上线就被用户投诉“答非所问”。原因很简单基准分数测的是“标准化问题”业务里的真实问题是“同一意图的上百种说法”。所以我的验收流程分三层。第一层是回归测试把线上历史badcase跑一遍确认蒸馏和稀疏化没有把已有能力弄丢。第二层是变体测试针对每个业务核心问题构造三种不同的prompt写法验证模型输出是否稳定。第三层是做人工抽查哪怕只抽50条也要真人在读。变体测试的代码思路如下# acceptance_check.py cases [ { 意图: 查询订单物流, prompts: [ 帮我查一下订单号12345到哪里了, 我的包裹12345现在是什么状态, 订单12345还能查到物流信息吗, ], }, # ... 其他业务场景 ] def check_prompt_invariance(model, tokenizer, case): outputs [] for p in case[prompts]: resp model.generate(tokenizer(p, return_tensorspt)) outputs.append(resp) # 比较三条回答的核心语义是否一致比如是否都包含订单号与当前状态 return outputs跑完变体测试后如果三条输出说的不是同一件事说明这轮训练对措辞的稳定性还不过关先不要上线回去调整Prompt-Dropout比例或补充同义改写数据。评估指标同样重要。对业务导向的蒸馏模型我一般同时看四类指标事实一致性模型有没有捏造不存在的参数、指令遵循率用户给的条件有没有遗漏、拒答准确率不该答的是否明确拒绝、以及输出格式合规率。单看ROUGE或BLEU完全无法反映这些维度。从流程上看我还有一个小习惯把稀疏化前后的同一个问题放在一起并排看输出。蒸馏和稀疏化每次改动都是黑匣子操作不并排对比很难看出“哪一步把能力弄丢了”。深入处理模型每周从线上抽一批失败样本人工标注后放进下一轮微调数据里这样才能让整个自监督、Prompt-Dropout、蒸馏和稀疏化的循环持续转起来。希望这套从训练到验收的路径能帮你少走几趟弯路。毕竟调模型不只是跑通代码更是一场不断排错、对比、验证的工程长跑希望帮到正在这条路上踩坑的你。本文还有配套的精品资源点击获取