已关闭
[Bug]: SGLang 多 DP 场景下 L1 KV 亲和不生效 #672
chaofengdev创建于  20 天前关闭于  4 天前
chaofengdev
chaofengdev
20 天前 创建

在提交新问题之前,请确保您已经在社区中搜索过相关问题,并使用了社区中提供的资源/工具后,仍未找到满意的解决方式。

⚠️ 安全信息提醒:本文已脱敏,不含令牌、密码、私有地址或集群账号。

环境信息

  • 操作系统:Ubuntu 22.04(aarch64)
  • 昇腾硬件:800I A3
  • CANN 软件版本:CANN 9.1.0 B070
  • 推理引擎:SGLang(MindIE-Motor 集成,镜像 mindie-motor-sglang nightly + CANN 9.1.0 B070 / Python 3.12)
  • Motor:3.1.0
  • 模型:DeepSeek-V4-Flash(DSV4,page-size=128,attention-backend=dsv4)
  • 部署:2P1D PD 分离,dp-size=16,enable-dp-attention=true,enable_multi_endpoints=false(每 P 实例仅 1 个 HTTP)
  • 调度:scheduler_type=kv_cache_affinity,kv_affinity.mode=unified,w_npu=1.0
  • KV 事件:P 开启 kv-events-config(ZMQ publisher,endpoint=tcp://*:5557,replay_endpoint=tcp://*:6667),kv_conductor_config.block_size=128,engine_type=sglang

🐛 问题描述

SGLang 在官方 launch_server --dp-size 下是 单 HTTP + 进程内 DataParallelController,每个 DP 单独发 ZMQ KV 事件(5557+rank)。Motor 原 KV 亲和实现按 vLLM 多 HTTP(1 HTTP = 1 DP) 假设工作:

  1. Coordinator 只按实例上的 HTTP endpoint 向 kv-conductor 注册 ZMQ,单 HTTP 时只订到 DP0。
  2. 查询命中后按 endpoint.id 取 DP["0"],DP>0 上的 L1 前缀对调度不可见。
  3. Coordinator 镜像无 vLLM 时,DSV4 tokenizer 加载失败,token_ids 为空,conductor 查询永远 miss。
  4. 注册 medium_endpoints 时把引擎 ZMQ 同时填到 cpu/disk,conductor 会把该流当成 pool,引擎侧 L1 BlockStored(medium=GPU) 进不了 HBM 树。

结果:配置已开 kv_cache_affinity,重复相同长前缀仍经常 matched=None 并回退 load_balance,L1 亲和不生效。

期望: 同一长前缀第二次及以后,conductor 返回 npu_blocks>0,调度 policy=kv_cache_affinity,打到已有 L1 的 P 实例。

实际(修复前): 冷请求 policy=load_balance matched=None;热请求仍可能 miss(只看到 DP0,或 tokenize 失败)。

复现步骤

  1. 按上述并行度拉起 2P1D,P 打开 kv-events-config,Coordinator scheduler_type=kv_cache_affinity。
  2. POST /v1/completions,同一长 prompt(约 4k~6k token)连打 2 次,max_tokens 取小值即可。
  3. 看 Coordinator 日志:conductor query response、scheduled role=prefill ... policy=。

修复前第二次仍常见:

conductor query response: {'default': {}}
scheduled role=prefill ... policy=load_balance matched=None

修复说明(已合入)

仅修 L1(HBM)亲和,不包含 L2/HiCache:

  • conductor_api_client:单 HTTP 时按 parallel_config.dp_size 展开 ZMQ(5557+rank / 6667+rank)。
  • medium_endpoints 默认只报 npu,引擎口按 EventSource::Engine 订阅,避免 L1 事件被当成 pool。
  • kv_cache_affinity:实例只有 1 个 HTTP 时,对 conductor 返回的各 DP 取最长命中再打分(fold_engine_dps)。
  • Tokenizer:DSV4 在无 vLLM DeepseekV4Tokenizer 时回退 AutoTokenizer;/v1/completions 用 encode(prompt) 即可对齐 block hash。

修复后同一前缀第二次可见:

conductor query response: {..., 'npu_blocks': 20, 'cpu_blocks': 0, ...}
scheduled role=prefill ... policy=kv_cache_affinity matched=2560 hbm=2560

热路径端到端约从 ~9s 降到 ~2s(与前缀长度、是否落到已缓存 DP 有关)。SGLang 实例内仍是 round_robin,亲和只能选到 P 实例,不能钉到具体 DP。

已知非本问题范围

  • L2(HiCache / CPU_PINNED):write_through 下 exclusive 分区会把 cpu_blocks 扣成 0;PD 释放 HBM 时引擎常不发 BlockRemoved medium=GPU,线上 L2 计分当前不可用。相关改动已回退,不在本 issue 修复范围。
  • 未改 dp-size,未把 SGLang 拆成每 DP 一个 HTTP(社区 launch_server 限制)。

欢迎加入社区,感谢您对社区的贡献 🎉

likedislike
ascend-robotascend-robot成员
20 天前 添加了label:bug
chaofengdevchaofengdev
20 天前 修改标题为 “[Bug]: SGLang 多 DP 场景下 L1 KV 亲和不生效”,原标题为“[Bug]: 111”
chaofengdevchaofengdev
20 天前 修改了issue 的描述
chaofengdevchaofengdev
20 天前 关联了pull request:[fix] 修复 SGLang 单端口多 DP 时 KV 亲和选不到已缓存实例的问题
chaofengdevchaofengdev
20 天前 关联了pull request:[fix] 修复 SGLang 单端口多 DP 时 KV 亲和选不到已缓存实例的问题
wangyang
wangyang成员
19 天前 评论:

👋 您好,感谢向 mindie-motor 提交 Issue!
🎉 我们已收到您的反馈,感谢你对开源社区的支持!

📅 处理时效 维护团队将在工作日 24 小时内查看并回复您的问题。
🔍 自助排查(推荐优先查看) 在等待回复期间,您可以先查阅仓库README以及历史 Issue 中相似问题的解决方案,多数问题可快速解决。
💡 为了更快定位问题,请您确保 Issue 包含:

清晰的问题描述
可复现的操作步骤
相关日志、截图或环境信息
我们会尽快跟进,感谢您的理解与配合!

likedislike
chaofengdevchaofengdev
4 天前 issue状态由 TODO 改变为 DONE
chaofengdevchaofengdev
4 天前 关闭了 issue
ascend-robotascend-robot成员
4 天前 添加了label:resolved