Skip to content

fix: apply KV modes to model-owned caches - #1400

Merged
inureyes merged 3 commits into
mainfrom
fix/issue-1330-model-owned-kv
Aug 24, 2026
Merged

inureyes merged 3 commits into
mainfrom
fix/issue-1330-model-owned-kv

Conversation

@inureyes

@inureyes inureyes commented Aug 24, 2026 •

Copy link
Copy Markdown
Member

Summary

Apply the resolved effective KV cache mode table to model-owned attention caches so --kv-cache-mode and --kv-bits no longer stop at dense external cache slices, while keeping observability and prompt-cache reuse aligned with the mode that is actually active.

What changed

  • Added LanguageModel KV-mode table hooks plus a shared KvCacheLayerModes helper and delegated the hooks through loaded-model and VLM wrappers.
  • Injected resolved per-layer modes from the CLI generator and server scheduler, including Boundary-V and batch KV quantization policy, then reported the applied-layer count in the CLI and server surfaces.
  • Updated Gemma 3, AFMoE, Gemma 4, Qwen 3.5, Qwen3-Next, Bailing MoE Linear, LFM2, and Llama 4 regular attention caches to use the injected mode while keeping recurrent, convolutional, gated-delta, and Llama 4 chunked caches unchanged.
  • Made dense prompt-cache adoption reject stale per-layer KV modes with kv_mode_mismatch, and made model-owned snapshot restore refuse non-FP16 or mode-mismatched attention state instead of silently truncating quantization sidecars.
  • Added kv_cache_mode_effective to cache statistics, preferring the batch KV quantization base mode when --kv-bits is active and otherwise using the legacy effective mode.
  • Documented model-owned KV-mode behavior, snapshot conservatism, prompt-cache mismatch observability, and the Llama 4 ChunkedKVCache exception.

Changes during review

  • Fixed /v1/cache/stats to report the batch KV quantization mode instead of incorrectly falling back to fp16 when BatchKvQuantConfig is enabled.

Validation

  • cargo test --workspace --profile test-fast --features metal,accelerate
  • cargo clippy --workspace --all-targets -- -D warnings
  • cargo fmt --all -- --check
  • Focused generator forwarding, Qwen3-Next snapshot, dense prompt-cache mismatch, and cache-stats effective-mode tests
  • Gemma 3 real-checkpoint generation on Metal with both fp16 and int8

Real checkpoint result: Gemma 3 FP16 and INT8 both completed on Metal, the banners reported applied to 26 of 26 layers, stderr was empty, and the greedy outputs differed, confirming that the model-owned cache consumed the configured mode.

Closes #1330

Model-owned families were building their internal attention caches with default FP16 constructors, so the resolved KV mode only affected dense external cache slices and left Gemma 3/4, Qwen 3.5, Qwen3-Next, LFM2, Bailing MoE Linear, AFMoE, and Llama 4 regular attention arms unchanged.

Add model-owned per-layer KV-mode hooks, inject the already-resolved effective layer table from the CLI generator and server scheduler, and teach the affected model-owned constructors and VLM wrappers to consume it while keeping recurrent, convolutional, gated-delta, and Llama 4 chunked state at FP16.

Make prompt-cache and snapshot reuse conservative across KV modes by rejecting stale dense detached cache modes with a named reason and refusing non-FP16 model-owned snapshots unless their mode matches the live configured table.

Validation:

- cargo check -p mlxcel --lib
- cargo check -p mlxcel --tests
- cargo test --profile test-fast -p mlxcel-core reset_with_model_forwards_resolved_modes_to_model_owned_caches -- --nocapture
- cargo test --profile test-fast -p mlxcel --lib qwen3_next::cache_tests -- --nocapture
- cargo test --profile test-fast -p mlxcel --lib dense_detached_kv_mode_validation -- --nocapture
- cargo build -p mlxcel --bin mlxcel --profile test-fast
- target/test-fast/mlxcel generate -m models/gemma3-1b-4bit -p 'Write a detailed 300 word essay about the history of Roman aqueducts, their engineering, and their legacy.' -n 200 -t 0 --kv-cache-mode fp16
- target/test-fast/mlxcel generate -m models/gemma3-1b-4bit -p 'Write a detailed 300 word essay about the history of Roman aqueducts, their engineering, and their legacy.' -n 200 -t 0 --kv-cache-mode int8

Refs #1330
@inureyes inureyes added status:review Under review type:bug Bug fixes, error corrections, or issue resolutions priority:high High priority area:models Model architectures, weights, loading, metadata area:docs User and developer documentation area:core mlxcel-core: MLX FFI, primitives, KV cache, layers area:inference Generation, sampling, decoding (incl. speculative, DRY) modeltype:text Text-only language model modeltype:vlm Vision-language model arch:dense Dense transformer decoder arch:hybrid Hybrid attention stack (linear/sliding/full or attention+SSM interleave) labels Aug 24, 2026
The cache stats route added kv_cache_mode_effective for issue #1330, but it still read only the legacy kv_cache_mode field. When server-side --kv-bits enabled BatchKvQuantConfig, the scheduler applied Int8 or Turbo4Asym while /v1/cache/stats continued to report fp16.

