Uh oh!
There was an error while loading. Please reload this page.
[MLX] Add off-graph KV cache export mode for HF models - #21680
Conversation
🔗 Helpful Links🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/21680
Note: Links to docs will display an error until the docs builds have been completed. ✅ You can merge normally! (1 Unrelated Failure)As of commit 8d0517b with merge base 5b3da18 ( FLAKY - The following job failed but was likely due to flakiness present on trunk:
This comment was automatically generated by Dr. CI and updates every 15 minutes. |
This PR needs a |
metascroy
commented
Aug 7, 2026
@claude review this code |
Claude finished @metascroy's task in 3m 39s —— View job Code Review — Off-graph KV cache export modeRead the diff plus Correctness1. assertsoftcapisNone, "update_and_attend does not support attention logit softcapping"asserthead_maskisNone, "update_and_attend does not support head_mask"This turns a silent-wrong-output footgun into a clear export-time error. Fix this → 2. Sliding-window masking is published but not enforced in the eager reference. The export publishes Consistency / minor3. 4. Module docstring is now stale ( 5. Nits
I did not run the export end-to-end (requires downloading the HF checkpoints), so the review is static only. The logic and the published layout look self-consistent. |
f0b551a to
8e7c18dComparekiymetakdemir
commented
Aug 7, 2026
@claude review this code |
Claude finished @kiymetakdemir's task in 1m 50s —— View job Code Review — Off-graph KV cache export modeRe-read the diff against The design is coherent and the tracer-facing contract ( Correctness / worth verifying1. Does the dynamic seq dim admit 2. Sliding-window masking is published but not enforced by the eager oracle. 3. Consistency / minor4. Batch dim is implicitly 1. 5. 6. Boilerplate duplication. Nit
I did not run the export end-to-end (requires the HF checkpoints), so this is static review only. Items 2–6 are advisory; item 1 is the one I'd confirm before merge. |
8e7c18d to
2e8cb61Comparemetascroy
commented
Aug 10, 2026
@claude review this code |
Claude finished @metascroy's task in 2m 23s —— View job Code Review — Off-graph KV cache export modeRe-read the full diff ( One item I'd confirm before merge (still open from the last round), the rest advisory. Worth confirming before merge1. Does Advisory (not blocking)2. 3. Sliding-window masking is published but not enforced by the eager oracle. 4. 5. 6. Boilerplate duplication. Nit
Static review only — I could not run the export end-to-end (Python execution is gated in this environment and the HF checkpoints aren't available). Item 1 is the one I'd verify before merge; 2–6 are advisory. |
| scaling: Optional[float] = None, | ||
| softcap: Optional[float] = None, | ||
| head_mask: Optional[torch.Tensor] = None, | ||
| **kwargs, |
There was a problem hiding this comment.
Is it better to have **kwargs catch everything else (including softcap), and then raise if kwargs is non-empty? That way more unknown kwargs don't sneak in
There was a problem hiding this comment.
It makes sense for catching unknown ones, I added a sweep that pops the args we handle elsewhere (is_causal, use_cache, sliding_window, dropout) and raises on anything left. But softcap and head_mask still need to be named, models pass them often as None which still would raise.
2e8cb61 to
0505923Comparekiymetakdemir
commented
Aug 10, 2026
For claude review;
|
0505923 to
8d0517bCompareUh oh!
There was an error while loading. Please reload this page.
**Summary** This runner builds an MLXSequenceCache, installs it, and passes the cache key, so it's the run path for .pte files exported with --use-offgraph-cache. The cache's shape is read from the .pte metadata. The flags left are policy the model can't imply: --kv-max-capacity, --kv-storage-dtype, --kv-initial-capacity, --kv-max-write, --kv-windows. Depends on #21680; the new CI job fails until that lands. **Files** - run_llm_hf.cpp — the runner: chat templates, greedy decode, benchmarking, and an interactive mode with /reset and /undo [N]. - CMakeLists.txt — standalone find_package(executorch) project. - .github/workflows/mlx.yml — test-mlx-llm-offgraph for llama-1b, gemma3-1b and gemma4-e2b. **Test** CI builds the runner, then for llama-1b, gemma3-1b and gemma4-e2b exports off-graph and asserts the same "Paris" answer test-mlx-llm checks.
Summary
Adds --use-offgraph-cache, which exports a HuggingFace causal LM against kvcache::update_and_attend instead of an in-graph cache. The model runs with use_cache=False and past_key_values=None, so each attention layer emits one op fed only that step's k/v; history lives in a cache the runtime owns and binds by cache_key. KV-sharing layers address their donor's cache rather than one of their own, so gemma-4 E2B needs 15 caches for its 35 layers.
Files
Test
Exported Llama-3.2-1B and gemma-3-1b; both partition into a single MLX subgraph, and the published layout matches each architecture — 16 flat caches for llama, 26 for gemma-3 with full attention at layers 5/11/17/23.
python -m executorch.backends.mlx.examples.llm.export_llm_hf
--model-id unsloth/gemma-3-1b-it --output gemma3_offgraph.pte
--use-offgraph-cache --max-seq-len 2048 --dtype fp32
python -m executorch.backends.mlx.examples.llm.export_llm_hf
--model-id unsloth/Llama-3.2-1B-Instruct --output llama_offgraph.pte
--use-offgraph-cache --max-seq-len 2048 --dtype bf16
Add --qlinear 4w for INT4.