Back to writing

/ AI Infra

[Infra-15] From Inference Engine to Cloud Service: The Full Stack Behind an LLM API

A request-path walkthrough of the complete LLM cloud stack, covering inference engines, model serving, orchestration, gateways, observability, security, billing, and the boundaries between them.

3 minInfra · LLM Serving · Cloud · Kubernetes

讨论大模型部署时,“推理引擎”和“云服务”经常被放在一起。比如,一个系统使用 vLLM 暴露了 OpenAI-compatible API,我们很容易说它已经是一个大模型云服务。

但真正面向大量用户、多个模型和一整个 GPU 集群时,能够生成 token 只是起点。系统还要回答:请求发到哪里、资源不足时如何排队、实例故障时如何恢复、不同租户如何隔离、模型如何灰度升级、每个用户用了多少 token,以及怎样观测整条链路。

因此,更准确的关系是:

LLM 云服务
  = 推理引擎
  + 模型 Serving
  + 调度与编排
  + 云基础设施
  + API 与流量治理
  + 可观测性
  + 安全、配额与计费

推理引擎负责把模型高效地跑起来;云服务负责把这种计算能力变成一个稳定、可扩展、可运营的产品。

1. 先看一条完整的请求链路#

假设用户调用一个类似 OpenAI Chat Completions 的接口,请求大致会经过:

Client
  |
  v
Load Balancer / API Gateway
  |
  +-- TLS termination
  +-- Authentication
  +-- Rate limit / Quota
  |
  v
Model Router
  |
  +-- model / version selection
  +-- tenant and region routing
  +-- load-aware routing
  |
  v
Serving Control Plane / Scheduler
  |
  +-- replica lifecycle
  +-- GPU placement
  +-- autoscaling
  |
  v
Model Server
  |
  v
Inference Engine
  |
  v
CUDA / ROCm / Accelerator + GPU Cluster

响应会沿着这条路径反向流回用户。对于流式生成,它不是一个普通的“一问一答” HTTP 请求:连接可能维持几十秒,token 会通过 SSE 或 gRPC stream 持续返回,中途还可能遇到客户端断连、超时和背压。

与此同时,另一条运营链路会异步记录 metrics、logs、traces、token usage 和审计事件:

Request events
  +--> Metrics --> Prometheus --> Grafana / Alerting
  +--> Logs -------------------> ELK / Loki
  +--> Traces --> OpenTelemetry --> Trace backend
  +--> Usage events --> Metering --> Billing / Quota

只有把这两条链路放在一起,才是完整的云端模型服务。

2. 云服务技术栈的分层#

下面这张表给出常见分层。具体产品可能合并若干层,也可能用自研系统替代开源组件,但职责基本相似。

层级常见技术核心职责
云基础设施AWS、Azure、GCP、阿里云、腾讯云,VM、VPC、对象存储提供计算、网络和存储资源
容器与编排Docker、Kubernetes、Helm打包服务,维护实例状态,完成部署与扩缩容
GPU 与通信CUDA、ROCm、NCCL、MIG、RDMA、InfiniBand执行加速、设备隔离和多卡通信
推理引擎vLLM、TensorRT-LLM、SGLang、TGI、llama.cpp高效执行模型的 prefill 与 decode
模型 ServingTriton Inference Server、KServe、Ray Serve、BentoML管理模型端点、实例生命周期和服务化接口
路由与网关Envoy、Nginx、Kong、云 API Gateway、gRPC接入、鉴权、限流、路由和流式传输
调度Kubernetes Scheduler、Ray、Slurm、自定义 GPU Scheduler分配 GPU,处理拓扑、优先级和资源竞争
缓存与队列Redis、Kafka、RabbitMQ缓存热点数据,削峰,承载异步事件
数据与存储S3、OSS、Ceph、数据库、向量数据库保存权重、配置、业务数据和检索数据
可观测性Prometheus、Grafana、OpenTelemetry、ELK、Loki观测延迟、吞吐、资源和错误
安全IAM、KMS、Vault、WAF身份、密钥、网络和租户隔离
商业化Metering、Quota、Billing用量计量、套餐、限额和计费

这不是一份固定的“选型菜单”。例如 KServe 更偏 Kubernetes 上的模型 Serving 控制面,Ray Serve 同时包含应用编排和副本调度能力,而 TGI 既有推理 runtime,也直接提供服务接口。真实系统中的产品边界并不会像表格一样整齐,判断一个组件的位置,应该看它承担的职责,而不是只看名字。

3. 推理引擎:让每张 GPU 生成更多 token#

推理引擎解决的核心问题可以概括为:

给定模型、请求和 GPU,怎样以更低延迟、更高吞吐和更少显存完成推理?

它直接管理模型执行,重点通常包括:

  • continuous batching:动态把不同时间到达的请求放进同一批执行;
  • KV Cache 与 PagedAttention:减少显存碎片,提高可容纳的并发量;
  • prefix cache:复用相同前缀的计算和 KV Cache;
  • quantization:用更低精度降低显存和计算成本;
  • speculative decoding:用草稿模型或额外 head 加速生成;
  • FlashAttention 与定制 kernel:提高算子的访存和计算效率;
  • TP、PP、DP、EP:让单个模型或请求跨多卡、多机执行;
  • CUDA Graph 和通信优化:减少调度开销与多卡通信瓶颈。