Prefer the batch KV base mode whenever batch quantization is enabled, and cover the Int8, TurboQuant, and legacy fallback cases with a route helper test.

Validation:

- cargo test --profile test-fast -p mlxcel --lib cache_stats_effective_kv_mode_prefers_batch_kv_quant_when_enabled -- --nocapture

Refs #1330
@inureyes

Copy link
Copy Markdown
Member Author

Security/performance review after 0177304

Findings

Validation

  • Passed: cargo test --profile test-fast -p mlxcel-core generate::tests::reset_with_model_forwards_resolved_modes_to_model_owned_caches.
  • Attempted: cargo test --profile test-fast -p mlxcel server::batch::scheduler_tests::dense_detached_kv_mode_validation compiled the root test target for an extended period without reaching test execution, so I interrupted it and did not count it as passing.

Safety audit

  • No files were modified by this review, no commits were made, no branch or PR was created, and status labels were not changed.
  • Protected untracked files were left untouched and unstaged: download.md, mlxcel-claude.tgz, and report_cohere_command_r.md.

@inureyes inureyes added status:done Completed and removed status:review Under review labels Aug 24, 2026
@inureyes
inureyes merged commit fa4bd5c into main Aug 24, 2026
11 checks passed
@inureyes
inureyes deleted the fix/issue-1330-model-owned-kv branch August 24, 2026 17:48
@inureyes inureyes self-assigned this Aug 27, 2026
be-free-snowboy pushed a commit to freestylejs/snowbrain-mlxcel that referenced this pull request Oct 27, 2026
## Summary

Apply the resolved effective KV cache mode table to model-owned attention caches so `--kv-cache-mode` and `--kv-bits` no longer stop at dense external cache slices, while keeping observability and prompt-cache reuse aligned with the mode that is actually active.

## What changed

- Added `LanguageModel` KV-mode table hooks plus a shared `KvCacheLayerModes` helper and delegated the hooks through loaded-model and VLM wrappers.
- Injected resolved per-layer modes from the CLI generator and server scheduler, including Boundary-V and batch KV quantization policy, then reported the applied-layer count in the CLI and server surfaces.
- Updated Gemma 3, AFMoE, Gemma 4, Qwen 3.5, Qwen3-Next, Bailing MoE Linear, LFM2, and Llama 4 regular attention caches to use the injected mode while keeping recurrent, convolutional, gated-delta, and Llama 4 chunked caches unchanged.
- Made dense prompt-cache adoption reject stale per-layer KV modes with `kv_mode_mismatch`, and made model-owned snapshot restore refuse non-FP16 or mode-mismatched attention state instead of silently truncating quantization sidecars.
- Added `kv_cache_mode_effective` to cache statistics, preferring the batch KV quantization base mode when `--kv-bits` is active and otherwise using the legacy effective mode.
- Documented model-owned KV-mode behavior, snapshot conservatism, prompt-cache mismatch observability, and the Llama 4 `ChunkedKVCache` exception.

## Changes during review

- Fixed `/v1/cache/stats` to report the batch KV quantization mode instead of incorrectly falling back to `fp16` when `BatchKvQuantConfig` is enabled.

## Validation

- [x] `cargo test --workspace --profile test-fast --features metal,accelerate`
- [x] `cargo clippy --workspace --all-targets -- -D warnings`
- [x] `cargo fmt --all -- --check`
- [x] Focused generator forwarding, Qwen3-Next snapshot, dense prompt-cache mismatch, and cache-stats effective-mode tests
- [x] Gemma 3 real-checkpoint generation on Metal with both `fp16` and `int8`

Real checkpoint result: Gemma 3 FP16 and INT8 both completed on Metal, the banners reported `applied to 26 of 26 layers`, stderr was empty, and the greedy outputs differed, confirming that the model-owned cache consumed the configured mode.

Closes lablup#1330
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

arch:dense Dense transformer decoder arch:hybrid Hybrid attention stack (linear/sliding/full or attention+SSM interleave) area:core mlxcel-core: MLX FFI, primitives, KV cache, layers area:docs User and developer documentation area:inference Generation, sampling, decoding (incl. speculative, DRY) area:models Model architectures, weights, loading, metadata modeltype:text Text-only language model modeltype:vlm Vision-language model priority:high High priority status:done Completed type:bug Bug fixes, error corrections, or issue resolutions

Projects

None yet

1 participant