Example: SGLang 1P2D (PD-disaggregated) — Kimi-K2.6-MXFP4 on MI355X#
A PD-disaggregated SGLang deployment for amd/Kimi-K2.6-MXFP4 on AMD MI355X:
one prefill worker feeding two decode workers (1P2D), fronted by
the Infera router, with the KV cache moved over Mooncake RDMA, then
throughput-swept end to end.
The runnable scripts for this example live in the repo under
examples/sglang_1p2d_kimi2.6/.
This page is the short overview; the
README.md
in that directory is the authoritative, copy-paste step-by-step guide. Every
script is driven by environment variables and needs no editing.
The package covers two tests — run the single-node one first:
SGLang single-node — sanity-check that
Kimi-K2.6-MXFP4starts and serves on one 4-GPU SGLang instance.Infera router + SGLang PD (1P2D) — the real multi-node target.
For the concepts behind PD, read PD disaggregation first.
PD only pays off over real RDMA
Cross-node PD moves the KV cache over the fabric on every request. It’s a win
only on an RDMA fabric (ionic RoCEv2 here) — over TCP it is slower than a single
node. The container’s ionic provider must match the host driver, or KV transfer
silently falls back to TCP. So run preflight_rdma.sh on every PD node before
the bring-up and confirm the visible port count equals the node’s active ports (not
0) — see §3 of the
README.md.
Topology (1P2D)#
1P2D = 1 prefill + 2 decodes, spread over three nodes (8× MI355X each):
Node |
Role |
|---|---|
|
etcd + Infera router + prefill + verify + benchmark entrypoint |
|
decode-0 |
|
decode-1 |
The tuned recipe#
Both PD legs share the aiter attention backend, fp8 KV, DP-attention, and
Mooncake KV transfer. They differ mainly by GPU count and --disaggregation-mode:
leg |
GPUs |
parallelism |
mem-fraction |
key flags |
|---|---|---|---|---|
prefill |
4 (TP4) |
|
|
|
decode |
8 (TP8) |
|
|
|
Shared by both: --attention-backend aiter --kv-cache-dtype fp8_e4m3 --trust-remote-code --no-enable-kv-events --disaggregation-transfer-backend mooncake, plus env MC_GID_INDEX=1 SGLANG_USE_AITER=1.
Prerequisites#
Hardware: 3 nodes, 8× MI355X each (ROCm 7.2.0), Docker with GPU access. node-0 prefill uses 4 GPUs; each decode node uses all 8.
Model:
amd/Kimi-K2.6-MXFP4(~550B, license modified-mit, NOT gated).Image:
rocm/infera:sglang-v0.1.1.
Download the model to a local directory (it is bind-mounted read-only) and
point MODEL at it. Benchmarking needs a local clone of InferenceX (IX). Full
details, including the model download and the “adapt to your cluster” env vars, are
in §1 Prerequisites / §2 Adapt to your cluster of the
README.md.
Scripts#
All scripts are in
examples/sglang_1p2d_kimi2.6/:
Script |
Purpose |
|---|---|
|
Single-node SGLang server, default 4 GPUs / TP4. |
|
RDMA preflight: container port visibility + (optional) cross-node fabric check. |
|
Start etcd (PD shared registry). |
|
Start the Infera router/server (PD). |
|
SGLang prefill leg, default 4 GPUs / TP4 / DP4. |
|
SGLang decode leg, default 8 GPUs / TP8 / DP8 / EP1. |
|
Smoke-test the router (workers + chat). |
|
Benchmark via InferenceX. |
Run#
Export the shared vars (MODEL, IX, DATA_NET, IMAGE) on every node, then run in this order:
single-node: engine -> verify -> benchmark
1P2D: preflight -> etcd -> server -> prefill -> decode -> verify -> benchmark
Single-node (any 4-GPU MI355X):
IMAGE=rocm/infera:sglang-v0.1.1 \
MODEL=/your/path/Kimi-K2.6-MXFP4 bash sglang_naive_engine.sh
1P2D — first run the RDMA preflight on each PD node (the reported port count
must equal the node’s active ports, not 0):
bash preflight_rdma.sh
Then, on node-0 (example data-net IP 10.0.0.1):
bash infera_0_etcd.sh
ETCD_ENDPOINT=10.0.0.1:2379 bash infera_1_server.sh
ETCD_ENDPOINT=10.0.0.1:2379 bash infera_2_sglang_prefill.sh
On node-1 and node-2 (ETCD_ENDPOINT must point at node-0):
ETCD_ENDPOINT=10.0.0.1:2379 bash infera_3_sglang_decode.sh
Verify through the router (bash curl.sh) — expect 1 prefill + 2 decodes plus
a coherent completion — then sweep concurrency with bench_inferencex.sh (we swept
32→2048 for 1P2D). See §4 Run in the
README.md
for the exact commands, verify/benchmark details, and how to stop the services.
Notes & gotchas#
Infera router auto-pairs; no static worker list.
infera.serverwatches etcd and shapes each request to the 1P2D group — one server,--router-policy round-robin.Advertise the data-network IP.
--advertise-host(andSGLANG_HOST_IP/HOST_IP) must be each node’s data-net IP the peers can reach, not the public NIC.RDMA passthrough on the PD legs.
--device=/dev/infiniband,--cap-add=IPC_LOCK,MC_GID_INDEX=1, and the hostlibionic.sobind-mount keep the container’s RDMA provider aligned with the host driver — otherwise KV transfer silently degrades to TCP. Run the preflight checks first.Attention backend is
aiterfor both single-node and PD on this image.
The full gotchas list (cold-start behaviour, --no-enable-kv-events rationale, the
decode-leg MoRI env) is in Notes & gotchas of the
README.md.