Skip to content

perf(trainer): keep router-replay routes compact until the GPU, shard them for CP on the host - #4215

Merged
faresobeid merged 1 commit into
mainfrom
perf/router-replay-batch-memory
Oct 22, 2026
Merged

faresobeid merged 1 commit into
mainfrom
perf/router-replay-batch-memory

Conversation

@faresobeid

@faresobeid faresobeid commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Router-replay routes arrive from the orchestrator in vLLM's wire dtype (uint8 for ≤256 experts, uint16 above). On main the trainer:

  • widens the whole batch's routes to int32 on the host in DataLoader._micro_batch_to_tensor (4x the uint8 bytes, 2x the uint16 bytes);
  • copies the full [1, seq, layers, top_k] tensor to the GPU and only then takes the CP chunk. The chunk is a view, so the full tensor stays allocated on the GPU;
  • keeps the previous step's micro batches until dataloader.get_batch() returns, so two converted batches are alive while the next one is received.

This PR keeps routes in the wire dtype on the host, takes the CP chunk on the host, copies only that chunk to the GPU and widens it to int32 there. It also drops the step's micro batches after the micro-step loop. The model receives the same int32 tensor as before.

Memory

One trainer rank, 16 micro batches × 65,536 tokens (1M tokens), CP=4, two steps. Routes are the only per-token array that changes. Host peak is RSS above the received frame, sampled after each micro batch is converted. GPU is the peak allocation for the routes in one micro step (H200).

routes host peak, main host peak, this PR GPU per micro step, main GPU per micro step, this PR
46 layers × top-8, uint8 (GLM-4.5-Air) 3.46 GiB 0.57 GiB 92 MiB 30 MiB
48 layers × top-10, uint16 (Qwen3.8-Flash-Next) 4.91 GiB 1.10 GiB 120 MiB 46 MiB

Host memory is per rank. Every CP rank of a data rank still receives the full payload, so a node holds 8x these numbers.

Overlap


Note

Low Risk
Behavior-preserving memory optimization for MoE router replay; model still receives int32 routed experts after CP shard. Minor risk only if CP sharding or dtype handling on CPU diverged from the old GPU path.

Overview
Router-replay routed_experts stay in vLLM wire dtype (uint8/uint16) on the host longer, instead of widening to int32 in DataLoader._micro_batch_to_tensor.

In the training loop, routes are no longer copied to GPU before context-parallel (CP) sharding. CP slicing runs on the host; only the rank’s chunk is moved to CUDA and cast to int32 right before forward—same int32 input to the model, but less host and GPU memory (especially when CP>1, since the full sequence no longer has to live on GPU as a view).

After the micro-batch forward/backward loop, the step del micro_batches, micro_batch drops the converted batch so the next receive/convert does not keep two batches alive at once.

Reviewed by Cursor Bugbot for commit c5204b9. Bugbot is set up for automated code reviews on this repo. Configure here.

… them for CP on the host, free the batch after the step
@faresobeid
faresobeid marked this pull request as ready for review October 22, 2026 14:50
@faresobeid
faresobeid merged commit b1cc8ec into main Oct 22, 2026
24 of 26 checks passed
faresobeid added a commit that referenced this pull request Oct 24, 2026
Re-pin deps/verifiers to verifiers#2765 (6e235e7) and deps/renderers to renderers#170 (424ba10), both merged with main. Read by-handle routing rows in their wire dtype and expand routed layers on GPU after the host CP shard (#4215); read masks over the full sequence when score centering is on (#4176).
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.

2 participants