Repository navigation
metal: Spark2.5's and Llama's prompt attention from one source, Llama at WINDOW and RING 0 (#2251) - #3269
metal: Spark2.5's and Llama's prompt attention from one source, Llama at WINDOW and RING 0 (#2251)#3269jschmied wants to merge 2 commits into
Conversation
… at WINDOW and RING 0 (ashhart#2251)
|
Thanks @jschmied, this is a tidy, well-scoped consolidation. I re-derived the equivalence from the source rather than relying only on the IR claim: the shared text folds back to Llama's old kernel at
Must-fixes: none. The byte-identical IR comparison for the three configs and the M5 "prompt sees the next key" control are Mac-only, so for now they rest on your device run; we'll check them on our side before landing. Optional: no host test pins the Llama fold today. A cheap assertion that the loader's
|
…t WINDOW 0 and RING 0 (ashhart#2251) Every line of core/prompt_attention_nax.metal that names WINDOW or RING must be one of its four guarded forms, the mask line among them, and Llama's loader must define both as 0 over the shared text, so a later edit can't unfold it. A control checks that an unguarded window term or a missing mask line fails. It runs in test-kernel-symbols-host.
|
Thanks for the review. I took the optional ask.
I planted two faults and saw it go red before green: dropping the loader's two defines, and unguarding the window term in the shared text. A second test checks that the checker itself rejects both faults. It's a second commit on top of |
The first section-2 group of #2251. On main f8dacd7 (the bf16 argmax PR #2949 is merged; this no longer stacks on it). Two commits: the change, then a host test that pins Llama's fold (head 35bd11b).
What changes
llama/attention_nax.metalwasspark25/attention_nax.metalwith two folds:WINDOWandRINGfolded to 0: the window's first key block, the ring slot of a key and value row, and the window's mask term;core/prompt_attention_nax.metal, Spark2.5's text with the kernel named byTF_PROMPT_ATTENTION.sources.ziggives each family its name:spark25_attention_nax=#define TF_PROMPT_ATTENTION sp_prompt_attention++ it, andllama_attention_nax=... ll_prompt_attention++ it.llama/contracts.zig attentionSourceHeads, which the model and the contract share) adds#define WINDOW 0and#define RING 0to its geometry defines. With those, the shared text folds back to Llama's old kernel.col > row ? kMasked, which only the old Llama text had. It now edits the shared mask line,const bool out = col > row ||tocol > row + 1 ||, the same edit as Spark2.5's full-layer control. One contract comment names the new path.attention_naxadds a block bitmap (SEL) and Gemma 4's is the parent with its own cache layout; they are the next steps of this template.Same code before and after (M3 Pro)
Compiled code: the LLVM IR is byte-identical, old against new, for three configurations, source path aside:
DH 128, NQ 56, G 7, KVH 8);WINDOW 0, RING 0);WINDOW 1024, RING 1088).Each source was its loader's defines ++ the source with
nax.hinlined, compiled withxcrun metal -std=metal4.1 -S -emit-llvmunder-fmetal-math-mode=safe, with-fmetal-math-fp32-functions=fastand=precise.Kernel contract (main f8dacd7 against this change):
--only llama(22 kernels: 22 pass gates 1-4 ... 12 controls: 12 red as planted),--only spark25and--only "Llama Nanbeige"(the masked-attention cases) all give output identical apart from the SUMMARY's timings.spark25 attentionlimit gate builds the shared text here, for both layer kinds, and passes.Tests: native build;
test-spark25-host(12/12),test-lfm2-dspark(57/57) andtest-kernel-symbols-host(3/3) pass. Lean 341 vs 341, 0 new;zig fmt --checkandgit diff --checkclean.Fold test (35bd11b):
zig/tests/prompt_attention_fold.zig, run bytest-kernel-symbols-host, pins Llama's fold. Every WINDOW/RING use in the shared text is guarded, and Llama's loader defines both as 0. Planted red first: dropping the loader's defines, or unguarding(WINDOW && colin the shared text, fails it.x86 CI (Linux build + host tests on 35bd11b,
test-kernel-symbols-hostincluded): green, 730/730 steps, 9470/9542 tests passed (72 skipped), 322/335 equal to server goldens with 0 unexpected differences,zig fmt --checkclean.Served evidence: not run. The compiled IR is byte-identical, so seeded and greedy replies, resume and concurrency against main cannot change. No refusal is added.
Proposed CHANGELOG line (yours to place):
Metal: Spark2.5 and Llama prompt attention now build from one shared source (#2251).