Skip to content

perf(llama3): project only the sampled row through the LM head at prefill - #1969

Merged
inureyes merged 1 commit into
mainfrom
update/issue-1968-llama3-last-row-prefill
Sep 24, 2026
Merged

inureyes merged 1 commit into
mainfrom
update/issue-1968-llama3-last-row-prefill

Conversation

@inureyes

Copy link
Copy Markdown
Member

Llama3-family prefill (Llama 3.x, Mistral, Qwen2/2.5) now projects only the sampled row through the LM head, as Cohere2 does since #1955.

  • Llama3Model's two duplicated forward bodies become one hidden_states path (embeddings, layers, final norm), and forward_last_logits, forward_last_logits_with_sequence_id and forward_last_logits_with_embeddings_and_sequence_id slice the hidden state at last_pos before the head. The final norm and head act per position, so the row equals the full forward's.
  • generate::logits_at_position is now public so overrides can slice hidden states with it.
  • VisionLanguageModel forwards the three entry points to its text model; before, the trait default ran behind the wrapper and skipped any text-model override (Gemma 3 VLM, LLaVA, FastVLM, Llama 4 VLM).

Measurement

M1 Ultra, mlxcel-bench-decode with bench_decode.sh's arguments, the old path reproduced through a measurement-only switch, ABBA:

Model pp512 prefill pp2048 prefill
Llama 3.1 8B 4-bit 771 to 826 (+7.1%) 765 to 819 (+7.1%)
Qwen2.5 7B 4-bit 817 to 881 (+7.8%) 816 to 881 (+7.9%)

Decode unchanged. Record: docs/benchmark_results/llama3-last-row-prefill-m1ultra-2026-09-24.md.

Validation

  • Greedy output identical between the arms on Llama 3.1 8B and Qwen2.5 7B (three prompts including a 512-token one, 150 tokens) and on LLaVA 1.6 Mistral 7B with an image.
  • New test: all three entry points match the sliced full forward at the last and an interior position, and the caches advance; shifting the slice by one row fails it.
  • make verify-test: 11433 passed, 0 failed. Workspace clippy and fmt pass.
  • Remaining families (Qwen3, Qwen3-MoE, Phi-3, Mixtral, Gemma 2/3, DeepSeek V3, Nemotron-H, Jamba) are the follow-up.

Closes #1968

…fill

Llama3Model, which also serves Mistral and Qwen2/Qwen2.5, used the forward_last_logits default, so every single-sequence prefill computed [1, L, vocab] logits through the LM head and kept one row (about 0.5 TFLOP at 512 tokens for a 128k-152k vocabulary). Its two duplicated forward bodies become one hidden_states path, and the three forward_last_logits entry points slice the final-normed hidden state at last_pos before the head; the final norm and head act per position, so the row is the one the full forward produces. generate::logits_at_position becomes public for that. VisionLanguageModel now forwards the three entry points to its text model, so text-model overrides are no longer skipped behind the vision wrapper.

M1 Ultra, bench_decode.sh arguments, ABBA: Llama 3.1 8B 4-bit prefill 771 to 826 tok/s at pp512 and 765 to 819 at pp2048 (+7.1%); Qwen2.5 7B 4-bit 817 to 881 at both lengths (+7.8%); decode unchanged. Greedy output identical on three prompts per model and on LLaVA 1.6 Mistral with an image. A new test checks all three entry points against the sliced full forward; shifting the slice by one row fails it.

Closes #1968
@inureyes inureyes added status:review Under review type:performance Performance improvements priority:medium Medium priority area:models Model architectures, weights, loading, metadata platform:macos macOS (Apple Silicon) specific labels Sep 24, 2026
@inureyes
inureyes merged commit 13b6d33 into main Sep 24, 2026
20 checks passed
@inureyes inureyes added status:done Completed and removed status:review Under review labels Sep 24, 2026
@inureyes
inureyes deleted the update/issue-1968-llama3-last-row-prefill branch October 6, 2026 12:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:models Model architectures, weights, loading, metadata platform:macos macOS (Apple Silicon) specific priority:medium Medium priority status:done Completed type:performance Performance improvements

Projects

None yet

Development

Successfully merging this pull request may close these issues.

perf(llama3): project only the sampled row through the LM head at prefill

1 participant