衡量这一层时,常见指标是 TTFT、TPOT、inter-token latency、吞吐量、并发数和 GPU 利用率。

但推理引擎通常不知道用户购买了什么套餐,也不负责整个集群的模型发布策略。它能决定一个 engine 实例内部下一轮执行哪些 sequence,却未必决定某个 Pod 应该被放到哪台机器上。这正是推理引擎内调度与集群调度的边界。

4. Model Serving:把进程变成长期在线的服务#

如果直接运行一个模型脚本,它可能已经能接收 prompt 并返回结果,但生产服务还需要稳定的 endpoint、健康检查、配置管理、版本管理和副本生命周期。

Model Serving 位于推理引擎外侧,负责把 runtime 包装成可持续运营的服务。常见职责包括:

  • 定义模型、版本、runtime 和资源需求;
  • 创建、更新和回收服务实例;
  • 暴露 HTTP、SSE 或 gRPC 接口;
  • 执行 readiness、liveness 和启动探测;
  • 支持滚动发布、蓝绿发布与 canary;
  • 收集请求指标并对接自动扩缩容;
  • 在部分架构中编排预处理、推理和后处理流水线。

Serving 和推理引擎经常被打包在同一个容器中,所以看起来像同一层。不过两者优化目标不同:引擎优化一次模型执行,Serving 管理服务实例及其生命周期。

5. 两级调度:请求调度与资源调度#

LLM 云服务至少存在两种尺度不同的调度。

第一种是集群级资源调度。Kubernetes Scheduler、Ray、Slurm 或自定义 GPU Scheduler 决定:

  • 一个模型副本放在哪台节点上;
  • 分配哪几张 GPU;
  • tensor parallel 是否满足 NVLink 或 RDMA 拓扑;
  • 多个模型和租户如何共享集群;
  • 在线请求、离线任务和训练任务谁优先;
  • 节点故障后实例在哪里重建。

第二种是请求级调度。router 和推理引擎决定:

  • 请求进入哪个模型版本和哪个副本;
  • 是否优先路由到已经拥有相同 prefix cache 的实例;
  • 请求何时进入 batch;
  • prefill 和 decode 如何共享计算预算;
  • 长请求是否会阻塞短请求。
Cluster scheduler: model replica -> node / GPU
Request router:    user request -> model replica
Engine scheduler:  sequence      -> current iteration / batch

三者如果各自只看局部指标,很容易互相抵消。例如,普通 round-robin 路由看似均衡连接数,却可能破坏 prefix cache locality;只按 GPU utilization 扩容,也可能因为模型冷启动需要数分钟而来不及应对流量峰值。真正高效的系统需要让路由、扩缩容和引擎状态协同。

6. API Gateway:把模型能力变成多租户接口#

网关并不执行模型,但它定义了外部用户如何安全、公平地访问服务。它通常负责:

  • TLS、API Key、OAuth 或 IAM 鉴权;
  • 按用户、租户、模型实施 QPS 和 token rate limit;
  • 校验请求大小、上下文长度和参数;
  • 路由模型别名、版本、区域与灰度流量;
  • 设置超时、重试和熔断策略;
  • 处理 SSE、WebSocket 或 gRPC 流;
  • 注入 request ID,形成端到端追踪。

LLM 的限流不能只看请求数。一个 10 token 请求和一个包含 100K 上下文、输出数千 token 的请求,成本相差巨大。因此生产系统往往同时约束 RPM、TPM、并发连接、输入长度和最大输出长度。

重试策略也需要谨慎。普通 REST 服务可以在超时后自动重试,但生成请求可能已经消耗了大量 GPU 时间,流式响应也可能已经向用户发送了一部分 token。盲目重试会制造重复计费、重复输出和重试风暴。

7. 扩缩容为什么比普通 Web 服务更难#

传统无状态 Web 服务启动快,CPU 使用率经常足以作为扩缩容信号。大模型副本则有几个特殊性质:

  • 权重可能有数十到数百 GB,下载和加载很慢;
  • 多卡实例需要同时获得一组满足拓扑要求的 GPU;
  • 启动后还可能进行 kernel 编译、显存分配和 warmup;
  • GPU utilization 高不一定代表拥塞,低也不一定代表可以缩容;
  • 缩掉实例会同时丢失它持有的 KV Cache 和 prefix cache;
  • 流式请求持续时间长,实例下线必须先 drain。

因此,扩缩容通常要联合观察 queue depth、waiting tokens、running sequences、TTFT、KV Cache usage 和历史流量趋势,而不能只看 GPU utilization。

应对冷启动的常见办法包括保留 warm pool、提前预取权重、使用本地缓存、按预测流量扩容,以及让模型副本优雅下线。这里的目标不是“副本数永远最少”,而是在 SLO 和 GPU 成本之间找到可控的平衡。

