Skip to content

perf(bindings): read SelectionService token_ids lists without iterator overhead - #17337

Merged
jthomson04 merged 2 commits into
mainfrom
jthomson04/select-token-list-read
Oct 26, 2026
Merged

jthomson04 merged 2 commits into
mainfrom
jthomson04/select-token-list-read

Conversation

@jthomson04

@jthomson04 jthomson04 commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

Overview:

Every SelectionService call that carries a prompt converts the whole token_ids list on the calling thread, under the GIL; in Ray Serve LLM's KVAwareRouter that is select_and_reserve on every request. pyo3's generic Vec<u32> extraction walks the list through the sequence iterator and takes and drops a reference to every element, which costs more than converting the ints. This PR reads a plain list of ints by index with borrowed items and falls back to the existing extraction for anything else.

99k-token prompt, GB200 Grace, Python 3.12 Before After
token_ids conversion 7.9 ns/token 3.4 ns/token
select_and_reserve call, CPU on the calling thread 0.83 ms 0.37 ms
Ray-style embedded ingress, one replica, req/s (GIL-bound) 214.8 238.7 (+11%)

Setup:

Details:

  • lib/bindings/python/rust/llm/kv.rs: what the fast path does.
    • extract_token_ids reads an exact list with PyList_GetItem (borrowed) plus PyLong_AsUnsignedLong on exact ints.
    • It falls back on any other element type (including bool and objects with __index__), and on a value that is negative or above u32::MAX.
    • Only an exact list takes the fast path. List subclasses (whose __iter__ the generic conversion honors), tuples and other sequences use the existing conversion.
    • In every fallback case the existing extract::<Vec<u32>>() accepts the input or raises the same ValueError as before.
  • Safety. The GIL is held for the whole loop, and the loop runs no Python code, so the borrowed items stay valid.
  • Scope. This covers every prompt-carrying binding call: select, select_and_reserve, create_reservation, overlap_scores and potential_loads.

Where should the reviewer start?

extract_token_ids in lib/bindings/python/rust/llm/kv.rs.

Related Issues

Validation

  • cargo clippy --features select-service -- -D warnings in lib/bindings/python
  • pytest lib/bindings/python/tests/test_kv_bindings.py -k selection_service: 16 passed. The select test also sends a tuple (generic path). The malformed-payload test covers negative, out-of-range and non-int ids, and a list subclass whose iterator yields an invalid id (it fails without the exact-list check).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Python requests now handle lists of valid integer token IDs more reliably, while retaining support for other accepted token sequences.
    • Invalid token IDs—including negative, out-of-range, and non-integer values—now produce a clear ValueError identifying token_ids.
    • Worker selection continues to support tuple token sequences and lists containing booleans.

…r overhead

pyo3's generic Vec<u32> extraction walks the list through the sequence
iterator and takes and drops a reference to every element, which costs more
than converting the ints. Read a plain list of ints by index with borrowed
items, and fall back to the generic extraction for any other input so
accepted values and errors are unchanged.

On GB200 Grace with a 99k-token prompt, select_and_reserve CPU on the
calling thread drops from 0.83 to 0.37 ms, and a Ray-style embedded ingress
goes from 214.8 to 238.7 req/s.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: jthomson04 <jwillthomson19@gmail.com>
@jthomson04
jthomson04 requested a review from a team as a code owner October 26, 2026 20:28
@jthomson04

Copy link
Copy Markdown
Contributor Author

/ok to test 1ff5678

@github-actions github-actions Bot added the perf label Oct 26, 2026
@coderabbitai

coderabbitai Bot commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between 8222ff0 and 1ff5678.

Files selected for processing: 2
  • lib/bindings/python/rust/llm/kv.rs
  • lib/bindings/python/tests/test_kv_bindings.py

Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 11 remain after this review.

Walkthrough

The Python binding now attempts direct conversion of valid integer lists for token_ids before using generic extraction. Tests cover tuple and boolean-containing token sequences, and verify errors for negative, out-of-range, and string token IDs.

Changes

Python token ID conversion

Layer / File(s) Summary
Token conversion and validation
lib/bindings/python/rust/llm/kv.rs, lib/bindings/python/tests/test_kv_bindings.py
depythonize_prompt_request attempts direct conversion for lists of exact integers that fit in u32. Other inputs use the existing generic extraction path. Tests cover tuple and boolean-containing inputs, and malformed token IDs that raise ValueError mentioning token_ids.

Priority: Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: Minimal · up to 1ff56

No merge-blocking issue is identified; the token-conversion change is ready for normal checks.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 2 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title clearly and concisely describes the main change: improving token_ids list conversion performance in Python bindings.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Description check Passed The pull request description includes all required sections: Overview, Details, reviewer starting point, and Related Issues. It identifies Relates to #17238 and provides clear implementation details, …
Full details: Description check

Explanation

The pull request description includes all required sections: Overview, Details, reviewer starting point, and Related Issues. It identifies Relates to #17238 and provides clear implementation details, scope, safety considerations, benchmarks, and validation results.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

Comment thread lib/bindings/python/rust/llm/kv.rs Outdated
Comment thread lib/bindings/python/rust/llm/kv.rs Outdated
Comment thread lib/bindings/python/tests/test_kv_bindings.py Outdated
A list subclass can override __iter__, which the generic conversion
honors; reading its backing storage by index would select on different
token ids. Restrict the borrowed-item read to exact lists, and fold it and
the fallback into one extract_token_ids helper.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: jthomson04 <jwillthomson19@gmail.com>
@jthomson04

Copy link
Copy Markdown
Contributor Author

/ok to test 9c4b219

@devin-ai-integration

Copy link
Copy Markdown
Contributor

✅ Dynamo PR CI passed — run 40400231408 (attempt 1) on 9c4b219648

Gate checks: ✅ backend-status-check · ✅ deploy-status-check · ✅ dynamo-status-check

Posted automatically by Devin for run 40400231408. Updated on every full-CI run of this PR.

@jthomson04
jthomson04 merged commit e3b7b76 into main Oct 26, 2026
128 checks passed
@jthomson04
jthomson04 deleted the jthomson04/select-token-list-read branch October 26, 2026 22:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants