ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

大模型推理选型实战:vLLM 与 SGLang 配 TaoToken 统一 Key 的 config.toml 骨架

大模型推理选型实战:vLLM 与 SGLang 配 TaoToken 统一 Key 的 config.toml 骨架 1. 为什么本地推理引擎一多Key 管理就开始失控本地部署大模型推理服务时vLLM 和 SGLang 是目前最常被同时维护的两套引擎。vLLM 靠 PagedAttention 和 Continuous Batching 把吞吐量拉满适合高并发文本对话SGLang 靠 RadixAttention 和结构化生成在 RAG、多轮对话、Agent 分支决策场景里首字延迟优势明显。很多团队的做法是白天用 vLLM 扛在线流量晚上或特定业务切到 SGLang 跑结构化任务两套引擎并存。问题就出在“并存”这两个字上。vLLM 默认监听 8000 端口SGLang 默认监听 30000 端口各自有各自的 OpenAI 兼容接口。如果每个引擎都单独配一套 Key、单独维护一套调用地址客户端代码里就会散落一堆 base_url 和 api_key。切换引擎时改配置、改环境变量、重新打包稍不留神就把请求打到已经下线的那个后端上。我试过同时维护三套推理后端最头疼的不是模型加载慢而是调用入口不统一。客户端明明只想发一个 chat/completions 请求却要先判断“这次走哪个引擎”再拼对应的地址和 Key。后来把 TaoToken 作为统一 Key/API 通道接进来config.toml 里只保留一份凭证引擎切换只改一个字段客户端完全无感。这篇就把这套骨架拆开讲清楚包括 vLLM 和 SGLang 各自的启动参数、config.toml 怎么写、怎么验证连通性、以及最容易踩的几个坑。TaoToken 在这里的角色是统一调用入口它对外提供一套 OpenAI 兼容的 API 通道对内可以指向你本地或内网的 vLLM、SGLang 服务。你只需要在 TaoToken 侧配置好后端映射客户端拿同一个 Key 就能访问不同引擎。官网入口在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 基址是 https://taotoken.net/api 注意 API 地址不带 UTM 参数。2. TaoToken 前置统一 Key 与通道准备在写 config.toml 之前先把 TaoToken 侧的准备工作做完。这一步的目标是拿到一个能同时访问 vLLM 和 SGLang 的 Key并确认两个后端的映射关系。2.1 创建统一 API Key登录 TaoToken 控制台进入 API Keys 页面创建一个新 Key。这个 Key 就是后面 config.toml 里唯一要填的凭证。建议按用途命名比如local-inference-unified方便以后区分是给本地推理用的还是给云端模型用的。创建完成后立刻复制保存页面刷新后就不再完整显示。控制台地址是 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API Keys 管理页在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。2.2 确认后端映射TaoToken 的统一通道需要知道请求最终落到哪个引擎。通常有两种做法一种是在 TaoToken 侧配置多个“模型名 → 后端地址”的映射客户端通过 model 字段区分另一种是配置多个通道客户端通过不同的 base_url 路径区分。无论哪种核心是让 vLLM 和 SGLang 各自有一个稳定的内网地址。假设你的部署环境是这样的引擎内网地址默认端口用途vLLMhttp://10.0.0.118000高并发在线对话SGLanghttp://10.0.0.1230000RAG / 结构化生成在 TaoToken 侧把这两个地址登记为后端并给它们分别绑定一个模型别名比如vllm-chat和sglang-structured。这样客户端请求里 model 填哪个就走哪个引擎。注意TaoToken 是统一调用入口不是用来替代 vLLM 或 SGLang 本身的。推理计算仍然发生在你的本地引擎上TaoToken 负责的是 Key 管理和请求转发。2.3 确认 API 基址所有客户端请求的 base_url 统一写成https://taotoken.net/api。不要带 UTM 参数UTM 只用于官网跳转统计。这一点在 config.toml 里体现为一个固定字段后面会给出完整写法。3. 可复制配置vLLM 与 SGLang 的 config.toml 骨架这一节是全文的核心。先给出两个引擎的启动命令再给出统一的 config.toml 骨架最后解释每个字段的作用。3.1 vLLM 启动参数vLLM 用 OpenAI 兼容模式启动关键参数是--served-model-name它决定了客户端请求里 model 字段填什么。启动命令如下python -m vllm.entrypoints.openai.api_server \ --model /models/Qwen2.5-7B-Instruct \ --served-model-name vllm-chat \ --host 0.0.0.0 \ --port 8000 \ --tensor-parallel-size 1 \ --gpu-memory-utilization 0.90 \ --max-model-len 8192 \ --enable-prefix-caching几个参数说明--served-model-name vllm-chat让客户端用vllm-chat这个别名调用而不是一长串模型路径--gpu-memory-utilization 0.90控制显存占用比例留 10% 给系统--enable-prefix-caching开启前缀缓存对多轮对话和 RAG 场景有明显收益这一点和 SGLang 的 RadixAttention 思路一致只是实现层面不同。3.2 SGLang 启动参数SGLang 的启动方式类似但它默认端口是 30000且对结构化生成有原生支持python -m sglang.launch_server \ --model-path /models/Qwen2.5-7B-Instruct \ --served-model-name sglang-structured \ --host 0.0.0.0 \ --port 30000 \ --tp-size 1 \ --mem-fraction-static 0.85 \ --context-length 8192 \ --enable-radix-cache--enable-radix-cache是 SGLang 的核心它把公共前缀的 KV Cache 挂在显存里的 Radix Tree 上重复前缀直接命中不用重算 Prefill。--mem-fraction-static 0.85控制静态显存分配比例比 vLLM 略保守因为 Radix Tree 本身也要占一部分显存做索引。3.3 config.toml 完整骨架下面这份 config.toml 是统一入口的核心。它把 TaoToken 的 Key、API 基址、两个引擎的模型别名和超时参数集中管理客户端只读这一份配置。# config.toml - 统一推理调用配置 # 客户端只依赖本文件切换引擎不改代码 [gateway] # TaoToken 统一 API 基址不带 UTM 参数 base_url https://taotoken.net/api # 统一 Key从 TaoToken 控制台获取 api_key sk-你的TaoToken统一Key # 默认超时单位秒 timeout 120 # 最大重试次数 max_retries 2 [engines.vllm] # 对应 TaoToken 侧登记的 vLLM 后端 model vllm-chat # 该引擎的额外请求头可留空 extra_headers {} # 单次请求最大 token 数 max_tokens 4096 # 温度 temperature 0.7 [engines.sglang] # 对应 TaoToken 侧登记的 SGLang 后端 model sglang-structured extra_headers {} max_tokens 4096 temperature 0.3 # SGLang 结构化生成时可用普通对话留空 regex [router] # 当前激活的引擎切换只改这一行 active vllm # 引擎别名到配置段的映射 map { vllm engines.vllm, sglang engines.sglang }这份骨架的关键设计是[router]段。active字段决定当前走哪个引擎客户端代码只读active对应的配置段不关心底层是 vLLM 还是 SGLang。切换引擎时把active vllm改成active sglang重启客户端即可Key 和 base_url 完全不动。3.4 Python 读取配置的示例为了让骨架真正可跟做给一段读取 config.toml 并发送请求的 Python 代码import tomllib from openai import OpenAI with open(config.toml, rb) as f: cfg tomllib.load(f) gateway cfg[gateway] router cfg[router] engine_key router[map][router[active]] engine cfg[engine_key.split(.)[0]][engine_key.split(.)[1]] client OpenAI( base_urlgateway[base_url], api_keygateway[api_key], timeoutgateway[timeout], max_retriesgateway[max_retries], ) resp client.chat.completions.create( modelengine[model], messages[{role: user, content: 用一句话解释 PagedAttention}], max_tokensengine[max_tokens], temperatureengine[temperature], ) print(resp.choices[0].message.content)这段代码里没有任何硬编码的引擎地址全部从 config.toml 读取。切换引擎只需要改active字段代码零改动。4. 验证请求确认两个引擎都能通配置写完后必须做连通性验证。分三步先验证 TaoToken 通道本身再分别验证 vLLM 和 SGLang 后端。4.1 验证 TaoToken 通道用 curl 直接打 TaoToken 的 API 基址确认 Key 有效curl -s https://taotoken.net/api/v1/models \ -H Authorization: Bearer sk-你的TaoToken统一Key \ | python -m json.tool如果返回的模型列表里能看到vllm-chat和sglang-structured说明 TaoToken 侧的映射已经生效。如果只看到一个或报 401先检查 Key 是否复制完整、后端映射是否保存。4.2 验证 vLLM 后端把 config.toml 的active设为vllm运行上面的 Python 示例。预期结果是模型正常返回一段关于 PagedAttention 的解释。如果返回 404通常是model字段和 vLLM 启动时的--served-model-name不一致如果返回 502说明 TaoToken 到 vLLM 的内网地址不通检查防火墙和端口。4.3 验证 SGLang 后端把active改成sglang再跑一次。SGLang 在结构化生成场景下可以加 regex 约束验证时可以故意让它输出 JSONresp client.chat.completions.create( modelengine[model], messages[{role: user, content: 返回一个包含 name 和 age 的 JSON}], max_tokens256, temperature0.1, extra_body{regex: r\{name:\s*[^],\s*age:\s*\d\}}, ) print(resp.choices[0].message.content)如果 SGLang 返回的 JSON 严格符合正则说明 RadixAttention 和结构化生成都在正常工作。这一步也顺便验证了 config.toml 里regex字段的传递链路。4.4 切换引擎不换 Key 的实测把两次验证的结果放在一起看同一个api_key同一个base_url只改了active字段请求就分别落到了 vLLM 和 SGLang。这就是统一 Key 的价值。实测下来切换过程客户端不需要重新初始化只要重新读取 config.toml 即可。5. 本篇常见错排查配置过程中最容易出问题的几个点集中列一下。5.1 model 字段与 served-model-name 不匹配这是最高频的报错。vLLM 启动时--served-model-name vllm-chatconfig.toml 里model就必须是vllm-chat。如果填成模型路径/models/Qwen2.5-7B-InstructvLLM 会返回 404。SGLang 同理--served-model-name和 config 里的model必须一字不差。5.2 端口冲突与内网地址写错vLLM 默认 8000SGLang 默认 30000如果两个引擎部署在同一台机器上端口不能重复。另外 TaoToken 侧登记的后端地址必须是内网可达的 IP不能写127.0.0.1除非 TaoToken 和引擎在同一台机器上。跨机器部署时写127.0.0.1是最隐蔽的坑表现为 TaoToken 侧一切正常但请求永远超时。5.3 显存不足导致引擎启动失败vLLM 的--gpu-memory-utilization和 SGLang 的--mem-fraction-static加起来不能超过 1.0。如果两个引擎跑在同一张卡上建议 vLLM 设 0.45、SGLang 设 0.45留 10% 余量。如果启动时报 OOM先把其中一个引擎停掉单独验证另一个。5.4 超时设置过短大模型推理的首字延迟在长上下文场景下可能达到几秒甚至十几秒。config.toml 里timeout 120是保守值如果跑 RAG 长文档建议调到 300。超时太短会表现为请求被中断但引擎日志里看不到错误容易误判为网络问题。5.5 regex 字段传给不支持的后端config.toml 里regex字段是给 SGLang 用的。如果active是 vLLM却把 regex 传过去vLLM 会忽略或报参数错误。正确做法是在代码里判断只有active sglang时才把 regex 放进extra_body。5.6 TaoToken Key 权限不足如果 TaoToken 侧创建 Key 时限制了可访问的后端而 config.toml 里请求了未授权的模型别名会返回 403。排查方法是先用/v1/models接口确认当前 Key 能看到哪些模型再对照 config.toml 里的model字段。6. 统一入口之后按场景分流调用配置跑通之后实际使用中可以根据场景做分流。纯文本对话、高并发在线请求走 vLLM因为 Continuous Batching 在吞吐量上更有优势RAG 知识库问答、多轮长上下文、Agent 多分支决策走 SGLang因为 RadixAttention 能把重复前缀的 Prefill 成本降到接近零。如果你需要长期跑编码类任务或 Agent 工作流可以了解 Coding Plan它适合把统一入口接到持续性的开发场景里https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。如果只是想先验证模型对话是否正常模型对话页面可以直接试https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API Keys 管理在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。最后留一个实用技巧config.toml 里的[router]段可以扩展成按请求类型自动选引擎。比如在代码里判断 messages 总长度超过 4000 token 就走 SGLang否则走 vLLM。这样既保留了统一 Key 的简洁又让两个引擎各发挥所长。骨架已经给全剩下的就是按你的业务流量调参数了。
返回列表