注意力可视化:如何看懂 Transformer 的注意力

自 2017 年 Transformer 提出以来,注意力(attention)几乎成了现代语言模型的代名词。但「注意力」到底长什么样、又该怎么解读,很多人只停留在公式层面。本文带你从动机讲到实操,用一张热力图看清 Transformer 究竟把「目光」投向了哪些词。

1. 为什么要可视化注意力

注意力权重是一组介于 0 到 1 之间的数值,描述序列中某个 token 在计算表示时「看了」其他哪些 token、各看了多少。把它们画出来,至少有三类用途。

第一,理解模型关注了哪些 token。比如让模型做指代消解(「它」指代谁),我们直接看「它」这个位置的注意力分布,常常能发现权重集中投向了某个实体名词。

第二,调试模型行为。模型输出异常(比如翻译漏词、摘要跑偏)时,注意力热图能帮我们快速定位:是注意力被无关 token 抢走,还是根本没关注到关键信息。

第三,服务于可解释性研究。注意力被视为一种「模型自己给出的注意力分布」,天然带有透明度的想象空间,因此成为解释 NLP 模型最常用的切入点之一。但需要提前提醒:注意力权重并不等于模型决策的真正原因,这一点我们在第 6 节专门讨论。

2. 注意力矩阵与热图基础

在 Transformer 中,注意力不是单个数字,而是一个多层、多头、token 乘 token 的四维张量。拆解如下。

层(layer):模型从浅到深堆叠了若干层(BERT-base 为 12 层,BERT-large 为 24 层),每一层都有自己独立的注意力。

头(head):每一层内部又被切成多个「头」,每个头学习不同的注意力模式(BERT-base 为 12 头)。多头机制让模型可以并行关注不同关系。

token 乘 token 矩阵:对单个头而言,注意力是一个 seq_len × seq_len 的矩阵。第 i 行、第 j 列的值,表示第 i 个 token(作为 query)在生成自身表示时,分配给第 j 个 token(作为 key)的权重。由于经过 softmax 归一化,每一行的数值之和恒为 1。

因此完整的注意力张量形状为 (num_layers, num_heads, seq_len, seq_len)(以编码器自注意力为例)。解码器的自注意力还要叠加上三角掩码(causal mask),保证第 i 个 token 只能关注自身及之前的 token;编码器-解码器注意力则是 (target_len, source_len) 的跨序列矩阵。

把某个「层 × 头」的矩阵画成热力图:横轴是被关注的 token(key),纵轴是发出注意力的 token(query),颜色越亮表示该权重越大。这就是我们通篇说的「注意力热图」。

3. 主流工具与方法

下面三类的可视化能力各有侧重,可按需取用。

BertViz

