Prhub

#26862 Add random-ids dataset, round-robin expert simulation, and kill_process_tree logging

原始 PR 作者 merrymercy 合并时间 2026-06-01 11:50 文件变更 4 提交数 2 评论 1 代码增减 +59 / -9

执行摘要

添加 random-ids 数据集和轮询专家模拟

基准测试中,使用随机或虚拟权重时,MoE 的路由会引入专家负载不均衡,导致 benchmark 结果噪声大。通过确定性轮询分配专家,可以消除路由随机性,获得可重复的性能数据。此外,预生成 token ID 的数据集 random-ids 可避免 tokenization 开销,专注测试推理引擎本身。

值得关注,尤其是 MoE 基准测试流程的设计思路和确定性模拟的实现。

讨论亮点

PR 无实质性讨论,gemini-code-assist 机器人仅确认无 review 意见。

实现拆解

  1. environ.py 中添加 SGLANG_SIMULATE_ROUND_ROBIN_EXPERTS 环境变量,默认 False。
  2. topk.py 中新增 _make_round_robin_expert_ids 函数,根据 token 序号和 layer_id 进行轮询计算专家 ID,并处理 topk=0 边界。
  3. select_experts 中读取两个环境变量,若同时设置则抛出 ValueError;否则根据设置分别执行轮询或均匀模拟,并对均匀模拟增加了 k>0 守卫防止崩溃。
  4. common.pykill_process_tree 开头添加 logger.info 记录调用参数。
  5. bench_one_batch_server_internal.py 的 CLI 和数据集校验列表中加入 random-ids
文件 模块 状态 重要度
python/sglang/srt/layers/moe/topk.py MoE 路由 modified 7.18
python/sglang/srt/environ.py 环境配置 modified 4.55
python/sglang/srt/utils/common.py 工具函数 modified 4.92
python/sglang/test/bench_one_batch_server_internal.py 基准测试 modified 3.95

关键符号

_make_round_robin_expert_ids select_experts kill_process_tree

关键源码片段

python/sglang/srt/layers/moe/topk.py core-logic

核心变更:新增轮询专家 ID 生成函数,重构 uniform 模拟,添加互斥检查

# 注:以下代码位于 python/sglang/srt/layers/moe/topk.pydef _make_round_robin_expert_ids(
    num_tokens: int,
    topk: int,
    num_experts: int,
    *,
    device: torch.device,
    dtype: torch.dtype,
    layer_id: Optional[int] = None,
) -> torch.Tensor:
    """生成轮询专家 ID,使每个 token 按顺序分配不同专家,避免路由随机性。    当 topk == 0 时返回空张量,防止后续运算崩溃。
    """
    if topk == 0:
        return torch.empty((num_tokens, 0), device=device, dtype=dtype)
​
    step = max(num_experts // topk, 1) # 每步跳过 expert 数,确保均匀分布
    layer_offset = 0 if layer_id is None else layer_id # 不同层引入偏移,避免层间对齐
    offsets = torch.arange(num_tokens, device=device, dtype=dtype).unsqueeze(1) # token 行索引
    steps = torch.arange(topk, device=device, dtype=dtype).unsqueeze(0) * step # topk 列步长
    return (offsets + layer_offset + steps) % num_experts
​
​
def select_experts(...):
    # ... 省略前面路由逻辑 ...
​
    # 读取环境变量并做互斥检查
    simulate_uniform_experts = envs.SGLANG_SIMULATE_UNIFORM_EXPERTS.get()
    simulate_round_robin_experts = envs.SGLANG_SIMULATE_ROUND_ROBIN_EXPERTS.get()
    if simulate_uniform_experts and simulate_round_robin_experts:
        raise ValueError(
            "SGLANG_SIMULATE_UNIFORM_EXPERTS and "
            "SGLANG_SIMULATE_ROUND_ROBIN_EXPERTS are mutually exclusive"
        )
​
    if simulate_uniform_experts:
        # 均匀模拟:为每个 token 随机设置起始偏移,然后按步长取专家
        num_tokens, k = topk_ids.shape
        num_experts = router_logits.shape[1]
        if k > 0: # 防止 topk_ids 为空时除零
            offsets = torch.randint(
                0, num_experts, (num_tokens, 1), device=topk_ids.device
            )
            steps = torch.arange(k, device=topk_ids.device).unsqueeze(0)
            step = max(num_experts // k, 1)
            topk_ids = ((offsets + steps * step) % num_experts).to(topk_ids.dtype)
            topk_weights = torch.ones_like(topk_weights) / k
    elif simulate_round_robin_experts:
        # 轮询模拟:基于 token 和 layer 确定性分配专家
        num_tokens, k = topk_ids.shape
        num_experts = router_logits.shape[1]
        topk_ids = _make_round_robin_expert_ids(
            num_tokens, k, num_experts,
            device=topk_ids.device, dtype=topk_ids.dtype, layer_id=layer_id,
        )
        if k > 0:
            topk_weights = torch.full_like(topk_weights, 1.0 / k)
​
    # ... 后续处理 ...

评论区精华

没有提炼出高价值讨论线程

当前评论区没有形成足够清晰的争议点或结论,后续有更多讨论时会体现在这里。

风险与影响

新增环境变量若与现有配置冲突可能引发 ValueError,但已做互斥检查;轮询模拟仅用于 benchmark,不影响生产;kill_process_tree 日志不会造成问题。

影响范围小,主要影响 MoE 基准测试用户;可复现性提升;日志有助于调试进程清理问题。

互斥环境变量需同时设置 k=0 边界已修复 仅用于 benchmark 不影响生产

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论