File size: 7,652 Bytes
55b60a8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# FT 多跳案例分析 & IFR 标准可视化(exp/case_study)

此目录提供一个轻量的单样本 IFR 可视化流程,不改动核心评测代码。

## 功能
- 读取单个样本(默认 `exp/exp2/data/morehopqa.jsonl`,索引 0)。
- 支持多种模式:
  - `ft`:当前使用的多跳 FT 归因(内部调用 `LLMIFRAttribution.calculate_ifr_multi_hop`)。
  - `ifr`:标准 IFR(单 hop),默认对指定 sink span 做**聚合 IFR**(只显示 1 个面板)。
  - `ifr_all_positions_output_only`:只对 `sink_span` 范围内的 output tokens 计算 IFR token-level 矩阵,并基于该矩阵得到 Row / Recursive(CAGE)两张面板。
  - `attnlrp`:AttnLRP hop0(复用 FT-AttnLRP 的 span-aggregate 逻辑,等价于 `LLMLRPAttribution.calculate_attnlrp_multi_hop(n_hops=0)`,并可视化 `raw_attributions[0].token_importance_total`)。
  - `ft_attnlrp`:FT-AttnLRP(严格复用 `LLMLRPAttribution.calculate_attnlrp_aggregated_multi_hop`,与 `exp/exp2/` 保持一致;直接可视化每 hop 的 `token_importance_total`)。
- 可视化两个视图:
  - **裁剪前 token 级(full)**:带 chat template 的完整序列热力图(template + user prompt + generation)。
  - **Prompt-only token 级**:只显示 user prompt tokens 的热力图(不包含 generation tokens)。
- 热力图按 `|score|` 上色(不区分正负);每个面板的 full/prompt 两张图各自用 p99.5(`|score|`) 独立归一化颜色深度。
- 输出 JSON(完整数值)和 HTML(逐跳热力图)。
- 额外提供 MAS(faithfulness / token perturbation)可视化:对指定归因方法做 token 级扰动评估,并渲染扰动影响热力图 + MAS 分数。

## 快速开始
```bash
# 根据本地模型修改 model/model_path
# 多跳 FT(默认) ft_split_hop,ft_improve
python exp/case_study/run_ifr_case.py \
  --mode ft_split_hop \
  --dataset exp/exp2/data/morehopqa.jsonl \
  --index 0 \
  --model qwen-8B \
  --model_path /opt/share/models/Qwen/Qwen3-8B/ \
  --cuda 0 \
  --n_hops 3

# 标准 IFR(单 hop,可指定 sink span)
python exp/case_study/run_ifr_case.py \
  --mode ifr \
  --dataset exp/exp2/data/morehopqa.jsonl \
  --index 0 \
  --model qwen-8B \
  --model_path /opt/share/models/Qwen/Qwen3-8B/ \
  --cuda 0 \
  --sink_span 0 0

# IFR output-only:只在 output 范围计算 IFR 矩阵,并生成 Row/Recursive(CAGE)两面板
python exp/case_study/run_ifr_case.py \
  --mode ifr_all_positions_output_only \
  --dataset exp/exp2/data/short-morehopqa.jsonl \
  --index 0 \
  --model qwen-8B \
  --model_path /opt/share/models/Qwen/Qwen3-8B/ \
  --cuda 0

# AttnLRP hop0(复用 FT-AttnLRP span-aggregate;可视化 hop0 raw 向量)
python exp/case_study/run_ifr_case.py \
  --mode attnlrp \
  --dataset exp/exp2/data/morehopqa.jsonl \
  --index 0 \
  --model qwen-8B \
  --model_path /opt/share/models/Qwen/Qwen3-8B/ \
  --cuda 0 \
  --sink_span 0 20

# FT-attnLRP(多跳递归 AttnLRP)
python exp/case_study/run_ifr_case.py \
  --mode ft_attnlrp \
  --dataset exp/exp2/data/morehopqa.jsonl \
  --index 0 \
  --model qwen-8B \
  --model_path /opt/share/models/Qwen/Qwen3-8B/ \
  --cuda 0,2,3,4,5,7 \
  --n_hops 3 \
  --attnlrp_neg_handling abs \
  --attnlrp_norm_mode norm
```

产物位于 `exp/case_study/out/`,文件名前缀根据模式变化,例如:
- `ft_case_<dataset>_idx<idx>.json/html`
- `ifr_case_<dataset>_idx<idx>.json/html`
- `ifr_output_only_case_<dataset>_idx<idx>.json/html`
- `attnlrp_case_<dataset>_idx<idx>.json/html`
- `ft_attnlrp_case_<dataset>_idx<idx>.json/html`

## MAS(Faithfulness / Token Perturbation)可视化

