:::tip 🎮 交互式演练场 可视化演示: 试玩一下 推理成本探索器 - 无需编写代码。 :::
每月 8 万美元的 LLM 账单
这款 AI 写作助手上线已有半年,用户增长正如产品团队所愿。直到基础设施账单寄来:82,000forthem
他们使用的是通过 OpenAI API 调用的 GPT-4。每一条用户消息都会触发一次包含 3,000–4,000 Token 上下文的请求(系统指令+对话记录+检索文档),且回复平均包含 800 个 Token。按照 GPT-4 的价格 - 0.03/1Kinputtokens, 0.06/1K output tokens - 算下来账单非常残酷:单次交互成本高达 0.14 美元。而产品中重度活跃用户每天会产生 20 次以上的交互。
工程团队手握四个抓手:模型筛选、请求缓存、上下文压缩以及批处理。单用其中任何一个都无法根治问题。但在六周内系统性地应用这些策略后,月账单降至 $18,500 —— 削减了 77%,且在 94% 的场景下没有感知到质量下降。剩下 6% 的复杂查询依然使用 GPT-4,但仅限于真正必要的情况。
这个案例旨在传授这套系统化流程。推理成本优化并非寻找某种灵丹妙药 —— 而是要深入理解每一层级的经济学逻辑,并将正确的工具应用到对应的问题上。
为何推理成本如此独特
训练属于一次性投入。而推理则是伴随使用量的持续性支出 —— 这意味着随着产品成功,成本也会水涨船高。这就构成了一个独特的难题:产品越成功,运营费用就越高。这与大多数软件经济学背道而驰,后者通常因基础设施共享,用户越多,单用户成本越低。
ML 推理无法像传统软件那样实现同等规模经济的原因在于:成本受制于模型,而非基础设施。传统的 Web 服务器可以通过横向扩展廉价实例来处理 10 倍的请求。LLM 服务系统也能处理 10 倍的请求,但每次请求的成本依然大致相同,因为瓶颈在于每个 Token 消耗的 GPU 显存带宽 —— 这是一个物理限制,无法通过横向规模扩充来改善。
这意味着成本优化必须在模型和请求层面进行,而不仅仅停留在基础设施层面。
推理成本栈
动手优化之前,先搞清楚钱到底花在了哪里:
对于基于 API 的 LLM(如 OpenAI、Anthropic),成本主要按 Token 计费。对于自部署模型,成本主要取决于算力。相应的优化策略也有所不同。
抓手 1:模型筛选与路由
最高杠杆的优化手段是不要在弱力模型能胜任时动用强力模型。这就是所谓的模型路由或级联。
成本-质量帕累托边界
不同模型在成本-质量曲线上占据的位置各不相同:
| 模型 | 输入成本 (每 1K) | 输出成本 (每 1K) | 相对质量 |
|---|---|---|---|
| GPT-4 Turbo | $0.01 | $0.03 | 100% (基准) |
| GPT-4o | $0.005 | $0.015 | 98% |
| GPT-3.5 Turbo | $0.0005 | $0.0015 | 82% |
| Llama 3 8B (自部署) | $0.00008 | $0.00008 | 74% |
| Llama 3 70B (自部署) | $0.0004 | $0.0004 | 90% |
在许多现实任务中,GPT-3.5 或 Llama 3 70B 的表现与 GPT-4 持平。关键在于按任务类别衡量质量,而不是想当然地认为所有场景都需要最好的模型。
实施模型路由
from enum import Enum
from typing import Optional
import re
class ModelTier(Enum):
FAST = "gpt-3.5-turbo" # 简单任务,低费率
BALANCED = "gpt-4o-mini" # 多数任务,中等费率
POWERFUL = "gpt-4-turbo" # 复杂任务,高费率
def classify_request_complexity(
user_message: str,
conversation_history: list[dict],
max_history_turns: int = 10,
) -> ModelTier:
"""
依据复杂度将请求分发至合适的模型层级。
这是一个基于规则的方法;可替换为基于
(请求, 质量结果) 对训练的轻量级分类器。
"""
msg_lower = user_message.lower()
# 高复杂度信号 - 分发至强力模型
high_complexity_signals = [
len(conversation_history) > max_history_turns, # 深度上下文
any(w in msg_lower for w in ["analyze", "compare", "critique", "evaluate"]),
len(user_message) > 500, # 复杂提问
"code" in msg_lower and "debug" in msg_lower, # 代码调试
bool(re.search(r'\d+[\+\-\*\/]\d+', user_message)), # 数学运算
]
# 简单任务信号 - 分发至快速模型
low_complexity_signals = [
len(user_message) < 50, # 短消息
any(w in msg_lower for w in ["summarize", "translate", "format"]),
user_message.endswith("?") and len(user_message) < 100, # 简单提问
len(conversation_history) == 0, # 首条消息
]
high_score = sum(high_complexity_signals)
low_score = sum(low_complexity_signals)
if high_score >= 2:
return ModelTier.POWERFUL
elif low_score >= 2:
return ModelTier.FAST
else:
return ModelTier.BALANCED
class RoutedLLMClient:
"""具备成本感知及自动路由能力的 LLM 客户端。"""
def __init__(self, openai_client, default_tier: ModelTier = ModelTier.BALANCED):
self.client = openai_client
self.default_tier = default_tier
self._cost_tracker = {"fast": 0, "balanced": 0, "powerful": 0}
def complete(
self,
messages: list[dict],
force_tier: Optional[ModelTier] = None,
) -> dict:
# 分发至合适的层级
if force_tier:
tier = force_tier
elif len(messages) > 1:
user_msg = messages[-1]["content"]