Skip to content

dflash: fix VL/multimodal crash by clearing draft on position gap#7

Closed
dblmca wants to merge 1 commit into
ruixiang63:dflashfrom
dblmca:dflash-vl-fix
Closed

dflash: fix VL/multimodal crash by clearing draft on position gap#7
dblmca wants to merge 1 commit into
ruixiang63:dflashfrom
dblmca:dflash-vl-fix

Conversation

@dblmca

@dblmca dblmca commented Jun 28, 2026

Copy link
Copy Markdown

Summary

DFlash crashes when processing requests containing images (VL/multimodal) with:

failed to process speculative batch

Root cause: When the server processes image embeddings through the target model, the draft context's KV cache misses those positions (embedding-only batches are correctly skipped in process()). This creates a non-consecutive position gap — the draft has positions 0..X, but the next text batch starts at Y > X+1. llama_decode(ctx_dft) enforces consecutive positions and fails.

Fix: Detect position gaps between llama_memory_seq_pos_max(ctx_dft) and the incoming batch position. When a gap is found, clear the draft sequence with llama_memory_seq_rm() and let processing rebuild from the current text position. Spec decode gracefully degrades for the first few tokens after an image, then resumes normally.

Same class of bug as EAGLE3 + VL (ggml-org#24816) and MTP + VL (ggml-org#22867).

Benchmark Results

Tested on Qwen3.6-27B VL (Q4_K + mmproj-f16) with DFlash drafter on RTX 8000:

Metric Baseline (no DFlash) DFlash + VL fix
BrightPath Score 0.965 0.976
Total Time (34 cases) 581s 264s (2.2x faster)
Text draft acceptance 37-64%
VL image processing ✅ works ✅ works (no crash)

The benchmark covers all 11 BrightPath LLM call types including vision grading (math work, spelling, vocab, sentence combining/expansion) with synthetic handwriting images.

The patch

22 lines added to common_speculative_impl_draft_dflash::process() — a position gap detection loop inserted before the main per-seq processing loop. No changes to any other files.

Reviewed by Codex (gpt-5.5) and GLM 5.2 before submission — both approved the core mechanism and confirmed llama_memory_seq_rm(mem, seq_id, -1, -1) is the correct API for full-sequence KV clear.

Test plan

  • Text-only generation: DFlash spec decode works (~26 tok/s, 37-64% acceptance)
  • VL with image: face recognition pipeline processes images without crash
  • BrightPath benchmark: 34/34 cases pass, score 0.976, 2.2x faster than baseline
  • Multi-slot: gap detection is per-sequence, doesn't affect text-only slots

When image/audio embeddings are processed by the target model, the
draft context's KV cache misses those positions because embedding-only
batches are correctly skipped in process(). This causes a
non-consecutive position error ("Y = X + 1" assertion) on the next
text batch, crashing the server with "failed to process speculative
batch".

Fix: detect position gaps between the draft KV cache and incoming
batch positions. When a gap is found (indicating image/audio tokens
were processed in between), clear the draft sequence and let
processing rebuild from the current text position. Speculative
decoding gracefully degrades for the first few tokens after an image,
then resumes normally.

This is the same class of bug as:
- EAGLE3 + VL (issue ggml-org#24816)
- MTP + VL (issue ggml-org#22867, fixed by calvarado2004)

Tested on Qwen3.6-27B VL with DFlash drafter:
- Text-only: 37-64% draft acceptance, ~2.2x speedup
- VL with images: no crash, face recognition working
- BrightPath benchmark: 0.976 score (vs 0.965 baseline), 264s (vs 581s)

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
@ruixiang63

Copy link
Copy Markdown
Owner

Thanks. But need to close this per ggml-org#22105 (comment) for now.

@ruixiang63 ruixiang63 closed this Jun 28, 2026
@dblmca

dblmca commented Jun 29, 2026 via email

Copy link
Copy Markdown
Author

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants