Forward raw reward, document-count model version, and per-token model version - #150
Merged
Conversation
Fast-LLM now sends `document_count` (cumulative documents seen) alongside `step` in the `weights_ready` event. Stamp `document_count` as `propagated_weight_version` so rollout staleness is measured in documents, aligning with DeepSpeed's clock; keep the raw `step` in `completed_step` for logging. Falls back to `step` when `document_count` is absent (older trainers), so the change is backward-compatible. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
`convert_to_fast_llm_format` now includes the per-rollout raw reward (already on the entry, previously dropped) so the Fast-LLM trainer can log reward statistics as a single source of truth. It is a diagnostic and does not affect the loss (the group-relative advantage is unchanged). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Weight swaps can happen mid-generation (pause mode "keep" keeps in-flight tokens), so a rollout's tokens may span more than one model version. Capture that as a genuine per-token version and send it to the trainer, which already consumes a per-token model_version array; fall back to the per-rollout version when the server does not report one. Producer (vLLM 0.18.1 v1 output path, API-server process, monkeypatched): - Track the active version in a holder set at each weight-swap completion, before generation resumes, so post-swap tokens get the new version. - Annotate each committed decode position's Logprob with that version in LogprobsProcessor.update_from_output. - Encode it into the existing per-token token string in OpenAIServingChat._create_chat_logprobs (token_id:<id> -> token_id:<id>:v<v>), so no response schema changes. Defensive install: an unpatchable/moved seam disables per-token versions rather than crashing the server. Plumbing: - Parse the optional :v<version> suffix (parse_token_id_and_version), carried on TokenLogprob.version and TrainingText.token_versions (parallel to logprobs). - convert_to_fast_llm_format emits model_version left-padded to the full sequence like old_log_probabilities, or broadcasts the per-rollout version. The vLLM output-path monkeypatch exercises engine internals that cannot be run without a GPU/vLLM; it needs validation on a live streaming run (confirm the per-token version varies across an in-flight swap and the trainer's model_version/staleness metrics populate). The pure parse/pad logic is verified. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The two vLLM output-path hooks run per generated token / per response. Guard the annotation blocks so an unexpected shape (or a future vLLM change) disables per-token tagging and falls back to the per-rollout version instead of raising into the output processor or response builder. Self-disables after the first failure (logged once) so it degrades cheaply rather than throwing per token. Verified the patched seams exist and match on vLLM 0.16.0, 0.18.1, and 0.24.0: - OpenAIServingChat._create_chat_logprobs in chat_completion/serving.py, kwargs call convention, token string is `token_id:<id>` (via _get_decoded_token / format_token_id_placeholder). - LogprobsProcessor.update_from_output in v1/engine/logprobs.py, self.logprobs a list[dict[token_id, Logprob]] (FlatLogprobs alternative is guarded). - Logprob is a mutable dataclass; OpenAIBaseModel is extra="allow" and not frozen. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…hook - Log the raw trainer step (`completed_step`) in the actor's published stats alongside `trainer_model_version`, so it is no longer write-only. - Make the `update_from_output` hook forward `*args/**kwargs` to the original, matching the `_create_chat_logprobs` seam, so a vLLM signature drift degrades to the per-rollout fallback instead of raising into the output processor. - Rename `before` -> `previous_length`; trim two comments (testing directive and an overstated guarantee). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- tests/test_model_version.py: cover parse_token_id_and_version (with/without the :v<n> suffix, v0, multi-digit) and convert_to_fast_llm_format's model_version padding/fallback (per-token left-pad, pad-with-first when no scalar, scalar broadcast, absent, full-completion). Logic previously verified standalone. - Reword the serving-class import comment: the chat_completion package predates 0.18.1, so drop the specific-version attribution. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.
Claude Opus 4.8, on behalf of @jlamypoirier.
Summary
Producer-side changes paired with the Fast-LLM trainer PR (ServiceNow/Fast-LLM#553), which consolidates
RL diagnostics on the Fast-LLM side. Both trainer-clock changes are backward-compatible.
Targets the
fast-llmbranch (which carries the Fast-LLM streaming producer).Changes
document_count(cumulative documents seen) alongside
stepin theweights_readyevent.TrainerStatestampsdocument_countaspropagated_weight_versionso rollout staleness is measured in documents(aligning with DeepSpeed's clock), and keeps the raw
stepincompleted_stepfor logging. Fallsback to
stepwhendocument_countis absent, so it works against older trainers too.convert_to_fast_llm_formatnow includes the per-rollout raw reward(already on the entry, previously dropped) so the trainer can log reward statistics. It is a
diagnostic and does not affect the loss — the group-relative advantage is unchanged.
model_version. Weight swaps can happen mid-generation (pause modekeepretains in-flight tokens), so a rollout's tokens may span more than one version. The vLLM v1 output
path is monkeypatched (API-server process) to tag each generated token with the version active when
it is committed: a holder set at swap completion before generation resumes,
LogprobsProcessorannotates each committed position's
Logprob, andOpenAIServingChat._create_chat_logprobsencodesit into the existing token string (
token_id:<id>→token_id:<id>:v<version>, no response-schemachange).
parse_token_id_and_versioncarries it onTokenLogprob.version→TrainingText.token_versions→convert_to_fast_llm_format, which left-pads it to the full sequencelike
old_log_probabilities. When the server reports no per-token version, it falls back tobroadcasting the per-rollout version, so the wire format is identical either way. The Fast-LLM
consumer already accepts the per-token array.
Caveats
end-to-end here (requires a live streaming RL run); a smoke run is advisable before relying on the
new trainer-side metrics.
model_versionproducer exercises vLLM 0.18.1 v1 internals (LogprobsProcessor,OpenAIServingChat) that cannot be run without a GPU/vLLM. It is grounded in the real v0.18.1 sourcebut is not runtime-tested — validate on a live streaming run: confirm the per-token version varies
across an in-flight weight swap and that the trainer's
model_version/staleness metrics populate. Theinstall is defensive: if the vLLM seam has moved (different build), per-token capture is disabled and
it falls back to the per-rollout version rather than crashing the server. The pure parse/pad logic and
the Fast-LLM consumer round-trip are verified.
🤖 Generated with Claude Code