Skip to content

[Tokenizer] Validate caller token IDs against the vocab and active multimodal markers - #41735

Open
rodamani wants to merge 4 commits into
sgl-project:mainfrom
modal-projects:rohan/up/mm-caller-token-id-validation
Open

rodamani wants to merge 4 commits into
sgl-project:mainfrom
modal-projects:rohan/up/mm-caller-token-id-validation

Conversation

@rodamani

@rodamani rodamani commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Motivation

Caller-supplied input_ids are not validated against the vocabulary before multimodal expansion (_validate_input_ids_in_vocab was removed from TokenizerManager as a dead helper). Out-of-range or negative IDs are not rejected at admission, and a caller can place a processor's multimodal marker ID in a prompt that supplies no media.

Modifications

  • TokenizerManager._validate_generation_input_ids checks each normalized prompt against the text vocabulary (hf_text_config.vocab_size), allowing only the active processor's placeholder IDs for media actually supplied with that prompt (per batch item). Empty prompts, embedding overrides, session continuation and batch metadata keep their existing contracts.
  • Processors expose get_input_token_ids_for_data (base, LLaVA, inkling).
  • Warmup synthetic IDs are bounded to the vocabulary (otherwise warmup on models with a vocabulary under 65536 would trip the new check).
  • The optional SGLANG_MM_STRIP_PROCESSOR_INPUT_IDS payload reduction that was originally bundled here is split into its own PR.
  • Tests: test/registered/unit/managers/test_tokenizer_input_contracts.py (new), test_tokenizer_manager_rid_cleanup.py, test/registered/unit/entrypoints/test_server_warmup.py.

Relationship to open PRs: #31908 wires a plain [0, vocab_size) check into _validate_one_request, which does not know about processor-registered multimodal markers (it would reject valid placeholder IDs outside the text vocabulary, or accept a marker with no supplied media) and does not bound warmup IDs.

Accuracy Tests

CPU: 55 passed, 23 subtests passed across the three files. Porting note: one test needed scheduler.model_config on its stub because main's _process_and_broadcast_mm_inputs now reads requires_mm_token_modalities.

Compatibility

Requests whose input_ids are all inside [0, vocab_size) (or are the active processor's placeholders for media supplied with that prompt) behave as before. Requests with negative or out-of-vocabulary IDs, or with a multimodal marker but no matching media, now get a ValueError (400) at admission instead of reaching the model. No new flags; text-only and embedding requests are unaffected.

Speed Tests and Profiling

Adds a Python pass over caller-supplied input_ids at admission (text-only requests have no media lookups). Not separately benchmarked.

Checklist

Review and Merge Process

  1. Ping Merge Oncalls to start the process. See the PR Merge Process.
  2. Get approvals from CODEOWNERS and other reviewers.
  3. Trigger CI tests with comments or contact authorized users to do so.
    • Common commands include /tag-and-rerun-ci, /tag-run-ci-label, /rerun-failed-ci
  4. After green CI and required approvals, ask Merge Oncalls or people with Write permission to merge the PR.

CI States

Latest PR Test (Base): ✅ Run #36767748375
Latest PR Test (Extra): ❌ Run #36767747692
Latest PR Test (AMD ROCm 10): ❌ Run #36767748350

Validate normalized prompts against the text input vocabulary and the active processor markers for their supplied modalities. Keep output-token bounds, embedding overrides, session continuation and batch metadata setup on their existing contracts.

Bound synthetic warmup inputs and add optional reduction of duplicate processor IDs after canonical request copying, preserving padded IDs and output ownership.

Relationship to upstream: sgl-project#31908 (open) wires a plain
[0, vocab_size) check into _validate_one_request. That check does not know
about processor-registered multimodal markers (it would reject valid
placeholder IDs outside the text vocabulary, or accept an image marker with
no supplied media) and does not bound warmup IDs. sgl-project#35903 (same plain check)
was closed without merge.

Carried from #42.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
SGLANG_MM_STRIP_PROCESSOR_INPUT_IDS is an independent payload optimization,
so it moves to its own PR. The caller token-ID validation and warmup bound
are unchanged.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@rodamani

Copy link
Copy Markdown
Contributor Author

/tag-and-rerun-ci

@github-actions github-actions Bot added the run-ci CI: run the baseline test suite on this PR label Sep 30, 2026

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

npu run-ci CI: run the baseline test suite on this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants