Skip to content

perf(r3): accelerate routed-expert transport with packed arrays#1909

Open
dyurk-lila wants to merge 2 commits into
NovaSky-AI:mainfrom
dyurk-lila:upstream/r3-packed-transport
Open

perf(r3): accelerate routed-expert transport with packed arrays#1909
dyurk-lila wants to merge 2 commits into
NovaSky-AI:mainfrom
dyurk-lila:upstream/r3-packed-transport

Conversation

@dyurk-lila

Copy link
Copy Markdown
Contributor

Note on the diff: This PR is part of a routed-expert-replay / sampler-support series and builds on the PRs below. GitHub can't show the intermediate branches here, so the diff is cumulative on top of main — the changes new to this PR sit on top of:

Reviewing in PR order (lowest number first) shows each incremental change cleanly.

Problem

The routed-expert (R3) generation path returns one expert ID for every generated token, MoE layer, and top-k slot. Serializing that integer tensor as nested JSON lists creates a large HTTP payload and substantial Python/JSON overhead before training sees the data.

Implementation

  • Compact routed-expert IDs to the smallest safe uint8, int16, or int32 NumPy dtype.
  • Base64-encode the contiguous buffer alongside its shape and dtype, and decode it back into a validated compact NumPy array on the client.
  • Serialize the vLLM response and parse client responses with orjson.
  • Gate packed routes behind the existing routed-expert request flag, so the transport is only used when routed experts are requested.
  • Accept the decoded NumPy route arrays at preprocessing, validating dtype and shape before padding and tensor conversion.

This change is intentionally scoped to transport and preprocessing: it does not alter batching, Experience, device placement, or backend replay setup.

Testing

CPU tests run with:

uv run --isolated --extra dev --extra fsdp pytest \
  tests/backends/skyrl_train/inference_servers/test_remote_inference_client.py \
  tests/backends/skyrl_train/inference_servers/test_routed_experts_wire.py \
  tests/train/dataset/test_preprocess.py \
  tests/train/generators/test_generator_output_utils.py \
  tests/train/generators/test_skyrl_gym_generator.py \
  tests/train/test_trainer_utils.py -q --ignore=tests/backends/skyrl_train/gpu

The suite covers route preprocessing, dtype selection, base64 round trips, malformed payloads, and the packed wire codec. ruff and black (line length 120) pass on the changed files.

This is part of a small series of routed-expert transport improvements.

dyurk-lila and others added 2 commits July 16, 2026 21:27
Fix routed-expert replay (R3) correctness for RL training and introduce a
shared token-metadata layout that later routed-expert and sampler-support
work builds on.

- Scope global RouterReplay state to one Megatron pipeline schedule so a
  forward-only logprob pass can no longer leak backward replay state into
  the next training schedule (clear before the schedule and in `finally`).
- Keep `rollout_expert_indices` ragged and treat its length as the
  captured-prefix length. Derive a `router_padding_mask` after left padding
  that marks alignment padding and the uncaptured trajectory suffix, and
  carry it through the training data, replay experiences, microbatch
  padding, and the Megatron model call.
- Build one `TokenMetadataLayout` per microbatch and apply it to both routes
  and the padding mask. Generic construction, alignment, next-token shifting,
  and packed-output restoration live in `skyrl/utils/token_metadata.py`.
- Pass Megatron's `padding_mask` through the model and apply a narrow
  compatibility shim so `[tokens]` masks broadcast over experts in expert-bias
  accounting.
- Slice every per-trajectory generator field generically during dynamic-sampling
  replacement and filtering so route metadata stays attached to its trajectory.

Synthetic padding rows use distinct dummy experts `[0, ..., topk - 1]`; the
mask excludes them from expert-bias accounting while preserving Megatron's
dropless `tokens * topk` dispatcher invariant.
Store routed-expert (R3) generation data as compact NumPy arrays instead
of large nested Python lists, and send it over the network base64-encoded
alongside its shape and dtype. Expert IDs are compacted to the smallest
safe uint8/int16/int32 dtype, vLLM responses and client responses use
orjson, and preprocessing accepts the decoded NumPy route arrays directly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Warning

Gemini encountered an error creating the review. You can try again by commenting /gemini review.

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