Skip to content

fix(vlm): isolate short multimodal embeddings - #36724

Open
kflansburg wants to merge 13 commits into
sgl-project:mainfrom
kflansburg:kflansburg/fix-fresh-mm-embedding-length
Open

kflansburg wants to merge 13 commits into
sgl-project:mainfrom
kflansburg:kflansburg/fix-fresh-mm-embedding-length

Conversation

@kflansburg

@kflansburg kflansburg commented Aug 27, 2026 •

Copy link
Copy Markdown
Contributor

Motivation

Malformed fresh multimodal embeddings can currently terminate the scheduler instead of failing only the affected request. Cache-entry validation in #36595 does not cover fresh encoder output.

This PR contains the failure; it does not diagnose why an encoder produced incorrect embeddings.

Changes

  • Require exact token counts before cache insertion, including overlong outputs and precomputed embeddings. Reject empty/misaligned per-item lists and invalid embedding widths.
  • Retry ambiguous combined results (including incorrect hidden widths) per item, with rank consensus before re-entering a TP-aware encoder. Preserve healthy items and keep failed-item fillers out of the embedding cache.
  • Carry request-aligned failures through TP/PP, overlap, speculative relay, beam search, and result processing. Return HTTP 500 for failed requests, never filler-derived model output.
  • Propagate validation errors out of private eager and captured-body batch views so they reach the worker and scheduler.
  • Fence radix insertion and KV transfer until validation completes. Drain in-flight chunks before reclaiming KV/Mamba states and multimodal features; sender notification/cleanup failures must not prevent local resource release.
  • Merge current main while preserving its KV ownership, speculative relay, and disaggregated-abort APIs.

Validation

Regression coverage includes mixed healthy/malformed outputs, runner batch-copy boundaries, bundled and precomputed embeddings, two-process retry/error consensus (Gloo and optional NVIDIA NCCL), real KV/Mamba allocator recovery after repeated failures, chunked abort races, and hidden-state/logprob cursor alignment. Registered tests have executable entry points.

Remaining merge gates:

  • Latest-head CPU and NVIDIA CI.
  • NVIDIA server fault-injection smoke, including TP/PP and disaggregation.
  • Measure healthy-request latency/throughput overhead. Fresh multimodal batches add consensus work; no performance improvement is claimed.

The PR is non-draft to allow CI to run, not a declaration that these integration gates have passed.


CI States

Latest PR Test (Base): ❌ Run #34298142921
Latest PR Test (Extra): ❌ Run #34298142863
Latest PR Test (AMD ROCm 7.2): ❌ Run #34298143057

agent added 6 commits August 27, 2026 12:21
Fresh encoder output can contain fewer embedding rows than the request's multimodal placeholder span. The late length assertion then exits the scheduler and restarts every TP rank.\n\nValidate fresh outputs before caching or concatenation, preserve batch shape for failed rows, synchronize request failures across ranks, and return an internal request error while healthy rows continue. Fence radix and disaggregated KV state until overlap validation completes.\n\nAccuracy: unchanged for valid requests; malformed requests now fail with HTTP 500.\nSpeed: valid multimodal forwards add a small fixed error-consensus collective.\nTests: focused multimodal, scheduler, disaggregation, beam, overlap, and cache tests.
Cover malformed fresh outputs, mixed healthy and failed requests, overlap validation fences, TP and PP error propagation, disaggregated cleanup, beam teardown, cache admission, and output cursor accounting.\n\nTests: 48 focused CPU tests.
Multimodal embedding validation relies on extend-only metadata. Pure decode and target-verify batches can retain stale request-shaped multimodal state after disaggregated merges, so inspecting those lists can terminate the scheduler before model execution.

Run validation only for non-speculative extend modes, including mixed batches, and apply the same rule to batch-less worker calls.

Accuracy: unchanged.

Speed: decode and target-verify avoid unnecessary validation work.

Tests: focused validation-index and request-isolation unit tests.
Cover pure decode, target verify, disaggregated decode merges, aligned extend and mixed batches, strict malformed extend metadata, and batch-less worker calls.

Tests: 26 focused validation and request-isolation tests.
Overlap scheduling can plan the next multimodal chunk before the previous validation result is processed. Because unvalidated KV is intentionally excluded from radix cache, replanning rematches the old prefix and repeatedly allocates the same chunk.

