optim

1. 双口网卡问题

背景: 在 b300 上验证发现,8 gpu 配 16 个 400g nic 时,会出现 redispatch(mooncake 的 fault tolerance逻辑),而 pxn 我最开始假设为每个 gpu 用一个最近 pcie nic 来转发流量。当请求拿着tcp 传来的 target 的结构体后(preferred_hca字段内是 2 个 nic),pxn 认为对端只有一个和我是可以发的 故流量进来 不知道选本地哪个网卡发 出现错误。

增加双口网卡支持,确定 pfc 得到有效解决,commit: 71b641d0de3c98f3616ce6e731d60915e4056a0d ✅ 2026-08-29

2. 每个 transfer engine的 pxn worker 效率低

背景:第一版设计时,我们的一个 pxn worker 需要兼顾把上层任务下来拆分后,丢到 relay buffer 内,还有负责 relay buffer 内的任务再丢给 rdma 搬走,还有对应这俩任务的结束时间的 pollcq和 update completed等等控制面操作,且每次扫一遍每个 lane,对每个 lane 内的 18 个 slots 都推进一格消耗一格,这么操作导致的任务提交和消耗都很慢。

sender 侧改为 2 个线程分别下 cudaMemcpyBatchAsync、submitToRdma,以及 poll 任务从一次 poll 一个改为 poll 一堆。性能确定达到 97%原生 ✅ 2026-08-29

3. 分析瓶颈(97→100%)

在日志内增加 lane 内每个 slots 状态,确定当前瓶颈在下nvlink操作被 sglang 阻塞。具体原因为多个 batch 操作会被 reshard 到上层的一个线程内,导致并发的 batch—WriteSync 操作少,然后下nvlink操作的并行度大打折扣。 ✅ 2026-08-30

发现 sglang 内单 decode 的时候即使每个 engine 有多个 thread 下 batch put 的操作,但是多线程的 reshard 是分给多个 decode 的。所以我调整为一个 d 的时候也能用多个 thread 下 transfer 的请求。(这个收益是明确为正的)。

/root/sglang/python/sglang/srt/disaggregation/mooncake/conn.py

diff --git a/python/sglang/srt/disaggregation/mooncake/conn.py b/python/sglang/srt/disaggregation/mooncake/conn.py
index 66ac63b34c..f1ac2acfee 100644
--- a/python/sglang/srt/disaggregation/mooncake/conn.py
+++ b/python/sglang/srt/disaggregation/mooncake/conn.py
@@ -2166,12 +2166,7 @@ class MooncakeKVManager(CommonKVManager):
             # add further chunks into the transfer queue.
             return
 
-        # NOTE(shangming): sharding according to the dst_infos to make sure
-        # requests with the same dst_sessions will be added into the same
-        # queue, which enables early abort with failed sessions.
-        dst_infos = self.transfer_infos[bootstrap_room].keys()
-        session_port_sum = sum(int(session.rsplit(":", 1)[1]) for session in dst_infos)
-        shard_idx = session_port_sum % len(self.transfer_queues)
+        shard_idx = bootstrap_room % len(self.transfer_queues)
 
         if trace_ctx is None:
             trace_ctx = TraceNullContext()

/Users/joker/Desktop/project/baai/log-analysis/log/glm/pxn-ori/comparison_bar.png

4. 为什么原生的 mooncake 测试时候发现 rank0的流量会比别人多

因为GLM-5 是 MLA+DSA, sglang 侧 is_mla_backend=True:

  • KV latent 复制 ×8(每 prefill rank → 全部 8 个 decode rank);
  • DSA indexer state 只由 prefill CP rank0 发送(mooncake/conn.py:1216-1234),×8 份。

又因为我们的开了 MC_ENABLE_DEST_DEVICE_AFFINITY=1 同名匹配 → 这些流量在 decode 侧全部从同名的 mlx5_000/001 进入;

    def _get_dsa_cache_transfer_skip_flags(
        self, info: Optional[KVArgsRegisterInfo]
    ) -> Tuple[bool, bool]:
        skip_kv = False
        skip_state = False
 
        # Must be checked before the non-hybrid early return below, or every CP
        # rank re-sends the same state and we transfer it cp_size times over.
        # Prefill CP all-gathers before writing the pool, so every CP rank holds
        # the full state regardless of whether the pool is hybrid. We assume no
        # structure about the state rows, so we don't split them across CP ranks
        # -- just let rank 0 send the whole thing (unless layer split already
        # shards it per rank).
        if (
            self.attn_cp_size > 1
            and self.attn_cp_rank != 0
            and not get_parallel().enable_dsa_cache_layer_split
        ):
            skip_state = True
 
        if not self.is_hybrid_mla_backend:
            return skip_kv, skip_state
 
        if info is not None and self.attn_tp_size > info.dst_attn_tp_size:
            sub_rank = (self.kv_args.engine_rank % self.attn_tp_size) % (
                self.attn_tp_size // info.dst_attn_tp_size
            )
            if sub_rank != 0:
                skip_kv = True
                # Hybrid-MLA KV is replicated across these source ranks, but
                # TP-sharded state needs every rank for the aggregation path.
 
        return skip_kv, skip_state

5 分析瓶颈(>100%)

要想进一步提升收益,在统计了各种参数组合(开关rr,调整上层 batch put 的线程数及并发数等等)提升都是有限。从代码层面进一步猜测 1:sglang 的传输本身就是全都是小 size 导致我们 pxn 的缺点(时延)进一步放大进而全串行。

CHUNK1M PXN8M PXN512KBdirect
64KB2.712.542.1018.0
512KB10.810.611.5121.1
1MB15.415.011.8122.0
2MB16.721.7-22.1
4MB17.323.0-22.2
8MB17.723.712.1721.8
1k1k
[2026-09-01 05:27:49 ATTN_CP1 TP1] Mooncake batch_transfer_sync: src_addrs_count=11, total_bytes=9792 (0.01 MiB), avg_length=0.87 KiB, min_length=64, max_length=8192, lengths=(64, 64, 64, 64, 512, 512, 64, 128, 64, 8192, 64)
[2026-09-01 05:28:23 ATTN_CP5 TP5] Mooncake batch_transfer_sync: src_addrs_count=78, total_bytes=184025088 (175.50 MiB), avg_length=2304.00 KiB, min_length=2359296, max_length=2359296, lengths=(2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296, 2359296)

8k1k
[2026-09-01 05:28:46 ATTN_CP6 TP6] Mooncake batch_transfer_sync: src_addrs_count=11, total_bytes=9792 (0.01 MiB), avg_length=0.87 KiB, min_length=64, max_length=8192, lengths=(64, 64, 64, 64, 512, 512, 64, 128, 64, 8192, 64)
[2026-09-01 05:28:46 ATTN_CP0 TP0] Mooncake batch_transfer_sync: src_addrs_count=78, total_bytes=336720384 (321.12 MiB), avg_length=4215.75 KiB, min_length=4316928, max_length=4316928, lengths=(4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928, 4316928)

64k1k
[2026-09-01 05:31:50 ATTN_CP0 TP0] Mooncake batch_transfer_sync: src_addrs_count=11, total_bytes=9792 (0.01 MiB), avg_length=0.87 KiB, min_length=64, max_length=8192, lengths=(64, 64, 64, 64, 512, 512, 64, 128, 64, 8192, 64)
[2026-09-01 05:31:50 ATTN_CP0 TP0] Mooncake batch_transfer_sync: src_addrs_count=78, total_bytes=674758656 (643.50 MiB), avg_length=8448.00 KiB, min_length=8650752, max_length=8650752, lengths=(8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752, 8650752)