logo

小模型路线:蒸馏、剪枝与任务专用模型

Published on

小模型路线:蒸馏、剪枝与任务专用模型

大模型刚开始流行时,大家都在比谁能调用更大的模型。后来真正把产品做起来,问题却慢慢变成了另一种:一次回答要花多少钱?用户要等多久?数据能不能离开内网?模型服务断了以后,系统还能不能工作?

这时小模型重新变得重要。

小模型不是“大模型的残次品”,也不是把参数随便砍掉一半。一个面向客服分类的 1B 模型,完全可能比一个通用大模型更稳定;一个只负责抽取发票字段的专用模型,也没有必要具备写诗和编程的能力。真正的目标不是让小模型在所有任务上都像大模型,而是让它在一个明确的任务上,质量够用、速度够快、成本可控。

一、先判断:你到底需要一个什么模型

在压缩模型之前,先把任务写清楚。不要只写“做一个 AI 助手”,而应该明确输入、输出和失败代价:

type TaskSpec = {
  input: string
  output: '分类' | '抽取' | '排序' | '生成' | '判断'
  qualityMetric: string
  maxLatencyMs: number
  maxCostPerRequest: number
  failureRisk: 'low' | 'medium' | 'high'
}

分类、抽取、意图识别通常很适合小模型,因为输出空间比较窄,容易建立高质量标注集。开放式长文本生成则更难压缩,尤其是需要广泛知识、复杂推理和长上下文的任务。

我经常提醒团队:如果一个任务连验收标准都说不清楚,就不要急着做模型优化。没有指标时,所谓“模型变小了但效果还行”只是主观感觉;等上线后遇到投诉,大家又会回到争论。

二、四条常见的小模型路线

1. 量化:先减少每个参数占多少空间

量化是最容易落地的路线。模型原本可能使用 FP16,每个参数占 16 位;量化后可以用 INT8、INT4,参数占用明显下降,内存带宽压力也会减小。

简单理解,就是把很多精细的小数映射到更少的离散数值。代价是一定的信息损失,但如果校准数据和量化方法合适,质量下降可能很小。

量化适合解决显存和部署问题,但它不会自动改变模型的知识边界。一个本来就不会回答业务问题的模型,量化后不会突然学会;一个推理逻辑脆弱的模型,也不会因为变成 INT4 就更可靠。

2. 剪枝:删除不重要的结构

剪枝试图找出对输出影响较小的参数或结构并删除。非结构化剪枝可以把很多单独权重置零,但硬件未必能因此获得明显加速;结构化剪枝直接删除通道、头或层,更容易换来实际速度提升,但质量损失也可能更明显。

所以剪枝不能只看“参数少了多少”,还要看目标硬件是否真的利用了这种稀疏结构。纸面上的压缩率,不等于线上延迟下降。

3. 知识蒸馏:让学生学习老师的行为

蒸馏通常让一个较小的 Student 模型学习 Teacher 模型产生的输出。训练数据可以包含真实标签,也可以包含教师生成的答案、概率分布或中间特征。

原始问题 + 正确标签 ──────┐
                           ├─→ Student Loss
原始问题 + Teacher 输出 ───┘

如果只让学生学习最终答案,学生能学到任务结果;如果还能学习教师的概率分布,就能获得更丰富的“哪些答案相近、哪些答案明显错误”的信息。工程上常见的是混合损失:

总损失 = α × 真实标签损失 + (1 - α) × 教师软目标损失

蒸馏最容易被误解的地方,是以为教师说什么学生就照抄什么。教师有幻觉,学生也会把幻觉学进去。因此蒸馏数据必须评估和清洗,尤其不能把没有人工验证的线上回答全部当成黄金答案。

4. 任务专用微调:只学真正需要的能力

如果任务边界清楚,LoRA、Adapter 或全量微调都可以让模型更贴近业务。比如让模型把客服问题分成 12 类,或者从合同中抽取固定字段。这类模型不需要知道全世界的知识,但需要对业务术语和输出格式非常稳定。

任务专用模型通常和 RAG 配合使用:小模型负责意图识别、查询改写、重排或结构化抽取,大模型负责复杂生成。不要把所有事情都压到一只模型身上,系统可以像一支球队,让每个模型承担它擅长的工作。

