最近在网上看到一个很有意思的问题:字节 Seed 为什么不蒸馏别的模型?围绕这个话题,不少讨论把“知识蒸馏”“数据蒸馏”“自蒸馏”“模型同质化”这些概念全部牵扯进来。这篇文章不打算替字节做任何内部决策背书,而是借这个题,把蒸馏技术的原理、收益边界、工程取舍讲清楚,同时给出一个可以直接运行的最小案例,帮助大家理解:如果目标是自研基座模型,为什么不把“蒸馏别人”作为核心策略;以及在业务落地时,什么情况下蒸馏依然是高性价比方案。
无论你是刚接触大模型的初学者,还是已经在做模型压缩的工程师,这篇文章都能提供一个相对完整的分析框架。读完你会掌握知识蒸馏的核心公式,理解“软标签”和“温度系数”的作用,也能看懂 Seed 这类自研模型在技术路线上的通用逻辑。
1. 背景:Seed 话题与技术路线之争
1.1 为什么这个问题会引发讨论
在 AI 技术社区里,“蒸馏”一直是个高频词。从早期的模型压缩,到后来大模型时代的“用大模型教小模型”,蒸馏已经从小众技巧变成了常规工程手段。很多团队为了快速追赶头部模型的生成能力,会直接拿市面上效果最好的模型作为教师,蒸馏出一个能力相近、参数量更小的模型,再部署到具体业务中。
这套打法省钱、省时间,还能快速拿到一个可用的模型。于是很多人就会产生一个疑问:既然蒸馏这么好用,字节 Seed 为什么不用同样的方式,直接蒸馏别的模型?这个问题之所以有热度,是因为它触及了大模型研发路线的一个核心矛盾——是“站在巨人肩膀上快速追赶”,还是“从数据、预训练、对齐全链路自研”。
1.2 先厘清概念:蒸馏不是简单的“抄作业”
在展开讨论之前,先把容易混淆的概念梳理清楚。知识蒸馏(Knowledge Distillation)最早由 Hinton 等人在 2015 年提出,核心思想是让一个小模型(Student)去学习一个大模型(Teacher)的输出分布。这里的输出不只是最终的 hard label,还包括 logits 经过温度系数软化后的概率分布,也就是“软标签”。
软标签比硬标签携带更多信息。举个例子,分类任务里一张猫的图片,硬标签是“猫”,软标签可能是“猫 0.9、老虎 0.07、狗 0.03”。这种细微的相似度信息,对训练一个小模型往往比一个绝对正确的硬标签更有指导意义。
所以,蒸馏不是简单地拿大模型的生成结果当训练数据,而是让 Student 去模仿 Teacher 的“思考方式”。到了大模型时代,这种模仿已经延伸到数据分布、推理轨迹、偏好排序等多个维度,衍生出数据蒸馏、自蒸馏、黑盒蒸馏等不同分支。
2. 模型蒸馏的原理拆解
2.1 知识蒸馏的基本公式
以分类任务为例,知识蒸馏的损失函数通常由两部分组成:
- 蒸馏损失:Student 的软输出与 Teacher 的软输出之间的 KL 散度;
- 常规损失:Student 的硬输出与真实标签之间的交叉熵。
公式可以抽象为:
L = alpha * KL(softmax(S / T), softmax(T_teacher / T)) * T^2 + (1 - alpha) * CE(S, y)其中,T 是温度系数。温度越高,概率分布越平滑,Student 能学到的“暗知识”越多;温度越低,分布越接近 one-hot,训练越接近普通交叉熵。alpha 控制软标签和硬标签的权重。
用 PyTorch 表达这个损失非常直观:
import torch import torch.nn.functional as F def distill_loss(student_logits, teacher_logits, labels, temperature=3.0, alpha=0.7): # 教师模型的软标签 soft_targets = F.softmax(teacher_logits / temperature, dim=-1) # 学生模型的 log 软概率 student_log_probs = F.log_softmax(student_logits / temperature, dim=-1) # KL 散度,乘以 T^2 是为了保持梯度量级 kl_loss = F.kl_div(student_log_probs, soft_targets, reduction='batchmean') * (temperature ** 2) # 硬标签交叉熵 ce_loss = F.cross_entropy(student_logits, labels) return alpha * kl_loss + (1 - alpha) * ce_loss这里的kl_div要求第一个输入是 log-probabilities,第二个输入是 probabilities,顺序不要搞反。乘上temperature ** 2是 Hinton 论文里的做法,目的是抵消温度缩放对梯度尺度的影响,否则高温蒸馏时梯度会变小,训练收敛变慢。
2.2 数据蒸馏与自蒸馏
在大模型领域,知识蒸馏的概念被扩展了很多。除了直接让 Student 拟合 Teacher 的 logits,还有几种常见形式:
- 数据蒸馏:用一个强模型生成大量高质量的指令数据或偏好数据,再用这些数据训练新模型。OpenAI 在论文里提到过用模型生成数据来训练后一个模型,本质上也属于这一类。
- 自蒸馏:让模型自己教自己,通常是同一个模型的多个 checkpoint 互相学习,或者用大模型自身的高质量输出修正自己的训练数据。
- 黑盒蒸馏:只能访问教师模型的 API,拿不到内部 logits,只能通过采样生成结果来构造训练集。这种做法在商业应用里很常见,但效率和上限都受限于 API 的采样质量。
很多人讨论“字节 Seed 为什么不蒸馏别的模型”时,其实把上面几种混在一起了。如果只是问“Seed 会不会用数据蒸馏”,那几乎所有大模型团队都会用强模型生成合成数据来增强训练集。但“以另一个公司的模型为核心教师,蒸馏出自家基座模型”,这是完全不同的路线选择。
2.3 蒸馏的收益来源
蒸馏之所以有效,本质原因是它降低了学习难度。Teacher 已经把原始数据中的规律压缩到了参数里,Student 只需要模仿 Teacher 的输入输出行为,不需要重新从海量文本中发现所有规律。对算力有限、数据有限、时间有限的团队来说,这是极具吸引力的加速路径。
在实际工程中,蒸馏还能带来几个额外收益:
- 模型体积变小,推理成本降低;
- 推理延迟下降,适合端侧和实时场景;
- 可以通过蒸馏把多个模型的优点融合到一个小模型里;
- 可以在不暴露原始数据的情况下迁移能力。
这也是为什么很多中小团队选择蒸馏路线,而不是从头训练一个大模型。
3. 为什么不蒸馏别的模型?技术逻辑分析
下面从技术逻辑角度分析,如果目标是做 Seed 这样的自研基座模型,为什么不把“蒸馏别的模型”作为核心策略。需要再次说明,以下分析基于公开技术路线和行业常识,不代表字节官方口径。
3.1 蒸馏上限受限于教师模型
蒸馏的天花板是教师模型。Student 学得再好,也很难超过 Teacher 的能力上限,因为在训练过程中,Student 的知识来源主要是 Teacher 的输出。如果 Teacher 在某个领域存在系统性缺陷,Student 也会继承这个缺陷。
自研基座模型的目标是探索更优的模型能力,而不是复刻某个已有模型的水平。如果选择直接蒸馏别人,相当于把自己的上限锁死在别人的当前版本上。一旦教师模型升级,学生模型也要跟着重新蒸馏,长期来看反而更累。
3.2 同质化陷阱:大家都蒸馏,模型会趋同
如果一个行业里大家都用同一个最强模型做教师,那么所有蒸馏出来的模型都会带上同一个“知识偏好”,同一个“回答风格”,甚至同一个“错误倾向”。这样的生态会让模型越来越同质化,最终大家都变成了某个模型的“变体”,失去了自研的差异化价值。
从技术演进角度看,真正的创新往往来自数据配比、模型架构、训练算法、对齐方式上的独立探索。如果 Seed 直接以别的模型为教师,就相当于放弃了这些维度的自主权。即使短期能力追上了,长期竞争力也会被削弱。
3.3 合规与安全风险
大模型的训练数据通常依赖公开语料和自建数据,直接使用另一个商业模型的输出作为训练数据,在法律和合规层面存在很大不确定性。很多模型服务条款明确禁止使用其输出训练竞品模型。一旦被发现,不仅面临法律风险,还可能引发严重的声誉问题。
对于字节这种体量的公司,合规风险是不可接受的。相比之下,用公开数据集、自采数据、自建数据飞轮来训练模型,虽然成本更高,但权属清晰、风险可控,也更符合长期战略。
3.4 数据飞轮与长线能力
大模型的竞争,长期来看是数据和用户反馈的竞争。Seed 旗下模型如果部署在豆包等产品中,可以持续收集真实用户的使用数据、编辑行为、反馈信号,形成数据飞轮。这种闭环能力是外部模型蒸馏无法提供的。
蒸馏只能给你一个静态的能力快照,而数据飞轮能让你持续进化。ChatGPT 类的产品每天产生海量的人机交互数据,这些数据经过清洗和筛选后,可以用于 SFT(监督微调)、RLHF(基于人类反馈的强化学习)和模型评估。字节产品生态足够大,如果选择蒸馏别人,等于浪费了自己最强的情报来源。
3.5 算力与成本的真实权衡
有人说自研模型比蒸馏贵得多,这话不完全对。算力成本要分两个维度看:
- 短期一次性成本:从头预训练一个千亿模型需要大量 GPU,确实比蒸馏贵;
- 长期边际成本:蒸馏模型的推理能力受限于教师模型,而且每次教师升级都要重新蒸馏,迭代成本很高。
此外,字节在算力基础设施上的投入非常大,自研芯片、大规模分布式训练框架都是公开信息。对 Seed 这样的团队来说,算力不是瓶颈,真正稀缺的是高质量数据和原创算法。所以把资源投入到自研数据管道和训练算法上,比投入到“蒸馏别人”上更符合战略目标。
3.6 自研路线需要积累基座能力
基座模型的能力不是靠一次蒸馏就能稳定获得的。预训练阶段学到的世界知识、推理能力、上下文建模能力,都需要在模型架构、训练数据的规模与配比、训练稳定性等方面做大量原始积累。这些能力只有通过自研实验才能沉淀为团队的技术壁垒。
反过来看,如果一个团队长期依赖蒸馏,团队成员可能只会“调蒸馏参数”,对模型内部机制、数据分布、训练动力学缺乏深入理解。一旦教师模型不可用,或者业务需要超出教师能力的场景,整个团队就会陷入被动。Seed 选择自研路线,本质上是在积累长期技术能力。
4. 如果要做“不蒸馏别人”,有哪些替代路线
4.1 数据工程与数据配比
自研模型的核心是数据。数据清洗、去重、毒性过滤、多语种配比、领域平衡,这些都直接影响模型上限。相比直接蒸馏第三方模型,自研数据管道可以做到完全可控,并且能针对目标场景定制数据分布。
实际工程中,数据团队通常会先构建一个大规模语料库,然后做质量打分、去重、隐私过滤,再按比例混合通用数据与领域数据。这个过程虽然繁琐,但每优化一步,模型能力都能实实在在提升。
4.2 合成数据与自蒸馏
不使用别人模型,不代表不能使用“合成数据”。Seed 完全可以用自己的最强模型生成合成数据,再用这些数据训练更小的模型,或者用旧版本模型生成数据训练新版本模型。这种“自己教自己”的方式,在工程上叫自蒸馏或自我提升。
自蒸馏的好处是没有外部依赖,数据版权可控,而且可以在一个内部闭环里持续迭代。比如用当前最好的模型生成一批推理过程,经过规则过滤和人工抽检后,加入下一轮训练的 SFT 数据中。
4.3 强化学习与人类反馈
除了模仿教师输出,大模型还可以通过奖励模型来学习。RLHF 的核心是让模型生成多个候选回答,由人类或奖励模型打分,然后通过强化学习算法优化策略。这种方式不依赖某个“教师模型”,而是直接优化模型在真实需求上的表现。
字节在强化学习、奖励模型上的投入也是公开信息。通过大规模用户反馈训练奖励模型,再反过来优化生成模型,形成比蒸馏更强大的迭代信号。
4.4 模型融合与协同训练
有些场景需要综合多个模型的长处,此时可以尝试模型融合。比如多个 expert 模型各自擅长不同领域,通过门控机制动态选择输出;或者在参数层面做模型插值,得到一个新模型。这种思路不同于蒸馏,但它也能把已有能力迁移到新模型里,同时保留一定的自主性。
4.5 推理侧优化:量化、剪枝、蒸馏自己
对于已经训练好的大模型,部署阶段的压缩手段很多:量化、剪枝、稀疏化、蒸馏自己等。这里的“蒸馏自己”是指用大模型自身的输出来训练一个小模型,用于替代大模型做推理。这种蒸馏不涉及外部模型,只影响部署成本,不影响模型能力上限。
在业务中,这是最常用也最稳妥的路线。大模型负责高质量生成,小模型负责高效推理,两者形成互补。
5. 实战:用 PyTorch 跑一个知识蒸馏最小示例
为了加深理解,我们写一个可运行的蒸馏示例。这个例子不涉及大模型,只演示核心机制:教师模型把软标签传递给学生模型。你可以在 CPU 环境下直接运行,代码基于 PyTorch 和 scikit-learn,请确保已安装这两个库。
5.1 生成模拟数据
我们使用make_moons生成一个二分类数据集,包含 2000 个样本。
import numpy as np import torch import torch.nn as nn import torch.optim as optim from sklearn.datasets import make_moons from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score torch.manual_seed(0) np.random.seed(0) X, y = make_moons(n_samples=2000, noise=0.2, random_state=42) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) X_train_t = torch.tensor(X_train, dtype=torch.float32) y_train_t = torch.tensor(y_train, dtype=torch.long) X_test_t = torch.tensor(X_test, dtype=torch.float32) y_test_t = torch.tensor(y_test, dtype=torch.long) print(X_train.shape, X_test.shape)输出是训练集 1600 个样本,测试集 400 个样本,特征维度为 2。
5.2 定义模型
我们定义一个简单的 MLP 模型,可以通过hidden参数控制宽度。教师模型用较宽的 128 隐藏层,学生模型用较窄的 32 隐藏层。
class MLP(nn.Module): def __init__(self, hidden=64): super().__init__() self.net = nn.Sequential( nn.Linear(2, hidden), nn.ReLU(), nn.Linear(hidden, hidden), nn.ReLU(), nn.Linear(hidden, 2) ) def forward(self, x): return self.net(x)5.3 训练教师模型
教师模型直接用交叉熵损失训练 200 轮。
teacher = MLP(hidden=128) opt_t = optim.Adam(teacher.parameters(), lr=0.01) loss_fn = nn.CrossEntropyLoss() for epoch in range(200): opt_t.zero_grad() logits = teacher(X_train_t) loss = loss_fn(logits, y_train_t) loss.backward() opt_t.step() if epoch % 50 == 0: print(f"teacher epoch {epoch}, loss: {loss.item():.4f}")5.4 用蒸馏方式训练学生模型
先定义蒸馏损失函数,再训练学生模型。这里温度取 3.0,alpha 取 0.7,也就是软标签占比 70%,硬标签占比 30%。
def distill_loss(student_logits, teacher_logits, labels, temperature=3.0, alpha=0.7): soft_targets = torch.nn.functional.softmax(teacher_logits / temperature, dim=-1) student_log_probs = torch.nn.functional.log_softmax(student_logits / temperature, dim=-1) kl_loss = torch.nn.functional.kl_div(student_log_probs, soft_targets, reduction='batchmean') * (temperature ** 2) ce_loss = torch.nn.functional.cross_entropy(student_logits, labels) return alpha * kl_loss + (1 - alpha) * ce_loss student = MLP(hidden=32) opt_s = optim.Adam(student.parameters(), lr=0.01) teacher.eval() for epoch in range(200): opt_s.zero_grad() with torch.no_grad(): teacher_logits = teacher(X_train_t) student_logits = student(X_train_t) loss = distill_loss(student_logits, teacher_logits, y_train_t) loss.backward() opt_s.step() if epoch % 50 == 0: print(f"student distill epoch {epoch}, loss: {loss.item():.4f}")5.5 对比测试集准确率
训练完成后,分别评估教师模型和蒸馏学生模型在测试集上的准确率。
teacher.eval() student.eval() with torch.no_grad(): teacher_pred = teacher(X_test_t).argmax(dim=1).numpy() student_pred = student(X_test_t).argmax(dim=1).numpy() print("teacher acc:", accuracy_score(y_test, teacher_pred)) print("student distill acc:", accuracy_score(y_test, student_pred))由于数据本身不复杂,两个模型的准确率可能都在 0.95 左右。你可以试着把教师模型的隐藏层改成 256,学生模型改成 8,或者把温度从 1 调到 10,观察蒸馏效果的变化。这个实验虽然小,但已经能反映蒸馏的本质:学生模型在更小的参数量下,尽可能逼近教师模型的决策边界。
6. 常见问题与误区
| 问题现象 | 常见原因 | 解决思路 |
|---|---|---|
| 蒸馏后学生模型效果比直接训练还差 | 温度系数过高或过低,alpha 权重设置不合理 | 网格搜索温度和 alpha,用验证集评估 |
| KL 散度出现 NaN | teacher_logits 没有 detach,导致梯度回传到教师模型 | 使用with torch.no_grad()或teacher_logits.detach() |
| 学生模型只是简单复制教师,没有学到暗知识 | 温度太低,软标签接近 one-hot | 提高温度,让概率分布更平滑 |
| 蒸馏的收益在简单任务上不明显 | 任务太简单,小模型直接训练就能达到上限 | 换成更复杂的数据集或更大的模型再看收益 |
| 误以为蒸馏必须用别人的模型 | 把“知识蒸馏”和“套壳复刻”混为一谈 | 自蒸馏、数据蒸馏、模型压缩都属于蒸馏范畴 |
还有一个常见误区是“蒸馏是万能的”。蒸馏可以减少模型体积,但不能突破教师模型的能力上限;蒸馏可以加速迭代,但不能替代底层的预训练、对齐和数据飞轮。在实际项目中,要根据资源、目标、合规要求综合选择。
7. 工程实践建议
7.1 什么场景适合蒸馏
如果你的目标是在有限算力下部署一个端侧模型,或者快速验证一个小模型在业务上的可行性,蒸馏依然是最可靠的路径之一。具体来说:
- 希望把大模型压缩到手机或边缘设备;
- 多个小模型需要集成到一个统一模型里;
- 需要快速复制一个已上线模型的业务能力;
- 作为模型压缩流程中的一环,与量化、剪枝配合使用。
在这些场景下,建议优先使用“自蒸馏”或“内部大模型蒸馏”,避免直接使用竞品模型输出,降低合规风险。
7.2 什么场景必须自研
如果你要做的是基座大模型,或者产品能力长期建立在模型迭代之上,那么必须自研。包括:
- 模型架构创新;
- 大规模预训练;
- 多模态融合;
- 长文本、推理能力等底层能力突破;
- 需要掌控数据权属和模型权属的业务。
自研不排斥蒸馏,但蒸馏应该被用在“部署压缩”和“内部知识迁移”上,而不是作为基座模型的培养方式。
7.3 如果一定要蒸馏,如何降低风险
如果由于业务原因,必须参考外部模型的知识,可以采取以下措施:
- 优先使用公开数据集或自建数据,不直接抓取商业模型输出;
- 如果需要合成数据,做好数据溯源和过滤;
- 在训练数据中加入多样性约束,避免模型同质化;
- 对生成结果进行人工抽检和自动质量评估;
- 保留完整的实验记录,方便事后审计。
这些措施不能完全消除风险,但可以把风险控制在可管理范围。
7.4 工程师该如何学习这条路线
与其纠结“字节 Seed 为什么不蒸馏别的模型”,不如把这个问题当成一个学习线索。你可以沿着下面几条线深入:
- 理解蒸馏的数学原理:读 Hinton 的 Distilling the Knowledge in a Neural Network;
- 熟悉蒸馏的工程实现:在真实数据集上跑一遍 Teacher-Student 训练;
- 了解数据蒸馏和合成数据:研究大模型如何通过自举提升能力;
- 关注模型压缩:量化、剪枝、蒸馏的组合使用;
- 思考数据飞轮:为什么真实用户反馈比蒸馏更能驱动长期进化。
把这些知识串起来,你会发现“蒸馏别人”只是无数技术选项中的一个。真正重要的是你想让模型往哪个方向进化,以及你手上有哪些别人替代不了的数据和场景。
8. 回到开头的问题
回到“字节 Seed 为什么不蒸馏别的模型”这个问题,从技术逻辑上看,答案其实并不复杂:蒸馏是高效的工程手段,但不是基座模型的成长路径。自研模型需要的是数据、算法、算力、反馈闭环综合作用,而不是复刻另一个模型的影子。
如果你对蒸馏技术本身感兴趣,建议从文中的最小示例开始动手。把温度参数从 1 调到 10,观察学生模型的预测分布变化;把教师模型换成更大结构,看看蒸馏上限在哪里;再试着加入自蒸馏、数据增强、多教师融合等进阶玩法。只有亲手跑过几组实验,才能真正理解“蒸馏别人”和“训练自己”不是一道二选一的选择题,而是一道需要根据目标和资源来权衡的工程题。