跳转至

Understanding Counting Mechanisms in Large Language and Vision-Language Models

会议: CVPR 2026
arXiv: 2511.17699
代码: https://github.com/sharif-ml-lab/counting-mechanisms (有)
领域: 机制可解释性 / 多模态VLM
关键词: 机制可解释性、计数、激活补丁、因果中介分析、内部计数器

一句话总结

作者用一套受控的"重复物体计数"实验 + 自研的因果探针工具 CountScope,逐层逐 token 地剖开 LLM 和 LVLM 是怎么数数的,发现计数不是一次性求和,而是一个随层数逐步涌现、靠"内部计数器"逐项更新、并严重依赖分隔符等结构捷径的分层过程。

研究背景与动机

领域现状:计数是 LLM / LVLM 最基础的能力之一,支撑物体枚举、定量描述、算术推理等一大类任务。但已有大量工作表明模型连"数清楚一串重复物品"这种简单任务都常常出错——会漏数、重复计、对 prompt 措辞敏感。

现有痛点:以往研究几乎都停在行为层面——用准确率或不同 prompt 去测模型"数得对不对",却几乎没人去打开模型内部,看它到底在哪里、用什么机制表示和更新这个数字。换句话说,大家知道模型会数错,但不知道它数数的内部回路长什么样。

核心矛盾:要回答"内部机制"必须用因果方法,而不是相关性观察。直接拿现成的相关性探针(如 Logit Lens / Tuned Lens)去读数字概念时噪声极大、读不出稳定模式,在 LVLM 里因为图文模态差距更糟。所以缺的是一个专门针对数值信息的因果解码工具

本文目标:(1) 定位计数相关信息存在模型的哪些 token / 区域 / 层;(2) 刻画这些数值表示如何随层、随模态涌现;(3) 揭示模型更新计数的内部机制(是全量求和还是增量计数器?)。

切入角度:放弃自然语料里不可控的混杂因素,构造一个完全受控的合成数据集(文本列表 + 合成几何图像,物体类型和数量都能精确调),再用激活补丁(activation patching)做因果干预——直接改中间激活、看输出怎么变,从而判断哪个组件因果地决定了最终数字。

核心 idea:设计 CountScope——把目标 token 的激活搬进一个极简的"占位符 + 计数问题"目标上下文里,用模型自己解码出"这个激活里藏着数字几",从而精确读出任意 token / 层 / 模态内部编码的潜在计数。

方法详解

整体框架

本文不是提出一个新模型,而是一套机制可解释性的实验+分析框架,目标是"看清 LLM/LVLM 计数时内部发生了什么"。整体可以理解为三层:受控实验台 → 因果探针工具 → 一组针对性分析

受控实验台:向模型呈现一串重复物体(文本如 "apple, apple, apple",视觉为含 1–9 个几何形状的合成图),再问"有几个"。文本侧有 list-first / question-first 两种摆放、monotypic(单一类型)/ polytypic(多类型)两种构成、specific(问某类数量)/ general(问总数)两种问法;视觉侧对应单/多类型布局。所有变量都可精确控制。

