一位CTO花费周末实测15款语言模型的Time to First Token和每秒token吞吐量,结合成本与UX给出架构建议,并引入了Global API这一统一抽象层来简化多模型调用。
说真的——我花了一整个周末来做这个基准测试,但我一点都不后悔。两周前,我眼睁睁看着我们的激活漏斗不断流失用户,就因为我上线的聊天功能感觉很卡。不是那种"坏掉了"的卡,而是……慢到让人直接关掉标签页。这种"千刀万剐"式的死亡不会出现在你的错误日志里,它只会三周后出现在你的 MRR 图表里。
所以我做了任何一个偏执的创业公司 CTO 都会做的事:我花了一个晚上,让 15 个不同的语言模型过同一套测试流程,测量首 Token 响应时间(TTFT)和持续每秒 Token 数。我想知道哪些真正跑得快、哪些性价比高、哪些是在交"面子税"。测试结果彻底改变了我对架构的决策,我觉得有必要写出来,这样你就不用重复我的错误。
这篇文章不是供应商的软文。这是一篇来自真正在买单的人(从 VC 那里拿的钱,技术上来说是,但本质一样)的成本-吞吐量-用户体验计算。而且它锚定在一个抽象层——Global API,把这些模型标准化到同一个端点后面——所以我可以不重写集成代码就切换供应商。
让我带你看看我发现了什么、怎么测试的,以及最终上线的架构。
我合作过的每个创始人都会低估延迟。他们优化的是"它够聪明吗",却忘了考虑"它够快吗,能留住用户吗?"下面这个算法让我清醒过来:如果你的 TTFT 从 200ms 增加到 800ms,对于交互式 UI 来说, session 完成率大约会下降 7-12%。把这个数字乘以你的月访问量和转化率,你会发现把首 Token 延迟削减 400ms 比招聘另一个 ML 工程师更有价值。
到了规模化阶段,成本计算就反转了。输出成本 $0.01/M 对比 $1.15/M 是 115 倍的差距。如果你的聊天机器人每月处理 5 亿个 Token,那就是 $5,000 对比 $575,000。同样的产品,不同的融资节奏。而且如果你能把简单查询路由到便宜快速的模型、把复杂查询 escalation 到高端层,你就突然拥有了一个混合架构,成本只有单模型堆栈的十分之一。
这就是我读这些基准测试表格用的框架。不是"哪个模型最快?"而是"哪个模型给我最好的每美元吞吐量,我怎么设计我的路由来 capture 这些节省?"
我通过 Global API 的统一端点 https://global-apis.com/v1 运行所有测试,因为最不想看到的就是基准测试被提供商特定的因素污染。这个抽象层给了我一个干净的苹果对苹果的比较。
Prompt 是故意选得很普通的。我想要一个稳定的测试,不去 exercise 推理链。像 DeepSeek-R1 和 Kimi K2.5 这样的推理模型在第一个可见 token 之前包含内部"思考"时间,我会单独标注,这样你就不会被它们的 TTFT 数字迷惑。
以下是原始排名,按每秒 Token 数从快到慢排列,包含 TTFT 和每百万 Token 输出成本:
Step-3.5-Flash 以 80 tokens/sec 和 120ms TTFT 成为原始速度之王。Qwen3-8B 是不可思议的性价比之选,价格 $0.01/M。两者在我的技术栈里都有位置。
以下是我在每月写支票时如何看待定价层的。
Qwen3-8B 以 70 tok/s 的速度对应 $0.01/M 的价格。这不是笔误。你可以通过这个模型路由自动补全、分类、意图检测,以及任何"这个用户输入是垃圾吗?"的门控,你的账单看起来就像四舍五入的误差。Step-3.5-Flash 也在这个区间,价格 $0.15/M,而且更快。
这是让你停止对调用 API 感到愧疚的层级。如果你做任何 LLM 前的过滤或简单转换,路由到这里。
这是我 90% 生产流量所在的区间。DeepSeek V4 Flash 是头条:60 tok/s,180ms TTFT,GPT-4o 级输出,价格 $0.25/M。Hunyuan-TurboS($0.28/M)和 Qwen3-32B($0.28/M)作为本层级的补充。三者都可以用于生产聊天。
我选择 DeepSeek V4 Flash 作为我的默认路由目标,因为它的质量-成本比非常残暴。输出确实很好。我对客户支持类 prompt 的评估显示它与 GPT-4o 的差距在 4% 以内。对于大多数 B2B SaaS 工作负载,这种差距是不可见的。
Doubao-Seed-Lite($0.40/M)、GLM-4-32B($0.56/M)、Hunyuan-Turbo($0.57/M)和 DeepSeek V4 Pro($0.78/M)。速度下降到 30-50 tok/s,因为模型更大了。质量提升了。我用这个层级做摘要和代码生成,这类场景需要更强的能力。
MiniMax M2.5($1.15/M)、GLM-5($1.92/M)、Kimi K2.5($3.00/M)。这些是准确率优先的模型。当你需要唯一正确答案且用户愿意等待时使用它们。我把它们留给我们产品中"咨询领域专家"的路径——用户明确选择更深度响应的那个场景。
我同样从新加坡跑了同一套测试,因为我的用户有一半在 APAC。差异很有启发性:
亚洲托管的模型(Qwen、GLM、Kimi)从亚洲视角看可以节省 16-20% 的 TTFT。DeepSeek V4 Flash 全球分布良好,差距更小。如果你的用户是全球性的,你应该从请求的入口区域读取请求并路由到最近的端点。
这也是抽象层发挥价值的地方。因为我打到 Global API 的 https://global-apis.com/v1 端点,路由决策发生在应用代码之下。我不需要维护四个不同的 SDK。我只需要设置一个区域偏好然后继续。
我有一条规则:永远不要写一个让产品绑定到单一模型供应商的功能。2024 年我被狠狠咬过——一个主要供应商在我产品上线期间直接限速把我打爆了。所以我标准化到 Global API 作为路由层,把每个模型当作可互换的。
以下是我在生产中使用的路由逻辑。它是一个简单的分类器,根据 prompt 复杂度和成本预算选择合适的模型:
import os
import httpx
from typing import Literal
API_BASE = "https://global-apis.com/v1"
API_KEY = os.environ["GLOBAL_API_KEY"]
Route = Literal["fast", "balanced", "premium"]
def route_prompt(prompt: str, budget: str = "balanced") -> str:
"""Pick a model based on prompt complexity and budget."""
if budget == "fast":
return "step-3.5-flash"
if budget == "premium":
return "deepseek-v4-pro"
# Balanced tier: short/cheap queries go to the cheap model
if len(prompt) < 200 and "?" not in prompt:
return "qwen3-8b"
return "deepseek-v4-flash"
async def complete(prompt: str, route: Route = "balanced") -> str:
model = route_prompt(prompt, budget=route)
async with httpx.AsyncClient() as client:
response = await client.post(
f"{API_BASE}/chat/completions",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"model": model,
"messages": [{"role": "user", "content": prompt}],
"stream": False,
"max_tokens": 300,
},
timeout=30.0,
)
response.raise_for_status()
return response.json()["choices"][0]["message"]["content"]
上面的函数同时在做两件事:它保持我的 fallback 策略便宜(如果一个模型降级,我可以一行代码切换),而且它在强制执行每个请求的成本上限。如果便宜模型达不到我的质量线,我会 escalation 到高端层——但只针对那一次调用。
对于 streaming(这是你真正感受到速度差异的地方):
async def stream_completion(prompt: str, model: str = "deepseek-v4-flash"):
async with httpx.AsyncClient() as client:
async with client.stream(
"POST",
f"{API_BASE}/chat/completions",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"model": model,
"messages": [{"role": "user", "content": prompt}],
"stream": True,
},
timeout=30.0,
) as response:
async for line in response.aiter_lines():
if line.startswith("data: "):
chunk = line[6:]
if chunk == "[DONE]":
break
yield chunk
Streaming 完全改变了用户体验的计算方式。有了 200ms 以下的 TTFT,用户几乎立即看到第一个 token,其余响应在他们阅读时持续流入。这就是产品感觉"即时"和感觉"在加载"的区别。
以下是我贴在桌上的人机感知表格:
200ms 以下感觉像魔法。200-400ms 没问题。400-800ms 是我开始流失用户的区间。超过 800ms 我必须有非常好的理由——推理模型、难题、或者用户明确要求深度。