Park the current chunk until validation completes, register validation before disaggregated early-send, fence KV transfer, and drain pending PP-disaggregated aborts before chunk processing.

Accuracy: unchanged.

Speed: affected chunked requests wait one result-processing turn instead of replaying work.

Tests: focused chunk progress, transfer fencing, and abort accounting tests.
Cover scheduler parking, single chunk advancement, queued-owner isolation, disaggregated transfer fencing, bootstrap and yield bookkeeping, early-send ordering, and abort pool accounting.

Tests: 24 focused scheduler and embedding-error tests.
@mickqian

Copy link
Copy Markdown
Collaborator

I fault-injected the short-embedding error after a real Qwen3.5-0.8B hybrid forward on H200 with SGLANG_ENABLE_STRICT_MEM_CHECK_DURING_IDLE=2. The failed image request returned 500, a following image request returned 200, and the idle KV/Mamba invariant stayed healthy; this validates the non-inserting rollback path. Please add one hybrid-pool regression test that exercises real KV and Mamba release rather than mocking release_kv_cache, since the production symptom was exactly one request worth of both resources.

@mickqian

Copy link
Copy Markdown
Collaborator

The per-item paths still assert len(all_miss_embedding) == len(miss_items), and _retry_individual_embeddings() asserts a single retry result. A wrong per-item output count is another fresh-encoder shape fault that can still escape the scheduler; please route it through the same request-level error/padding path instead of asserting.

Comment thread python/sglang/srt/managers/mm_schedule.py Outdated
@rwang5203

Copy link
Copy Markdown
Collaborator

Commit 132652e5 does repair the callers and tests, but 2380ae93 changes the helper return shapes first, leaving nine focused failures at that intermediate commit. Try squashing the pair or moving those compatibility updates into the implementation commit would keep each reviewable commit independently green.

@mickqian

Copy link
Copy Markdown
Collaborator

The idle InvariantChecker report is downstream evidence that this exception skipped request teardown: exactly one 16,384-token KV reservation and 3 Mamba states remained allocated. The recovery boundary should therefore finish request-level KV/Mamba rollback before returning the 500; please do not catch or suppress the invariant itself, since at that point global accounting is already inconsistent.

@mickqian

mickqian commented Aug 29, 2026 •

Copy link
Copy Markdown
Collaborator

There is still a symmetric fresh-output escape: _split_or_retry_short_combined_embedding() calls torch.split whenever actual_total >= expected_total, so an overlong combined output raises before the request-level error channel and can skip teardown. _get_chunked_embedding_full() also caches any overlong fresh result and downstream _adjust_embedding_length() silently truncates it from the end, which can feed the wrong visual tokens. Please treat every non-EVS actual != expected as a mismatch, retry only when per-item attribution is needed, and route all per-item count/length mismatches (including the remaining len assertions) through the same padded request-local failure path.

@mickqian

Copy link
Copy Markdown
Collaborator

The VLM error path still calls req.disagg_kv_sender.abort() before local cleanup in both defer_mm_embedding_abort() and process_pending_chunked_abort(). If transport abort raises, the request can again bypass KV/Mamba release; make transport abort best-effort and guarantee local teardown (including metadata/HiCache) in a finally-safe path.

@mickqian

Copy link
Copy Markdown
Collaborator

After rebasing, please remove the new reflective fallbacks: mm_embedding_errors, skipped_output_comm, skip_radix_cache_insert, and mm_embedding_validation_count are typed fields and should be accessed directly. For HiCache cleanup, pass the explicit capability/state or add a base cache API instead of probing release_aborted_request with getattr, so a missing integration cannot silently skip cleanup.

@kflansburg

Copy link
Copy Markdown
Contributor Author

Waiting for #36926 to land, then I’ll rebase once and resolve the merged-main overlap.

@mickqian mickqian added the run-ci CI: run the baseline test suite on this PR label Sep 6, 2026
@mickqian
mickqian marked this pull request as ready for review September 6, 2026 06:54

This branch has not been deployed

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

Labels

run-ci CI: run the baseline test suite on this PR unified-radix-cache

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants