Skip to content
Charles Shao
Go back

推理运行时与服务框架选型:运行环境、服务框架、编排平台怎么分层

Updated:
–views

打包好的模型,接下来要问的是:用什么跑起来、怎么对外提供服务。这一步最容易走偏的,不是记错产品名,而是把职责不同的东西放在一起比较。一次计算怎么在 GPU 上跑完、请求怎么接进来、集群里副本怎么扩,其实是三件独立的事。有的产品会跨层——引擎顺便带一个 HTTP 服务,编排声明也能拉起一套推理进程——名字叠在一起了,职责并没有合并。不先把层分清,后面无论换成哪家实现,都还是鸡同鸭讲。

打个比方:运行环境是发动机,服务框架是柜台,编排平台是连锁门店。 发动机决定算得多快,柜台决定怎么接待客人、怎么把零散的小单攒成一锅,门店网络决定开几家分店、新店怎么灰度。三者是叠着用的,不是三选一。

运行环境管算,服务框架管接,编排平台管活。 分清层,再在每一层里填实现。

Table of contents

Open Table of contents

一、先立三层

选型混乱,是因为算、接、活被当成同一件事。拆开之后,产品名才有地方放:

三层叠加图。自上而下三块:③ 编排平台(开几家店、新店怎么灰度、挂了谁拉起来)→ ② 服务框架(接单、排队、把小单攒成一锅)→ ① 运行环境(这次计算在硬件上怎么跑完)。底部注明编排拉起服务框架,服务框架再调运行环境;LLM 引擎常把①②装进同一进程。

层管什么改什么算动这一层可以没有吗
运行环境一次计算怎么在硬件上走完换卡、换精度、换 IR / engine不能
服务框架请求怎么进、怎么攒批、超时怎么降级改协议、排队、batch 窗口模型很轻时可以内嵌,不单独起服务
编排平台几个副本、流量怎么切改副本、HPA、金丝雀「模型专用那一层」可以没有;进程总得有人拉起来

接口也很窄:运行环境吃张量、吐张量;服务框架对外是 RPC;编排对外是稳定入口 + 副本 + 流量比例。很多 LLM 引擎自己既算又接请求——那是把前两层装进同一进程,不是服务框架消失了。

所以「vLLM 和 Triton 哪个好」没有答案:一个常占运行环境+服务框架,一个是服务框架,肚子里还可以再挂运行环境。先问各占哪层,再比同层。


二、运行环境:怎么算

运行环境只关心计算。训练时 model(x) 能出数,不等于线上有可部署的运行环境。线上要执行计划稳定、精度确定、显存能事先估出来。

一次前向和 LLM 不能当同类引擎做容量规划:

一次前向(CTR / embedding / CV)自回归(LLM)
批处理多条拼成更大的矩阵运算生成过程中插入新请求(连续批处理)
显存权重 + 激活权重 + KV cache(随并发 × 上下文涨)
和服务框架可以分开:引擎当库几乎总是绑在一起
容量怎么估QPS × 单次耗时先问 KV 还塞得下多少人

选这一层,先定取向,再填名字(和上一篇的格式对上:ONNX 吃可移植运行环境,engine 吃编译型,GGUF 吃端上):

取向填什么别用在
可移植,CPU / GPU 都要跑ONNX Runtime;Intel 上可看 OpenVINO要单卡打满 Tensor Core 的深度模型
单卡峰值,接受换卡重编TensorRT(一次前向);TensorRT-LLM(生成)当可移植包提交,换卡就挂
LLM 在线高吞吐vLLM(默认起点);前缀很重 / Agent 看 SGLang用「QPS × 平均耗时」估机器数
本地 / 端上llama.cpp 一类(吃 GGUF)当服务端 GPU 池的主力

这一层选完,还没有对外服务——除非把引擎直接链进业务进程。


三、服务框架:怎么接

运行环境不开端口,也不会把同时到来的小请求攒成一次大计算。服务框架管:请求怎么进、排队等多久、何时开算、超时怎么降级。

线上变慢,第一反应常常是换引擎。更常见的其实是在排队:GPU 只算了 3ms,有 8ms 在等凑批。这两段要拆开——排队长了动服务框架或加副本;计算本身慢了才动运行环境。

攒批是吞吐和尾延迟的旋钮:等太短,GPU 吃不饱;等太长,队尾先超时。LLM 的连续批处理是同一件事:边生成边插新请求,所以必须和引擎长在一起,很难用普通 HTTP 网关代替。

比选哪个框架更要紧的,是独立成服务还是嵌进业务进程:

姿势何时用典型填法
独立服务深度模型要 GPU 池化、要跨请求攒批、换版不跟业务发版绑死一次前向用 Triton(挂 TensorRT / ONNX);LLM 用引擎自带的 server,或再收进 Triton
内嵌业务进程LR、树模型、粗排,CPU 就能跑;RPC 一跳比计算还贵ONNX Runtime 当库链进 Bidder

独立服务能在死预算里活下来,靠的不是 RPC 免费,而是调用方和推理服务同一区域、同一可用区,内网往返只有一点点,超时则退回粗排。跨区的话,这一跳会变成延迟大头,引擎再快也救不回来。广告深度 CTR 做成独立服务,是因为 GPU 不能塞进每台 Bidder,不是因为编排产品叫什么。

协议尽量稳:一次前向用 gRPC;LLM 用流式接口。换引擎不该逼调用方改客户端。一张卡跑多个模型能省钱,但要限制实例数和显存,否则互相拖慢。


四、编排平台:怎么在集群里活着

一台机器上把服务框架起起来,只说明「这一台能调」。生产还要:几份副本、按什么信号加机器、新模型切 10% 流量、挂了谁拉起来。

两样东西不要混成一个词:

通用容器编排模型推理编排
是什么K8s:进程、副本、探针、HPA底座之上:把「一个模型服务」收成一条声明
典型Deployment + Service + HPAKServe(InferenceService);多步应用看 Ray Serve
不上会怎样没地方跑容器扩缩、灰度、推理入口得自研

KServe 不是 K8s 的替代品,是架在上面的一层:声明里写模型在哪、什么格式、要几张卡,它再展开成 Deployment / 路由。只用 K8s 跑 Triton 完全合法,大厂很常见;上 KServe 是在买「算法能自助上线」这条能力,代价是多一套组件。

在线服务里几条硬习惯:


五、一张表填完选型

把三层填成可执行的组合(名字是各层的常见实现,不是必须绑定):

场景运行环境服务框架编排
LLM 在线对话vLLM / SGLang引擎自带 API(与左合一)KServe;多步链路用 Ray Serve
LLM 要压延迟TensorRT-LLM常再收进 TritonKServe,按 KV 留热副本
传统模型、多框架共卡TensorRT 或 ONNX RuntimeTritonKServe,或裸 K8s Deployment
广告 / 推荐深度 CTRTensorRT / ONNXTriton,独立服务,同 AZ gRPCGPU 池;K8s 或 KServe;minReplicas ≥ 1
粗排 / LR / 树模型ONNX Runtime内嵌 Bidder跟着业务服务走
RAG / AgentvLLM + embedding 引擎Ray Serve 把几步串起来偏应用编排
离线批量打分任意Spark / Ray 批处理,不是在线框架作业调度

三个问题按顺序问,就能落到表里的某一行:

  1. 算一次就结束,还是边生成边算?要不要 GPU? → 定运行环境,也定它要不要和服务框架绑在一起。
  2. 模型重不重? → 要 GPU 的深度模型走独立服务、同可用区、超时降级;很轻才内嵌。
  3. 要不要「模型自助上线」? → 模型多、要灰度 / 按并发扩 → KServe;已有发布体系或只有一两个模型 → 裸 K8s 托管 Triton 即可。

KServe 和 Triton 不是二选一:KServe 在外面管副本和灰度,Triton 在 Pod 里攒批、共卡、挂 TensorRT / ONNX。怎么接到注册表和 GitOps,见落地篇。


六、两条链路:表上的两行长什么样

LLM 对话(表第一行,要吞吐)

LLM 对话链路。用户请求打到 KServe 入口(热副本、灰度),落到同一进程里的 vLLM:接请求、连续批处理、KV、流式往回推。底部注明按 KV 容量加机器,不到瓶颈不必换 TensorRT-LLM。

计算和接请求不必拆开。加机器按 KV 还够不够用,不要按「QPS × 平均耗时」乘台数。不到瓶颈,不必换成 TensorRT-LLM。

广告深度 CTR / CVR(表第四行,要死延迟,仍独立成服务)

业界主流不是把深度模型编进 Bidder:

广告深度 CTR 链路。竞价请求进入 Bidder(同区域同 AZ),经 gRPC 打到 Triton(排队、攒批、超时降级),再由 TensorRT / ONNX 在 GPU 上前向。底部注明 GPU 池化、与 Bidder 解耦换版,副本常驻不缩到 0。

必须独立:GPU 要池化、换版要和 Bidder 解耦、多条竞价要攒在一起才喂满卡。延迟靠三件事:别跨区、排队单独限、超时退回粗排(见竞价链路架构)。LR / 树模型才走第五行,嵌进 Bidder。


七、变慢了动哪一层

按这个表查,避免三层的人同时开工:

你看到什么先动
P99 高,GPU 很闲,队列在涨服务框架:缩短攒批等待,或加队列上限
P99 高,GPU 已满,队列很长编排:加副本(按并发扩,不是按 CPU)
队列很短,GPU 忙,单次仍慢运行环境:精度、编译、模型结构
只有冷启动 / 第一次请求超时编排:热副本,别缩到零
延迟整体垫高一截,还在抖动拓扑:是不是跨可用区了
LLM 并发一高就 OOM 或拒绝运行环境的 KV 容量,不是再加「QPS 机器」

对应的坑,都是查反了层:拿引擎和编排比快慢;以为上了 KServe 就可以不要 K8s;推理服务跨区;按 CPU 给 GPU 做 HPA;深度模型复制到每台业务机器,或很小的模型也单独起服务;把排队算进「模型耗时」;把 TensorRT engine 当可移植包;LLM 容量只看 QPS。


一句话总结

先分三层,再填实现。 运行环境负责算(一次打分还是边生成边算,决定换哪类引擎、要不要和服务框架绑在一起);服务框架负责接(深度模型独立成服务,轻量模型嵌进业务);编排负责活着(要自助上线用 KServe,已有发布体系用裸 K8s)。KServe 托管 Triton,不是平替;vLLM 常常一个人干两层。

变慢时:先查跨区,再看队列,队列短了才动引擎。怎么接到注册表和 GitOps,见推理服务业界落地。


–views
Share this post on:

Previous Post
推理服务业界落地:从训练产物到推理服务怎么发布
Next Post
模型文件格式分类与选择:.pt / SavedModel / ONNX / safetensors / GGUF / TensorRT / PMML 到底怎么选