本模块预计时长: 1-1.5小时
目标: 可视化Transformer模型的注意力矩阵,了解模型在生成输出时"关注"了哪些单词。我们将使用bertviz和matplotlib等库创建交互式和静态可视化。
要求: 完成模块5(使用Hugging Face)。建议但非必需完成模块6。
Transformers不是黑盒子。它们的决策基于注意力权重——指示一个单词"关注"另一个单词多少的数字。
可视化这些权重让你能够:
🔹 有用的类比:
就像看到读者阅读文本时的眼动热图。
他们在哪停留最多?他们关联哪些单词?他们忽略什么?
这正是我们要对模型做的事情。
bertviz:你的注意力放大镜bertviz是IBM和谷歌研究人员创建的开源库,专门设计用于可视化Transformer模型中的注意力。
用以下命令安装:
pip install bertviz
注意:如果使用Google Colab,在单元格中运行
!pip install bertviz。
最受欢迎的视图。显示每层中每个注意力头的热图。
让我们在简单句子中可视化注意力。
from transformers import AutoTokenizer, AutoModel
from bertviz import head_view
# 加载模型和分词器(我们将使用BERT base)
model_name = "bert-base-uncased"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModel.from_pretrained(model_name, output_attentions=True) # 重要!
# 示例文本
text = "The cat sat on the mat because it was tired."
# 分词
inputs = tokenizer(text, return_tensors="pt")
# 通过模型传递
outputs = model(**inputs)
# 获取注意力矩阵
# 形状: (batch_size, num_heads, seq_len, seq_len)
attentions = outputs.attentions # 张量元组,每层一个
# 使用head_view可视化
head_view(attentions, tokenizer.convert_ids_to_tokens(inputs.input_ids[0]))
🔹 你将看到:
🔹 预期看到的内容:
理想用于获得整个模型中注意力流的总体视图。
from bertviz import model_view
model_view(attentions, tokenizer.convert_ids_to_tokens(inputs.input_ids[0]))
🔹 你将看到:
显示如何为特定单词对计算注意力,分解查询和键之间的点积。
from bertviz import neuron_view
# 可视化"it"到"cat"的注意力
neuron_view(model, "bert", tokenizer, text, display_mode="dark", layer=5, head=0)
注意:需要传递原始模型,而不仅仅是注意力。
让我们将bertviz应用到模块6中构建的QA模型。
from transformers import AutoTokenizer, AutoModelForQuestionAnswering
from bertviz import head_view
# 加载QA模型(带output_attentions=True!)
model_name = "deepset/roberta-base-squad2"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForQuestionAnswering.from_pretrained(model_name, output_attentions=True)
# 上下文和问题
context = "Barcelona is famous for Gaudí's architecture like the Sagrada Familia."
question = "Who is the famous architect in Barcelona?"
# 准备输入(问题 + 上下文)
inputs = tokenizer(question, context, return_tensors="pt")
# 通过模型传递
outputs = model(**inputs)
# 可视化注意力
head_view(outputs.attentions, tokenizer.convert_ids_to_tokens(inputs.input_ids[0]))
🔹 观察:
这让你对模型如何"推理"以提取答案有强大的直觉。
并非所有头都做同样的事情。常见模式:
🔹 局部注意力:
单词关注邻居。在较低层常见。
例如:"the cat" → "the"关注"cat"。
🔹 句法注意力:
主语 → 动词,动词 → 宾语。
例如:"cat sat" → "sat"关注"cat"。
🔹 回指注意力:
代词 → 先行词名词。
例如:"it" → "cat"。
🔹 语义注意力:
按含义相关的单词。
例如:"tired" → "sleep","exhausted"。
🔹 分隔符注意力:
单词关注[SEP]或[CLS]。可能指示"摘要"或"分类"。
⚠️ 重要: 注意力并不总是可解释的。
🔹 建议: 将可视化作为假设,而不是绝对真理。它们是探索工具,不是确定性工具。
取一个有歧义的句子:
"I saw the man with the telescope."
谁有望远镜?我还是那个男人?在BERT模型中可视化注意力。
"with"关注"I"还是"man"?
哪一层和哪个头显示更清晰的模式?
它是否符合你的直觉?
文本 → 分词器 → input_ids → 模型(带output_attentions=True) → attentions(张量) →
↓
bertviz.head_view() → 交互式热图
↓
解释:哪些单词相关?
你学会了打开Transformers的"黑盒子"。
你不再只是使用模型——你理解它们。
你知道它们如何查看文本,哪些单词它们关联,以及它们如何逐层逐头构建理解。这项技能是无价的:
- 用于研究。
- 用于调试模型。
- 用于向用户或监管机构解释。
- 最重要的是,用于你自己的好奇心和主题掌握。
恭喜!你已经完成了"解密Transformers"课程,达到了很少人能达到的深度。