按提示词动态剪 FFN,9B 激活 3B 追平稠密 9B

2026-08-04

苹果 IFPruning 让一个小预测器按指令挑 FFN 子网,9B 模型只激活 3B,编程数学几乎追平稠密 9B,端侧首 token 延迟降 57%。

这篇在解决什么

结构化剪枝是把大模型压小的标准手段:学一个二值掩码,删掉 FFN 整行整列,得到一个固定的小模型部署上线。问题在于这个掩码是静态的,同一个被剪过的模型要同时应付写代码、做数学、跑领域问答,而这些任务需要的参数和知识并不重合。一刀切剪出来的小模型,要么为了快牺牲精度,要么为了精度放弃提速空间。

真正的问题是:既然不同任务需要不同的参数子集,模型能不能根据当前这条指令,挑出最该激活的那部分?这篇 ICML 2025 论文(苹果 AI/ML 团队)给出的答案是能,而且挑得很准。

方法

核心是一个比 LLM 小得多的稀疏预测器(sparsity predictor,约 300M 参数)。它读用户指令,对每一层 FFN 输出一份打分,再用 SoftTopK 把打分变成一个恰好保留目标维度的可微掩码。掩码作用在 FFN 第一层矩阵的列和第二层矩阵的行上,把 9B 模型压成只激活 3B 的子网。

几个关键设计:

结果

把 6B、9B、12B 三个模型都压成激活 3B,跟三类基线比:用近两倍预训练量训出来的稠密 3B、先剪枝再用 12B 老师蒸馏的 3B、以及未剪枝的稠密 9B(上限参照)。

设置编程(平均)MATHMMLUHumanEval
稠密 3B34.331.861.835.2
剪枝+蒸馏 3B37.732.762.837.1
IFPruning 9B→3B43.037.166.143.3
稠密 9B(上限)44.237.367.846.5

几个事实:同样激活 3B 参数,IFPruning 9B→3B 比稠密 3B 在编程上高 8.7 个点、MATH 高 5.3、MMLU 高 4.3;和未剪枝的 9B 比,编程、数学、MMLU 几乎打平(HumanEval 43.3 对 46.5,MATH 37.1 对 37.3)。源模型越大(6B→9B→12B),效果越好,数学和编程上尤其明显。训练时没用过的 GPTeacher 数据,也能被正确路由到合适的子网。

它还能按任务而非按每条输入选参:一条任务指令定一个子网,该任务所有样本共用,无需额外微调,与按输入选参的差距大多在 1% 以内。

子网选择本身可解释:低层(比如第一层)对所有输入激活的子网高度雷同,越往上越按领域分化。MMLU 计算机子集和 Code-Alpaca 共享大量参数,数学、物理、GSM8K 聚成一簇,历史、法律、通用指令另成一类。

端侧延迟实测(batch=1、每 query 生成 4 条):9B 剪到 3B 后,首 token 时间(TTFT)最多降 57%,解码时间最多降 41%,整体最高 1.8 倍加速;预测选参加加载参数合计不到 0.1 秒,只占生成时间 1-2%。运行时跟静态剪枝的 3B 基本同速,却多了按输入定制的能力。

为什么重要

端侧推理是这篇的靶子。手机和笔记本上内存和算力都紧,既想用大模型的能力,又不能把 9B 整个塞进去跑。IFPruning 给了一条具体路径:存一个 9B 的权重库,每次按指令只激活 3B,速度等同于跑一个 3B 稠密模型,精度却逼近 9B。MoE 在小 batch 下搬运权重反而更贵,这套「选一次、跑全程」的设计在小 batch 端侧场景更划算。

它还顺带给出一个反直觉结论:大模型里其实有大量针对当前任务用不上的参数,一个小到 300M 的预测器就能把该用的那部分挑出来。

局限与存疑

作者自己点了几条:目前只剪 FFN,注意力头和隐藏维度还没动;端到端训练可能没把训练样本榨干,用对比损失鼓励相似输入选相似子网或许更好;服务器端多任务批量服务时,同批请求任务不同、子网不同,批处理会变难(作者建议按任务聚类凑批)。

另有几点作者没正面回答:所有延迟是在 GPU 上「模拟」端侧(batch=1)测的,真上手机或笔记本的实测没有;编程、数学这种能力型任务几乎不掉点,但 AlpacaEval 这类开放式指令跟随提升不大,说明按指令选参并不是对所有任务类型同等有效。

术语

原文与代码

社区讨论

全部论文解读