1. 从「蒸馏」这个词说起:它到底指什么
先把话说在前头,我不是来站队的,也不打算去评判哪家公司对谁错。作为一个常年跟模型训练、微调、部署打交道的人,我更关心的是技术本身——「蒸馏」这两个字被反复提起,但很多人其实并不清楚它在工程上到底意味着什么,更不清楚为什么它会在行业里引发这么大的讨论。
所谓知识蒸馏(Knowledge Distillation),最早可以追溯到 Hinton 在 2015 年前后提出的那套思路:用一个已经训练好的、体量很大的「教师模型」,去指导一个体量更小的「学生模型」学习。学生模型不直接去拟合原始数据的硬标签,而是去拟合教师模型输出的软标签(soft label)——也就是那串概率分布。因为软标签里包含了「这个样本像 A 多一点、像 B 少一点」这种类间关系信息,学生模型能学到比单纯硬标签更丰富的东西。
打个生活化的比方:硬标签就像考试只告诉你「答案是 C」,而软标签相当于老师把「A 有 20% 可能、B 有 15% 可能、C 有 65% 可能」这套判断逻辑也一并教给你。后者信息量显然更大,学生自然学得更快、更稳。
那为什么这次会被「点名」?因为在大模型时代,蒸馏的形态变了。以前是同一个团队内部,教师和学生都是自己的;现在出现了跨公司、跨模型的黑盒蒸馏——你拿不到对方的权重,只能通过 API 调用,把对方模型的输出当成训练数据,去喂自己的模型。这就从「技术手段」变成了「数据来源是否合规」的问题。标题里说的「偷走了什么」,本质上问的就是:通过 API 输出蒸馏,到底拿走了对方模型的哪些能力,这些能力算不算资产。
我个人的判断是,被「拿走」的主要是三类东西:一是输出分布里的类间关系,二是特定任务上的推理路径,三是对齐后的表达风格。这三样东西,恰恰是砸了最多算力和人力才磨出来的。下面我会一层层拆开讲。
1.1 蒸馏、微调、RL 到底是不是一回事
很多刚入门的朋友会把蒸馏和微调混为一谈,这里必须掰扯清楚,因为热词里「大模型微调实战」「大模型微调技术」出现频率极高,概念混淆会直接影响你的技术选型。
微调(Fine-tuning)是在一个已有基座模型上,用你自己的数据继续训练,让模型适配你的任务。数据是你自己的,标签也是你自己的,目标是「让通用模型变成专用模型」。
蒸馏(Distillation)的核心是「有一个更强的老师」。数据可能不是你的,标签来自老师模型的输出,目标是「让小模型逼近大模型」。
强化学习(RL)则是另一条路,它不依赖标注好的标准答案,而是通过奖励信号去引导模型行为,典型的就是 RLHF(基于人类反馈的强化学习)。热词里的「RL」和「KL」经常一起出现,因为 RLHF 里通常会用KL 散度作为一个约束项,防止模型在追求奖励时跑偏太远、把语言能力练废。
| 维度 | 微调 | 蒸馏 | 强化学习 |
|---|---|---|---|
| 数据来源 | 自有标注数据 | 教师模型输出 | 奖励信号/偏好数据 |
| 核心目标 | 任务适配 | 能力迁移+压缩 | 行为对齐 |
| 典型损失 | 交叉熵 | KL 散度+交叉熵 | 策略梯度+KL 约束 |
| 算力需求 | 中 | 中到高 | 高 |
| 常见风险 | 过拟合 | 合规与能力上限 | 奖励黑客 |
这张表建议你存下来,选型的时候对着看,能省掉大量试错时间。
1.2 为什么「黑盒蒸馏」会成为争议焦点
白盒蒸馏,教师模型的权重、logits、中间层特征你都能拿到,学生学得充分,这是学术界的主流做法。但黑盒蒸馏不一样——你只能调用 API,拿到的是最终输出的文本,甚至连完整的 top-k 概率分布都拿不到(很多 API 只返回采样后的结果)。
那这种情况下还能蒸吗?能,而且效果比很多人想象的好。做法通常是:构造大量 prompt,调用教师 API 拿到回答,把这些「问题-回答」对当作监督数据,去训练自己的模型。这其实已经介于「蒸馏」和「用合成数据做指令微调」之间了。
争议点就在这儿:这些问答对,是教师模型能力的直接体现,用它训练出来的学生,本质上是在复现教师的行为。如果教师模型是别人花了几千万美元训出来的,你花几万块 API 费用就「学」走了它的部分能力,这在商业伦理和法律层面自然会引发讨论。标题里「7 家中国公司被点名」,说的就是这个层面的问题。
我不去评判对错,但从工程角度讲,黑盒蒸馏的天花板是明确的:你只能学到教师「表现出来」的能力,学不到它内部的表示和推理机制。所以指望靠黑盒蒸馏完全复刻一个顶级模型,是不现实的。
2. 蒸馏的技术内核:KL 散度、温度与损失函数
要真正理解蒸馏,绕不开几个数学概念。别怕,我用最直白的方式讲,保证你不需要重新翻概率论教材。
2.1 KL 散度:衡量两个分布「差多远」
KL 散度(Kullback-Leibler Divergence)是蒸馏里最核心的度量。它衡量的是「用分布 Q 去近似分布 P 时,损失了多少信息」。公式长这样:
KL(P || Q) = Σ P(x) * log(P(x) / Q(x))注意它不对称,KL(P||Q) ≠ KL(Q||P),这一点在实操里很关键。在蒸馏中,我们通常把教师分布当作 P,学生分布当作 Q,最小化KL(P||Q),意思是「让学生分布尽量去覆盖教师分布」。
为什么用 KL 而不是直接用交叉熵?因为交叉熵H(P,Q) = H(P) + KL(P||Q),当教师分布 P 固定时,H(P)是常数,最小化交叉熵等价于最小化 KL。所以两者在优化目标上是一致的,只是 KL 的物理意义更清晰。
提示:在 RLHF 里,KL 项的作用是约束新策略不要偏离参考策略太远,通常写成
reward - β * KL(policy || ref),β 是个需要仔细调的系数,调大了模型学不动,调小了模型容易「跑飞」。
2.2 温度系数:让软标签「更软」
教师模型输出的 logits 直接做 softmax,往往非常「尖锐」——正确类别的概率接近 1,其他接近 0,这样的软标签信息量其实不大。解决办法是引入温度系数 T:
softmax(z_i / T)T 越大,分布越平滑,类间关系暴露得越充分;T 越小,分布越尖锐,接近硬标签。蒸馏时通常用较大的 T(比如 3 到 10),训练学生;而学生自己推理时用 T=1。
这里有个实操细节:教师和学生在蒸馏阶段必须用同一个 T,否则分布对不齐,KL 会算错。我见过有人教师用 T=4、学生用 T=1,结果 loss 一直下不去,排查半天才发现是这个原因。
2.3 损失函数的组合拳
标准蒸馏的损失通常是两项加权:
Loss = α * KL(teacher_soft || student_soft) + (1-α) * CE(student_logits, hard_label)- 第一项是蒸馏损失,让学生学教师的软分布;
- 第二项是学生损失,让学生别丢掉真实标签的信息;
- α 是平衡系数,一般取 0.5 到 0.9 之间。
在大模型场景下,如果只有教师输出、没有硬标签(黑盒蒸馏常见情况),那第二项就退化成对教师文本的交叉熵,本质变成了「用教师生成的数据做监督微调」。
2.4 一个可跑的最小蒸馏示例
下面这段代码是我自己常用的蒸馏训练骨架,基于 PyTorch,逻辑清晰,你可以直接改成自己的场景:
import torch import torch.nn as nn import torch.nn.functional as F def distillation_loss(student_logits, teacher_logits, labels, T=4.0, alpha=0.7): # 软标签蒸馏损失 soft_teacher = F.softmax(teacher_logits / T, dim=-1) soft_student = F.log_softmax(student_logits / T, dim=-1) kd_loss = F.kl_div(soft_student, soft_teacher, reduction='batchmean') * (T * T) # 硬标签损失 ce_loss = F.cross_entropy(student_logits, labels) return alpha * kd_loss + (1 - alpha) * ce_loss注意那个* (T * T),这是 Hinton 原论文里的做法。因为对 softmax 求导时温度会带来1/T²的缩放,乘上T²是为了让蒸馏损失的梯度量级和硬标签损失保持一致。这个细节很多人会漏,漏了之后 loss 曲线会很难看。
注意:如果你做的是黑盒蒸馏,拿不到 teacher_logits,那这段代码就用不上,得改成「教师生成文本 + 学生监督微调」的范式,损失退化为普通交叉熵。
3. 从零复现一次蒸馏:完整实操流程
光讲原理没意思,我带你走一遍完整的流程。假设我们要把一个 7B 的模型蒸馏到一个 1.5B 的模型上,任务是指令跟随。这套流程我在实际项目里跑过好几轮,踩过的坑都会标出来。
3.1 环境与工具准备
先说硬件。1.5B 的学生模型全参数微调,单卡 24G 显存(比如 4090)勉强够用,但 batch size 只能开到很小。7B 的教师模型如果要做 logits 蒸馏,推理时至少需要 16G 显存,建议用两张卡分开跑,或者用 vLLM 这类推理框架做批量推理。
工具链我推荐这套组合:
- 训练框架:HuggingFace Transformers + PEFT(做 LoRA 省显存)
- 推理框架:vLLM(教师模型批量生成,吞吐高)
- 数据处理:datasets + 自己写的清洗脚本
- 实验管理:wandb 或 tensorboard
pip install torch transformers peft datasets accelerate vllm提示:vLLM 和训练框架的 CUDA 版本要一致,否则会出现「推理能跑、训练报错」的诡异情况。我一般先装 vLLM,再根据它的 torch 版本去配其他库。
3.2 数据构造:蒸馏的成败八成在这里
蒸馏效果好不好,数据质量占八成。我的经验是分三步走:
第一步,构造 prompt 池。覆盖你的目标任务分布,比如指令跟随就要覆盖问答、摘要、改写、推理等类型。数量上,几千到几万条不等,太少学不透,太多边际收益递减。
第二步,教师生成。用 vLLM 批量调用教师模型,拿到回答。这里有个关键参数——temperature。如果你想要多样性,用 0.7 到 1.0;如果你想要稳定的高质量答案,用 0.1 到 0.3。我一般会生成两版,一版低温做「标准答案」,一版高温做「多样性补充」。
第三步,清洗过滤。这一步最容易被忽略,但最重要。要过滤掉:太短的、重复的、包含明显错误的、格式混乱的。我通常会用一个小的判别模型或者规则脚本做初筛,再人工抽检 5%。
import json def clean_sample(item, min_len=20, max_len=2048): q, a = item['prompt'], item['response'] if len(a) < min_len or len(a) > max_len: return None if a.count(a[:10]) > 3: # 简单重复检测 return None return {'prompt': q, 'response': a} cleaned = [] with open('teacher_output.jsonl') as f: for line in f: item = json.loads(line) c = clean_sample(item) if c: cleaned.append(c) with open('train.jsonl', 'w') as f: for item in cleaned: f.write(json.dumps(item, ensure_ascii=False) + '\n')3.3 训练配置与参数选择
学生模型用 LoRA 微调,配置如下:
from peft import LoraConfig lora_config = LoraConfig( r=16, lora_alpha=32, target_modules=["q_proj", "k_proj", "v_proj", "o_proj"], lora_dropout=0.05, bias="none", task_type="CAUSAL_LM" )关键参数解释:
- r=16:LoRA 秩。太小欠拟合,太大显存吃紧。7B 以下模型 8 到 32 都常见,我一般从 16 起步。
- lora_alpha=32:缩放系数,通常取 r 的 2 倍。
- target_modules:注意力层的四个投影矩阵,这是性价比最高的选择。想效果更好可以加上 MLP 层,但显存会涨。
训练超参:
| 参数 | 推荐值 | 说明 |
|---|---|---|
| learning_rate | 1e-4 ~ 2e-4 | LoRA 常用,比全参微调大 |
| batch_size | 4 ~ 16 | 看显存,配合梯度累积 |
| gradient_accumulation | 4 ~ 8 | 等效放大 batch |
| epochs | 2 ~ 3 | 多了容易过拟合 |
| warmup_ratio | 0.03 | 稳定初期训练 |
| lr_scheduler | cosine | 平滑衰减 |
| max_seq_len | 2048 | 看任务需要 |
注意:蒸馏数据往往比普通微调数据「干净」,所以更容易过拟合。我一般会在第 2 个 epoch 后开始盯验证集 loss,一旦回升就停。
3.4 训练过程监控与现场记录
训练启动后,重点盯三个指标:训练 loss、验证 loss、生成样例。
我实测下来,一个 1.5B 学生模型在 2 万条蒸馏数据上,单卡 4090 跑 2 个 epoch 大约需要 6 到 8 小时。loss 曲线正常的话,前 500 步下降很快,之后趋于平缓。如果 loss 一直震荡,八成是学习率太大或者数据里有脏样本。
生成样例的抽检尤其重要。我一般每 200 步让模型生成几条,肉眼看质量。有一次我发现模型开始输出大量「作为AI助手」这类模板话术,排查后发现是教师输出里这类前缀太多,学生学去了。后来在清洗阶段加了前缀过滤,问题就解决了。
4. 常见问题与排查技巧实录
这一节是我最想分享的部分,因为下面这些问题,几乎每一个我都真实踩过,文档里基本不会写。
4.1 蒸馏后模型「变笨」了怎么办
这是最典型的问题。学生模型在通用能力上明显退化,尤其是数学、代码这类需要推理的任务。原因通常有两个:
一是数据分布偏了。你的蒸馏数据如果只覆盖某一类任务,学生就会「偏科」。解决办法是保证 prompt 池的多样性,必要时混入一部分通用指令数据。
二是容量瓶颈。1.5B 的模型就是装不下 7B 的全部能力,这是物理限制,不是训练技巧能解决的。这时候要么换更大的学生,要么接受「在特定任务上逼近、通用能力打折」的现实。
4.2 loss 不下降的排查清单
| 现象 | 可能原因 | 排查方法 |
|---|---|---|
| loss 完全不动 | 学习率过小/数据格式错 | 打印几条样本,检查 label 是否正确 |
| loss 震荡剧烈 | 学习率过大/batch 太小 | 降 lr,加梯度累积 |
| loss 下降但生成乱码 | tokenizer 不匹配 | 检查学生和教师的 tokenizer |
| 验证 loss 上升 | 过拟合 | 减 epoch,加 dropout |
| 显存 OOM | seq_len 太长 | 减 max_seq_len,开梯度检查点 |
这张表我建议打印出来贴在显示器边上,出问题先对着查一遍,能省掉大量瞎折腾的时间。
4.3 关于「蒸馏 vs 微调」的选型建议
经常有人问我:我到底该蒸馏还是该微调?我的判断标准很简单:
- 如果你有高质量的自有标注数据,直接微调,别绕弯子。
- 如果你没有数据,但能调用强模型 API,可以考虑蒸馏,但要评估合规风险。
- 如果你要压缩模型部署到端侧,蒸馏是刚需,因为你要的是「小模型逼近大模型」。
- 如果你只是想让模型适配某个垂直领域,微调 + RAG 往往比蒸馏更划算。
热词里「本地部署大模型让个人电脑智能化」「ollama 部署大模型」这些需求,其实很多场景下微调一个小模型 + 量化,比蒸馏一个大模型更实际。
4.4 合规红线:蒸馏前必须想清楚的事
这一点我必须单独拎出来说。用别人的模型输出做训练数据,涉及几个现实问题:
- 服务条款:很多 API 的 ToS 明确禁止用输出训练竞品模型,违反可能被封号甚至追责。
- 数据归属:教师输出算谁的?目前法律上还没有完全清晰的界定。
- 能力上限:黑盒蒸馏学不到教师的内部机制,天花板明显。
我的建议是:优先用开源模型做教师,比如那些权重公开、许可证允许商用的模型,这样既合规又省心。如果非要用闭源 API,务必先读清楚条款,别为了省事埋雷。
5. 蒸馏之外:大模型能力迁移的其它路径
蒸馏不是唯一的路,也不一定是最好的路。作为一个一线工程师,我更愿意把几种方案摆在一起对比,让你根据实际情况选。
5.1 合成数据微调:蒸馏的「近亲」
前面说过,黑盒蒸馏本质上就是「用教师生成的数据做监督微调」。那它和普通的合成数据微调有什么区别?区别在于目的性。蒸馏是明确奔着「复现教师能力」去的,而合成数据微调可能只是为了扩充数据量、提升某个任务的表现。
实操上,合成数据微调更灵活,你可以控制数据的配比、风格、难度。我做过一个项目,用教师模型生成大量「难例」,专门补学生模型的短板,效果比无差别蒸馏好很多。
5.2 模型合并:另一种「免费午餐」
模型合并(Model Merging)是近几年很火的方向,把多个同架构的微调模型权重做加权平均,往往能得到一个「集各家之长」的模型。它不需要训练,成本极低,但前提是这些模型来自同一个基座。
常见方法有 Task Arithmetic、TIES-Merging、DARE 等。我实测下来,在指令跟随任务上,合并两三个专精模型,效果能接近甚至超过单独微调。缺点是可控性差,出问题不好定位。
5.3 选型决策表
| 方案 | 成本 | 效果上限 | 合规风险 | 适用场景 |
|---|---|---|---|---|
| 全参微调 | 高 | 高 | 低 | 数据充足、追求极致 |
| LoRA 微调 | 中 | 中高 | 低 | 大多数垂直场景 |
| 白盒蒸馏 | 中高 | 高 | 低 | 有教师权重、要压缩 |
| 黑盒蒸馏 | 中 | 中 | 高 | 无数据、有 API |
| 模型合并 | 低 | 中 | 低 | 已有多个同源模型 |
| RAG | 低 | 中 | 低 | 知识密集型问答 |
这张表是我这些年做选型时总结的,不一定绝对,但大方向不会错。新手最容易犯的错是一上来就想蒸馏,其实很多时候 RAG 或者简单微调就够了。
6. 我个人的一些实操体会
聊了这么多技术细节,最后说点掏心窝的话。
蒸馏这件事,技术本身是中性的,它就是个工具。真正决定成败的,是你对数据质量的把控和对目标场景的理解。我见过太多人一上来就搭训练框架、调参,结果数据一塌糊涂,训出来的模型还不如直接用基座。
我的习惯是,任何蒸馏项目启动前,先花两天时间把数据摸清楚:教师输出长什么样、有没有系统性偏差、覆盖了哪些任务类型。这两天的投入,能省掉后面两周的返工。
另外,别迷信「蒸馏一定能超过微调」。在垂直领域,用几百条高质量人工标注数据做微调,效果经常吊打几万条蒸馏数据。数据质量永远比数量重要,这个道理在大模型时代依然成立。
至于标题里那些争议,我的态度是:技术人要懂技术,也要懂边界。用开源模型、遵守许可证、尊重数据来源,这些不是束缚,而是让整个行业能持续往前走的基础。踩过几次坑之后你会发现,合规的路线往往也是更可持续的路线。