[llm][kv][8/N] Move tokenization in-process of LLMRouter ingress replica - #64642
Conversation
There was a problem hiding this comment.
Code Review
This pull request refactors the pre-routing tokenization mechanism by replacing remote /tokenize endpoint calls with an in-process Tokenizer that utilizes vLLM's OnlineRenderer directly. This keeps the router engine-agnostic by lazily importing the tokenizer only when KV-aware routing is enabled. Feedback on the changes suggests adding a guard when dumping tools in _render_chat to handle cases where tools might be raw dictionaries instead of Pydantic models, preventing potential AttributeErrors.
| tool_dicts = ( | ||
| None | ||
| if request.tools is None | ||
| else [tool.model_dump() for tool in request.tools] | ||
| ) |
There was a problem hiding this comment.
If request.tools contains raw dictionaries (e.g., if validation allowed them or if they were bypassed), calling tool.model_dump() will raise an AttributeError. Using a guard like hasattr(tool, "model_dump") ensures compatibility with both Pydantic models and raw dictionaries.
tool_dicts = (
None
if request.tools is None
else [
tool.model_dump() if hasattr(tool, "model_dump") else tool
for tool in request.tools
]
)712a930 to
309d524
Compare
309d524 to
62c85a6
Compare
ad9bcdd to
d0e4494
Compare
…returning calls _svc.delete_worker's Rust binding returns a future, not a coroutine, so passing it straight to create_task raised TypeError. _schedule now wraps whatever it is given in a coroutine, keeping the call sites direct. Signed-off-by: Jeffrey Wang <jeffreywang@anyscale.com>
Pure relocation of the tokenizer module (and its unit test) from core/ingress to routing_policies/kv_aware, updating import paths. No logic change; the vLLM-specific rewrite follows in the next commit. Signed-off-by: Jeffrey Wang <jeffreywang@anyscale.com>
…s vLLM renderer Replace the per-request /tokenize RPC with an in-process tokenizer that drives the engine's own vLLM OnlineRenderer: render_chat for chat (the engine's own entry point, covering the HF chat template, Harmony for gpt_oss, and Mistral) and preprocess_completion for text prompts. Routing token ids are therefore byte-identical to the replica's prefill tokens without contending with inference on the replica processes. The vLLM renderer imports live at module top (OnlineRenderer needs vLLM >= 0.25); the ingress router imports the tokenizer lazily so non-KV paths never pull the renderer in. Signed-off-by: Jeffrey Wang <jeffreywang@anyscale.com>
d0e4494 to
22b77f0
Compare
/tokenize RPCLLMRouter ingress replica
There was a problem hiding this comment.
Code Review
This pull request refactors the pre-routing tokenization mechanism to run in-process using vLLM's OnlineRenderer instead of making remote calls to the replica's /tokenize endpoint. It introduces lazy loading of the tokenizer for KV-aware routers to keep the non-KV ingress path engine-agnostic, and adds comprehensive exactness tests comparing the in-process tokenizer with Hugging Face's transformers library. The review feedback suggests initializing the tokenizer synchronously on the main thread during startup to avoid potential thread-safety issues with asyncio.to_thread, and wrapping background tasks in _schedule with try-except blocks to prevent exceptions from failing silently.
Signed-off-by: Jeffrey Wang <jeffreywang@anyscale.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 5b7e662. Configure here.
kouroshHakha
left a comment
There was a problem hiding this comment.
does this approach work with fasttokens as well? https://github.com/vllm-project/vllm/blob/0b6aa3c47ce69a1f3c8a19cafe3b9dc2871d1f6b/docs/configuration/optimization.md?plain=1#L281 can we test that and confirm?
Signed-off-by: Jeffrey Wang <jeffreywang@anyscale.com>
Plumbed env var to enable that in fc63345 and added a test accordingly. Here's the API shape: |

Description
After this PR, pre-routing tokenization for KV-aware routing runs in-process inside
LLMRouter, using the engine's own vLLMOnlineRenderer, instead of issuing a per-request RPC to a model replica's/tokenize.KV-aware routing needs prompt token IDs to score replicas. Prior to this PR, the router obtained them via a per-request RPC to a replica's
/tokenize. That round-trip sits directly on the routing critical path and contends with inference traffic, so it collapses under concurrency. Tokenizing in-process removes the RPC entirely, so the router keeps up as concurrency scales.This PR also ships the enablement of
fastokens:Related issues
Additional information