hamer-p150 / code /scripts /micro /head_sdpa_decode.py
changh95's picture
Optimized build (2026-10-03): model call 3.49 ms, device 3.36 ms
58ba6df verified
Raw History Blame Contribute Delete
2.71 kB
"""Round 10: MANO-head cross-attention (1 query token, 8 heads x 64, 192 keys): the library SDPA as used now
([1, 8, 32, 64] query, row 0 meaningful) vs flash-decode SDPA ([1, 1, 8->32, 64] query, heads as rows).
usage: head_sdpa_decode.py"""
import sys, os
from pathlib import Path
from common import *
dev = open_dev()
try:
torch.manual_seed(0)
H, S, D = 8, 192, 64
q = torch.randn(H, D)
k = torch.randn(H, S, D)
v = torch.randn(H, S, D)
ref = torch.softmax((q[:, None, :] @ k.transpose(-1, -2)) * D ** -0.5, -1) @ v # [H, 1, D]
ref = ref[:, 0]
L1 = ttnn.L1_MEMORY_CONFIG
G = dev.compute_with_storage_grid_size()
tk_ = lambda t: ttnn.from_torch(t.to(torch.bfloat16), dtype=ttnn.bfloat16, layout=ttnn.TILE_LAYOUT, device=dev, memory_config=L1)
K, V = tk_(k[None]), tk_(v[None])
qh = torch.zeros(1, H, 32, D); qh[0, :, 0] = q
Q = tk_(qh)
pc = ttnn.SDPAProgramConfig(compute_with_storage_grid_size=G, q_chunk_size=32, k_chunk_size=192, exp_approx_mode=False)
cc = ttnn.init_device_compute_kernel_config(dev.arch(), math_fidelity=ttnn.MathFidelity.HiFi4, fp32_dest_acc_en=True,
math_approx_mode=False)
f0 = lambda: ttnn.transformer.scaled_dot_product_attention(Q, K, V, is_causal=False, scale=D ** -0.5, program_config=pc,
memory_config=L1, compute_kernel_config=cc)
o0 = ttnn.to_torch(f0()).float()[0, :, 0]
print(f"[sdpa] current: PCC {pcc(o0, ref):.7f} max|d| {float((o0 - ref).abs().max()):.4f} {time_op(dev, f0):.2f} us", flush=True)
qd = torch.zeros(1, 1, 32, D); qd[0, 0, :H] = q
DR = ttnn.DRAM_MEMORY_CONFIG
tkd = lambda t: ttnn.from_torch(t.to(torch.bfloat16), dtype=ttnn.bfloat16, layout=ttnn.TILE_LAYOUT, device=dev, memory_config=DR)
QD, K, V = tkd(qd), tkd(k[None]), tkd(v[None])
for kc in (32, 64, 128):
pcd = ttnn.SDPAProgramConfig(compute_with_storage_grid_size=G, q_chunk_size=32, k_chunk_size=kc, exp_approx_mode=False)
f1 = lambda pcd=pcd: ttnn.transformer.scaled_dot_product_attention_decode(
QD, K, V, is_causal=True, cur_pos=[S - 1], scale=D ** -0.5, program_config=pcd, memory_config=DR,
compute_kernel_config=cc)
try:
o1 = ttnn.to_torch(f1()).float()[0, 0, :H]
print(f"[sdpa] decode k_chunk {kc}: PCC {pcc(o1, ref):.7f} max|d| {float((o1 - ref).abs().max()):.4f} "
f"{time_op(dev, f1):.2f} us", flush=True)
except Exception as e: # noqa: BLE001
print(f"[sdpa] decode k_chunk {kc} FAIL {str(e).splitlines()[0][:200]}", flush=True)
finally:
ttnn.close_device(dev)