flashtrace / exp /case_study /README.md
wenbopan's picture
Sync FlashTrace package from GitHub
55b60a8

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 分数。

快速开始

# 根据本地模型修改 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 的“扰动影响热力图”。
# 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 的模式名对齐):

# 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):

python -m http.server 8888 --directory exp/case_study/out
  1. 用浏览器打开(注意是 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 渲染与热力图。