Repository navigation
Conversation
The single-sequence graph kept the LM head in the checkpoint layout and emitted `dot_general %x, %head, contracting_dims = [0] x [1]` against a `[vocab, hidden]` f32 tensor. On the pinned IREE that lowers to a materialized full-weight transpose fused with the f32 -> f16 convert, so every decode step streamed and rewrote the whole head: 9.64 ms of the 47.0 ms step on gfx1151 for llama-3.2-1b, with the head vecmat and argmax another 6.35 ms. `take_lm_head` now switches on the graph's `ProjectionLayout`. `InOut` (the single-sequence `IreeLlama` graphs) always declares one `[hidden, vocab]` head operand and the head sites use `linear_proj` / `linear_seq_proj`, so the contraction becomes `[0] x [0]` and the loader transposes the head once at upload, f16-resident when the f16 path is active. Tied checkpoints keep their `[vocab, hidden]` embed arg for the gather and add this second arg, read from the same tensor; untied checkpoints use `lm_head` for it, so their head goes from a 1.05 GB f32 whole tensor to a 0.53 GB f16 transposed one. `OutIn` (the ragged batch engine and every committed golden) keeps the exact previous head arg and `[V, H]` form, so the batch path and the goldens are unchanged. The tied single-sequence graph pays one extra f16 head copy (`hidden * vocab * 2` bytes, 525 MB for llama-3.2-1b). Validation on gfx1151 (hip, llama-3.2-1b-instruct-4bit, release build): the decode step drops from 47.0 to 39.6 ms and from 318 to 317 dispatches, and the head's `elementwise_transpose` dispatch is gone; the head is now one `vecmat_128256x2048` (3.49 ms) plus the argmax (3.86 ms). B=1 CLI at capacity 256, n=64 18.4-25.1 tok/s and n=128 19.1-27.8 tok/s (interleaved runs against the pre-#2861 binary: 10.5-11.3 and 10.5-11.0). Greedy output is token-identical on llama-3.2-1b and qwen3-1.7b (tied) and mistral-7b-instruct-v0.3 (untied, exercising the `lm_head` operand). Batch B=4 N=8 and B=8 N=16 still pass REFERENCE-EXACT at 65.4 and 74.3 tok/s. mlxcel-xla lib tests 387 pass with unchanged goldens; clippy clean at default and `iree` features. Refs #2863
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The single-sequence XLA/IREE graph kept the LM head in the checkpoint
[vocab, hidden]layout and emitteddot_general %x, %head, contracting_dims = [0] x [1]. On the pinned IREE that lowers to a materialized full-weight transpose fused with the f32 -> f16 convert, so every decode step streamed and rewrote the entire head: 9.64 ms of a 47.0 ms step on gfx1151 for llama-3.2-1b, with the head vecmat (2.49 ms) and argmax (3.86 ms) on top. Closes #2863.This PR gives the single-sequence graphs a pre-transposed
[hidden, vocab]head operand, uploaded once, and contracts its hidden axis.Changes
take_lm_headswitches on the graph'sProjectionLayout.InOutalways declares one[hidden, vocab]head operand, f16 when the precision is f16 and the weights are f16-resident (same rule as the dense projection args, now shared throughprojection_elt).OutInkeeps the exact previous arg list and[V, H]form.linear_proj/linear_seq_proj, soInOutemits[0] x [0]andOutInemits the unchanged[0] x [1].weight_specs_qpushesProj(embed)after the norm for a tiedInOutcheckpoint, orProj(lm_head)for an untied one. The head never takes the packedQuantRawpath.[vocab, hidden]embed arg for the gather and add the head as a second read of the same tensor. Untied checkpoints reuselm_head, which shrinks from a 1.05 GB f32 whole tensor to a 0.53 GB f16 transposed one.OutIn(the ragged batch engine and every committed golden) is untouched.Memory cost
A tied single-sequence checkpoint holds one extra f16 head copy of
hidden * vocab * 2bytes (525 MB for llama-3.2-1b). Untied checkpoints get smaller, as above. The issue records this trade; if a checkpoint makes the copy too expensive, a later change can gate it, but no model in this validation needed that.Validation (gfx1151, hip, llama-3.2-1b-instruct-4bit, release build)
rocprofv3decode trace: the head'selementwise_transpose_128256x2048_f32xf16dispatch is gone; the head is onevecmat_128256x2048_f16xf16xf32(3.49 ms) plusreduction_128256(3.86 ms).lm_headoperand).cargo test -p mlxcel-xla --lib387 passed (2 new: theInOuthead arg shape plus[0] x [0]contraction, and the tied/untied spec order), committed goldens unchanged.cargo clippy -p mlxcel-xla --all-targets -- -D warningsand with--features ireeclean;cargo fmt --checkclean.Out of scope
The remaining ~31 ms of the step is 100 projection vecmats at about 0.31 ms each against MLX
qmv_wideat about 0.04 ms, and the 3.86 ms argmax over 128256 f32 logits. Both are IREE codegen/dispatch-efficiency questions rather than graph-layout ones, as recorded in the issue.Closes #2863