sglang中的多进程tokenizer
相关 PR:
¶问题发现:
使用 9 机 72 卡 H100 跑 deepseek 时,在测试 decode 吞吐上限,发现在服务端日志看单卡吞吐达到了 2000 tps,然而测试客户端的结果无论是 ttft,tpot,还是吞吐。都差的很多。
一定是 python 的问题:
- http server 是 fastapi,如果输入很多,数据很大,这个 python 的 httpserver 会成为瓶颈,就算是换成 sanic 也不行。
- 测试脚本也是 python 的,既要发请求,又要持续收 stream,还要计时还要统计结果。
通过研究代码,发现可能是输出的 tps 太高了 ,只有一个 Detokenizer 根本处理不过来。经过计时,Detokenizer 处理一个需要 50~100us。如果 1s 内有 144000 个 token,需要 Detokenizer 达到 7us 内才行
graph TD subgraph 客户端 Client[Client] end subgraph Web服务器 HttpServer[HTTP Server] Tokenizer[Tokenizer] HttpServer -- 函数调用 --> Tokenizer end subgraph GPU集群 subgraph GPU1 Scheduler1[Scheduler] Worker1[Worker] Scheduler1 --> Worker1 end subgraph GPU2 Scheduler2[Scheduler] Worker2[Worker] Scheduler2 --> Worker2 end subgraph GPU3 Scheduler3[Scheduler] Worker3[Worker] Scheduler3 --> Worker3 end subgraph GPU4 Scheduler4[Scheduler] Worker4[Worker] Scheduler4 --> Worker4 end end subgraph 结果处理 Detokenizer[Detokenizer] end Client -->|HTTP请求| HttpServer Tokenizer -->|ZMQ请求| Scheduler1 Tokenizer -->|ZMQ请求| Scheduler2 Tokenizer -->|ZMQ请求| Scheduler3 Tokenizer -->|ZMQ请求| Scheduler4 Worker1 -->|ZMQ结果| Detokenizer Worker2 -->|ZMQ结果| Detokenizer Worker3 -->|ZMQ结果| Detokenizer Worker4 -->|ZMQ结果| Detokenizer Detokenizer -->|ZMQ返回| Tokenizer HttpServer -->|HTTP响应| Client style Detokenizer stroke:#f66,stroke-width:2px
现在问题很明确了:
- 把 detokenizer 改成多进程
- 测试脚本也改用多进程
¶sglang 这个 PR 怎么做的
全都多进程,不然任何一个“多对一”的地方都可能成为瓶颈
单机多进程使用 shm 通信,MultiTokenizerRegisterReq 维护每个 rid 从哪个 tokenizer 进来的再从哪里出去
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 JMY Space!