Repository navigation
fix(rollout): score-centering candidates as flat base64 arrays [fork fix-016] - #45
Merged
Merged
Conversation
…fix-016] Score-centering training calls asked SGLang's chat endpoint for top_logprobs=k with the default nested format, so each engine's single HTTP process decoded k candidate strings per generated token, built k TopLogprob objects with bytes, and serialized them twice. Session training requests now ask for SGLang's flat format (return_flat_raw_output_top_logprobs, base64 int32 ids and float32 logprobs in meta_info), and the session sample producer decodes those arrays. A response without them raises instead of falling back to the nested rows. Support mode and the native /generate path are unchanged. Patch page: fork/patches/fix-016-flat-topk-logprobs.md Fork-Fix: fix-016 Touches: miles/rollout/generate_utils/rollout_topk_logprobs.py, miles/rollout/session/samples/merge.py, tests/fast/rollout/generate_utils/test_score_centering_contracts.py, tests/fast/rollout/session/test_score_centering.py Evidence: 1-node probe replaying 128 recorded score-centering sessions: fixed per-call overhead 20.4 s with top_logprobs=32 vs 3.2 s without, SGLang tokenizer manager ~98% of a core with an empty engine queue. CPU replay of the sglang-miles 7b6993a response path at k=32: 1.0 s and 8 MB per 2,000-token response nested, 0.02 s and 1 MB flat Upstream-Status: not filed Remove-When: upstream Miles requests flat rollout top-k logprobs Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Fork-Infra: patch-fix-016 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
listar2000
force-pushed
the
claude/project-thread-fttpqk
branch
from
October 19, 2026 08:15
1fef503 to
1a99ec1
Compare
This was referenced Oct 19, 2026
listar2000
marked this pull request as ready for review
October 19, 2026 16:15
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.
Merge with rebase, not squash: fix-016 and its patch page are two commits by ledger rule.
Outcome
Score centering stops slowing every model call: per-call overhead 20.4 s → 3.9 s on a 1-node GPU probe (3.2 s with no top-k at all). Each engine's HTTP process spent about a second of CPU per 2,000-token reply formatting the candidate tokens, and every call queued behind that. This PR asks SGLang for the same candidates in its compact binary format. It is on by default for every score-centering run through the session server, with no flag to set.
Terms: score centering is a loss that needs, for every generated token, the engine's top-k candidate tokens and their log-probabilities (top-k logprobs, k=32 here). The session server is Miles' OpenAI-compatible proxy that agents call during rollout. The tokenizer manager is SGLang's single Python HTTP process per engine.
CPU replay of the engine's response code (sglang-miles 7b6993a, the engine in our image), k=32:
Cause. With
top_logprobs=32on/v1/chat/completions, SGLang turns onreturn_text_in_logprobs. For every generated token, the tokenizer manager then callstokenizer.batch_decodeon 32 candidates._build_token_logprobs_from_rawbuilds 32TopLogprobobjects with byte lists, and both copies (choices[].logprobsandmeta_info.output_top_logprobs) get serialized.Fix. SGLang's own option
return_flat_raw_output_top_logprobswithreturn_flat_raw_top_logprobs_b64(sgl-project/sglang#42890) returns the candidates once, as base64 int32 ids and float32 logprobs, built straight from the scheduler's arrays.Patch page: fork/patches/fix-016-flat-topk-logprobs.md
Contract
logprobsduring score-centering training now get emptytop_logprobslists (Harbor agents do not ask).Side-effects
--rollout-sampling-logprobs-mode support) and the native/generatepath are unchanged./generatenever decodes candidate text.[fork fix-016]:miles/rollout/generate_utils/rollout_topk_logprobs.py(pure insertions plus theflatkeyword onappend_rollout_topk_logprobs),miles/rollout/session/samples/merge.py, and the two score-centering test files.fork/patches/README.md; whichever PR lands second keeps both rows.Done
configure_rollout_topk_logprobs_requestsets both flat flags on OpenAI (session) training requests in "selected" mode and drops client-sent copies elsewhere, because the rollout args own these fields.append_rollout_topk_logprobs(..., flat=True)decodes the base64 arrays, honoring SGLang'sshape,null_prefixand dtype markers. The session producer passesflatfrom the backend request.Verification
python fork/tools/ledger.py check: okpre-commit run --files <changed>: all passpytest --noconftest tests/fast/rollout/session/test_score_centering.py tests/fast/rollout/generate_utils/test_score_centering_contracts.py: 70 passed. The widertests/fast/rollout/session+generate_utilsrun gives 411 passed, against 410 on main, with the same environment failures.strings /usr/local/bin/sgl-model-gateway | grep -c return_flat_raw_output_top_logprobs→ 1, and the same grep onsglang_router_rs.abi3.so(sglang-router 0.3.2) → 2.