Repository navigation
perf(kv-router): parse selection requests without serde flatten or path tracking - #17238
Conversation
…th tracking Selection requests carry a full prompt's token_ids. Three parse paths made that the dominant cost of the selection service and of the embedded SelectionService that Ray Serve LLM calls: - Prompt-carrying request types embedded PromptRequest with #[serde(flatten)], which buffers the whole body through serde Content first; under pythonize it also forced pyo3's slow 128-bit int extraction for every token. They now deserialize through flat wire structs (serde(from)) with the same public shape and wire fields. - The Python binding extracts token_ids with pyo3's typed Vec<u32> conversion before depythonizing the rest of the request. - The five prompt-carrying HTTP routes use a PromptJson extractor: serde_json::from_slice without axum Json's serde_path_to_error per-element path tracking, keeping Json's 415/400/422 rejections. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: jthomson04 <jwillthomson19@gmail.com>
|
/ok to test b3ace9a |
|
No actionable comments were generated in the recent review.
|
| Layer / File(s) | Summary |
|---|---|
Flat prompt request deserialization lib/kv-router/src/services/selection/types.rs, lib/kv-router/src/services/selection/tests.rs |
Wire structs deserialize top-level prompt fields into nested prompts and apply request defaults. Tests check prompt fields, defaults, and selected request values. |
Router JSON extraction and rejection responses lib/kv-router/src/services/selection/server.rs, lib/kv-router/src/services/selection/tests.rs |
Selection endpoints use PromptJson. It accepts JSON and +json content types, returns 415 for missing or unsupported types, preserves body-extraction rejection details, maps data errors to 422, and maps other parse errors to 400. Tests check selected rejection responses. |
Python prompt request deserialization lib/bindings/python/rust/llm/kv.rs |
A helper extracts non-None token_ids from dictionary inputs before request deserialization, then assigns them to the parsed prompt. Five request methods use the helper. |
Priority:
Estimated code review effort: 3 (Moderate) | ~20 minutes
Merge Risk: 
Minimal · up to b3ace
-
No merge-blocking behavior change was identified; the selection request parsing changes are ready for normal validation.
Pre-merge checks: 
4 · 
1
-
Failed checks: 1 warning Passed checks: 4 passed-
Full details: Description check
-
Explanation
The description is thorough and mostly complete. It has an Overview with the goal (removing serde flatten buffering, typed token_ids extraction, and HTTP parsing without serde_path_to_error), a Details section that lists the changed files and the reasoning, a Where should the reviewer start section, and a Validation section with commands and results. Benchmark data supports the claims. The one required gap is the Related Issues section. It still holds the template placeholder 'Closes
#XXXX' and does not name a real issue, although the objectives cite PR#17238and the template marks this section as required. The check passes on overall completeness, but the Related Issues section needs a real reference before merge.
-
-
Finishing Touches: 💡 1
-
🛠️ Fix failing CI checks: 💡
-
- Commit to this branch
- Create a new PR
-
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Comment @coderabbitai help to get the list of available commands.
✅ Dynamo PR CI passed — run 40131064575 (attempt 1) on
|
Without flatten, the wire struct's typed bool went through pythonize's deserialize_bool, which reads Python truthiness: "is_eagle": "false" enabled Eagle hashing. Accept only a boolean or null, as the flattened path did. HTTP is unchanged; serde_json's bool was already strict. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: jthomson04 <jwillthomson19@gmail.com>
- Binding: one depythonize_prompt_request taking a prompt accessor replaces the PromptRequestBody trait, its impl macro and module. - has_json_content_type matches the +json suffix without allocating. - types.rs: the wire macro and strict_bool sit next to the request types that use them; BlockExtraInfo joins the crate::protocols import. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: jthomson04 <jwillthomson19@gmail.com>
|
/ok to test 654d716 |
Overview:
Selection requests carry a whole prompt's
token_ids. Parsing them was the largest cost in both the standalone selection service and the embeddedSelectionServicethat Ray Serve LLM'sKVAwareRoutercalls. This PR removes the serdeflattenbuffering on the prompt, extractstoken_idswith a typed pyo3 conversion in the binding, and parses HTTP bodies withoutserde_path_to_error.A/B on one GB200 Grace node, same allocation. Setup: 1,024 mocker workers publishing real ZMQ KV events, 8,192 concurrent AgentX sessions with a 16k shared prompt (mean ISL 99k tokens), service pinned to 16 cores, 0 errors in every arm.
ContentbufferingParse microbench, 100k-token
/selectbody, local x86: 3.8 ms before, 1.55 ms withoutflatten, 0.82 ms with both changes.Details:
services/selection/types.rs.SelectRequest,SelectAndReserveRequest,ReservationRequest,PotentialLoadsRequestandOverlapScoresRequestdeserialize through flat wire structs (#[serde(from)], generated byinline_prompt_wire!) instead of#[serde(flatten)] prompt. The public structs and the wire fields are unchanged.flattenbuffered the body into serdeContent; under pythonize it also forced pyo3's slow 128-bit int extraction, about 48 ns per token.is_eaglestill accepts only a boolean or null: a plain typedboolwould let pythonize coerce truthy values such as"false".lib/bindings/python/rust/llm/kv.rs.select,select_and_reserve,create_reservation,overlap_scoresandpotential_loadsextracttoken_idsas a typedVec<u32>, then depythonize the rest of the dict. Invalid tokens still raiseValueError.services/selection/server.rs. The five prompt-carrying routes use aPromptJson<T>extractor:serde_json::from_slice, without axumJson's per-element path tracking. It keepsJson's rejections: 415 for a missing or non-JSONContent-Type, 400 for malformed JSON, 422 for a body of the wrong shape, and the body limit.Where should the reviewer start?
services/selection/types.rs(inline_prompt_wire!), thenPromptJsoninserver.rs.Validation
cargo clippy -p dynamo-kv-router --features standalone-selection --all-targets -- -D warningscargo clippy --features select-service -- -D warningsinlib/bindings/pythoncargo test -p dynamo-kv-router --features standalone-selection --lib services::: 251 passed, including the newprompt_carrying_requests_read_top_level_prompt_fieldsandprompt_routes_keep_json_rejection_statusespytest lib/bindings/python/tests/test_kv_bindings.py -k selection_service: 16 passed; the malformed-payload test now also covers"is_eagle": "false"(fails before the fix)🤖 Generated with Claude Code