分析分三类:行为分析(测准确率,放在附录)、观察分析(被动看内部表示,用 PCA 和余弦相似度)、因果中介分析(主动干预激活看输出变化,是本文重点)。因果分析的引擎是激活补丁——在 source(clean)上下文 \(C\) 与 target(corrupted)上下文 \(C'\) 之间互换/置零激活,得到被操纵的 \(C^*\),比较干预前后模型对正确数字的概率变化。

在此之上,本文的核心工具是 CountScope(4.1 节),其余每个分析小节(输入级定位、内部计数器、最大潜在计数、逐层涌现、线性可加、分隔符捷径)都是用 CountScope/补丁去验证一个关于"模型怎么数数"的具体假设。这是一篇纯机制分析论文,下面的"关键设计"即这些分析方法与所揭示的机制结论

关键设计

1. CountScope:把数字信息从激活里"读出来"的因果探针

这是全文的方法基石,针对的痛点是:现成的 Logit Lens / Tuned Lens 在数值概念上噪声太大、读不出稳定模式,LVLM 里更被模态差距搞乱。CountScope 的做法借鉴 PatchScope——构造一个极简目标上下文:含一个或多个占位符 token(文本或视觉),后面紧跟一句计数问题。把待研究的某个 source token / 层 / 区域的内部激活,用最小化的激活补丁搬进这个占位符,然后看目标上下文输出的数字 token 及其 softmax 概率——概率分布直接告诉你"被搬进来的那个激活里编码了数字几"。因为目标上下文极干净、只问计数,所以它把"这个激活携带多少计数信息"这件事从一堆混杂语义里因果地隔离出来,且文本/视觉两种模态通用。

配套的评估指标是作者提出的因果影响分数 CI(Causal Influence),受 Indirect Effect 启发。设 \(\tilde{r}\) 为某假设下期望的答案,\(r'\) 为竞争答案:

\[\mathrm{CI}=\tfrac{1}{2}\Big[\big(P(\tilde{r}\,|\,C^{*})-P(\tilde{r}\,|\,C')\big)+\big(P(r'\,|\,C')-P(r'\,|\,C^{*})\big)\Big]\]

第一项衡量干预把"期望答案"概率相对基线 \(C'\) 抬高了多少,第二项衡量它把"竞争答案"压低了多少。CI 越大越支持该假设,接近 0 表示干预只有随机水平的影响。后续每个机制结论都靠 CI 或正确数字概率的升降来下判断。

2. 数值表示的逐层涌现:小数早分化、大数晚分化

这是观察分析(PCA + 余弦相似度)给出的第一个机制画像。作者记录 1–9 个重复项各自生成的数字 token 隐表示,对所有 item 嵌入做 PCA,并算不同类型 item 在各 list 位置间的余弦相似度矩阵。结论一致:小数字的表示在浅层就能被分开,大数字只有到深层才区分得开——数值大小是沿模型层级逐步编码的。相似度矩阵呈清晰对角结构,小数的对角早早出现、随层数向高数延伸;还观察到类对数模式(log-like):越大的数字在 PCA 空间彼此越近、余弦越相似,呼应人类数感。这说明模型基于 token 顺序和跨层节奏,发展出了结构化的内部计数编码

3. 输入级定位:计数信息在"上下文"而非"问题",文本压在末项、视觉常落在背景

针对"数字到底存在输入哪一段"的问题,作者把输入粗分为 context(物品列表/图像)与 question(提问),用 offline zero patching / interchange patching 干预。结果非常干净:把 context 激活置零会让正确数字概率暴跌(LLM \(0.73\pm0.02\)、LVLM \(0.65\pm0.31\)),而置零 question 几乎无影响(\(0.03\) / \(0.05\));互换两个不同数量 context 的激活,预测跟着 source 走(CI LLM \(0.61\)、LVLM \(0.57\)),证明数字编码在上下文表示里。再细到 context 内部:文本任务里抹掉最后一个 item 的激活掉点最狠(\(0.95\pm0.04\)),说明末 token 编码了最终计数;视觉任务则反直觉——相当一部分计数信号落在背景区块而非物体本身(10×10 patch 下背景 \(0.61\) vs 前景 \(0.42\)),只有当画面留白很少时物体 patch 才更 informative。这种差异源于视觉编码器的全局空间注意力,使信息在解码前就被全局整合。

4. 内部计数器机制:无记忆增量、类型独立、读取上下文最大值、线性可加

这是本文最核心的一组机制发现,回答"模型是一次性求和还是维护一个逐项更新的计数器"。作者用一系列巧妙补丁实验逐条验证:

  • 逐项潜在计数(Per-Item):用 CountScope 探每个 item,发现各 item 携带其序列位置信息,嵌入编码了潜在的数值顺序,monotypic 文本对角最清晰。
  • 持续计数(Continued Counting,类马尔可夫):把 source 末 \(k\) 项在线补到 target 前 \(k\) 项后,第 \(k{+}1\) 项携带的不是按真实位置的 \(k{+}1\),而是 \(N_{\text{source}}{+}1\);最终预测为 \(\tilde{r}=N_{\text{source}}+N_{\text{target}}-k\)。即计数器不重算累积和,而是无记忆地从 source 末尾接着往下数,只依赖最近一次潜在计数。
  • 类型特定的重置计数器:polytypic 且同类聚团时(如 apple,apple,orange,orange,orange,...),模型不维护单一全局计数,而是每类一个计数器;同类被另一类隔开后再出现会重置(最终算成 4 而非 6),但若只隔一个就不重置——呈距离依赖的重置行为
  • 最大潜在计数(Maximum Latent Count):只换两输入的末项时,预测并非总跟 source。当 source 物品更多,预测 \(=N_{\text{source}}\);source 更少时预测 \(\approx N_{\text{target}}-1\)(换 \(k\) 项时近似 \(\max(N_{\text{target}}-k,N_{\text{source}})\))。说明模型不是简单复制末项数字,而是评估整段上下文、取其中的最大潜在计数
  • 线性可加(Linear Additivity):用各位置均值嵌入求"位置差向量",把它加到某 item 嵌入上,能把该 item 解码出的数字朝目标位置整体平移(CI 多数为正,且换成"数动物"任务估计的差向量仍成立)。说明潜在计数在激活空间里近似线性、且与具体物体类型解耦,支持简单的向量干预。

5. 分隔符捷径:逗号比物品本身更能预测计数

作者用 CountScope 探分隔符(如逗号)嵌入,发现分隔符单独就编码了足够的位置信息,且比 element token 预测性更强,尤其在 polytypic 或大数 monotypic 下;且第一个分隔符对应位置 1,之后每个分隔符编码下一个位置(第 3 个逗号反映数字 4 而非 3)。为验证依赖度,把上下文里所有分隔符都替换成"第一个分隔符"的激活,正确数字概率大幅下降(monotypic \(0.75\pm0.39\)、polytypic \(0.97\pm0.05\))——模型的输出跟着被篡改的分隔符模式走,而不是真实物品数。这说明模型把分隔符当成追踪计数的结构性捷径,这也是它在分隔符用法混乱时数错的根因之一。

损失函数 / 训练策略

本文不训练模型,无损失函数。所有实验在冻结的开源模型上做分析:LLM 用 Llama3 与 Qwen2.5,LVLM 用 InternVL3.5 与 Qwen2.5-VL,正文主要报告 Qwen2.5 7B 与 Qwen2.5-VL 7B,其余模型在附录。评估全部在可精确控制物体身份与数量的合成数据集上进行。

实验关键数据

主实验

输入级定位(context vs question)——计数信息几乎全在上下文,问题段无关:

干预 指标 LLM LVLM
context 置零 正确数字概率下降 \(0.73\pm0.02\) \(0.65\pm0.31\)
question 置零 正确数字概率下降 \(0.03\pm0.02\) \(0.05\pm0.03\)
context 互换 CI \(0.61\pm0.02\) \(0.57\pm0.12\)
question 互换 CI \(0.02\pm0.01\) \(0.03\pm0.04\)
文本抹掉末项 正确数字概率下降 \(0.95\pm0.04\)

视觉计数信号 前景 vs 背景(CountScope 解码正确数字的平均概率):

区域 3×3 patch 6×6 patch 10×10 patch
前景(Foreground) \(0.48\pm0.02\) \(0.46\pm0.01\) \(0.42\pm0.01\)
背景(Background) \(0.44\pm0.03\) \(0.58\pm0.02\) \(0.61\pm0.01\)

随分辨率升高,背景区块反而携带更强的计数信号——视觉计数信息会在前景/背景间随空间布局迁移。

实用启示:用视觉空间结构扩展计数容量(数 10–20 个物体的准确率):

设置 准确率
无结构 + 无 CoT(baseline) 10.0%
文本 CoT(无图像分区) 15.3%
图像分四区(structured,无文本 CoT) 50.4%

把图像用线分成 4 区,能让模型把计数分解成小子问题、在视觉 token 上分摊算力,最后三个分区的正确计数平均概率从无结构的 0.18 升到 0.37,远胜文本 CoT。

消融实验

本文以"假设验证"代替传统消融,下表是不同 prompt 结构对核心机制假设的 CI 支持度(越高越支持):

机制假设 配置 关键 CI 说明
持续计数(Continued) LLM question-first, k=2 \(0.90\pm0.07\) question-first 下计数器"接着数"最明显
持续计数 LLM question-last, k=2 \(0.16\pm0.05\) 问句在前才触发,question-last 几乎不成立
最大潜在计数 LLM question-first, \(N_s{>}N_t\), k=2 \(0.80\pm0.13\) source 更多时预测取 source 计数
最大潜在计数 LVLM system-prompt, k=2 \(0.87\sim0.89\) LVLM 在 system-prompt 配置下最稳
线性可加 LLM, 位置差 k=3 \(0.85\pm0.11\) 仅中介 21–26 层即可平移计数
线性可加 LVLM, 位置差 k=4 \(0.25\pm0.07\) LVLM 大位移下加性变弱
分隔符捷径 polytypic 篡改分隔符 概率降 \(0.97\pm0.05\) 输出跟着假分隔符走,不看真实物品

关键发现

  • 计数受 Transformer 深度制约:逐层解码显示 1→9 的计数从约第 5 层到第 16 层依次涌现,大数字必须靠更高层表示,这直接解释了模型为何数不清长序列。
  • 机制依赖 prompt 摆放:持续计数、最大潜在计数等假设在 question-first(LVLM 为 system-prompt) 下最显著,question-last 下大幅减弱——任务定义是否在前会改变内部计数行为。
  • LVLM 五个物体后掉灵敏度:视觉模型在物体数 >5 后内部信号灵敏度下降,而文本模型可稳到 10;视觉计数信号本身比文本更"吵"。
  • 文本 vs 视觉的定位差异:文本最强信号锁在最后一个 item,视觉最 informative 区域不总在最后一个物体(受视觉编码器全局注意力影响),且常落在背景。

亮点与洞察

  • CountScope 把"占位符 + 极简问句"当解码探针:通过把任意激活搬进一个只问计数的干净上下文,巧妙地把"这个激活里藏了数字几"从混杂语义中因果隔离出来,且文本/视觉通用——这个思路可迁移去探测任何"离散标量"概念(如顺序、层级、计量)。
  • "无记忆计数器"这一结论最让人啊哈:把 source 末项补进 target,模型不重算累积和,而是从 source 末尾接着往下数(\(N_{\text{source}}+N_{\text{target}}-k\)),等于实锤了 Transformer 内部存在一个马尔可夫式的潜在状态机。
  • 分隔符是隐形主角:逗号比物品本身更能预测计数,篡改分隔符比扰动物品更致命——提示"结构化标记"在序列建模里承担了远超想象的计数职责,也给"数错"找到了一个可干预的抓手。
  • 可迁移的工程启示:既然计数被深度卡住,那就把算力摊到空间上——给图像加分区线把 10–20 物体准确率从 10% 拉到 50%,是一个不改模型、纯靠输入结构化的实用 trick,可迁移到密集计数、表格读取等场景。

局限与展望

  • 缺完整电路发现:作者承认只刻画了核心机制,尚未做完整的 circuit discovery,没把参与计数的注意力头/MLP 全链路画出来。
  • System-2 设定下不清楚:CoT 解码等 System-2 计数机制还没研究透,本文实用启示只是初步直觉。
  • 以合成数据为主:为精确控制变量,主分析建立在合成列表/几何图像上,自然语料只做了最小因果分析(附录 E),真实场景中物体多样性、遮挡、密集排布是否仍遵循同样机制有待验证。
  • 结论对 prompt 结构敏感:多个机制只在 question-first / system-prompt 下显著,泛化到任意 prompt 排布的鲁棒性是个开放问题;横向比较不同配置的 CI 时也需注意任务难度不一致。

相关工作与启发

  • vs Logit Lens / Tuned Lens:它们是相关性探针,对具体概念有效但读数值时噪声太大、LVLM 里被模态差距搞乱;本文的 CountScope 是因果工具,用极简目标上下文 + 激活补丁专门解码数值信息,更精确且跨模态通用。
  • vs PatchScope:CountScope 借鉴了 PatchScope"把激活搬进目标上下文解码"的范式,但针对计数任务定制了"占位符 + 计数问句"的目标上下文,并配上 CI 分数专门评估数值假设。
  • vs 既有计数评测工作:以往多停在行为准确率/prompt 评测层面,只回答"数得对不对";本文用因果中介把问题推进到"在哪、用什么机制数",给出可干预的内部解释。
  • vs CoT 类 System-2 计数方法:现有方法靠生成文本 token 扩展计算;本文提出正交视角——把视觉 token(图像分区)当额外的计数算力来分摊,避开了只靠模型深度或文本 CoT 的瓶颈。

评分

  • 新颖性: ⭐⭐⭐⭐⭐ 首次系统地对 LLM+LVLM 计数做因果机制刻画,CountScope 工具与"无记忆/类型重置计数器"等结论都是新发现
  • 实验充分度: ⭐⭐⭐⭐ 受控变量充分、多模型多模态多假设交叉验证,但主分析偏合成数据、自然场景验证较少
  • 写作质量: ⭐⭐⭐⭐ 逻辑由观察到因果层层递进、假设清晰,但机制点繁多,初读需要跟着图表才能串起来
  • 价值: ⭐⭐⭐⭐⭐ 既解释了"模型为何数不清大数",又给出图像分区这类不改模型的实用提升,对可解释性与多模态计数都有价值