@torch.no_grad()
def record_probe(
out_dir: str,
layer: int,
query: torch.Tensor,
key: torch.Tensor,
scores: torch.Tensor,
attn_metadata,
) -> None:
"""scores: [B, H, n, n] scaled pooled scores; query/key tiled BSHD."""
step = int(attn_metadata.current_timestep)
P = attn_metadata.num_prefix_tiles
V = attn_metadata.num_video_tiles
probs = torch.softmax(scores.float(), dim=-1) # pooled attention, all tiles
vid_q = probs[:, :, P:, :] # video-query rows
prefix_mass = vid_q[..., :P].sum(-1).mean(dim=(0, 2)) # [H]
vid_vid = vid_q[..., P:]
vid_vid = vid_vid / vid_vid.sum(-1, keepdim=True).clamp_min(1e-12)
sorted_mass = vid_vid.sort(dim=-1, descending=True).values.cumsum(-1) # [B,H,Vq,V]
ks = [max(1, min(int(round(f * V)), V)) for f in _FRACS]
recall = torch.stack([sorted_mass[..., k - 1] for k in ks]) # [F,B,H,Vq]
recall_mean = recall.mean(dim=(1, 3)) # [F,H]
# token-true check on sampled rows (exact row softmax, tile-aggregated)
gen = torch.Generator(device="cpu").manual_seed(step * 1000 + layer)
# sample among video rows in the PADDED/tiled domain that are non-pad
from fastvideo.attention.backends.video_sparse_attn_h3 import token_tile_and_valid
token_tile, token_valid = token_tile_and_valid(attn_metadata.variable_block_sizes, attn_metadata.tile_elems)
video_rows = torch.nonzero((token_tile >= P) & token_valid, as_tuple=False).flatten()
idx = video_rows[torch.randint(0, video_rows.numel(), (_TRUE_ROWS, ), generator=gen).to(query.device)]
q_s = query[:, idx].float() # [B, R, H, D]
logits = torch.einsum("brhd,bshd->bhrs", q_s, key.float()) / (query.shape[-1]**0.5)
logits = logits.masked_fill(~token_valid.view(1, 1, 1, -1), float("-inf"))
true_probs = torch.softmax(logits, dim=-1)
n_tiles = attn_metadata.variable_block_sizes.numel()
tile_mass = torch.zeros(*true_probs.shape[:3], n_tiles, device=query.device, dtype=true_probs.dtype)
tile_mass.index_add_(3, token_tile, true_probs) # [B,H,R,n]
tm_vid = tile_mass[..., P:]
tm_vid = tm_vid / tm_vid.sum(-1, keepdim=True).clamp_min(1e-12)
# pooled ranking per sampled row's q-tile
pooled_rank = scores[:, :, P:, P:].argsort(dim=-1, descending=True) # [B,H,Vq,V]
row_qtile = (token_tile[idx] - P).view(1, 1, -1, 1).expand(pooled_rank.shape[0], pooled_rank.shape[1], -1, 1)
row_rank = pooled_rank.gather(2, row_qtile.expand(-1, -1, -1, pooled_rank.shape[-1])) # [B,H,R,V]
perfect_sorted = tm_vid.sort(dim=-1, descending=True).values.cumsum(-1) # selection ceiling
true_recall = {}
perfect_recall = {}
for f, k in zip(_FRACS, ks, strict=True):
captured = tm_vid.gather(-1, row_rank[..., :k]).sum(-1) # [B,H,R]
true_recall[f] = captured.mean().item()
perfect_recall[f] = perfect_sorted[..., k - 1].mean().item()
os.makedirs(out_dir, exist_ok=True)
payload = dict(step=step,
layer=layer,
P=P,
V=V,
fracs=_FRACS,
prefix_mass=prefix_mass.cpu(),
recall_mean=recall_mean.cpu(),
true_recall=true_recall,
perfect_recall=perfect_recall)
# under SP each rank holds a distinct head subset; keep every rank's stats
rank = torch.distributed.get_rank() if torch.distributed.is_initialized() else 0
torch.save(payload, os.path.join(out_dir, f"probe_step{step:03d}_layer{layer:03d}_r{rank}.pt"))