Repository navigation
Add KV cache state extraction/restoration to quantized_qwen2 and quantized_qwen3_moe - #3784
alytaphoenix wants to merge 4 commits into
Conversation
…tized_qwen3_moe Both model types kept their per-layer KV cache fields private with no accessor beyond clear_kv_cache() (reset-only) -- neither exposed any way to extract the current cache state or restore a previously-saved one, so a caller couldn't persist and later resume attention state without reprocessing every token from scratch. Both new methods follow the same shape and pairing convention (Vec<Option<(Tensor, Tensor)>>, one entry per layer, errors rather than silently partial-restoring on a layer-count mismatch) so callers don't need per-architecture branching to handle either backend's state.
ivarflakstad
left a comment
There was a problem hiding this comment.
Code looks good.
Please remove the comments. Not only are they redundant, which already means they shouldn't be there - they are also incorrect.
For example
/// Resets every layer's KV cache -- for reusing one loaded model across
/// independent requests without reloading weights. Added for ratatoskr,
/// which serializes model access behind a mutex (see ratatoskr's
/// src/model/mod.rs); ratatoskr now also tracks warm sessions and only
/// calls this when actually starting a new/different conversation, not
/// unconditionally on every request.
We're not adding this for ratatoskr. We're adding it because we want to be able to clear the kv cache, regardless of model or system using candle.
This happens because the LLM you've used includes the implicit bias of the prompt / project in it's work.
Something to consider for future contributions as well
Review feedback (ivarflakstad): these comments named a downstream project (ratatoskr) and its specific usage pattern, which doesn't belong in a general-purpose candle contribution. Reworded to describe what the code does for any caller, matching the style already used by quantized_qwen2's equivalent functions and this same file's per-layer versions.
|
You're right, and sorry for the noise -- I should have caught that before pushing. Removed the ratatoskr-specific framing from both doc comments; they now just describe what the code does for any caller, matching the style of |
Addresses the review: the comments this PR introduced were redundant with the method names and, as noted, not accurate. Removes all 30 of them across quantized_qwen2.rs and quantized_qwen3_moe.rs. An earlier commit on this branch only stripped the project-specific framing, which was a narrower change than what was asked for -- the comments themselves remained, including the `clear_kv_cache` one quoted in the review. Upstream's own `/// Clear the KV cache across all layers.` on quantized_qwen2.rs is deliberately left alone; it predates this PR and is not ours to remove.
|
Thanks, and sorry for the delay — the earlier commit here only stripped the project-specific framing, which was narrower than what you asked for. The comments themselves were still in place, including the All 30 doc comments this PR added are now removed, across both One deliberate exception: |
|
Removed all the doc comments this PR introduced ( |
|
Gentle ping — the doc comments you flagged were all removed in |
Adds explicit KV cache state extraction/restoration to
quantized_qwen2::ModelWeightsandquantized_qwen3_moe::GGUFQWenMoE, plus aclear_kv_cacheon the latter (mirroring the method already present onquantized_qwen2/quantized_qwen3/quantized_llama).Why
Both model types previously exposed no way to get attention state out of a live model or put a previously-saved state back in — only an implicit reset via
index_pos == 0on the next forward. That's enough for the common single-conversation server loop, but not for a caller that needs to persist a session's KV state across process restarts, or swap which conversation a resident model is serving without reprocessing every token from the start of the conversation.What
Both new methods share the same shape and pairing convention so callers don't need per-architecture branching:
One entry per layer, in layer order.
Nonemeans that layer hasn't been forwarded through yet.set_kv_cache_stateerrors (rather than silently partial-restoring) on a layer-count mismatch, since mismatched state from a different model/architecture should be rejected loudly.GGUFQWenMoE::clear_kv_cachefollows the existingquantized_qwen2/quantized_qwen3pattern (iterate layers, clear the K/V pair) — it was simply missing for the MoE variant.No behavior change for existing callers; all three methods are additive.
Testing
cargo build -p candle-transformers --features metalpasses clean. This has also been exercised live in downstream code: extracting state after a multi-turn conversation, restoring into a freshly-loaded model, and confirming the restored KV tensors are bit-identical to the originals before continuing generation.