LLM 应用的成本工程 2026:从 KV cache 到模型路由的统一架构
把 KV cache 复用、prompt cache、连续 batching、模型路由四层成本架构串联成一个统一方程,让 LLM 应用的月度账单从事后审计变成事前可设计的工程属性。
约 31 分钟阅读9,184 字1 次阅读博主

把 KV cache 复用、prompt cache、连续 batching、模型路由四层成本架构串联成一个统一方程,让 LLM 应用的月度账单从事后审计变成事前可设计的工程属性。

一句话摘要:当 LLM 应用的请求量从 PoC 阶段跨过每秒百次请求的门槛,每一项工程决策——缓存命中率、批处理窗口、模型路由权重、token 计费口径——都会在月度账单上被放大成五位数美元的偏差;本文用一套统一的成本方程把 KV cache 复用、prompt cache、动态批处理、模型路由、可观测性闭环串联起来,让成本从"事后审计的账单"变成"事前可设计的工程属性"。
把"成本工程"当成"少调用几次 LLM"是绝大多数团队的第一反应,也是绝大多数团队最终在生产环境里失控的起点。LLM 应用的成本不是单一维度的线性变量,而是由四个相互耦合的子成本构成的复合函数:输入 token 成本、输出 token 成本、基础设施成本(GPU 时长、KV cache 显存占用、跨可用区流量)、机会成本(延迟导致用户流失、命中率低导致重算)。每一个子成本都有自己独立的优化曲线,而任意两个子成本之间的优化路径往往是冲突的:例如提高 KV cache 复用率会拉低输入 token 成本,但过长的 prefix 会增加首字延迟(TTFT)从而推高机会成本;提高批处理并发度会拉低 GPU 时长成本,但批窗口过长会让 P99 延迟飙升至体验红线之外。
要把 LLM 应用的成本从"事后审计"转成"事前可设计",需要一个统一的成本方程,把所有可调参数折叠进同一个目标函数,然后用工程手段让目标函数单调下降。本文要回答的核心问题是:当一个 LLM 应用已经稳定运行、且无法再通过"换更便宜的模型"这种单点降本手段进一步压缩账单时,工程团队的下一步应该是什么?
答案分四个层次:第一层,KV cache 复用与 prefix sharing——让相同前缀的请求共享 prefill 阶段的计算结果;第二层,prompt cache 与语义缓存——把整段 prompt 模板甚至语义级查询结果缓存到 Redis 或专用向量库;第三层,动态批处理与连续 batching——把多个请求合并到同一个 forward pass 里,摊薄 GPU 调度开销;第四层,模型路由与级联调用——根据请求复杂度路由到不同规格的模型,让"简单问题用小模型、复杂问题用大模型"从口号变成可度量的生产策略。这四层不是四个并列的技术,而是一个统一的成本架构,每一层都向上层暴露明确的接口契约。
把 LLM 应用在时间窗口 内的总成本记为 ,可以分解为:
其中 是窗口内总请求数, 是第 个请求实际路由到的模型, 和 是按模型定价的 token 单价, / 是输入 / 输出 token 数, 是单 GPU 时长成本(自托管场景)或等效的推理 API 服务费, 是窗口内 GPU 总占用时长, 是平均延迟, 是重试率。
四个子成本项之间通过三个可调参数耦合:
统一成本架构的目标是:在给定业务约束 、 的前提下,求使 最小的参数三元组 。
KV cache 是 transformer 推理过程中 prefill 阶段计算的 key / value 张量缓存。每个请求的 prefill 阶段都要为 prompt 中的每一个 token 计算 K / V,并缓存下来供后续 decode 阶段复用。如果两个请求的 prompt 前缀完全一致(按 token 序列对齐),那么第二个请求可以从第一个请求缓存的最后一个共享 token 位置继续 prefill,跳过所有共享 token 的 K / V 计算。这就是 prefix sharing。
工程实现上,prefix sharing 需要三个基础设施:第一,prefix tree——按 token 序列构造一棵 trie,每个节点保存该前缀对应的 KV cache 块句柄;第二,块管理——KV cache 按固定大小的 block 分配(如每块 16 或 64 个 token),通过 PagedAttention 风格的块表管理显存;第三,TTL 与淘汰——prefix tree 节点按 LRU 或按业务时间窗口淘汰,避免无限制占用显存。
prefix sharing 的成本收益可用一个简单公式估算:设平均 prompt 长度为 ,平均共享前缀长度为 ,共享比例为 ,则 prefill 计算量下降为原来的 。对一个 token、 token 的应用(典型 RAG 场景,系统 prompt + 检索结果前缀固定),,prefill 计算量下降 75%。考虑到 prefill 通常占总推理时长的 30-50%,整体推理时长下降约 22-37%,对应 GPU 时长成本下降同等比例。
Prefix sharing 的工程坑点:(1) prefix 必须按精确 token 序列匹配,少一个 token 或换行符差异都会 miss;(2) prefix 的命中率与请求分布强相关,长尾请求的 prefix 几乎不共享,需要为长尾设计 fallback;(3) prefix tree 的并发修改需要锁,热点 prefix 的根节点会成为锁瓶颈,可用 COW(copy-on-write)或 RCU 风格的无锁结构缓解。
KV cache 复用解决的是"相同 prefix"的问题,但实际生产中大量请求的 prefix 并不完全相同,而是语义上相似——同一个 RAG 系统的 prompt 模板 + 同一份文档的不同切片、同一段 system prompt + 用户不同表述的同一问题、同一组 few-shot 示例 + 同一类查询。语义缓存的目标是把这种"语义级复用"也纳入成本优化。
工程上,语义缓存分两层:第一层,精确字符串缓存——用 prompt 哈希(SHA-256 of canonicalized prompt)作为 key,把完整的 prompt-response 对存到 Redis。命中率受 prompt 模板的稳定性影响:模板越稳定、变量越少,命中率越高。这一层廉价且可靠,是每套 LLM 应用都应该默认开启的"基础设施级缓存"。第二层,向量语义缓存——用 embedding 模型把 prompt 编码为向量,在向量数据库(如 Milvus、Qdrant、pgvector)里检索 top-1 相似 prompt,若相似度超过阈值(如 cosine > 0.95)则返回缓存结果。
精确字符串缓存的命中率经验值在稳定生产系统中通常达到 20-45%——比多数团队的预期高一个数量级,因为大量业务请求的"自由文本"部分其实很短,前 80% 的 token 都来自固定的 system prompt 与 few-shot 模板。向量语义缓存可在此基础上再提升 10-20%,但误命中风险显著升高:embedding 模型的语义相似度与人判断的"等价"并不一致,相似但不等价的 prompt 返回错误缓存会导致严重的产品体验问题,必须配置信度阈值 + 关键字段校验双重兜底。
Prompt cache 的工程坑点:(1) 缓存失效是永远的难题——任何 prompt 模板变更、模型版本切换、底层数据更新都可能让历史缓存失效,必须建立版本化的缓存命名空间(如 cache_v3_gpt-4o-2026-01);(2) 缓存污染——错误响应被缓存后会被反复返回,需要在响应侧加异常检测与主动失效;(3) 隐私与合规——prompt 可能含用户隐私数据,缓存层必须有TTL + 用户级隔离 + 加密三件套。
批处理是把多个请求合并到同一个 forward pass 里执行,从而摊薄每次 forward 的固定开销(kernel launch、attention 计算的 memory bandwidth)。传统静态批处理需要等一个 batch 凑齐才能执行,导致单请求延迟被批窗口主导。连续 batching(continuous batching,也称 in-flight batching)通过在 decode 阶段逐 token 替换已完成的请求来实现"批窗口不阻塞",是当前生产级推理框架的事实标准。
连续 batching 的关键工程参数是最大批大小 与单请求最大长度 。 越大 GPU 利用率越高,但单请求被其他请求 stall 的概率也越大; 越长,长尾请求会拖慢整个 batch。生产经验值: 通常取 32-128(取决于 GPU 显存与单请求 KV 大小), 取 2048-8192 token(视业务而定)。
连续 batching 与 KV cache 复用是正交的:批处理摊薄的是单次 forward 的调度开销,prefix sharing 摊薄的是 prefill 阶段的计算开销。两者结合的效果是乘性的——一个 、prefix 命中率 70% 的推理服务,相比单请求无 prefix sharing 的基线,GPU 时长成本可下降 60-80%。
批处理的成本坑点:(1) 请求长度方差——若 batch 内同时有 50 token 的短请求与 4000 token 的长请求,长请求会拖慢所有短请求(短请求必须等 batch 内所有请求都完成该 decode step),需要按长度分桶(bucketing)或动态 padding;(2) 优先级缺失——所有请求平等排队,付费用户、SLA 用户与免费用户混在同一个 batch 里,需要实现优先级队列;(3) 背压——当请求涌入速率超过 GPU 处理能力,队列无限增长,延迟无界上升,需要主动拒绝(429)或优雅降级(自动降级到小模型)。
模型路由是成本架构里杠杆最大的一层。同一个查询,用 GPT-4o-mini(每百万 token 输入 0.15 美元、输出 0.60 美元)相比 GPT-4o(输入 2.50 美元、输出 10.00 美元),输入便宜 16.7 倍、输出便宜 16.7 倍。如果路由策略能把 70% 的查询路由到 mini 模型、30% 路由到 full 模型,仅输入成本就下降 70% × 0.15 + 30% × 2.50 = 0.86 美元/百万 token,相比 100% 路由 full 模型的 2.50 美元下降 65.6%。
工程上,模型路由有三种主流策略:第一,规则路由——按查询特征(如 token 数、关键词、用户分层)写死路由规则,可解释但维护成本高;第二,分类器路由——训练一个轻量分类器(如 BERT-base)预测查询复杂度,根据预测结果路由,可学习但需持续训练与监控;第三,级联调用(cascade)——先调用小模型,若小模型置信度低(可通过 logprob 或 self-consistency 检测)再升级到大模型,理论上最优但工程复杂度最高。
级联调用的成本最优性可用一个简化模型说明:设小模型单独调用成本 、大模型单独调用成本 、小模型回答不充分需升级的比例为 (即升级率),则级联调用的期望成本为:
升级率 与小模型能力负相关、与业务对回答质量的容忍度正相关。生产经验值:在 chat 类应用里,一个 7B-13B 级别的小模型对 50-60% 的查询能给"足够好"的回答,升级率 40-50%。代入数字:、、, 美元/请求,相比 100% 大模型的 0.01 美元下降 45%。这是一个保守估计,实际中升级率通过 prompt 设计、检索增强、self-consistency 等手段可压低到 25-35%,对应成本下降 65-72%。
模型路由的工程坑点:(1) 升级成本不只是 token 成本——升级到更大模型意味着更高的延迟与更长的 GPU 占用,端到端 P99 延迟可能恶化;(2) 小模型 vs 小模型家族——不是"小模型都行",需要针对业务做微调或选型,否则小模型的低质量回答会被用户感知并导致 churn;(3) 路由策略本身需要监控——分类器可能因数据漂移失效,需要持续追踪升级率、误升级率、欠升级率三个指标。
把上述四层成本架构翻译成可执行的工程决策,按优先级排序:
决策一:先开后即上 KV cache 复用。prefix sharing 在 vLLM、TGI、SGLang、TensorRT-LLM 等主流推理框架里已是一等公民,启用成本仅是配置 PagedAttention + prefix cache 参数。即使应用 prompt 模板不变,prefix sharing 在 30-50% 的请求上也能拿到命中率(取决于请求分布),对应 GPU 时长成本下降 15-25%。
决策二:精确字符串缓存作为默认基础设施。Redis + SHA-256 哈希的精确缓存,实现成本低于 100 行代码、运维成本接近零,命中率经验值 20-45%。把这条决策放在第二优先级是因为它"几乎免费",任何 LLM 应用都应该默认开启。
决策三:连续 batching 替换静态 batching。如果推理框架还在用静态 batching(等 batch 凑齐才执行),迁移到连续 batching 是必须的——单这一步通常带来 2-4 倍的吞吐量提升,等价于 GPU 时长成本下降 50-75%。vLLM 与 TGI 已默认连续 batching。
决策四:建立小模型微调或选型能力。不是"用开源小模型就行",而是要根据业务 query 分布选型(小模型对垂直领域可能比通用大模型更好)或做轻量微调(LoRA / QLoRA),把升级率压到 25-35% 以下。这一步的成本最高、回报也最高,需要团队具备 MLOps 能力。
决策五:模型路由要可观测、可回滚、可降级。路由策略上线必须有金标集评估(离线评估不同路由策略的升级率与质量)、灰度发布(先 5% 流量)、快速回滚(路由错误导致质量下降时 5 分钟内回退到单模型)、自动降级(小模型服务异常时自动切到大模型)。
把上述四层成本架构放到一个更长的时间维度看,会发现它要求工程团队从"按功能交付"的文化转向"按成本与质量共同交付"的文化。这个转变比任何单点技术优化都难,但也比任何单点技术优化的回报都大。
具体而言,文化转变体现在三个层面:第一,可观测性必须包含成本维度——传统的 latency / error rate / throughput 三件套不够,必须增加按请求的成本(输入 token、输出 token、缓存命中、批大小、路由模型)、按用户的成本(单个用户生命周期总成本)、按功能的成本(每个产品功能的边际成本贡献率);第二,成本进入 PR review 与架构评审的 check list——任何新增的 LLM 调用都要回答"为什么不用更小的模型"、"为什么不用缓存"、"为什么不用批处理";第三,成本异常要有 alerting 与 oncall——当月度账单偏离预算超过 15% 时自动告警,由 oncall 工程师按预设 runbook 处理(常见原因:路由策略漂移、缓存命中率下降、prompt 模板变更导致 prefix 失效、模型版本切换导致定价变化)。
成本工程的局限性也需要承认:当应用规模小到一定程度(如每日请求 < 1 万次),单点优化的工程投入可能超过回报——此时"接受账单"反而是最优决策。当应用对延迟极度敏感(如实时语音 agent),缓存与批处理的延迟代价可能超过成本节省。当业务对回答质量要求极高(如医疗、法律),升级率会远高于经验值,模型路由的杠杆会大打折扣。成本工程不是"越极致越好",而是要找到业务约束下的成本-质量-延迟三维 Pareto 前沿。
按本文的统一成本方程与四层架构,新接手或重构一个 LLM 应用时,建议按以下顺序推进:
这七步不是"全做完才上线"的瀑布式流程,而是可以渐进叠加的敏捷流程——每一步都能独立带来 15-45% 的成本下降,且每一步都向下兼容(不影响线上流量)。一个 6 人 LLM 应用团队用 4-6 周时间走完这七步,通常能把单位请求成本压到原基线的 25-40%,同时不牺牲 P99 延迟与回答质量。
最后要强调的是:成本工程的最终目标不是"把账单压到最低",而是"在给定的业务约束下,找到成本-质量-延迟三维 Pareto 前沿上的最优点"。一个 LLM 应用如果把成本压到极致但回答质量崩塌、用户大量流失,那成本优化的结果是负的。工程是约束条件下的优化问题,不是单目标极值问题——这一点,是成本工程作为一门工程学科的核心。
为把上文抽象的成本下降百分比落到具体数字上,引用三个公开案例的实测数据点(截至 2026-09 仍未有跨团队统一基准,数字仅作量级参考):
这三个案例说明:不同应用类型的成本优化路径完全不同,照搬"前缀缓存命中率 70%"的经验值会误导团队。正确的做法是先识别自己应用的 prefix 共享结构,再选择对应的优化组合——这就是"成本架构"作为工程学科的核心方法论。
Conversation
0 条