> 说明:这里的 MAS 与项目 `llm_attr_eval.LLMAttributionEvaluator.faithfulness_test()` 保持一致:
> 1) 先对样本跑指定方法的归因,并取 token-level attribution(Seq / Row / Recursive)。
> 2) 按 prompt token 的重要性排序,逐步将 token id 替换为 `tokenizer.pad_token_id`(token 级扰动)。
> 3) 用 `sum log p(generation + EOS | prompt)` 得到分数曲线,计算 RISE / MAS / RISE+AP。
> 4) 可视化时用“每一步扰动带来的边际 logprob 变化”作为 token 分数,渲染为 token spans 的“扰动影响热力图”。

```bash
# FT-IFR(ifr_multi_hop;默认 --method ft)
python exp/case_study/run_mas_case.py \
  --dataset exp/exp2/data/short-morehopqa.jsonl \
  --index 0 \
  --model qwen-8B \
  --model_path /opt/share/models/Qwen/Qwen3-8B/ \
  --cuda 0 \
  --method ft \
  --n_hops 3
```

常用方法选择(与 `run_ifr_case.py` 的模式名对齐):
```bash
# IFR(需要 sink_span;默认会优先使用数据集缓存字段)
python exp/case_study/run_mas_case.py --method ifr --sink_span 0 20 ...

# IFR output-only(仅对 sink_span 内的 output token 计算 IFR token-level matrix)
python exp/case_study/run_mas_case.py --method ifr_all_positions_output_only --sink_span 0 20 ...

# FT-IFR(ifr_multi_hop)
python exp/case_study/run_mas_case.py --method ft --n_hops 1 --sink_span 0 20 --thinking_span 0 20 ...

# AttnLRP hop0(复用 FT-AttnLRP hop0;仍然需要 indices_to_explain/sink_span 来取 Seq/Row/Rec)
python exp/case_study/run_mas_case.py --method attnlrp --sink_span 0 20 ...

# FT-AttnLRP(attnlrp_aggregated_multi_hop)
python exp/case_study/run_mas_case.py --method ft_attnlrp --n_hops 1 --sink_span 0 20 --thinking_span 0 20 ...
```

产物位于 `exp/case_study/out/`,文件名前缀为:
- `mas_case_<method>_<dataset>_idx<idx>.json/html`

HTML 默认包含 3 个 attribution 视角面板(Seq / Row / Recursive),每个面板里有 2 行 token 级热力图:
- **Method attribution(token weights)**:该方法的 token 归因权重(用于排序/密度)。
- **Attribution-guided MAS marginal(path deltas)**:按归因排序逐步替换的边际影响(这就是评测中实际使用的扰动路径)。

## 在浏览器中查看 HTML
1) 先运行上面的命令生成 `.html`(终端会打印形如 `wrote exp/case_study/out/...html`)。

2) 在仓库根目录启动一个静态文件服务(任选一个端口,例如 8888):
```bash
python -m http.server 8888 --directory exp/case_study/out
```

3) 用浏览器打开(注意是 `http://`,不是 `https://`):
- 本机:`http://127.0.0.1:8888/<你的html文件名>`
- 远程机器(推荐端口转发):在本地执行 `ssh -L 8888:127.0.0.1:8888 <user>@<server>`,然后在本地浏览器打开 `http://127.0.0.1:8888/<你的html文件名>`

如果你在 `http.server` 日志里看到大量 `400 Bad request version` 且伴随乱码,通常是有客户端用 HTTPS 去连了 HTTP 端口;请确认浏览器地址栏是 `http://...`## 可选参数
- `--sink_span a b` / `--thinking_span a b`:覆盖生成侧的 sink/thinking 句子 span(默认使用缓存字段)。
- `--attnlrp_neg_handling drop|abs`:FT-AttnLRP 每跳负值处理(drop=clamp>=0,abs=取绝对值)。
- `--attnlrp_norm_mode norm|no_norm`:FT-AttnLRP 正则化与 hop ratio 开关(norm=全局+thinking 归一化并启用 ratio;no_norm=三者都禁用)。
- `--chunk_tokens` / `--sink_chunk_tokens`:IFR 分块参数。
- `--output_dir`:修改输出目录。

## 文件说明
- `run_ifr_case.py`:命令行入口与落盘(支持 `ft`/`ifr`/`ifr_all_positions_output_only`/`attnlrp`/`ft_attnlrp` 模式)。
- `run_mas_case.py`:MAS(faithfulness / token perturbation)可视化入口与落盘(支持 `ifr`/`ifr_all_positions_output_only`/`ft`/`attnlrp`/`ft_attnlrp`)。
- `analysis.py`:逐跳清洗与封装(token-level)。
- `viz.py`:HTML 渲染与热力图。