ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

推理即产品:大模型服务上线的延迟、成本与稳定性实践

推理即产品:大模型服务上线的延迟、成本与稳定性实践

去年年中,我去找一位做AI产品的朋友聊天,聊到一半他叹了口气说:模型效果刷得够高了,可用户还是不满意。我翻了翻他拿出来的工单截图,“回答太慢”“转圈半天没反应”“问着问着就断了”占了一大半。那一刻我意识到,他不是个例——很多团队正把训练当成产品的交付前夜,却把用户真正摸到的推理服务当成了理所当然的附属品。

“推理即产品,训练只是研发”这句话,我后来用了很久,越用越觉得它能救很多项目。它不是否定训练的价值,而是说训练产出的是“能力原料”,用户根本看不到;用户看到的、用到的、抱怨的,全是推理这层。这篇就围绕这句话展开:推理产品化到底要盯什么指标,训练和推理两条线怎么交接,以及我实操下来发现最容易被忽视的几个坑。写个负责模型落地的算法工程师、推理工程同学、AI产品经理,还有那些正在把模型塞进业务里的技术管理者做参考。

1. 先把“研发”和“产品”的边界画清楚

1.1 训练阶段产出的是一堆“可能性”,不是交付物

训练、微调、对齐,这些工作的终点通常是一个权重文件,外加一份离线评测报告。报告上写着准确率提升了两个点,某个任务上的指标从多少涨到多少。但这些东西有一个共同特征:用户接触不到。

用户不会因为你的模型在公开测试集上排名靠前而觉得好用,也不会因为你用了几万条指令微调而对你有好感。他们能感知的只有一件事:自己输入一段内容之后,系统返回了什么、花了多长时间、中间有没有报错。哪怕你的模型能力再强,只要推理服务不稳定、响应太慢、偶尔断流,前面的研发投入就全部被体验黑洞吞掉了。

我习惯把训练阶段比喻成写菜谱,把推理阶段比喻成真正上桌的菜。菜谱写得好不好当然重要,但顾客评价的是端到面前那盘菜——温度、摆盘、口味、上菜速度。很多团队的问题在于,把所有的评审精力都放在了菜谱评审上,等菜真正端出去才发现餐具是漏的,服务员也不知道该怎么上菜。

还有一层容易被忽略的差异:研发阶段的失败容忍度非常高。训练跑挂了可以重跑,离线评测慢了可以等三天,指标不理想可以继续调。但推理阶段的失败容忍度是秒级的,用户没有耐心等你重新推理一次,也不会因为你服务端在高负载下偶然超时就原谅你。这种“研发可以反复试错、产品必须稳定交付”的本质差异,决定了我们必须把两条线分清楚。

1.2 推理服务才是用户真正摸到的那一面

如果把一个模型应用拆给用户看,用户层面的全部构成大概只有这些:输入框、输出内容、响应速度、错误提示,以及背后那个看不见但一直在被调用的接口。没有一个人会关心你用了什么架构、做了哪些微调策略、甚至用的是开源底座还是自研权重。

推理服务在产品生命周期里是一个持续运行的在线系统。它天然要承担流量、计费、服务等级协议、兜底逻辑、安全策略。训练是一次性的、有明确结束时间的任务;推理是常驻的、每分每秒都在消耗算力的服务。这两者的工作模式完全不同,要求的能力也不同。

所以“推理即产品”这句话的真正含义是:产品的形态等于“服务接口 + 体验表现 + 成本结构 + 稳定性兜底”的总和。模型权重只是其中一块原料。哪怕是同一个权重,交给两组人分别部署,用户感受到的可能是两个完全不同的产品。一个响应流畅、错误处理得当、成本可控;另一个接口频繁超时、排队严重、一上线就被用户抛弃。差别不在模型,在推理层的产品化水平。

1.3 “训练只是研发”的另一层意思:研发结果必须经过产品化才成立

我一直觉得“训练只是研发”这个说法不是贬低训练,而是帮训练团队解套。因为一旦把训练定位成研发环节,就可以名正言顺地引入工程约束——你是研发,你产出的东西就必须能在产品里跑起来。

这带来一个很实际的改变:训练阶段就要把推理侧的参数写进选型和验收条件。显存预算多少、延迟预算多少、单次请求成本上限多少,这些不再是推理团队上线时才考虑的“意外”,而是训练一开始就要背上的约束。我在后面会详细说模型出厂的验收清单,这里先点出这个思路:发动机再猛,装不进底盘就谈不上造车。

这个视角也能解决团队内部争论。很多时候算法团队和工程团队互相觉得对方不懂事——算法觉得工程不优化,工程觉得算法不考虑成本。但两者其实在同一个系统里,只是各自背着不同的指标。能把这套指标统一到“最终产品体验”上,争吵自然就变成合作了。

2. 推理产品化必须盯住的四个工程指标:延迟、成本、并发与可观测性

2.1 首token延迟和总生成时间:体验的分水岭

我那位朋友的团队,当时优化重点是模型效果。他们做了非常全面的离线评测,多轮对话的合理率也刷上去了。但线上用户还是说慢。后来我们拉了一下监控,发现首token延迟(TTFT)平均就过了5秒,某些长输入下甚至到10秒以上。问题一下子清楚了:用户点完发送,等了五秒才看到第一个字——这对即时交流场景来说已经是不可接受的水平。

所谓首token延迟,是指从用户请求到达服务端到模型输出第一个token的耗时。它对应的是大模型推理里的 prefill 阶段:模型要把整段输入并行处理一遍,生成KV缓存,然后才开始逐字输出。这个时间受输入长度影响非常大,输入越长,prefill 越久。而首token之后的生成速度(TPOT,每个输出token的耗时),则主要由模型规模、推理加速设备和解码策略决定。

不同场景对这两者的容忍度差异很大。给一个我实际划分的经验区间:

场景核心指标可接受水平主要优化手段
对话客服首token延迟1.5秒以内,配合流式输出缩短输入上下文、前缀缓存、动态批处理
代码补全总生成时间300毫秒到1秒小模型、投机采样、用户侧预判
内容生成总生成时间3秒以内可接受流式输出、队列调度、预生成
离线批处理吞吐分钟级均可大吞吐优先,不需要低延迟

流式输出是当前产品化的标配,它能把用户感知的等待时间从“全部生成完”压缩到“第一个字出来”。但流式也带来新的工程问题:连接要保持更久、中间结果需要流式校验、中断要能感知。没有流式输出还想保住对话体验,基本是给自己找麻烦。

2.2 推理成本不是边角料,是“每秒token”的算力账

很多人对推理成本没有概念,觉得训练这么贵的算力都花了,部署个推理服务算什么。但训练是一次性投入,推理是按时间持续燃烧。一个每周都要训一轮的团队,算力消耗可能都不如一个7x24小时对外服务的推理实例来得猛。

推理成本有一个很粗略的估算方式:一次请求的成本约等于“输入token数 + 输出token数”乘以单token的边际成本。而单token边际成本取决于加速卡的单价、有效吞吐、批处理效率。上下文长度对成本的影响尤其隐蔽:同样的硬件,上下文从2K扩展到8K,KV cache占用的显存会明显上升,并发能力可能直接腰斩,单次请求的成本自然跟着翻倍。

我见过一个做知识库问答的团队,上线前按每天一万次请求估计成本,结果忽略了平均问题长度和引用内容长度远高于预期,每个请求的输入token数几乎是预算的三倍。一个月后账单出来,整个项目差点因为成本问题被砍掉。所以训练团队在卷效果的时候,如果顺手把上下文长度压一压、把输出长度限制一下,其实就是在帮产品省钱。

成本这块还要考虑服务化的固有开销:在线服务必须按峰值流量预留容量,不能像离线任务一样排队慢慢跑。这意味着大部分时间里的算力是闲置的,这个闲置成本也要算进产品定价里。谁的批处理效率高、谁的显存利用合理,谁就能在同样的硬件投入下服务更多请求,这本身就是产品竞争力。

2.3 并发与弹性:上线能力的真正门槛

并发能力直接决定一个AI应用能不能叫“产品”。你可以有一个效果惊艳的模型,但如果一堆用户同时访问时服务就瘫,那就只能算Demo。并发能力的核心限制往往不在GPU算力本身,而在显存。

大模型在推理时,系统提示词、KV cache都要占用显存。上下文越长,单个请求占的资源越多,能同时处理的请求数就越少。这是为什么同样的推理框架,有人能扛住几百路并发,有人只能跑几十路——差别往往不是工程水平,而是请求上下文长度的设计。

主流的推理框架基本都实现了连续批处理机制:不是等整个批次的请求全部结束再处理下一批,而是某个请求结束后立刻补一个新请求进来,让GPU的每一步都在满负荷运载。这个机制很香,但要注意它优化的是整体吞吐,个别长请求可能被调度器反复“插队”,P99延迟反而上升。我后面会专门讲批处理调度的取舍。

弹性扩缩容是另一个容易被低估的问题。模型的加载和预热比普通Java应用慢得多,一个大权重从加载到可用可能要几十秒甚至几分钟。流量波峰来得突然时,扩容根本来不及。我们后来采用的做法是:常驻一小批实例应对日常流量,再预留一批热实例用于快速扩容,真正等流量到了才启动冷实例一般都晚了。

2.4 可观测性:没有指标,就没法讨论体验

推理侧最怕的不是出问题,而是出问题之后找不到原因。很多人只盯着GPU利用率看,满不满、高不高,但这其实是最表层的信息。GPU满可能是在忙得有效率,也可能是在跑大量低效请求;GPU不满可能是真的空闲,也可能是请求都被排队挡住了根本没到GPU。

我给自己带的推理服务定了一个最小可观测指标集,线上必须全部有:

指标含义为什么重要
TTFT首token延迟直接影响用户第一印象
TPOT每个输出token耗时决定生成总时长
排队等待时长请求进入调度器前的等待高并发下P99主要被它拉高
缓存命中率前缀或语义缓存的有效性命中率差意味着大量浪费
超时率首token超时或总超时比例超过阈值就要告警
错误率服务端返回错误的比例最直接的稳定性指标
单请求成本每次请求的平均算力消耗产品定价和优化的依据

这套指标不需要很复杂的平台,最开始用日志聚合加一套简单看板就能跑起来。关键是让算法同学和工程同学都能看到同一个数字,讨论“这个版本能不能上”的时候才有共同依据。没有指标的推理服务就像没有仪表盘的飞机——飞是能飞,但什么时候出问题全凭感觉。

3. 模型的“出厂”与服务的“上线”:两拨人如何交接

3.1 模型出厂标准不能只看离线效果

做训练的同学可能觉得,模型效果达标就算交付了。但放到“推理即产品”的框架里,这个交付是不完整的。出厂的模型制品,除了权重本身,还必须附带一份性能画像:在目标硬件上的显存占用、预估延迟区间、最大上下文下的并发能力、单token成本。

为什么这么较真?因为一次替换模型的上线决策,本质上是效果收益和资源代价的权衡。离线效果涨两个点,但权重体积翻了一倍、延迟涨了百分之四十,那到了线上就要看这两个点值不值得背后的成本。很多团队从来不算这笔账,等发布评审会上工程团队突然提出“这个版本上线会超预算”,算法团队才意识到自己少准备了一堆数据。

我给一个“出厂验收清单”参考:第一,目标硬件上的多并发压测报告;第二,不同输入长度下的延迟分布;第三,显存峰值和推荐的最大并发数;第四,上下文窗口变化带来的行为差异说明;第五,可预期的失败模式,比如幻觉分布、超长输出行为。如果一份发布材料里只有离线评测集的结果,我建议先别急着进发布流程。

3.2 推理团队在一等公民位置上的职责清单

有些团队把推理工程当成“部署模型的运维活”,这是误解。推理工程承担的职责远不止拉一个镜像、起一个服务。服务化接口、路由策略、缓存层、限流降级、监控告警、版本管理,全是推理团队的日常工作。

接口层面,不只是提供一个HTTP入口那么简单。请求体要处理多模态吗?输出要支持流式吗?错误码怎么设计?超时怎么约定?这些接口协议直接决定前端交互的实现方式。路由层面,多模型共存、不同租户隔离、实验分流,都需要设计。缓存层面,哪些请求可以命中、命中之后如何保证新鲜度,也是产品体验的一部分。

推理团队还要主动建立和算法团队的协作接口:模型用的是哪个精度版本,默认上下文窗口设多少,有没有自定义特殊token行为,输入输出是否需要后处理。这些问题不提前对齐,上了线就是事故。我见过一个很典型的场景:算法同学在训练时改了一段指令模板,没有通知推理团队,结果线上还在用旧的模板拼接请求,新模型的优势全被输入格式错配抵消了。

3.3 两种注定出问题的协作模式

第一种,训练团队扔包走人。他们把模型文件发给工程团队,然后就不闻不问。线上出了问题,工程团队不知道该找谁;工程团队请求优化,算法团队觉得“已经交付了”,不愿意再调整。最后的结果是:谁都不为线上体验负责,产品体验一路滑坡。

第二种,推理团队在不理解模型特征的情况下盲目调参。不知道模型擅长什么、不擅长什么,只能靠猜。批处理调错了维度、量化精度选过了头、上下文长度限制设得太狠,都会让模型效果剧烈下降,而推理团队还以为是硬件问题。

好的协作模式应该是共享SLA。算法团队和推理团队共同背一个线上服务等级目标,比如首token延迟P99不超过某个阈值、错误率不超过多少。发布新模型要走联合门禁:离线效果达标、压测数据达标、成本预算达标,三个条件都满足才放量。灰度期间两个团队一起盯看板,任何一方发现问题,都有权叫停发布。这套流程跑起来以后,我这边模型发布的返工率明显下降了。

4. 推理服务上线时,我实操下来最值得注意的细节

4.1 缓存是被低估的加速器

很多人一提到缓存就觉得只是Redis存字符串的老套路,在推理服务里其实不然。推理侧的缓存有两层:语义缓存和前缀缓存。语义缓存解决的是“用户反复问同一个问题”的场景,比如客服系统里最常被问的那几十个问题。通过向量相似度把请求路由到预定义答案或之前的推理结果,命中后完全不需要模型参与,延迟直接从秒级降到几十毫秒,成本几乎为零。

前缀缓存解决的是另一类问题:所有请求都带着一大段系统提示词和固定上下文。模型处理这些固定前缀时,每次都要重新做一遍prefill,极其浪费。支持的推理框架会把前缀部分的KV cache单独缓存,新请求只要前缀和缓存一致,就能跳过这段计算。实测下来,带长系统提示词的服务,开启前缀缓存后TTFT能下降百分之四十以上。

缓存层放在哪也有讲究。放在网关层,可以控制维度更细的语义缓存;放在推理引擎内部,更擅长做前缀缓存。我们最终是两层都放:网关层做语义缓存兜住高热点问题,推理引擎内部开前缀缓存处理公共上下文。缓存命中率要单独列为线上指标,如果长时间偏低,说明访问模式分散或者缓存策略没配对,需要重新设计。

4.2 动态批处理不是开箱即用,要理解它在调度什么

主流推理框架的连续批处理机制很好用,但调度策略对业务场景很敏感。批处理的核心逻辑是:把多个请求的token计算合并成一个大矩阵运算,提高GPU利用率。批越大,硬件利用率越高,单位成本越低。但代价是,一个请求要等其他请求的token算完才能继续,单个请求的延迟会被拖长。

用户感受到的响应时间其实是:排队时间 + prefill时间 + decode时间。动态批处理优化的是整体吞吐,但可能牺牲掉一部分长请求的延迟。比如一个平均输出400 token的长回复请求,和一个只输出20 token的短请求混在一起,短请求会很幸运地很快结束,长请求则可能被多轮调度拖很久。

我的经验是:如果产品里不同请求的上下文长度差异很大,最好按长度做队列分离,短请求优先、长请求走专属队列。如果做不到队列分离,至少要把批的大小和最大等待时间设成动态,让调度器在“追求吞吐”和“保障延迟”之间自动找平衡。上线前压测时,不要只看平均延迟,一定要看P95、P99,动态批处理下P99的波动会给你不少惊喜。

4.3 限流、超时和降级:产品化最重要的兜底

这是推理服务最容易被业务方忽略、也最容易出事故的部分。没有限流,服务会在流量峰值时直接被打垮;没有合理的超时配置,用户会无限等待;没有降级策略,模型一抽风整条业务线就瘫痪。

限流不能只按QPS设,因为大模型请求的消耗差异太大了。一个长上下文的请求和一个短问题的请求,资源消耗可能差几十倍。我建议按并发数或显存占用做限流:同时处理的请求达到上限,后面的请求直接返回排队提示或走降级通道。这样至少能保证已经在处理中的请求不受影响。

超时配置要分两层:首token超时和整体超时。首token超时建议设得短一些,比如5秒到10秒,因为prefill通常很快,这么久还没出第一个字大概率是排队死了。流式场景下还要检测流中断:如果一段时间没有新token到达,要主动断流提示用户重试。重试要带退避,不然雪崩时会形成重试风暴。

降级策略要提前设计好,而不是出事再想。我在团队里给降级分了几个档位:轻度降级是简化系统提示词、缩短上下文;中度降级是切换成更小更快的模型;重度降级是直接返回静态兜底答案或告知用户系统繁忙。这套策略在一次意外流量冲击中救过我们。当时上游大量请求涌入,如果硬扛,整个服务都会雪崩,最后是切换到了轻度降级模式,把长上下文全部截断,硬生生挺过了波峰。

5. 不要漏掉的最后一块拼图:训练和推理之间的评估闭环

5.1 离线涨分和线上体验为何可能背道而驰

我见过最冤的情况是:离线评测三个指标全面上涨,线上A/B测试用户满意度却下降。问题出在离线环境模拟不了真实的上下文。离线评测往往是给定一个标准问题,而线上用户输入带大量历史对话、噪音、隐含要求。模型在离线测试题上表现好,不代表它能处理好真实分布的数据。

另一个隐蔽因素是:模型效果涨分有时是通过增加输出长度实现的。回答更啰嗦了,信息量可能一样,但用户看到长篇幅就觉得“系统又在废话”。离线评测不会惩罚冗长,但用户体验会。要让训练结果真正转化为产品价值,必须建一套线上评估回流机制:小流量A/B、用户反馈关键词追踪、会话级的质量抽检。

我建议训练团队每轮迭代都做一次线上效果对照评测,哪怕样本量只有几百条。用同一批真实请求去测旧模型和新模型,比较结果的好坏、长度、以及是否符合产品预期。这套数据比任何公开评测集都对产品决策有价值。

5.2 模型、prompt、推理配置要当成同一个发布单元

很多团队踩过的坑是:模型更新了,但prompt还是旧版;prompt改了,但没重新做模型评估;推理参数调整了,但没人记录变更。等到线上出现问题,各方互相甩锅,最后发现是三者的版本组合完全错乱导致的。

正确的做法是把模型权重、prompt模板、推理参数、甚至前端交互配置,都打进同一个发布单元。一次发布,要么全用新版,要么全用旧版。回滚的时候也要整体回滚,不能只回滚模型不回滚prompt。这套规则看起来笨,但在复杂系统里是保命的。

上线流程上,我建议至少经历三档:第一档shadow模式,把线上真实流量复制给新模型,但不影响主链路,用来观察行为差异;第二档小流量,比如百分之五的流量切到新版本,对比错误率和延迟;第三档再放量到全量。每一档都要设自动回滚条件,比如错误率超过某个阈值或者延迟P99恶化百分之二十,自动切回旧版本。这套流程跑顺之后,模型发布就从一个“技术事件”变成了一个“常规操作”。

5.3 两个团队要用同一套语言谈体验

最后想说的是组织层面的问题。算法团队谈指标,工程团队谈SLA,产品团队谈用户满意度,三个团队如果各说各话,永远在对不上焦。要让“推理即产品”真正落地,必须统一语言。

统一的第一步是定义清楚什么算“好的回复”。这不只是满意度分数,还包括回答是否有用、格式是否合规、是否出现严重幻觉。这一部分需要产品团队提供判断标准。第二步是定义清楚什么算“可用的服务”,这交给工程团队的SLA:延迟、成功率、成本。两个定义合在一起,才是完整的体验定义。

我们在例会上会把这个闭环跑一遍:看一轮线上真实案例、过一遍延迟和成本趋势、对比一下新旧模型的线上行为差异。这个节奏坚持下来之后,算法同学开始主动问“这个改动会增加多少延迟”,工程同学也开始理解“为什么这里需要多留一点上下文”,团队之间那种剑拔弩张的协作氛围明显缓解了。

我在实际项目中体会最深的一件事是:模型应用竞争到最后,拼的不是谁的底座参数更多、谁在某张测试榜单上更靠前,而是谁能把推理这层产品做得更稳、更快、更便宜。模型能力会被快速追平,但一套围绕推理服务建立的工程体系、缓存策略、降级机制、评估闭环,是真正的护城河。如果你手里正好有一个模型马上要交付,我建议从今天开始,把“推理服务”当成一个独立产品来立项,把延迟、成本、稳定性放进和模型效果同等重要的验收单里。顺手再做一件事:从下一次实验开始,把“效果数字 + 延迟数字 + 成本数字”三个数记录在案。这个习惯我用了很久,它让我在做任何一个上线决策时,都有一组真实的数可以拍板,而不是靠感觉。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进