三、蒸馏数据怎么做才不把错误放大

高质量蒸馏数据通常来自三部分:人工标注样本、可信业务规则和教师模型生成样本。流程可以是:

  1. 先从真实业务中抽取代表性问题。
  2. 去除个人信息、重复样本和不允许使用的数据。
  3. 让一个或多个教师模型生成候选答案。
  4. 用规则、程序和人工抽查过滤错误。
  5. 划分训练集、验证集和完全隔离的测试集。
  6. 记录每条样本的来源、教师版本和审核状态。

数据的难度要分层。全是简单问题,学生模型会在演示里表现很好,一遇到真实长尾就崩。应该刻意加入边界样本:错别字、口语表达、相似类别、缺少字段、冲突信息和明确应该拒答的问题。

训练集和测试集不能只是随机切分。相同客户、相同模板或同一文档的近似内容如果同时出现在两边,测试分数会虚高。更合理的方式是按时间、客户、文档来源或业务场景做隔离,尽量模拟上线后的未知输入。

四、评测不能只看平均准确率

小模型很容易在平均指标上看起来不错,却在关键场景上失败。至少要同时看:

  • 总体准确率或 F1;
  • 各类别的召回率,尤其是少数类;
  • 结构化字段的逐字段准确率;
  • 拒答和安全边界的准确率;
  • P50/P95 延迟;
  • 单次请求的真实成本;
  • 不同硬件和并发下的吞吐。

例如一个风控分类器总体准确率 98%,听起来很好,但如果高风险类别召回率只有 70%,它可能根本不能上线。模型优化必须先定义不能退让的指标,再讨论哪些指标可以换取速度和成本。

建议保留“大模型基线”和“规则基线”:

规则系统:成本最低,边界清楚,但覆盖有限
小模型:速度快,适合稳定重复任务
大模型:能力强,适合复杂和长尾问题

如果小模型没有超过规则系统,就不一定值得部署;如果小模型只比大模型便宜一点,却增加了维护和故障复杂度,也要认真算账。

五、路由比二选一更现实

生产环境很少是“永远用小模型”或“永远用大模型”。更实用的是分层路由:先让便宜快速的小模型处理高频、低风险问题;遇到低置信度、长文本、冲突证据或高风险场景,再升级给大模型或人工。

async function route(request: Request) {
  const smallResult = await smallModel.predict(request)

  if (
    smallResult.confidence >= 0.92 &&
    smallResult.risk === 'low' &&
    smallResult.validSchema
  ) {
    return smallResult
  }

  return largeModel.generate(request)
}

置信度不能盲信。它应该在独立验证集上校准,并且不同类别可能需要不同阈值。对退款、医疗、合同和权限操作等高风险任务,升级条件宁可保守一些。

六、部署时别忘了真实硬件

模型压缩后的效果必须在目标环境测量。开发机上的单请求速度,不能代表生产并发;显存节省,也不代表 Token 吞吐一定提高。要记录模型加载时间、首 Token 延迟、生成速度、峰值内存、并发下的 P95 和错误率。

还要考虑版本回滚。量化模型、Tokenizer、推理引擎和 Prompt 往往需要一起发布,不能只替换一个权重文件。每次上线都保留模型版本、配置、评测报告和发布日期,质量退化时才能快速切回旧版本。

总结:小模型不是妥协,而是边界清楚

我研究这条路线以后,最大的收获不是某个压缩算法,而是对“模型够不够大”的看法变了。模型大小只是手段,任务成功率、延迟、成本、隐私和可维护性才是产品真正关心的结果。

量化解决资源占用,剪枝尝试减少无效结构,蒸馏把教师能力迁移给学生,任务专用训练则让模型不再为用不到的能力买单。它们可以单独使用,也可以组合使用,但每一步都必须用独立测试集和真实硬件验证。

一个可靠的小模型,应该知道自己的边界:能处理的事情快速完成,没把握的事情交给更强的模型,涉及高风险的事情请求人工确认。能做得少一点,但做得稳定、便宜、可解释,这不是退步,而是工程成熟的表现。

🤪 您也可以编辑此页: