feat(vllm): route embedding worker through Rust preprocessor (opt-in via --use-vllm-tokenizer) - #11109
Draft
tzulingk wants to merge 1 commit into
Draft
feat(vllm): route embedding worker through Rust preprocessor (opt-in via --use-vllm-tokenizer)#11109tzulingk wants to merge 1 commit into
tzulingk wants to merge 1 commit into
Conversation
…via --use-vllm-tokenizer)
Make the vLLM embedding worker able to receive pre-tokenized input from
Dynamo's Rust OpenAIPreprocessor (tokenize off the engine process),
selectable at launch via --use-vllm-tokenizer like chat/completions.
- worker_factory.py: embedding registration picks ModelInput.Text if
use_vllm_tokenizer else ModelInput.Tokens (was hardcoded Text); threads
the flag into the handler + health-check payload.
- handlers.py: EmbeddingWorkerHandler.generate dispatches on the flag —
Text mode (raw {input} in, OpenAI out) unchanged; Tokens mode reads
{token_ids} from PreprocessedEmbeddingRequest, wraps each in TokensPrompt,
and returns EmbeddingsEngineOutput for the Rust postprocessor. Shared
_run_encode + _parse/_check_embedding_dimensions helpers.
- health_check.py: payload gains use_text_input (probe {input} vs {token_ids}).
- tests updated for the new default.
WIP snapshot for A/B benchmarking (text-input throughput, baseline vs
candidate). Default is now the Tokens/Rust path.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Tzu-Ling <tzulingk@nvidia.com>
Contributor
|
This PR is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days. |
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.
Overview:
Route the vLLM embedding worker through Dynamo's Rust
OpenAIPreprocessor(tokenize off the engine process) instead of only handing raw text to vLLM — selectable at launch via the existing--use-vllm-tokenizerflag, exactly like chat/completions. Motivation: on text-input embeddings, vLLM tokenizes in-engine; moving tokenization to the Rust frontend is measurably faster (early A/B below).Details:
EmbeddingWorkerHandler.generatenow dispatches onuse_vllm_tokenizer:Text mode (
--use-vllm-tokenizer, baseline): unchanged — raw{input}in, OpenAI{data:[…base64…]}out.Tokens mode (default now): reads
{token_ids}from thePreprocessedEmbeddingRequest, wraps each inTokensPrompt(so vLLM skips its own tokenizer), and returns the rawEmbeddingsEngineOutputshape so the Rust postprocessor does OpenAI formatting/base64.worker_factory.py— embedding registration picksModelInput.Textifconfig.use_vllm_tokenizerelseModelInput.Tokens(was hardcodedText); threads the flag into the handler and the health-check payload.handlers.py— extracted a shared_run_encodeplus_parse_embedding_dimensions/_check_embedding_dimensionsso both paths validate + encode identically (incl. thetask="embed"pooling + Matryoshkadimensionshandling from fix(vllm): pool embedding worker output via PoolingParams(task="embed") #10248).health_check.py—VllmEmbeddingHealthCheckPayloadgainsuse_text_input; probes with{input:"probe"}for Text mode and{token_ids:[[1]]}for Tokens mode (otherwise the probe fails with a missing-field error).Tests — embedding registration-contract test (flag →
ModelInput), tokens-mode handler tests, and updated health-check payload tests for the new default; existing text-path tests pinned touse_vllm_tokenizer=True.Behavior change: the default is now the Tokens/Rust path, so any embedding model whose tokenizer the frontend can't resolve must be launched with
--use-vllm-tokenizer.Early A/B (single GB200, vLLM 0.24.0,
vllm bench serve --backend openai-embeddings, text input, 4096 prompts,Qwen/Qwen3-Embedding-0.6B— embeddinggemma-300m is gated, run pending an HF token): candidate (Rust) vs baseline (--use-vllm-tokenizer) throughput = +27% / +46% / +13% at max-concurrency 128 / 512 / 1024. Tracking in DIS-2307.Where should the reviewer start?
components/src/dynamo/vllm/handlers.py—EmbeddingWorkerHandler.generatedispatch, the new_generate_tokens_mode, and the shared_run_encode.components/src/dynamo/vllm/worker_factory.py— theModelInput.Text/Tokensselection driven byuse_vllm_tokenizer.🤖 Generated with Claude Code