由 Jesse Vig 开发,是应用最广的注意力可视化工具之一(官方站点为 https://jessevig.github.io/bertviz,代码仓库为 https://github.com/jessevig/bertviz)。它基于 Jupyter / Colab 环境,通过一个简单的 Python API 渲染交互式可视化,支持大多数 Hugging Face 模型。它提供三种视图:

  • Head View(头部视图):展示同一层中一个或多个注意力头的注意力,适合聚焦特定头与层。
  • Model View(模型视图):给出所有层、所有头的「鸟瞰图」,便于纵览模型整体。
  • Neuron View(神经元视图):深入到 query 与 key 向量中的单个神经元,展示它们如何参与注意力计算;该视图仅支持 BertViz 自带的 BERT、GPT-2、RoBERTa 自定义版本。

支持的模型包括 BERT、GPT-2、DistilBERT、RoBERTa 等自注意力模型,以及 BART、T5、MarianMT 等编码器-解码器模型(后两者仅 head view 与 model view 支持)。

Hugging Face transformers 自带的注意力输出

最轻量的方式是不依赖额外工具:用 transformers 加载模型时设置 output_attentions=True,再直接读取 outputs.attentions,即可拿到上述四维张量,随后用 matplotlib 自行绘制。第 4 节的代码用的就是这条路。

exBERT 等同类工具

exBERThttps://hojae.github.io/exbert/)提供网页端交互式探索,可按层、按头筛选并悬停查看每个 token 的注意力分布,偏重「行为探索」而非一次性出图。另外社区还出现过若干围绕注意力与特征分析的可视化项目(名称与可用性随版本更迭,行文中不逐一列举)。

说明:BertViz 的官方站点、仓库与三种视图已通过 WebFetch 核验;exBERT 与 Hugging Face 注意力输出的具体功能描述为通用知识,文中提及的站点 URL 建议以实际访问为准,相关细节标注为「待核实」。

4. 实操:用 Python 画出某一层的注意力热图

下面这段代码不依赖 BertViz 的交互组件,直接用 transformers 取注意力、matplotlib 出图,在任何本地环境都能跑通。我们以 BERT-base 为例,输入一句带代词的句子,观察「it」把注意力投向了谁。

import torch
import numpy as np
import matplotlib.pyplot as plt
from transformers import AutoTokenizer, AutoModel

# 1. 加载 BERT-base,并开启注意力输出
model_name = "bert-base-uncased"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModel.from_pretrained(model_name, output_attentions=True)

# 2. 准备输入文本(含代词 it,可观察其指代)
text = "The cat sat on the mat because it was tired"
inputs = tokenizer(text, return_tensors="pt")

# 3. 前向推理,取出注意力
with torch.no_grad():
    outputs = model(**inputs)

# outputs.attentions 是长度为层数的元组
# 每个元素形状为 (batch, num_heads, seq_len, seq_len)
attentions = outputs.attentions
print("层数:", len(attentions))
print("第 0 层形状:", tuple(attentions[0].shape))

# 4. 取第 0 层、第 0 个头的注意力矩阵
layer_idx, head_idx = 0, 0
attn = attentions[layer_idx][0, head_idx].numpy()  # 形状 (seq_len, seq_len)

tokens = tokenizer.convert_ids_to_tokens(inputs["input_ids"][0])

# 5. 画热力图
fig, ax = plt.subplots(figsize=(8, 7))
im = ax.imshow(attn, cmap="viridis")
ax.set_xticks(range(len(tokens)))
ax.set_yticks(range(len(tokens)))
ax.set_xticklabels(tokens, rotation=90)
ax.set_yticklabels(tokens)
ax.set_xlabel("被关注的 token(key)")
ax.set_ylabel("发出注意力的 token(query)")
ax.set_title(f"Layer {layer_idx} / Head {head_idx} 注意力热图")
fig.colorbar(im, ax=ax)
plt.tight_layout()
plt.show()

运行后,观察纵轴 it 那一行的颜色分布:在不少头里,it 会把显著权重投向 cat(或 mat),直观呈现了「代词回到先行词」的注意力模式。把 layer_idxhead_idx 换成别的值,就能逐一探索不同层、不同头的关注重点。

如果想快速体验 BertViz 的交互视图,安装与最小调用如下:

pip install bertviz jupyterlab ipywidgets
from transformers import AutoTokenizer, AutoModel, utils
from bertviz import head_view
utils.logging.set_verbosity_error()

tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")
model = AutoModel.from_pretrained("bert-base-uncased", output_attentions=True)
inputs = tokenizer.encode("The cat sat on the mat", return_tensors="pt")
outputs = model(inputs)
attention = outputs[-1]          # 注意力权重元组
tokens = tokenizer.convert_ids_to_tokens(inputs[0])
head_view(attention, tokens)     # 在 notebook 中渲染交互图

5. 怎么读热力图

拿到一张热图后,可以从以下几个角度解读其中的结构。

对角线(self-attention 的「看自己」)。自注意力中每个 token 通常都会给自己分配相当权重,因此对角线往往偏亮。解码器由于因果掩码,每个 token 至少能看到自己,对角线几乎必然是高值。

相邻 token(局部依赖)。很多头会把权重集中在相邻位置(关注前一个或后一个词),对应局部短语、子词拼接等表层规律。这类模式在浅层尤为常见。

跨句 / 跨段注意力。在句对任务或含 [SEP] 的序列中,常出现某些 token 把权重投向另一个句子、或集中投向 [CLS][SEP] 这类特殊分隔符,反映段落边界与全局聚合。

特定 head 的语法 / 语义专门化。研究发现,不同头会逐渐「分工」:有的头倾向于捕捉句法依存(如动词关注其主语或宾语),有的头负责共指(代词关注先行名词),有的头几乎只盯着分隔符。BERT 的若干中层 head 能稳定还原出近似句法树的结构(相关结论见 Clark et al., 2019,论文号待核实)。

读取时的要点:先横向看「某一行亮在哪些列」,那才是该 token 实际关注的来源;不要被整张图的冷暖平均误导。同时,低层多为局部、表层模式,高层才逐渐出现语义与句法层面的远程依赖。

6. 局限:注意力不等于可解释性本身

可视化注意力很有用,但它不能直接当作「模型为什么这么预测」的答案。关键的反驳来自 Jain 与 Wallace 的研究。

他们在 2019 年的论文中指出:注意力权重与模型最终输出之间,并不存在可靠的因果或对应关系。两个核心发现是:(1)学到的注意力权重,与基于梯度的特征重要性度量常常几乎不相关;(2)可以找到「完全不同的注意力分布」,却让模型给出完全一致的预测。换句话说,扰动注意力权重未必改变预测结果,因此标准注意力模块并不提供有意义的解释,不应被当作解释来对待。

这带来三点提醒。第一,注意力热图是「模型内部信号之一」,不是决策证据链。第二,高权重只说明该 token 在表示层面被大量使用,不证明它是预测的关键原因。第三,实证研究中应把注意力作为辅助线索,配合探针(probing)、归因(attribution)、因果干预等方法,才能得到可辩护的结论。

小结

本文从动机、数学结构、工具、实操到解读与局限,系统梳理了注意力可视化。要点如下:注意力是 (层, 头, token, token) 的四维权重,每一行归一化到 1;BertViz 提供 head / model / neuron 三类视图,transformers 的 outputs.attentions 则能直接喂给 matplotlib 出图;读图时关注「行方向亮在哪些列」,并结合对角线、相邻、跨段与 head 专门化等模式;最后务必记住,注意力是辅助信号而非解释本身,Jain 与 Wallace 已证明权重可被扰动而预测不变。

参考与延伸阅读

  • Vaswani et al., 《Attention Is All You Need》, 2017, arXiv:1706.03762。提出完全基于注意力机制的 Transformer 架构。已核验(WebFetch 核对标题、作者与摘要)。
  • Jesse Vig, BertViz 仓库与官方站点。提供 head view / model view / neuron view 三种注意力可视化视图。已核验(WebFetch 核对 GitHub 仓库与视图说明;官方站点 URL 见 https://jessevig.github.io/bertviz)。
  • Sarthak Jain, Byron C. Wallace, 《Attention is not Explanation》, 2019, arXiv:1902.10186。论证注意力权重不能被当作模型预测的可靠解释,且可被扰动而预测不变。已核验(WebFetch 核对标题、作者、会议与摘要;论文实际发表于 NAACL 2019,而非 ACL 2019,文中已修正)。
  • Jesse Vig, 《A Multiscale Visualization of Attention in the Transformer Model》, ACL 2019(BertViz 相关论文)。待核实(会议与标题为依据通用信息,建议二次确认)。
  • Clark et al., 《What Does BERT Look At? An Analysis of BERT’s Attention》, 2019。发现注意力 head 能还原近似句法结构。待核实(论文号未在本次 WebFetch 中核对,建议确认 arXiv 编号后补充)。
  • exBERT 交互式探索工具,站点 https://hojae.github.io/exbert/。待核实(具体功能与可用性建议以实际访问为准)。
本文累计阅读