fix(server): skip the prompt cache for VLM-loaded models (b769 text chat failures) - #194
Merged
Merged
Conversation
Most VLM processors return [1, T] tokens even for text-only input, and the prompt cache paths slice on axis 0. On b769 this makes every text request to an auto-detected Qwen3.5/3.6 VLM fail in the #189 hybrid split (unsupportedBatchContinuation), makes the second shared-prefix request to Qwen3-VL fail (missingState ropeDeltas: the cache does not store LMOutput.State), and silently re-feeds the whole prompt on generic cache hits for Gemma and other [1, T] VLMs. Skip restore and save when context.model is any VLMModel (also covers --audio Omni loads). LLM-factory models, including text-only hybrid models, are unchanged. Add Test 7 to test-speculative.sh: a no-draft Qwen3.5 load is served as a VLM, answers text chat, and bypasses the cache. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Sep 25, 2026
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.
Problem
On b769, text chat with an auto-detected VLM goes through the prompt cache and breaks:
mlx-community/Qwen3.5-0.8B-4bit): every text request fails with HTTP 500unsupportedBatchContinuation(model: "Qwen35"). This covers single-turn, multi-turn and streaming requests. It comes from the hybrid prompt cache added in feat: prompt cache for hybrid recurrent/attention models (Qwen3.5/3.6) #189.mlx-community/Qwen3-VL-2B-Instruct-4bit): the second request that shares a prefix fails withmissingState(model: "Qwen3VL", key: "qwen35vl.ropeDeltas"). It comes from the generic cache hit path plus the fail-closed continuation check that came in with the mlx-swift-lm bump in b769.Image requests are not affected, because they already skip the prompt cache.
Root cause
Most VLM processors return
[1, T]tokens, even for text-only input. The prompt cache paths slice on axis 0 and useMLXArray.count(dim(0), so 1):tokens[boundary...]yields[0, T].startIndex = 0, trims 1 token and feeds all T tokens again.Qwen3.5 and Qwen3-VL also need the
LMOutput.State(ropeDeltas) of the cached prefix, and the prompt cache does not store it.Fix
Skip the prompt cache, both restore and save, when
context.model is any VLMModel. The check is on the model type rather thanconfig.isVision, so--audio(OmniModelFactory) loads are covered too. LLM-factory models are unchanged, including text-only hybrid models on the #189 path.A startup note is printed for VLM/Omni loads.
Cost
Text chat on VLM loads re-prefills the full prompt every turn. For Qwen3.5 this is the pre-#189 behaviour. Because of auto-detection, this includes default launches of mlx-community Qwen3.5/3.6 and Gemma 4. Qwen2-VL, Qwen2.5-VL and LFM2-VL, which use 1-D tokens, also lose cache reuse that did work before.
Testing
swift build -c release, SwiftLMTests (194, 0 failures) and SwiftBuddyTests (127, 9 existing skips, 0 failures).End to end at temp 0 on port 5440/5441:
missingStatevision_configremoved)Prompt cache HIT (hybrid)still logged on the repeated request (feat: prompt cache for hybrid recurrent/attention models (Qwen3.5/3.6) #189 path intact)New Test 7 in
tests/test-speculative.sh: loadsmlx-community/Qwen3.5-2B-4bitwithout a draft. It asserts:Every other Qwen3.5 launch in CI passes a draft model, which turns off VLM auto-detection. That is why CI missed this.
Local run: passes with the fix; the two chat checks fail on b769.
Follow-ups (not in this PR)
LMOutput.Statewith the cache entry and pass it togenerate(state:);PromptCacheTeststest the production skip decision instead of a copied formula.AI usage: Claude Code (Claude Opus 5.5) found the bug, wrote the fix and Test 7, ran the verification and wrote this description.
🤖 Generated with Claude Code