Repository navigation
Gemma 1–4 support and Gemma performance (1.2.0) - #6
Merged
Merged
Conversation
Gemma 1/2/3 and the dense Gemma 4 models (gemma4_text, gemma4_unified) run on the engine: (1 + w) RMSNorm, scaled embeddings, GeGLU, sandwich norms fused into the residual-add kernel, attention and final-logit soft-capping, sliding-window layers with their own RoPE base, mixed 256/512 head sizes, proportional RoPE, KV sharing across layers, K = V global attention, per-layer input embeddings and layer scalars. Attention kernels take a window and a soft-cap (soft-capping is a template instantiation, so the other models' inner loops are unchanged). New kernel tests compare decode, split decode, prefill and flash prefill with a CPU reference at head sizes 128/256/512. Chat formats for <start_of_turn> and <|turn> templates match transformers' apply_chat_template; Gemma's tokenizer adds no dummy prefix and decodes runs of spaces. Teacher-forced logits match mlx-lm on Gemma 1.1 2B, Gemma 2 2B, Gemma 3 270M/1B/4B, Gemma 4 E2B and 12B (argmax identical at every position, within 0.035 of a float32 run). Existing architectures: greedy output token-identical, throughput within noise (3 alternating pairs). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Decode: the 4-bit matvec gets an instantiation per remainder of K mod 1024 (Gemma's hidden sizes 1152/2304/2560/1536 left a pass with 4-16 of 32 lanes busy): +12% on Gemma 3 1B, +5% on Gemma 2 2B, +4% on Gemma 3 4B. Split decode attention for head sizes 256/512 with query heads in pairs: +3.5-6% at 1K context. Gemma 4's per-layer input gate folds its GELU into the matvec epilogue. Prefill: flash attention for head_dim 256 (8-key blocks), +6-7%. Existing models: greedy output token-identical, throughput within noise (3 alternating pairs). Rejected after measuring: a GLU epilogue in the gate/up matvec, split-K, tail code inside the one matvec kernel, 8-byte tail loads, 4 heads per split-attention simdgroup. Review fixes: Gemma replies keep leading spaces; BOS from the tokenizer's post-processor; trie-based added-token matching (Gemma 3 encode 100x faster); non-special added tokens kept in message content; per-layer-input norm eps·H; MoE Gemma 4 repos marked not runnable; vision sidecars excluded from load and budget; flat gemma3 / transformers-5 rope_parameters configs; sliding_window bound; outer eos union; Gemma 4 system turns; layer_scalar only for Gemma 4; model tests run for every installed Gemma checkpoint. Teacher-forced parity with mlx-lm holds on all seven Gemma checkpoints (same argmax at every position, within 0.05 of a float32 run). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
🚀 Deploying Preview to Cloudflare 🚀Preview Deployments by commit
|
Tensor.floats() used Float(Float16), which does not exist on x86_64 macOS, the target of CodeQL's Swift autobuild. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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
Gemma support for the engine, app, CLI and server:
gemma(1),gemma2,gemma3/gemma3_text, and the dense Gemma 4 models (gemma4/gemma4_text,gemma4_unified). Verified checkpoints: gemma-1.1-2b, gemma-2-2b, gemma-3-270m / 1b / text-4b, gemma-4-e2b and gemma-4-12B (all mlx-community 4-bit / OptiQ).<start_of_turn>and<|turn>renderers checked against transformers'apply_chat_template; Gemma's tokenizer adds no dummy prefix. No tool calling and no Gemma 4 thinking mode (runs with thinking off); Gemma 4 MoE (26B-A4B) and Gemma 3n are not supported and are marked not runnable.Performance (M2 Pro, 3 alternating pairs; mlx-lm 0.32.2 on the same files)
hidden_sizemod 1024 (Gemma's 1152 / 2304 / 2560 / 1536 left a pass with 4–16 of 32 lanes busy): decode +12% on Gemma 3 1B, +5% on Gemma 2 2B, +4% on Gemma 3 4B.Review fixes
From a
/code-review maxpass on the first commit: Gemma replies keep leading spaces and indentation; raw completions add<bos>when the tokenizer's post-processor does; Gemma 3 encoding of long HTML/code chats is ~100× faster (trie instead of a 6,000-way regex); non-special added tokens are kept inside message content; Gemma 4's per-layer-input norm uses the reference's exact eps; MoE repos marked not runnable; OptiQ vision sidecars no longer mapped or budgeted; flatgemma3/ transformers 5rope_parametersconfigs, outer eos union, Gemma 2 soft-cap defaults, boundedsliding_window; later system messages render as<|turn>system;layer_scalarread only for Gemma 4; model tests run for every installed Gemma checkpoint.Not fixed (pre-existing, engine-wide, reported): MLX safetensors tensors are never 16-byte aligned, so
SafeTensorFilecopies every tensor at load instead of using the mmap zero-copy.Test plan
swift test— 131 tests pass (kernel tests for window/soft-cap/head sizes 128–512, split attention, 4-bit tails, Gemma configs/templates/tokenizers, prefill-vs-decode on every installed Gemma checkpoint)mlxr benchA/B againstmain, 3 alternating pairs, Qwen3 0.6B / Llama 3.2 1B / Mistral 7B within noise🤖 Generated with Claude Code