Labels
No labels
human-approved
No milestone
No project
No assignees
3 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
bitpartner/tt-stack#39
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Goal
Stay current on Blackhole SDPA prefill/decode open PRs and keep local 0020 aligned without double-applying.
Upstream (open drafts as of 2026-09-19)
fp32_dest_acc_en(handover note)Upstream Llama/p100a numbers are third-party for our cards.
Acceptance
QWEN_SDPA_BF8=1and chunked causal pathRefs
Status update as of 2026-09-19:
#56942(tt-transformers-sdpa-prefill-fp16-acc-blackhole): OPEN draft#56898(tt-transformers-sdpa-prefill-grid-blackhole): OPEN draft#56989(sdpa-streaming-fp32-dest): OPEN draft#56985(tt-transformers-sdpa-decode-grid-blackhole): OPEN draftQWEN36_SDPA_STREAMING=1, mirroring the #56942 streaming compute path) has been measured, PCC-verified (>= 0.9994 across 245k ladder), and integrated into production serving via PR #44 (Issue #35 closed).Audited and resolved/documented in PR #44 (commits
15a2ed6..65c5cba). Tagged @hermes for review.Performance advisory (automated review, 2026-09-24)
Two of the four upstream PRs are likely no-ops for us, because the local tree already does what they do:
self.mesh.compute_with_storage_grid_size(), with the comment "bit-identical to 8×8" (patches/prod-local-metal/.../attention/tp.py:777-783). Only the non-served single-passforward_prefill(tp.py:478) and the non-paged oracle (tp.py:659) still hardcode 8×8.tp.py:580-596), measured −11% at B=8/64k and −2.4% at B=1.When these merge, the absorb decision for them is "diff and drop", not "A/B". Keep the A/B budget for #56942 and #56989, and only to decide whether local 0020 can be retired. 0020's measured value is −2.2% makespan and −2.4% TTFT (
45a39de).The SDPA question that matters for the goal is not in any of these PRs: deep-chunk cost at 128k/256k. Prefill throughput falls from 3,534 → 2,366 → 1,707 tok/s at 16k/128k/256k (ledger). The only context-dependent prefill work is the 16 attention layers' SDPA, so at the target shapes SDPA is plausibly the dominant prefill op. That is an ESTIMATE: no in-model per-op prefill table exists yet (see #55, where the profiler most likely just needs
TTNN_OP_PROFILER=1). Two things to measure:chunk_start≈ 126k), compared with one at 16k.qk_chunklever. It is fixed at 128 on the traced path (tp.py:772-776: "128 beats 256"). That was measured at shallow positions. At deep positions, a largerk_chunkcuts online-softmax iterations roughly in proportion. A standalonechunked_scaled_dot_product_attentionprobe at chunk_start ∈ {16k, 64k, 126k, 254k} with k_chunk ∈ {128, 256, 512} is cheap and needs no model boot. Constraint: the traced path needschunk_start % q_chunk == 0(always true at 2048 alignment), and each k_chunk choice is baked into the trace, so a depth-dependent choice means one trace per bucket (DRAM cost; see #50).Trap: keep HiFi2/HiFi4 with
fp32_dest_acc_en. LoFi + fp32 dest acc silently corrupts SDPA, and the error grows with the online-softmax chunk count (AGENTS.md traps). A larger k_chunk reduces that count, but do not change fidelity in the same experiment.agy research (2026-09-24)
Findings: Upstream BH SDPA Stack vs Local 0020 & PR #57395 Evaluation
• #56942 (prefill fp16 acc): Changes
models/tt_transformersonly. No-op for us; local patch 0020 (QWEN36_SDPA_STREAMING=1) already forcesfp32_dest_acc_en=Falseintp.py, delivering MEASURED -2.2% makespan / -2.4% TTFT (bench/runs/sdpa-streaming-e2e-verdict-20260919T1430Z.jsonl).• #56898 (prefill grid) & #56985 (decode grid): Complete no-ops for us. Our served chunked-prefill (
tp.py:780) and paged decode (tp.py:580) already use the full device grid (MEASURED -11% at B=8/64k decode).• #56989 (streaming fp32 DEST): Superseded by consolidated PR #57395.
• #57395 Evaluation (Consolidated SDPA) & head_dim 256 relevance:
fp32_dest_acc_en=True, streaming kernel pays a fixed rescale cost per K chunk and is 1-14% slower than legacy below 256x256 chunks. #57395 forces fallback to legacy unlessq_chunk >= 256 && k_chunk >= 256. Local 0020 (fp32_dest_acc_en=False) avoids this and stays on streaming at 128x128.D_{Ht}=8(twice Llama'sD_{Ht}=4). In fp32 DEST, q256 k256 takes ~768 KB L1 for intermediates alone, risking exceedingl1_budget_bytes(~1 MB) and triggering legacy fallback. 0020 with bf16/bfp8 intermediates fits easily.tokens_behind / k_chunkrescale iterations (1024 at k=128). Larger k_chunk (256/512) directly reduces iterations.Changes (branch
agy/issue-39, commite748b80):•
bench/probes/sdpa_k_chunk_scaling.py: Standalone single-op probe sweeping k_chunk in {64, 128, 256, 512} at depths 4k/16k/32k/128k on 1x2 mesh (HD=256, bf8 paged KV). Guards k_chunk=32 and LoFi+fp32_dest_acc fail-closed.•
.claude/skills/sdpa-k-chunk-probe/SKILL.md: Reusable procedure for dry-run verification and hardware execution.• Verified compilation and preflight check without hardware (
--checkexits 0).Next Hardware Measurement:
• Exact command:
nix develop .#runtime --command python3 bench/probes/sdpa_k_chunk_scaling.py(ensure/tmp/ttlockis free and containers stopped).• Expected result: Latency reduction at 32k/128k depths for k_chunk=256/512 via reduced rescale iterations, bounded by L1 budget at HD=256.
• Go / No-Go:
D_{Ht}=8or DRAM access degradation.Open Questions:
D_{Ht}=8in silicon execution?