已合并
[fix] 修复 SGLang 单端口多 DP 时 KV 亲和选不到已缓存实例的问题 #1036
chaofengdev创建于 20 天前
[fix] 修复 SGLang 单端口多 DP 时 KV 亲和选不到已缓存实例的问题 #1036
已合并
Pull Request已成功合入, 合并人@tobking
(感谢 chaofengdev 的贡献)20 天前 创建了 pull request,commit b4e95630
20 天前 关联了issue:[Bug]: SGLang 多 DP 场景下 L1 KV 亲和不生效
atomgit-bot
20 天前 评论:
20 天前 评论:
变更摘要
本 PR 修复 SGLang 在单 HTTP 端口、enable_multi_endpoints=false、dp-size>1 拓扑下 KV 亲和无法选中已缓存实例的问题,聚焦 L1(HBM)亲和。核心思路是让 Coordinator 在「订阅、查询、选实例」三处按 SGLang 拓扑对齐引擎的 DP 数量:在 conductor_api_client 中按 dp_size 展开 ZMQ 订阅,在 kv_cache_affinity 中把单 HTTP 下各 DP 的命中折叠到唯一可路由端点,并让 TokenizerManager 在 SGLang 引擎下也能算出与引擎一致的 token。
主要改动
- 按
dp_size展开 ZMQ 订阅: 新增_instance_dp_size与_hbm_event_targets,当实例只有 1 个 HTTP 但parallel_config.dp_size>1时,用同一 IP 为 rank0..dp_size-1注册5557+rank/6667+rank,register_post/unregister_post/_build_register_payload及 YuanRong 节点注册均改为接收dp_rank,使各 DP 的 L1 事件都能进入 kv-conductor。 medium_endpoints默认只报npu:_build_medium_endpoints不再把通用endpoint回退值抄到cpu/disk,仅在显式配置cpu_endpoint/disk_endpoint时才包含对应项,避免引擎 ZMQ 被当作 pool 流而丢弃 GPUBlockStored事件。- 单 HTTP 时折叠各 DP 命中:
kv_cache_affinity新增_matched_raw_for_endpoint,当get_all_endpoints()长度为 1 时对所有 conductor 上报的 DP 取加权最长命中再为该 HTTP 打分,多 endpoint 实例仍按endpoint.id对齐。 - DSV4 tokenizer 引擎无关化与回退:
TokenizerManager不再要求engine_type=="vllm"才加载DeepseekV4Tokenizer,导入失败时回退到AutoTokenizer;chat 且无chat_template时通过新增的_encode_dsv4_messages手拼 DSV4 marker(_DSV4_USER_MARKER/_DSV4_ASSISTANT_MARKER/_DSV4_EOS_MARKER)。 - 单测覆盖: 新增/更新用例覆盖单 HTTP 展开多 DP 注册、npu-only medium map、单口折叠命中与 DSV4 tokenizer 回退等场景。


不准确?
atomgit-bot
20 天前 评论:
20 天前 评论:
20 天前 添加了label:ascend-cla/yes
此处折叠了87条消息 查看更多
tobking
19 天前 评论:
19 天前 评论:
/approve


19 天前 添加了label:approvedlgtm
19 天前 解决了最后一个问题
高鹏
19 天前 评论:
19 天前 评论:
/lgtm


19 天前 合入了pull request
1. 合入背景
Motor KV 亲和原先按 vLLM 的「一个 HTTP endpoint 对应一个 DP」来注册和打分。SGLang 官方
launch_server --dp-size是 一个 Tokenizer HTTP + 进程内 DataParallelController,每个 DP 单独发 ZMQ KV 事件(5557+rank)。在 SGLang 2P1D、
dp-size=16、enable_multi_endpoints=false下会出现:endpoint.id=0,DP>0 上的前缀对调度不可见,热请求回退load_balance。token_ids为空,query 永远 miss。BlockStored进不了 HBM 树。本 PR 只修 L1(HBM)亲和,让 SGLang 单 HTTP 多 DP 能按实例选到有缓存的 P。不包含 L2/HiCache。
Fixes:#672
2. 修改内容
交互链不变:引擎 ZMQ 发 BlockStored → kv-conductor 建 HBM 树 → Coordinator tokenize 后
/query→kv_cache_affinity给 P 实例打分 → 转发到该实例唯一 HTTP。本 PR 补的是 SGLang 拓扑下「订全、查对、选到实例」三处。conductor_api_client:按dp_size展开 ZMQ 订阅新增
_hbm_event_targets。实例只有 1 个 HTTP、但parallel_config.dp_size>1时,用同一 IP 为 rank0..dp_size-1注册5557+rank/6667+rank。vLLM 多 HTTP(endpoint 数 ≥ dp_size)仍走原来的 1:1。medium_endpoints默认只报npu不再把引擎口抄到 cpu/disk。未显式配置 pool 口时,subscriber 是
EventSource::Engine,L1BlockStored(medium=GPU)能进 HBM 树。YuanRong 等显式配了 cpu/disk 的路径不变。kv_cache_affinity:单 HTTP 时折叠各 DP 命中新增
_matched_raw_for_endpoint。get_all_endpoints()长度为 1 时,对 conductor 返回的所有 DP 取加权最长命中,再给这个 HTTP 打分。多 endpoint 实例仍按endpoint.id对齐。Tokenizer:SGLang + DSV4 能算出和引擎一致的 token
DSV4 不再要求
engine_type=="vllm"才加载;无DeepseekV4Tokenizer时回退AutoTokenizer。/v1/completions走encode(prompt)。chat 且无chat_template时用手拼 DSV4 marker 的_encode_dsv4_messages。单测
覆盖单 HTTP 展开多 DP 注册、npu-only medium map、单口折叠命中、DSV4 tokenizer 回退。
3. 资料变更
不涉及。调度配置项(
scheduler_type=kv_cache_affinity、kv_affinity、kv-events-config)沿用现有文档,无新增用户参数。4. 接口变更
不涉及。无跨仓协议变更,无客户面 REST/ZMQ 字段变更。kv-conductor
/register、/query语义不变,仅 Coordinator 注册的 DP 数量和打分时读取的 DP 集合按 SGLang 拓扑对齐。5. 测试结果
场景: 800I A3,CANN 9.1.0 B070,MindIE-Motor SGLang nightly,DeepSeek-V4-Flash,2P1D,
dp-size=16,DPA,单 HTTP,block_size=128。方法: 同一长前缀(约 4k~6k token)
POST /v1/completions连打;看 Coordinatorconductor query response与scheduled role=prefill policy=。功能验证:
冷启动第一次 miss,回退负载均衡:
第二次起开始命中:
性能验证:
6. CheckList
PR提交人对以下CheckList自检项进行全量自检,自检通过或不涉及,均修改 [ ] 为 [x]
[x] 代码注释完备
[x] 正确记录维测日志
[x] 是否有UT用例
[x] 若涉及多线程场景,考虑了并发场景,不存在死锁问题