首页 / 资讯中心 / 文章详情

GPUStack Day 0 支持 Kimi-K3:8×B300 上 vLLM 与 SGLang 推理实测与 TaoToken 统一 Key 接入

GPUStack Day 0 支持 Kimi-K3:8×B300 上 vLLM 与 SGLang 推理实测与 TaoToken 统一 Key 接入 ★ FEATURED ARTICLE
1. 8×B300 跑 Kimi-K3 的真实痛点为什么 Day 0 支持值得单独写一篇Kimi-K3 是面向复杂推理与长上下文任务的 MoE 模型单机 8×NVIDIA B300 是当前比较现实的高密度推理平台。GPUStack 在 Kimi-K3 发布当天就提供了 Day 0 支持意味着你不需要自己写一堆容器编排脚本就能在 GPUStack 里把 vLLM 和 SGLang 两套推理后端分别拉起来做对比。这篇文章要解决的问题很具体在 8×B300 上Kimi-K3 用 vLLM 还是 SGLang64K 和 200K 上下文下谁更快显存怎么分首 token 延迟怎么测才准以及怎么用 TaoToken 的统一 Key 把鉴权和压测验证串起来。适合谁看手里有 8 卡 B300 或类似高显存节点、正在做长上下文推理选型的工程师已经在用 GPUStack 管集群、想加自定义推理后端的运维以及需要给团队一个可复制压测流程的技术负责人。如果你只是想在单卡上跑个小模型这篇的配置对你偏重但排障思路和 TTFT 口径那部分仍然值得看。我试过把两套引擎放在同一台机器上轮流压最大的感受是真正拉开差距的不是 Prefill而是长上下文 Decode 阶段的 KV 读取方式。64K 输入、10 路并发下 vLLM 端到端 100.5 秒SGLang 150.8 秒vLLM 领先约 1.5 倍到了 200K 输入、10 路并发SGLang 225.3 秒反超 vLLM 的 295.2 秒领先约 1.31 倍。这个交叉点不是调参能绕开的后面会从源码层面解释为什么。需要先说明这不是严格对等的 A/B 测试。两套引擎在 DCP、显存分配、算子后端、接受判据上都有差异。本文更适合用来理解瓶颈和选型方向不要当成最终性能排名。测试环境是单机 8×B300单卡可见显存 267.69 GiB模型 Kimi-K3MXFP4草稿模型 Kimi-K3-DSpark输入 64K 和 200K输出 3K并发 10数据集 Random。2. TaoToken 统一 Key 前置把鉴权和 API 通道先理清楚在开始压测之前先把 API 通道准备好。TaoToken 提供统一的 Key 和 API 入口官网是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 地址是 https://taotoken.net/api 。它的作用是让你用一套 Key 去访问不同模型和推理服务省得每个后端都单独配鉴权。对于这次压测你可以把 GPUStack 里起来的 vLLM 和 SGLang 服务通过 TaoToken 的通道统一暴露压测脚本只认一个 Base URL 和一个 Key。具体操作路径先到模型对话页面确认你要用的模型 ID 能正常对话地址是 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 。然后去 API Keys 页面生成一个 Key地址是 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 。生成后复制保存后面配置里会用到。如果你打算长期跑编码或 Agent 任务可以看 Coding Plan 页面 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 按需选择。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里面有完整的请求格式说明。控制台在 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 可以看调用量和余额。如果你用 Claude Code 做开发Anthropic 兼容入口在 https://taotoken.net/claude-code-anthropic?utm_sourcetaotoken_aicg_blog_endutm_contentclaude_code_anthropicutm_campaignrewrite 。这里要强调一个配置三件套的概念不管你是接 Cline、Codex 还是 Claude Code只要涉及自定义后端就必须同时写全 Base URL、Key、Model ID 三个字段。少一个就会报 401 或者 model not found。下面给一个通用的 settings 片段示例路径按你实际工具调整{ base_url: https://taotoken.net/api, api_key: sk-你的TaoTokenKey, model: kimi-k3, timeout: 600 }如果你用的是 Codex 的 auth.json格式类似{ base_url: https://taotoken.net/api, api_key: sk-你的TaoTokenKey, model: kimi-k3 }注意不要把 Key 硬编码进公开仓库。压测脚本里建议用环境变量读取export TAOTOKEN_BASE_URLhttps://taotoken.net/api export TAOTOKEN_API_KEYsk-你的TaoTokenKey export TAOTOKEN_MODELkimi-k3这样后面无论切 vLLM 还是 SGLang客户端只改一个指向就行。TaoToken 在这里的角色是统一入口不是替代你的推理引擎GPUStack 负责调度和部署TaoToken 负责鉴权和通道。3. 可复制配置GPUStack 部署 vLLM 与 SGLang 的完整参数这一节是全文技术含量最高的部分所有参数都可以直接复制。先准备模型权重用 ModelScope 下载# 下载 Kimi-K3 主模型MXFP4 modelscope download \ --model moonshotai/Kimi-K3 \ --local_dir ./Kimi-K3 # 下载 vLLM 使用的 DSpark 草稿模型 modelscope download \ --model skyai/Kimi-K3-DSpark \ --local_dir ./Kimi-K3-DSpark # 下载 SGLang 使用的 DSpark 草稿模型 modelscope download \ --model skyai/sglang-Kimi-K3-DSpark \ --local_dir ./Kimi-K3-DSpark拉取推理镜像docker pull vllm/vllm-openai:kimi-k3 docker pull lmsysorg/sglang:kimi-k3镜像准备好后在 GPUStack 的推理后端里分别为 vLLM 和 SGLang 添加自定义版本。3.1 vLLM 自定义后端配置在 GPUStack 中创建 vLLM 自定义后端选择 Kimi-K3 模型、8 张 B300。环境变量如下VLLM_ENABLE_K3_LATENT_MOE_TAIL_FUSION1 VLLM_ALLREDUCE_USE_FLASHINFER1 VLLM_ENGINE_READY_TIMEOUT_S3600 VLLM_USE_V2_MODEL_RUNNER1 VLLM_USE_RUST_FRONTEND1启动参数--trust-remote-code --load-format fastsafetensors --moe-backend auto --gpu-memory-utilization 0.95 --tensor-parallel-size 8 --max-model-len 1000000 --kv-cache-dtype fp8 --attention-config {mla_prefill_backend:TRTLLM_RAGGED,use_prefill_query_quantization:true} --max-num-batched-tokens 32768 --enable-prefix-caching --enable-auto-tool-choice --tool-call-parser kimi_k3 --reasoning-parser kimi_k3 --max-num-seqs 32 --speculative-config {model:Inferact/Kimi-K3-DSpark,num_speculative_tokens:7,method:dspark,attention_backend:FLASHINFER_MLA,draft_sample_method:probabilistic,rejection_sample_method:block}这里有个坑要提前说--gpu-memory-utilization 0.95在本轮测试中导致 KV 池超额提交触发运行期 OOM 重试。日志提示若要真正落入 0.95 预算KV Cache 应降到 38.48 GiB而实际分配了 43.76 GiB。修正方式二选一# 方案一降低显存利用率 --gpu-memory-utilization 0.92 # 方案二显式限制 KV Cache --kv-cache-memory 413178854403.2 SGLang 自定义后端配置同样创建 SGLang 自定义后端选择 8 张 B300。启动参数--trust-remote-code --model-path Kimi-K3 模型路径 --tp-size 8 --dcp-size 8 --disable-custom-all-reduce --enable-symm-mem --mem-fraction-static 0.85 --reasoning-parser kimi_k3 --tool-call-parser kimi_k3 --mamba-full-memory-ratio 0.86 --host 0.0.0.0 --port 30000 --speculative-algorithm DSPARK --speculative-draft-model-path Kimi-K3-DSpark 模型路径 --speculative-dspark-block-size 7 --enable-linear-replayssm-spec --chunked-prefill-size 32768 --max-prefill-tokens 32768 --context-length 1000000 --kv-cache-dtype fp8_e4m3SGLang 这边要注意当前配置声明context-length1000000但全注意力池只有 916,672 token比目标上下文少约 8.3%。单条满 1M 请求无法完整放入 KV 池。同时max_running_requests从 48 被压缩到 39瓶颈来自 Mamba 状态缓存不是普通 KV Cache。如果要跑满 1M 高并发需要抬高--mamba-full-memory-ratio或改用 bf16 SSM并抬高 KV 池。服务启动后在 GPUStack 里可以看实时日志、吞吐和 KV Cache 状态。两套引擎总冷启动都在 10 分钟左右vLLM 约 10.6 分钟SGLang 约 10.2 分钟。vLLM 主要耗时在 profile、KV 分配和 warmup约 409.6 秒SGLang 主要在 CUDA Graph 捕获约 5.5 分钟。频繁扩缩容的话要把冷启动纳入容量规划。4. 验证请求与成功结果压测脚本、TTFT 口径与核心数据配置跑起来后先用一个简单请求确认服务可用。通过 TaoToken 通道发请求curl -s ${TAOTOKEN_BASE_URL}/v1/chat/completions \ -H Authorization: Bearer ${TAOTOKEN_API_KEY} \ -H Content-Type: application/json \ -d { model: ${TAOTOKEN_MODEL}, messages: [{role: user, content: 用一句话解释 MoE 模型}], max_tokens: 64, stream: true }如果返回正常说明鉴权和通道没问题。接下来做正式压测。64K 输入、3K 输出、10 路并发的核心结果场景vLLMSGLang结果64K 端到端耗时100.5 s150.8 svLLM 领先约 1.5×200K 端到端耗时295.2 s225.3 sSGLang 领先约 1.31×64K 稳定解码吞吐约 501 tok/s约 335 tok/svLLM 领先约 1.5×200K 稳定解码吞吐约 163 tok/s约 268 tok/sSGLang 领先约 1.64×64K→200K 解码退化3.29×1.25×SGLang 扩展性更好一句话解释vLLM 在较短上下文中没有 DCP 通信开销所以更快上下文增长后SGLang 的 DCP8 把每张卡需要读取的 KV 数据量大幅分摊长上下文 Decode 反而更有优势。但这不是vLLM 忘了开 DCP那么简单。读源码会发现vLLM 在config/speculative.py:978-986明确禁止 DCP 与 DSPARK 投机解码共存decode_context_parallel_size 1遇到 K3DSparkModel 会直接抛异常。想要 DCP 就必须放弃投机。SGLang 允许二者共存代价是dcp_size 1会强制设置SGLANG_RAGGED_VERIFY_MODEstaticDSPARK 的 SPS 成本表、STS 温度校准、置信度 planner 全部失效每个请求验证完整 8-token 窗口。这是架构层取舍不是配置疏漏。TTFT 口径必须统一。启用--reasoning-parser kimi_k3后思维链输出在delta.reasoning不在delta.content。如果压测工具只从delta.content算首 token两套引擎的 TTFT 都会被系统性抬高。更合理的口径是 time-to-first-any-delta收到第一个 reasoning 或 content 增量就停止计时。客户端指标里有些吞吐字段不可信。vLLM 200K 显示输出吞吐 1111.61 tok/s但按 10 × 3000 ÷ 295.21 算物理上限约 101.6 tok/s偏差接近 11 倍。所以本文只采用 TTFT、TPOT、ITL、延迟和总耗时吞吐统一以引擎日志为准。DSPARK 投机解码在 Random 数据集下基本没收益。两套引擎都设 7 个投机 token200K 场景下平均接受长度都接近 1vLLM 约 1.051.17SGLang 约 1.051.17。vLLM 200K 轮中 Drafted throughput 约 990 tok/sAccepted throughput 仅约 21 tok/s约 98% 草稿计算被丢弃。64K 下 vLLM 接受长度 2.272.51SGLang 只有 1.211.55同样数据同样草稿模型却差这么多值得单独查。结论是本轮测到的是投机解码纯负担场景不能外推到真实生产流量下一轮应改用 ShareGPT 或真实业务请求。5. 本篇常见错排查401、local proxy failed、reading choices、OAuth这一节按真实报错来排。第一个高频错误是 401 Unauthorized。原因通常是 Key 没写对、Base URL 少了/api、或者三件套没写全。检查顺序先确认TAOTOKEN_API_KEY环境变量有没有生效再确认 Base URL 是https://taotoken.net/api而不是首页地址最后确认 Model ID 和你在模型对话页面看到的一致。三件套缺一个都会报错。第二个是 local proxy failed。这个报错一般出现在客户端配置了本地代理但代理没起来或者代理地址写错。排查方法先去掉代理配置直连测试确认 TaoToken 通道本身可用再逐步加回代理。注意不要用任何非正规的网络工具企业环境里走正常的网络出口即可。第三个是 reading choices 相关报错通常表现为Error reading choices或返回体里 choices 为空。原因可能是模型返回了 reasoning 内容但客户端只解析 content或者流式响应被中途截断。检查--reasoning-parser kimi_k3是否生效压测脚本是否处理了delta.reasoning字段。如果是流式确认没有在第一个 chunk 就关闭连接。第四个是 OAuth 相关报错。如果你用 Claude Code 接 Anthropic 兼容入口OAuth 流程走不通时先确认用的是 API Key 模式而不是 OAuth 模式。Claude Code 的配置参考 https://taotoken.net/claude-code-anthropic?utm_sourcetaotoken_aicg_blog_endutm_contentclaude_code_anthropicutm_campaignrewrite 里面区分了两种鉴权方式。API Key 模式下不需要走 OAuth 回调。除了鉴权类错误还有几个引擎侧的坑。vLLM 的--gpu-memory-utilization 0.95导致 8 卡共 32 次软 OOM 重试集中在 64K 测试初期让该轮 Prefill 和首批 TTFT 偏悲观。修正就是降到 0.92 或钉住--kv-cache-memory38.48GiB。SGLang 日志里设备名一处识别为 NVIDIA L20D其他位置又正确识别为 B300/GB300DCP 通信后端会根据设备名查表建议确认 a2a 是否被错误条目触发。两边都提示 FP8 KV Cache 缺少 scaling factor 并回退到 1.0上线前要用固定评测集验证精度。两边都有 slow tokenizer 告警64K/200K 长输入下 Tokenizer 耗时会直接进 TTFT建议换 fast tokenizer。vLLM 还有个隐蔽问题norm_quant、act_quant、allreduce_rms显示已启用但这些是 Inductor 编译期 passKimi-K3 自动开启VLLM_USE_BREAKABLE_CUDAGRAPH后编译模式可能被强制设为 NONE融合未必真正生效。复测时要检查实际生效的编译和算子配置。SGLang 的 KDA 融合验证内核大概率没运行启动参数解析得到linear_attn_verify_backendnv_cutedsl但 dispatcher 在kda_backend.py:97-98直接把 verify_kernel 指向 triton_kernel日志最终显示verifyTritonKDAKernel验证侧还有性能潜力没释放。6. 语义一致 CTA按场景选通道把压测流程固化下来排障和接入阶段先把 API Keys 和接入文档过一遍。API Keys 在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。这两个页面能解决大部分鉴权和请求格式问题。验证模型是否正常去模型对话页面 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 用同一个 Key 发一条消息确认返回正常再进压测。长期做编码或 Agent 任务看 Coding Plan https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 按调用量选合适档位。控制台 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 用来看余额和调用记录。选型建议按输入长度分输入不超过 64K、吞吐优先选 vLLM本轮 64K 场景解码吞吐领先约 1.51.6 倍。200K 及以上长文服务优先考虑 SGLang DCP本轮 200K 解码领先约 1.64 倍退化更缓但上线前必须把 KV 池提高到不低于目标 context-length。长上下文加高并发当前配置下更倾向 vLLM但需要复测因为 vLLM 在 1M 上下文下理论 KV 容量约 2.69 路SGLang 全注意力池不足 1M 且 Mamba 状态缓存把最大运行请求数压到 39。下一轮严格复测的清单里最值得先做的几件事把--long-prefill-token-threshold设为 4096解决 vLLM 单条 Prefill 独占 32768 预算导致 Decode 饿死的问题换掉 Random 数据集改用 ShareGPT 或真实长文档TTFT 改用 time-to-first-any-delta 口径修复压测平台吞吐统计把gpu-memory-utilization降到 0.92增加 SGLang 关闭 DCP 的第三组做三方对照把--max-model-len降到真实业务长度解除scheduler_reserve_full_isl满长预留对并发的压制。最后留一个实用技巧压测脚本里把 Base URL、Key、Model ID 都从环境变量读切换 vLLM 和 SGLang 时只改一个指向不要改代码。这样你可以在同一套脚本里跑完两套引擎数据口径一致对比才有意义。GPUStack 负责把服务拉起来TaoToken 负责统一鉴权和通道压测平台负责出数三者分工清楚复测才不会乱。
阅读完成 · 觉得有帮助?
咨询建站