| # 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 渲染与热力图。 |
|
|