1. 可视化有什么用
大模型整体是黑盒,但注意力分数是少数可解释的窗口。通过看每个 token 关注哪些位置、关注强度如何,你能直观理解模型「为什么这么想」------答对时验证它的逻辑,答错时定位它的偏差。
对做 RAG、Agent、模型调试的 Java 工程师来说,注意力热图是性价比极高的诊断工具。
(见图 figure_15_1)
2. 注意力矩阵的解读
把注意力分数铺成 n×n 矩阵:行 = Query 位置,列 = Key 位置,格子越亮(值越大)表示关注越强。几种典型信号:
- 对角线强:每个词主要看自己(局部/自指);
- 某一列全亮 :所有词都盯着某个特殊位置(如
[CLS]、句号、分隔符),它是「信息汇聚点」; - 块状亮:短语/实体内部互相注意。
读图要结合语义,不能孤立看数值。
3. 典型模式
经验上常见三种模式:
- 对角线/局部:模型在抓相邻语法(「的」「了」附近的修饰关系);
- 垂直线/汇聚点 :被
[CLS]、标点、特殊符号吸走,这些位置充当「全局摘要站」; - 块状:实体或短语内部强关联(如「中国人民银行」四个字互相注意)。
不同 head 模式不同,这也是第 5 节说的「多头自发分工」的可视化证据。
(见图 figure_15_2)
4. 用 Java 打印热图
最简单的做法:把分数矩阵输出成 CSV 或直接打印 ASCII 网格,肉眼看亮区。需要更正式的热图,可以用 JFreeChart 画,或把数据导出给 Python 的 matplotlib。
生产里更常见的链路是:Python 侧导出注意力→Java 后端批量分析→前端展示。但核心计算都一样:拿到 [seqLen × seqLen] 的权重矩阵,按行看 Query 的关注分布。
(见图 figure_15_4)
5. 可视化不是万能
一个重要的研究结论:注意力权重高 ≠ 模型真依赖该位置。有论文证明,把注意力权重扰动后模型输出可能几乎不变,说明真正起作用的可能是其他机制(如 FFN 的记忆)。
所以注意力热图是第一步排查工具,要定位根因还得结合梯度归因、探针(probe)等方法。别把「它看这儿」直接等同于「它靠这儿」。
(见图 figure_15_3)
6. badcase 定位实战
举个 RAG 场景:模型答非所问。你可以查:
- Cross-Attention 的 top-k 位置是不是落在了错误召回的 chunk 上;
- 自注意力 是否被某个无关 token(如 prompt 模板里的特殊符号)带偏。
定位到「注意力跑偏」后,再决定是改召回、改重排、还是改 prompt。可视化把「玄学调参」变成「可定位的工程问题」。
java
/** 打印注意力矩阵(ASCII 热图简化版) */
public class AttentionHeatmap {
void print(double[][] attn) {
for (double[] row : attn) {
for (double v : row)
System.out.printf("%.2f ", v);
System.out.println();
}
}
}
| 模式 | 可视化特征 | 可能含义 |
|---|---|---|
| 对角线强 | 主对角线亮 | 自指 / 局部语法 |
| 竖条 | 某一列全亮 | 汇聚点(如特殊 token) |
| 块状 | 子矩阵亮 | 短语/实体内部关联 |
| 分散 | 无明显模式 | 全局平均或头分工 |