落地不是再选一个框架。训练刚结束时,手里是带版本的权重;线上要的是一份热的推理服务——深度模型和 LLM 多半在 GPU 上,树模型、逻辑回归、中小 ONNX 也经常跑在 CPU 上。调用方用稳定的协议来打。中间若靠 scp、人手 kubectl apply、改完 Ingress 才切流量,换版节奏就会卡在「谁有权限登集群」。业界把这件事收成一条发布链路:产物进仓库,期望状态进 Git,集群对账,服务框架加载并攒批,网关和指标把灰度跑完。硬件是池子里的机型,不是另一套发版。
换版的最小动作,应当是改一个 URI。 镜像、协议、调用方客户端都不该跟着动。
Table of contents
Open Table of contents
一、先把发布链路搭起来
生产里最常见、也最经得起换版的一条链是:
按实施顺序看每一环在干什么。缺一环,不会立刻挂,但会退回「有人记得怎么发」:
| 环节 | 落地时做什么 | 缺了之后换版会怎样 |
|---|---|---|
| 注册表 | 每次训练产物打版本,记下指标和来源 | 线上说不清跑的是哪一版,回滚靠猜 |
| 对象存储 | 按服务框架要求的目录放权重(Triton 还要 config.pbtxt) | 节点本地拷贝,发版变成 scp |
| GitOps | 集群只认 Git 里的声明,例如 storageUri | 人手 apply,环境和版本漂移 |
| 编排 | 把声明变成副本、探针、流量切分 | 扩缩和灰度各写一套,和业务发布对不齐 |
| 服务框架 | 从仓库加载、动态批处理、多模型共资源 | 硬件吃不满,或每个模型各起各的进程 |
| 网关与指标 | 统一入口;看利用率、实际 batch、排队、P99、降级 | 灰度靠改 DNS,调参靠感觉 |
训练侧产出之后,标准动作是:按仓库目录推进对象存储 → 注册表打 ctr-ranker/v4 → Git 里把 URI 指到新路径 → ArgoCD 同步 → 小流量金丝雀。权重不要打进镜像:镜像只装服务框架和运行环境,模型换版才不会变成一次镜像构建。
编排这一环可以是 KServe,也可以是已有的 K8s / 内部 PaaS。链路形状不变,变的是「谁来对账 Git 里的那份声明」。
二、先定落地形态,再买组件
同一条链路,团队成熟度不同,会落成不同形态。它们不是互斥标准,而是「你现在处在哪一档」。先问平台已经有什么,再决定 KServe 要不要上。
已经有 Kubeflow(或准备上 MLOps 平台)。 训练、Pipeline、Notebook 已经在同一套 RBAC 和命名空间里,KServe 就是它的服务组件,predictor 用 Triton(一次前向)或 vLLM(LLM)。算法从训练作业注册模型,到线上是同一条产品通路。适合模型种类多、要自助上线的团队。Kubeflow 本身重,服务就一两个、平台还没人养的,不要为了「全家桶」先背起来。
特征逻辑经常变,模型图要稳住。 用 KServe 把前处理 / 后处理放 Transformer(Python:拼特征、tokenize、截断),推理放 Predictor(Triton 挂 TensorRT、ONNX,GPU 或 CPU 后端)。对外仍是一个端点,两段可以各自扩缩:Transformer 吃 CPU,Predictor 按模型走 GPU 或 CPU。广告 / 推荐的特征拼装特别适合。
若前后处理能用 Triton 的 ensemble / BLS 表达,也可以整条编进 Predictor 侧,少一次 Pod 内跳转,灵活度会差一些。
微服务发布体系已经成熟。 发现、灰度、限流、降级是公司标准,再套 KServe(以及它常带的 Knative / Istio)等于两套流量规则。这时用 Deployment 跑 Triton 或 ONNX Runtime,扩缩和灰度接自研平台,模型仓库仍走对象存储。广告工程团队很常见。这不是落后,是编排能力已经有了,不必再买一层。
多种模型要共用上线流程。 注册表 → 存储 → GitOps 可以共用。LLM 把 predictor 换成 vLLM;深度 CTR 用 Triton 挂 GPU;树模型 / LR 用 ONNX Runtime、Triton CPU 或 JPMML。不要为每类模型另起一套发版。
| 你现在的情况 | 落地形态 |
|---|---|
| 有 Kubeflow,要自助上线 | Kubeflow + KServe + Triton / vLLM |
| 特征常变,模型要独立发 | KServe:Transformer + Predictor(Triton) |
| 已有 PaaS / 服务网格 | 裸 K8s Deployment + Triton / ORT |
| LLM、深度 CTR、CPU 粗排同一套发布 | 同一条 GitOps,换 runtime 和机型 |
三、实施按四条工作流推进
组件名单定了之后,落地是四条并行的工作流。缺哪条,链路上对应的那一环就会在发版时露馅。
1. 产物:版本在注册表,字节在对象存储
镜像只装服务框架和依赖(Triton / vLLM / ONNX Runtime,Java 侧则是 JPMML),不装权重。权重按服务框架的仓库规范进对象存储,例如 Triton 的 model_name/version/config.pbtxt + engine。注册表记下「v4 对应哪条路径、离线指标是多少、从哪次训练来」。回滚 = 把 URI 指回上一版路径,而不是翻备份盘。
上一篇里的格式选择在这里落地:深度一次前向常用 TensorRT engine 或 ONNX(GPU);树模型 / LR 常用 ONNX 或 PMML 跑在 CPU 上;LLM 常用 safetensors。仓库目录是服务框架的契约,换版只换目录,不换契约。
2. 发布:Git 是唯一的期望状态
换版路径固定写成:
广告 / 推荐经常天级甚至小时级换模型,登机器改配置跟不上。金丝雀必须看两套数:服务健康(错误率、超时、P99),以及模型有没有变差(线上 CTR / AUC 偏移、降级次数)。进程没挂,不等于这个 URI 能上全量。
3. 容量:推理池要热着,GPU 和 CPU 分开规划
深度模型和 LLM 吃 GPU:卡贵,不要一模型一张卡。服务框架里多模型共卡(Triton 的实例数、显存上限),再靠 K8s 把一张卡切开(MIG / MPS / time-slicing)。长尾吃切片;主力深度 CTR 往往独占一张卡保延迟。副本按并发或队列扩,不要按 CPU——GPU 打满时 CPU 可以仍然很低。
树模型、逻辑回归、中小 ONNX 经常跑在 CPU 上:机型按核数和内存规划,HPA 可以看 CPU 利用率。不要把它们和 vLLM 挤在同一张 GPU 节点上「顺便跑」——调度、隔离和成本账都会乱。Java 风控 / 粗排用 JPMML 吃 PMML,也是这条 CPU 路径,发布链路(注册表 → 存储 → Git)仍然适用。
延迟敏感的在线服务无论 GPU 还是 CPU,都留最小热副本(minReplicas ≥ 1)。缩到零对长尾、离线打分很香,但加载可能要几秒到几十秒,第一次请求会打崩 P99。上一篇里「同可用区内网 RPC + 超时降级」能成立,前提就是推理池一直是热的。调用方和推理池放同一可用区,是容量规划的一部分,不是网络优化彩蛋。
4. 路径与观测:协议稳定,数字能反过来调参
调用方(Bidder、对话网关)只认一种协议:一次前向用 Open Inference Protocol V2(或内部 gRPC),LLM 用兼容的流式 API。换引擎不该逼客户端升级。
前处理和推理能否拆开,决定发版节奏:特征加一个字段,不应迫使 TensorRT engine 重编。拆到 Transformer 或业务侧拼特征,CPU / GPU 也能分开扩。出了数值问题,才能分清是前处理没对齐,还是模型本身漂了。
指标至少要能回答三句话:硬件忙不忙(GPU 利用率 / 显存,或 CPU 与内存),柜台堵不堵(实际 batch、排队),用户侧崩没崩(P99、超时、降级)。攒批窗口和 HPA 阈值靠这组数调,不是靠感觉。
四、什么时候不必上 KServe
KServe 不是默认项。下面几种情况,裸 K8s 跑 Triton、vLLM 或 ONNX Runtime 通常更省事:
- 模型只有一两个:手写 Deployment / Service / HPA,比引入控制器更便宜。
- 已经有发布、灰度、限流、降级:再套一层等于两套规则打架。
- 延迟预算极死,控制面要短:少一个控制器、少一跳代理,排障面更小。协议可以直接打到服务框架的 gRPC。
- 没人养那套依赖:KServe 的价值要在「模型多、上线勤、算法要自助发」时才兑现。
一句话:平台还没有「模型上线」这条产品能力时,KServe 能买来;已经有了,就把服务框架当成普通微服务接进去。
五、三套参考实现
骨架都是「注册表 → 存储 → Git 声明 → 推理池 → 网关 / 监控」。predictor、GPU 还是 CPU、要不要 KServe,按场景换,不要为了标准架构强行对齐。
LLM 对话。
注册表里的 safetensors 进对象存储;Git 里声明 runtime 为 vLLM;KServe(或现有平台)管热副本和灰度;网关暴露兼容 API。加机器按 KV 是否还够,不要按 QPS 乘平均耗时。首 token 延迟敏感,同样不要缩到零。不到瓶颈,不必换成 TensorRT-LLM。
广告深度 CTR / CVR。
多数大厂用裸 K8s + Triton 接自研发布;中台化团队用 KServe。Bidder 同可用区 gRPC 调用;最小副本常驻;换版改 URI,金丝雀同时看 P99 和线上 CTR;超时退回粗排(见竞价链路)。
CPU 上的粗排 / 树模型 / LR。
发布链路不变,换的是机型和产物:ONNX 走 ONNX Runtime 或 Triton 的 CPU 后端;PMML 走 JPMML。可以独立成 CPU 推理服务(和 Bidder 同 AZ),模型很轻时也可以嵌进 Bidder 进程。不要为了「也有一条推理服务」把 LR 塞进 GPU 池。
一句话总结
落地是把训练产物声明式地推到推理服务上。 先搭发布链路:版本在注册表,字节在对象存储,期望状态在 Git,集群对账,服务框架加载并攒批。深度模型和 LLM 进 GPU 池,树模型 / LR / 中小 ONNX 进 CPU 池,发版方式相同。形态按平台已有能力选——有 MLOps 就用 KServe,有 PaaS 就把推理进程当普通微服务。
实施时四条工作流一起走:产物不进镜像、换版只改 URI、在线服务留热副本并同可用区、协议和指标能反过来调参。KServe 只在还缺「模型上线」能力时值得买。