8. 可观测性:从 GPU 指标到用户 SLO#

一个请求变慢,原因可能在任何一层:网关排队、router 倾斜、scheduler 等待 GPU、模型冷启动、prefill 过长、decode 拥塞、NCCL 通信抖动,甚至客户端读取太慢。

因此,监控至少需要覆盖三类指标:

视角代表指标回答的问题
用户体验成功率、TTFT、TPOT、端到端 P50/P95/P99用户是否获得稳定响应?
服务队列queue time、batch size、running/waiting requests、tokens/s请求在哪一层等待?
基础资源GPU utilization、显存、功耗、网络吞吐、NCCL 延迟瓶颈是否来自设备或通信?

Metrics 用于看趋势和告警,logs 用于查看离散事件,traces 用于还原一次请求跨越多个服务的时间线。三者应通过统一的 request ID、tenant ID、model ID 和 replica ID 关联起来。

监控本身也要注意成本和隐私。prompt 与 response 可能包含敏感数据,不能因为调试方便就默认写入日志;高基数的用户和请求标签也不能不加控制地放进 Prometheus。

9. 数据、安全与商业化不是外围功能#

模型权重通常存放在 S3、OSS、Ceph 等对象存储中,并通过本地 NVMe、共享文件系统或分层缓存加速加载。Redis 可以保存短期状态、限流计数或缓存,Kafka 等消息系统更适合承载异步用量与审计事件。向量数据库则属于 RAG 等应用链路,并不是所有基础模型服务都必需。

多租户系统还需要处理:

  • 身份和权限:谁可以访问哪个模型和管理接口;
  • 密钥管理:API Key、云凭据和证书如何存储与轮换;
  • 网络隔离:控制面、数据面和管理面是否最小权限互通;
  • 数据治理:prompt 是否留存、保留多久、是否跨区域;
  • 资源隔离:单个租户能否占满队列、显存或连接;
  • 审计:谁在什么时间调用或修改了什么资源。

计费也不仅是响应结束后数一下 token。系统要明确输入 token、输出 token、cached token、失败请求和重试分别如何计算,并保证 usage event 可追踪、可去重,最终账单能够与请求记录对账。

这意味着 metering 最好建立在稳定的事件语义上,而不是临时抓取日志。否则一旦消息重复、服务重启或链路部分失败,就容易发生漏记或重复计费。

10. 一个典型的参考组合#

如果要搭建一个面向多租户的 OpenAI-compatible LLM 服务,一种可能的组合是:

API contract       OpenAI-compatible HTTP + SSE
Gateway            Envoy / Kong / Nginx
Identity           API Key + IAM
Orchestration      Kubernetes + Helm
GPU scheduling     K8s Scheduler + custom scheduler / operator
Serving            KServe / Ray Serve / custom controller
Inference engine   vLLM / TensorRT-LLM / SGLang
Accelerator        H100 / H200 / B200 or other accelerators
State and events   Redis + Kafka
Model storage      S3 / OSS / Ceph + local cache
Observability      Prometheus + Grafana + OpenTelemetry + Loki
Commercial layer   Metering + Quota + Billing

这只是参考架构,不是每一层都必须单独部署。早期系统可以用一个 vLLM 实例、一个反向代理和少量监控快速上线;随着模型数量、租户数量和可靠性要求增长,再逐步拆出 router、控制面、计量和高级调度能力。

关键是先明确系统需要解决的问题,再选择组件,而不是为了“技术栈完整”堆叠基础设施。

11. 两类岗位,以及它们的交界面#

推理引擎工程师通常更关注:

  • C++、CUDA 或其他加速器编程;
  • GPU architecture、kernel 和算子融合;
  • Attention、KV Cache、量化和 speculative decoding;
  • TP、PP、EP 与多卡通信;
  • TTFT、TPOT、显存和吞吐优化。

AI 云服务或平台工程师通常更关注:

  • Kubernetes、Ray 和分布式系统;
  • Go / Python 服务、网络与 API gateway;
  • GPU 调度、容量规划和自动扩缩容;
  • observability、SRE 和故障恢复;
  • multi-tenancy、安全、配额与计费。

两者最重要的交界面是 Model Serving、request routing 和 GPU scheduling。平台工程师如果不了解 continuous batching、KV Cache 和模型并行,很难设计出真正有效的路由和扩缩容;引擎工程师如果不了解流量、SLO 和实例生命周期,也很难让局部性能优化转化为线上收益。

12. 一句话总结#

推理引擎回答的是:

给定模型和 GPU,怎样更快、更省显存地生成 token?

LLM 云服务回答的是:

怎样把一整个 GPU 集群里的模型计算,稳定、安全、公平且可计量地提供给大量用户?

前者是性能核心,后者是完整生产系统。理解大模型云服务,不能只看最底层的 token generation,也不能只看最上层的 API;真正决定系统能力的,是请求路径、资源路径和运营路径能否在所有层之间正确衔接。