有一段时间我特别迷信 Shapley 值。理由很充分:它是合作博弈论里唯一能满足全部公平性公理的解,数学底蕴无可挑剔。所以我天真地以为,所有解释模型输出的工具,背后都在默默计算 Shapley 值。

这个错觉持续到我真的看了一眼计算复杂度。
要给模型做特征归因,用 Shapley 值意味着枚举所有特征子集。特征数 n,子集数 2^n。输入里有 50 个词,就要跑 2^50 次模型。每次前向传播算 10 毫秒,你也要跑三十多万年。
所以现实很骨感:没有人真的在大模型上算 Shapley 值。
但 2017 年,Google 的三位研究者给出了一种“连续版本”,后来在各种解释工具里几乎成了默认选项。论文标题朴素得很——Axiomatic Attribution for Deep Networks,作者是 Mukund Sundararajan、Ankur Taly 和 Qiqi Yan。这就是 Integrated Gradients(积分梯度)。
Shapley 值是完美的答案,但算不出来
先回到 Shapley 值本身。它处理的是一个古老的分配问题:一桌人合作干了件大事,总收益怎么分才算公平?
Lloyd Shapley 在 1953 年给出的回答是:每个人分到的钱,等于他对所有可能联盟的边际贡献的平均值。公式长这样:
φ_i = Σ_{S ⊆ N\(i)} [ |S|!·(n-|S|-1)! / n! ] × [ v(S∪{i}) - v(S) ]
翻译成人话:随便挑一个不含 i 的特征集合 S,分别算 v(S) 和 v(S∪{i}),差值就是 i 在这个联盟里的边际贡献。穷举所有 S,加权求平均。
用在模型解释上,v(S) 的定义一般是:S 里的特征保持原值,其余特征替换成基线值(图像全黑、文本零向量),然后跑一次模型。本质上,每个子集都相当于一次“部分遮挡”的推理。
问题一目了然:n 个特征对应 2^n 个子集。GPT 一个 prompt 就好几千 token,这个复杂度不是工程优化能救的,是数学上不可行。
连续化:从 2^n 次穷举,到一条直线
困扰了我很久的一个问题是:离散穷举怎么就能变成一条直线上的积分?
答案藏在一门比深度学习老得多的学问里。1974 年,Aumann 和 Shapley 合写了 Values of Non-Atomic Games,本意是解决经济学里的成本分摊问题——比如一条电话线路的成本,在不同用户之间怎么公平计价。
他们的核心洞察是:离散模型里特征只有“在/不在”两种状态;但连续世界里,特征可以部分在场。用参数 α ∈ [0,1] 表示“在场程度”:
z(α) = x' + α·(x - x')
α=0 是基线(完全不在),α=1 是输入(完全在)。这条直线就是连续版的“加入联盟的过程”。在中间点 z(α) 上,特征 i 的边际贡献不是差分,而是梯度——无限细分的差分。
沿着这条路做积分,就得到积分梯度公式:
IG_i(x) = (x_i - x'_i) · ∫₀¹ ∂F(x' + α·(x-x')) / ∂x_i dα
说人话:从基线出发沿着直线一路走向输入,沿途每走一步就记录当前特征还能贡献多少梯度增量,把整段路程上的贡献全部加起来。
| 维度 | 离散 Shapley 值 | 积分梯度 |
|---|---|---|
| 理论源头 | Shapley 1953,合作博弈 | Aumann-Shapley 1974,连续博弈 |
| 贡献定义 | 边际贡献 v(S∪{i}) − v(S) | 路径梯度 ∂F/∂x_i 的积分 |
| 需要评估的点 | 2^n 个子集组合 | 直线上的采样点(实际 20-50 个) |
| 计算代价 | 指数级,不可行 | 近似线性,LLM 上可接受 |
| 公理对应 | 对称性、有效性、可加性、哑元 | 敏感性、实现不变性 |
这就是为什么 IG 可以自称 Shapley 值的连续版本——资格证不是 AI 圈发的,是博弈论和经济数学半个世纪前就准备好的。
为什么不能只用最终梯度?答:饱和
每次讲到这都有人问:反正都要算梯度,直接在输入 x 上求一次不行吗?为什么非要从基线走一路?
答案是三个字:梯度饱和。
我最早也不理解,直到自己做了个实验:训练一个把 good 判成 positive 的情感分类器。模型对 good 极度自信,置信度 0.99。这时你对 good 做微小扰动,输出几乎不动,梯度趋近于 0。
只看最终梯度的话,结论会是:good 对判断一点也不重要。这显然是错的。
真相是:模型梯度趋近于 0,恰恰因为它已经完全确定了,对微小扰动不再敏感。这就是饱和。
积分梯度的聪明之处,在于它不看终点,它看全程。IG 逼着模型从一无所知的基线出发,把每个词从“惊讶”到“确信”的过程中每一分贡献都记录在案。沿途的梯度,信息量远大于终点的梯度。
这一点被论文上升成一条公理,叫敏感性(Sensitivity):
If the baseline and the input differ in one feature but have different predictions, then the differing feature gets a non-zero attribution.
翻译:只要改动一个特征导致预测变了,这个特征就必须拿到非零归因。朴素梯度方法在饱和区会违反这条公理,IG 因为积了全程,不会。
另一条公理,淘汰了一众解释方法
论文还有第二条公理,实现不变性(Implementation Invariance):
For two networks, if their outputs are equal for all inputs, then their attributions are identical.
翻译:两个模型对外行为完全一致,不管内部结构差多大,解释结果必须一致。
这条看着朴素,杀伤力巨大。注意力权重常被拿来当解释,但 Attention is not Explanation(Jain & Wallace, 2019)用实验证明:attention 权重可以被大幅篡改而输出几乎不变——它根本不满足实现不变性。LIME 在预测点附近拟合线性模型,但拟合带随机性,两次运行结果都不同,同样不合格。
IG 满足这两条公理,意味着它的解释有一种可复现的数学保证:哪怕换成另一个行为完全相同的模型,归因结果也一致。
在大模型里,实际操作只有四步
理论说完了,LLM 里的操作反而很具体。常见场景:模型为什么把这句话判成负向、为什么触发安全拒绝、为什么生成了 token A 而不是 B。
- 选目标:确定对哪个输出做归因。生成式模型通常选目标 token 的 logit(比如 positive 的 logit),而不是整个概率分布。
- 选层:归因放在输入 embedding 层,而不是离散 token 上。embedding 是连续空间,才能求梯度。
- 选基线:文本任务一般用零向量 embedding,这也是原作者的建议。
- 聚合:把 embedding 各维度的归因按 L2 范数聚合成每个 token 一个分数,再画热力图。
from captum.attr import IntegratedGradients
ig = IntegratedGradients(model)
attr, delta = ig.attribute(
inputs=prompt_embedding, # 输入 prompt 的 embedding
baselines=torch.zeros_like(prompt_embedding),
target=positive_logit_idx, # 目标 logit
n_steps=50,
)
这套代码在 Captum 官方文档里开箱即用。
但有几个坑值得单独说:
- 步数:n_steps 至少 20,通常 50 够用。Sturmfels 等人 2020 年的评估发现,用 Gauss-Legendre 求积代替均匀采样,同样步数下积分近似误差能小一个量级。
- 基线敏感:IG 的结果依赖基线。把零向量换成随机 embedding,归因会明显漂移。论文对此也不回避。
- 长上下文开销:每步都要一次完整前向+反向传播,50 步就是 50 次。超长上下文跑到分钟级很正常,多目标归因还要线性叠加。
它做不到什么
优点说了不少,缺陷也一样要摊开。
路径是任意的。IG 默认走直线,但模型高度非线性时,不同路径给出不同归因,虽然每条路径都满足公理。这意味着“唯一正确的归因”在非线性世界里并不存在,直线只是最自然的选择,不是唯一选择。
不建模特征交互。Shapley 值能算两个特征的联合贡献,IG 只给单特征总账。它告诉你 good 值 0.3 分,但不告诉你 good 和 bad 同时出现时的化学反应。
只是局部解释。它解释的是“这个输入在这条预测里贡献怎么分”,不回答“这个模型整体可不可靠”。
所以我的判断是:需要单点归因的场景——调试模型为什么拒绝某个 prompt、审计一次错误判罚是怎么来的——IG 是目前数学上最体面的选择。但如果你要的是因果答案,比如“删掉这句话模型会怎么变”,你要找的是干预类方法(如 activation patching),不是任何梯度方法。
说到底:IG 确实不是严格意义上的 Shapley。但它是我们目前能在几秒钟内算出来、又离 Shapley 公理精神最近的东西。在“算不起”和“不想算”之间,它做出了最优雅的妥协。
原创文章,作者:guanweilu,如若转载,请注明出处:https://guanweilu.cn/article/583.html