Skip to content

Forward raw reward, document-count model version, and per-token model version - #150

Merged
jlamypoirier merged 6 commits into
fast-llmfrom
jlp_rl_metrics
Jul 8, 2026
Merged

Forward raw reward, document-count model version, and per-token model version#150
jlamypoirier merged 6 commits into
fast-llmfrom
jlp_rl_metrics

Conversation

@jlamypoirier

@jlamypoirier jlamypoirier commented Jul 7, 2026

Copy link
Copy Markdown

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-llm branch (which carries the Fast-LLM streaming producer).

Changes

  • Use the Fast-LLM document count as the model version. Fast-LLM now emits document_count
    (cumulative documents seen) alongside step in the weights_ready event. TrainerState stamps
    document_count as propagated_weight_version so rollout staleness is measured in documents
    (aligning with DeepSpeed's clock), and keeps the raw step in completed_step for logging. Falls
    back to step when document_count is absent, so it works against older trainers too.
  • Forward the raw reward. convert_to_fast_llm_format now 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.
  • Capture per-token model_version. Weight swaps can happen mid-generation (pause mode keep
    retains 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, LogprobsProcessor
    annotates each committed position's Logprob, and OpenAIServingChat._create_chat_logprobs encodes
    it into the existing token string (token_id:<id>token_id:<id>:v<version>, no response-schema
    change). parse_token_id_and_version carries it on TokenLogprob.version
    TrainingText.token_versionsconvert_to_fast_llm_format, which left-pads it to the full sequence
    like old_log_probabilities. When the server reports no per-token version, it falls back to
    broadcasting the per-rollout version, so the wire format is identical either way. The Fast-LLM
    consumer already accepts the per-token array.

Caveats

  • The reward + document-count-version changes are small and backward-compatible but not validated
    end-to-end here (requires a live streaming RL run); a smoke run is advisable before relying on the
    new trainer-side metrics.
  • The per-token model_version producer 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 source
    but 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. The
    install 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

jlamypoirier and others added 3 commits July 7, 2026 14:19
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>
@jlamypoirier jlamypoirier changed the title Forward raw reward and use Fast-LLM document count as the model version Forward raw reward, document-count model version, and per-token model version Jul 7, 2026
jlamypoirier and others added 3 commits July 7, 2026 17:04
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>
@jlamypoirier
jlamypoirier merged commit c77bdda into fast-llm Jul 8, 2026
1 check passed
@jlamypoirier
jlamypoirier deleted the jlp_rl_metrics branch July 8, 2026 16:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant