Skip to content
Merged
Show file tree
Hide file tree
Changes from 38 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
a3deb8c
p2p: write the speculative draft from the trainer's MTP layers
yueming-yuan Oct 8, 2026
0a39155
Add a GLM-4.7-Flash p2p e2e with a trained MTP draft
yueming-yuan Oct 8, 2026
97ac1b3
Add a Qwen3.5-35B-A3B p2p e2e with a trained MTP draft
yueming-yuan Oct 8, 2026
c2ed01e
Merge loader-probe cleanup into draft runners
yueming-yuan Oct 8, 2026
85cd7f6
Trim draft-update comments to the required constraints
yueming-yuan Oct 8, 2026
500831f
Name runner routing by the HF tensors its loader accepts
yueming-yuan Oct 8, 2026
ae080bf
Select draft construction scope at the call site
yueming-yuan Oct 8, 2026
0933731
Shorten the draft-update documentation
yueming-yuan Oct 8, 2026
3681d1a
Merge branch 'yueming/p2p-probe-cleanup' into yueming/p2p-draft-cleanup
yueming-yuan Oct 8, 2026
d031700
Merge branch 'yueming/p2p-probe-cleanup' into yueming/p2p-draft-cleanup
yueming-yuan Oct 8, 2026
cf2687d
Merge branch 'yueming/p2p-probe-cleanup' into yueming/p2p-draft-cleanup
yueming-yuan Oct 8, 2026
09e83cf
Merge branch 'yueming/p2p-probe-cleanup' into yueming/p2p-draft-cleanup
yueming-yuan Oct 8, 2026
d05725d
Merge branch 'yueming/p2p-probe-cleanup' into yueming/p2p-draft-cleanup
yueming-yuan Oct 8, 2026
94dfdd9
Merge branch 'yueming/p2p-draft-replicas' into yueming/p2p-draft-runners
yueming-yuan Oct 9, 2026
63ce081
Merge branch 'yueming/p2p-draft-replicas' into yueming/p2p-draft-runners
yueming-yuan Oct 9, 2026
8a5b79f
Merge branch 'yueming/p2p-draft-replicas' into yueming/p2p-draft-runners
yueming-yuan Oct 9, 2026
62eab3e
Merge branch 'yueming/p2p-draft-replicas' into yueming/p2p-draft-runners
yueming-yuan Oct 9, 2026
333408f
Merge branch 'yueming/p2p-draft-replicas' into yueming/p2p-draft-runners
yueming-yuan Oct 9, 2026
ddcfab3
Run the GLM-4.7-Flash p2p e2e on two pipeline stages
yueming-yuan Oct 9, 2026
415e695
Remove the Qwen3-30B-A3B p2p e2e
yueming-yuan Oct 9, 2026
bbce46c
Merge branch 'yueming/p2p-draft-replicas' into yueming/p2p-draft-runners
yueming-yuan Oct 9, 2026
44473a2
Set the MTP p2p e2e est_time from CI
yueming-yuan Oct 9, 2026
bff62b7
Reject a draft whose MoE backends differ from the target's
yueming-yuan Oct 10, 2026
8de3a9e
Format
yueming-yuan Oct 10, 2026
4e65f80
Merge branch 'yueming/p2p-draft-replicas' into yueming/p2p-draft-runners
yueming-yuan Oct 10, 2026
9c932e3
Declare the MTP p2p e2e GPU count
yueming-yuan Oct 10, 2026
9e485e2
Merge branch 'yueming/p2p-draft-replicas' into yueming/p2p-draft-runners
yueming-yuan Oct 10, 2026
088fc53
Merge branch 'yueming/p2p-draft-replicas' into yueming/p2p-draft-runners
yueming-yuan Oct 12, 2026
04a7485
Merge branch 'yueming/p2p-draft-replicas' into yueming/p2p-draft-runners
yueming-yuan Oct 12, 2026
2c6bc54
Merge branch 'yueming/p2p-draft-replicas' into yueming/p2p-draft-runners
yueming-yuan Oct 12, 2026
ceecaab
Merge branch 'yueming/p2p-draft-replicas' into yueming/p2p-draft-runners
yueming-yuan Oct 12, 2026
cfbc3da
docs: a draft with its own MoE backends is rejected at connect
yueming-yuan Oct 12, 2026
4294fbc
Merge branch 'yueming/p2p-draft-replicas' into yueming/p2p-draft-runners
yueming-yuan Oct 12, 2026
5b37cb4
Merge branch 'yueming/p2p-draft-replicas' into yueming/p2p-draft-runners
yueming-yuan Oct 12, 2026
8b6b7ce
Merge branch 'yueming/p2p-draft-replicas' into yueming/p2p-draft-runners
yueming-yuan Oct 12, 2026
d223e22
Reject a runner that loads a target HF tensor into unshared params
yueming-yuan Oct 12, 2026
e5fa9d9
Write each HF tensor to every runner whose loader loads it
yueming-yuan Oct 12, 2026
ee00ab4
Fail the first sync when no rollout engine loads a tensor the trainer…
yueming-yuan Oct 12, 2026
a7dc6cc
Revert "Fail the first sync when no rollout engine loads a tensor the…
yueming-yuan Oct 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/advanced/p2p-weight-transfer.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ Both broadcast and P2P modes share the same bucketed weight-update pipeline in `
| **Rollout engine rank assignment** | `protocols/utils/rollout_engine_rank_assignment.py` | Decides which rollout engine ranks each training rank sends weights to, for the rollout engines the rollout manager passes in (`engine_gpu_counts`). Senders are the training ranks that hold the same weights: those of one PP stage, or all ranks when PP is gathered (Megatron Bridge). Every (rollout engine, rollout engine rank) gets exactly one sender. First every sender gets one, so all of them send in parallel; the rest go to a sender that already sends the same rollout engine rank, so it prepares those weights once and sends them to several rollout engines. |
| **Model replica** | `protocols/utils/model_replica.py` | An sglang model of the target rank's layout, built on `meta` with no parameter storage and brought, one module at a time on the GPU, to the state the engine loads updates into: its startup postprocess, then the restore every update session begins with. Its `weight_loader` functions re-shard all-gathered HF weights into the exact bytes the target rank expects, loaded into a transfer buffer. `ModelReplicas` keeps one replica per shard layout (the rank's parallelism and the sglang arguments that change its bytes and may differ between server groups, such as quantization and MoE and GEMM backends) for the whole trainer process, so a reconnect rebuilds only the connections to the new engines. Rollout engines whose expert placement a replica cannot reproduce (redundant experts, a non-trivial `init_expert_location`, EPLB, elastic EP, DWDP, KTransformers) are rejected at connect. |
| **Transfer buffers** | `protocols/utils/transfer_buffers.py` | Two pinned host buffers per sender, sized to the larger of `--update-weight-buffer-size` and the largest complete parameter group, including alignment. Parameters sharing HF inputs stay in one group. Buffers are registered once per trainer process and reused only after every write reading them has returned; a write that failed or is still running after `--p2p-transfer-timeout` fails the update there. |
| **Speculative draft** | `p2p.py`, `protocols/utils/model_replica.py` | With MTP training and same-model EAGLE, senders update both `target` and `draft` roles. Each runner receives every weight its own loader loads, as in the engine's own weight updates; a weight both loaders load into storage the draft shares with the target is written twice with the same bytes. Draft replicas use the engine's speculative MoE settings. Multi-layer EAGLE, separate draft checkpoints and a draft MoE runner or a2a backend other than the target's are rejected at connect, since sglang reloads a draft under the target's MoE backends. |
| **Pipelined transfer** | `p2p.py`, `protocols/transports/mooncake.py` | While the writes reading one transfer buffer are in flight, the sender loads the next group of parameters into the other. Each rollout engine has its own write thread, so a stuck engine delays only its own writes. The end of the update waits for the remaining writes and fails it if any failed or is still running after `--p2p-transfer-timeout`. |

The model replica runs the rollout engine's own sglang code in the trainer process: its model construction, startup postprocess and weight loaders. The trainer and the rollout engines therefore run the same sglang build, and their GPUs share an architecture: postprocess chooses kernels and layouts by architecture (TRT-LLM MoE layouts and UE8M0 scales on Blackwell, for example), so a replica on a Hopper trainer would lay out bytes for Hopper while Blackwell engines expect their own.
Expand Down
8 changes: 4 additions & 4 deletions miles/backends/sglang_utils/sglang_api_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,21 +136,21 @@ async def update_weights_from_tensor(
payload,
)

async def get_remote_instance_transfer_engine_info(self, rank: int):
async def get_remote_instance_transfer_engine_info(self, rank: int, role: str):
# TODO: will be changed to `remote_instance_transfer_engine_info` when the sglang side is ready.
response = await GeneralHttpClientProvider.client().get(
f"{self.server_url}/get_remote_instance_transfer_engine_info",
params={"rank": rank},
params={"rank": rank, "role": role},
headers=self._headers,
timeout=5.0,
)
response.raise_for_status()
return response.json()["remote_instance_transfer_engine_info"]

async def get_parallelism_info(self, rank: int):
async def get_parallelism_info(self, rank: int, role: str):
response = await GeneralHttpClientProvider.client().get(
f"{self.server_url}/parallelism_config",
params={"rank": rank},
params={"rank": rank, "role": role},
headers=self._headers,
timeout=5.0,
)
Expand Down
Loading
Loading