路线图

05 线上稳定性与可观测

星辉 2026-07-02 阅读 7 min 1,326 字 路线图
05 线上稳定性与可观测 封面

学习目标:能设计可鉴权、可路由、可限流、可熔断、可 fallback、可灰度、可回滚、可弹性伸缩、可观测(含质量/成本)的模型服务入口;掌握 OpenTelemetry GenAI 语义约定的六层结构。 重点度:必会(20 分)


概述#

模型服务进入生产后,不能直接让业务访问裸实例——需要解决:

text
谁能调用?调用哪个模型?超量了怎么办?模型挂了怎么办?
延迟升高怎么办?负载有波峰波谷怎么扩缩?
输出质量变差怎么发现?每调用一次花了多少钱?

核心问题:如何把模型服务变成可稳定接入、可观测、可控成本、可弹性伸缩的线上服务?

这一章的核心能力矩阵:AI Gateway → 稳定性 → 弹性伸缩 → 可观测。2026 年的新增重点是 OpenTelemetry GenAI 语义约定、scale-to-zero、效果可观测(质量/幻觉)。


AI Gateway:模型服务的统一入口#

为什么需要专门的 AI Gateway#

普通 API Gateway(Nginx/Kong/APISIX)懂的是 HTTP 路由、限流、鉴权,但它不懂 LLM——不知道什么是 token、什么是模型路由、什么是 prompt 成本。

AI Gateway 在普通网关的基础上,增加 LLM 专属能力:

text
普通 API Gateway          AI Gateway(额外能力)
─────────────────        ──────────────────────
路由 / 限流 / 鉴权       模型路由 / token 计费
负载均衡 / 重试          Virtual Key / 租户隔离
                         成本统计 / 模型 Fallback
                         Prompt 审计 / Guardrails
                         context window fallback

LiteLLM:开源 LLM 网关的事实标准#

核心定位:所有 LLM Provider 都翻译成 OpenAI 兼容接口,然后做网关该做的事。

两种模式

  • SDK 模式:Python 库,from litellm import completion,适合本地脚本
  • Proxy 模式:HTTP 服务,集中管控、配额、审计、Fallback,生产唯一选择

最小配置

yaml
model_list:
  - model_name: gpt-4o-mini           # 业务侧看到的模型名(alias)
    litellm_params:
      model: openai/gpt-4o-mini        # 实际后端
      api_key: os.environ/OPENAI_API_KEY
  - model_name: llama-70b-internal
    litellm_params:
      model: openai/default
      api_base: http://vllm-llama70b:8000/v1
      api_key: EMPTY
  - model_name: deepseek-v3
    litellm_params:
      model: openai/default
      api_base: http://sglang-deepseek:30000/v1
      api_key: EMPTY

router_settings:
  routing_strategy: usage-based-routing-v2
  fallbacks:
    - gpt-4o-mini: ["claude-sonnet", "qwen-max"]
  context_window_fallbacks:
    - gpt-4o-mini: ["claude-sonnet"]   # prompt 超长时自动切大上下文模型

general_settings:
  master_key: sk-master-xxx
  database_url: postgresql://...

Virtual Key 与租户隔离#

AI Gateway 的核心能力是 Virtual Key——每个业务线/团队独立的 API Key,绑定模型白名单、预算、限流。

bash
# 为业务线创建 Virtual Key
curl http://litellm:4000/key/generate \
  -H "Authorization: Bearer sk-master-xxx" \
  -d '{
    "key_alias": "team-nlp-prod",
    "models": ["gpt-4o-mini", "llama-70b-internal"],
    "max_budget": 500.0,
    "budget_duration": "30d",
    "tpm_limit": 100000,
    "rpm_limit": 500,
    "metadata": {"team": "nlp", "env": "prod"}
  }'

业务方用返回的 sk-xxx 直接当 OpenAI Key 用,网关自动完成鉴权、限流、计费、审计。

Virtual Key 的多维控制

维度配置作用
模型白名单models限制可调用的模型
预算上限max_budget + budget_duration30 天最多花 500 美元
RPM 限流rpm_limit每分钟最多 500 请求
TPM 限流tpm_limit每分钟最多 100K token
元数据metadata团队/环境标签,用于成本归因

模型路由策略#

text
请求 → Gateway
      ├─ 鉴权(Virtual Key → 可用模型白名单)
      ├─ 路由决策
      │   ├─ cost-based:选最便宜的
      │   ├─ latency-based:选历史延迟最低的
      │   ├─ usage-based:选当前负载最低的
      │   └─ kv-aware:选 KV Cache 命中最长的节点
      ├─ Fallback(如果主模型不可用)
      └─ 限流(超过 RPM/TPM → 拒绝或排队)

Model Alias 设计

yaml
# 业务侧用语义化别名,底层模型可替换
fast-small: gpt-4o-mini / qwen-turbo / llama-8b
fast-medium: gpt-4o / qwen-max / llama-70b
smart: claude-sonnet / gpt-5.5 / deepseek-v4
local-only: vllm-internal(不 fallback 到公网)

业务侧代码只引用 alias(如 fast-medium),底层模型升级/切换/降本时网关层改配置,业务无感知。


稳定性能力#

限流#

yaml
# LiteLLM 支持三级限流
tpm_limit: 100000     # tokens per minute
rpm_limit: 500        # requests per minute
max_budget: 500.0     # 预算上限(美元/30天)

限流策略选择

  • RPM 限流:防止单租户刷爆 QPS
  • TPM 限流:防止长 prompt 烧光算力
  • 预算限流:防止成本失控(30 天 500 美元用完即拒)

限流优先于扩容:遇到流量峰值先限流保护已有服务,等扩容完成再放开。直接扩容可能扩容还没完成服务已经被打挂。

熔断与 Fallback#

yaml
router_settings:
  fallbacks:
    - gpt-4o-mini: ["claude-sonnet", "qwen-max"]
  context_window_fallbacks:
    - gpt-4o-mini: ["claude-sonnet"]  # prompt 超长时自动兜底
  allowed_fails: 3                     # 失败 N 次进入冷却
  cooldown_time: 60                    # 冷却 60 秒

熔断规则:

  • HTTP 5xx、连接失败、timeout → 触发切 fallback
  • 连续失败超过 allowed_fails → 进入冷却,暂停分配
  • 冷却期过后逐步恢复,避免雪崩

Fallback 链设计

text
主模型:gpt-4o-mini(便宜,快)
  ├─ fallback 1:claude-sonnet(贵但稳)
  └─ fallback 2:qwen-max(国产备选)

注意:fallback 模型可能更贵,不要兜底到比主模型贵 10x 的模型上

超时与重试#

yaml
router_settings:
  num_retries: 2    # 重试次数(只对 5xx,4xx 不重试)
  timeout: 30       # 单次请求超时(秒)

超时设计

  • 流式输出 timeout 要给够(输出 500 token 可能要 30s+)
  • 非 5xx 错误不重试(4xx 是业务错误,重试无用)
  • 重试要指数退避,避免雪崩

灰度发布#

模型灰度发布的典型流程:

text
v1 模型(在线)                  v2 模型(新版本)
     │                               │
     ├─ 90% 流量 ─────────────────────┤
     └─ 10% 流量 ─────────────────→  │
                              观察 TTFT/TPOT/质量
                              无异常 → 逐步提升到 100%
                              有异常 → 回滚

实现方式:

  • 网关级:路由规则按比例分流(如 LiteLLM 的 rpm_limit 分配)
  • 引擎级:Triton 的 version_policy: { specific: { versions: [1, 2] } } 配合客户端指定版本
  • K8s 级:两个 Deployment + Service 权重

灰度策略

  • 按比例灰度(10% → 50% → 100%)
  • 按租户灰度(先内部团队 → 再小客户 → 最后大客户)
  • 按地域灰度(先小地区 → 再大地区)

回滚#

在模型发布出现问题时:

  • 网关切回老模型后端(最快,几秒生效)
  • K8s 回滚到前一版本 Deployment
  • Triton 卸载新版、加载旧版 engine

回滚的核心前提是:老版本的模型/engine 仍在集群中可用。不要发布完就删老版本。建议保留最近 3 个 production 版本。


弹性伸缩#

HPA:按 GPU 指标伸缩(非 CPU)#

传统 HPA 按 CPU 扩缩,但 LLM 推理的瓶颈是 GPU。需要 GPU 指标的 HPA:

yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: vllm-hpa
spec:
  scaleTargetRef:
    name: vllm-deployment
  minReplicas: 2
  maxReplicas: 10
  metrics:
    - type: Pods
      pods:
        metric:
          name: vllm_num_requests_waiting  # 排队请求数
        target:
          type: AverageValue
          averageValue: "10"
    - type: Resource
      resource:
        name: memory
        target:
          type: Utilization
          averageUtilization: 85

为什么不用 CPU 指标:LLM 推理的 CPU 使用率和实际负载关系弱。tokenizer 和 sampling 用 CPU,但瓶颈在 GPU。用 num_requests_waiting 或 GPU SM 利用率作扩缩指标。

KEDA:事件驱动伸缩#

KEDA(Kubernetes Event-Driven Autoscaling)更适合批处理和自定义指标场景:

yaml
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: vllm-keda
spec:
  scaleTargetRef:
    name: vllm-deployment
  minReplicaCount: 1
  maxReplicaCount: 10
  cooldownPeriod: 300          # 缩容冷却 5 分钟
  triggers:
    - type: prometheus
      metadata:
        serverAddress: http://prometheus:9090
        metricName: vllm_queue_depth
        query: vllm:num_requests_waiting
        threshold: "5"

KEDA vs HPA

  • HPA 只能用 metrics.k8s.io 和 custom.metrics.k8s.io
  • KEDA 支持 Prometheus、Kafka、Redis、AWS CloudWatch 等 60+ 数据源
  • KEDA 支持 scale-to-zero(HPA 不支持)

Scale-to-Zero#

空闲时把推理实例缩到零,有请求时再启动。适合非实时、低频调用的模型:

yaml
# KServe + KEDA 实现 scale-to-zero
apiVersion: serving.kserve.io/v1beta1
kind: InferenceService
spec:
  predictor:
    minReplicas: 0  # 允许缩到零
    maxReplicas: 5
    scaleTarget: 0
    scaleMetric: concurrency

代价:模型从零启动需要加载权重(3-10 分钟),第一个请求超时。

冷启动优化

text
冷启动超时
├─ 模型加载时间:70B 模型约 3-5 分钟
├─ 优化方案:
│  ├─ 权重预缓存到本地 NVMe(不从 NFS 加载)
│  ├─ keep-warm 至少 1 副本(不完全 scale-to-zero)
│  ├─ startupProbe 给足够时间(failureThreshold > 60)
│  ├─ 客户端 timeout 匹配(不要 30s 就超时)
│  └─ 预热请求(启动后先发一个短 prompt 预热 KV Cache 和 CUDA Graph)
└─ 权衡:不完全 scale-to-zero vs 冷启动延迟

Scale-to-Zero 适用场景

  • 低频调用的内部工具模型(每天几十次请求)
  • 开发测试环境的模型
  • 非实时的批处理 API

不适用场景

  • 用户实时对话(冷启动超时不可接受)
  • 高 QPS 生产服务(频繁扩缩成本高)

GPU-aware 扩缩指标#

指标来源阈值扩缩动作
vllm:num_requests_waitingvLLM metrics> 10扩容
GPU SM 利用率DCGM Exporter> 85%扩容
GPU 显存占用DCGM Exporter> 92%扩容
KV Cache 使用率vLLM metrics> 90%扩容
GPU SM 利用率DCGM Exporter< 20% 持续 30min缩容

可观测体系#

系统指标#

层级指标来源告警阈值
请求级TTFT / TPOT / e2e latencyvLLM/SGLang metricsP95 > SLA
请求级Queue Length / num_runningvLLM/SGLang metricswaiting > 10,5min
资源级GPU 利用率 / 显存 / 温度DCGM Exporterutil < 20% / mem > 95%
通信级NCCL 带宽 / 错包DCGM + NCCL错包 > 0 立刻告警
引擎级Batch Size / KV Cache UsagevLLM metricsKV > 90%

成本指标#

  • 单请求成本prompt_tokens × input_price + completion_tokens × output_price
  • 单 token 成本:按模型拆分
  • 租户维度成本:按 Virtual Key / Team 聚合
  • 模型维度成本:按底层模型拆分
sql
-- LiteLLM SpendLogs 按团队 × 模型的花费矩阵
SELECT
    metadata->>'team' AS team,
    model,
    SUM(spend) AS spend,
    SUM(total_tokens) AS tokens
FROM "LiteLLM_SpendLogs"
WHERE startTime > NOW() - INTERVAL '30 days'
GROUP BY 1, 2 ORDER BY spend DESC;

-- GPU 闲置成本
SELECT
    node,
    (1 - AVG(gpu_utilization)) * gpu_hourly_cost AS idle_cost
FROM dcgm_metrics
GROUP BY 1;

效果指标(2026 新增)#

模型服务质量不仅看延迟和成本,还要看输出质量:

  • 质量漂移:同一批 benchmark prompt,对比新旧版本模型输出的差异
  • 幻觉检测:对 RAG 场景,检测生成内容是否与检索文档一致
  • 在线采样评估:对生产流量随机采样,人工或自动评估质量

效果指标采集方法

text
1. 离线评测:定期跑 benchmark(MMLU/HumanEval/C-Eval)
2. 在线采样:1% 生产流量 → 自动评分(LLM-as-a-Judge)
3. RAG 一致性:生成内容 vs 检索文档的 NLI(自然语言推理)分数
4. 用户反馈:点赞/点踩 → 质量信号

OpenTelemetry GenAI 语义约定(2026 现状)#

截至 2026 年,OpenTelemetry 的 GenAI 语义约定大部分仍处于 Experimental/Development 状态(尚未 stable、属性名仍可能变动),但已成为 LLM 可观测的事实对齐方向。它大致可分为六层属性:

text
L1: GenAI 系统(system, model, provider)
    gen_ai.system: "vllm"
    gen_ai.request.model: "qwen2.5-72b"
    gen_ai.provider: "litellm"

L2: 请求属性(max_tokens, temperature, top_p)
    gen_ai.request.max_tokens: 1024
    gen_ai.request.temperature: 0.3
    gen_ai.request.top_p: 0.9

L3: Token 用量(input_tokens, output_tokens, total_tokens)
    gen_ai.usage.input_tokens: 150
    gen_ai.usage.output_tokens: 320
    gen_ai.usage.total_tokens: 470

L4: 响应属性(finish_reasons, response_id)
    gen_ai.response.finish_reasons: ["stop"]   # 官方为数组
    gen_ai.response.id: "chatcmpl-xxx"

L5: 成本属性(注意:OTel 官方约定目前并无 cost 语义属性,
    以下为 LiteLLM 等厂商的自定义扩展,跨系统不保证一致)
    gen_ai.response.cost.amount: 0.0023        # 非官方
    gen_ai.response.cost.currency: "USD"       # 非官方

L6: Agent/MCP 工具调用(tool_name, tool_call_id, mcp_server)
    gen_ai.tool.name: "search_web"
    gen_ai.tool.call.id: "call_xxx"
    gen_ai.tool.mcp.server: "mcp-search"

标准化的意义:不同的推理引擎(vLLM/SGLang/TRT-LLM)、不同的中间件(LiteLLM/LangChain),只要遵循 OTel GenAI 约定,就能统一接入 Jaeger/Tempo 做链路追踪,Prometheus 做指标采集。不用为每个引擎写自定义 instrument。

接入方式

python
# vLLM 启动时启用 OTel
vllm serve Qwen/Qwen2.5-72B-Instruct \
  --otlp-traces-endpoint http://otel-collector:4317

# LiteLLM Proxy 配置 OTel
litellm_settings:
  otel:
    endpoint: http://otel-collector:4317
    service_name: litellm-proxy

监控技术栈#

组件用途采集内容
DCGM ExporterGPU 指标SM 利用率、显存、温度、功耗、NVLink 带宽、ECC
vLLM/SGLang /metrics推理引擎指标TTFT、TPOT、tokens/s、queue、KV Cache 使用率
LiteLLM /metrics网关指标QPS、Spend、Error rate、model/team 维度
Prometheus指标存储所有上述指标
Grafana可视化Dashboard 面板 + 告警规则
Loki / ELK日志聚合推理请求日志、错误日志
Jaeger / Tempo链路追踪OTel GenAI trace
LangfuseLLM 调用审计Prompt + Response + Token 全量记录

告警规则示例#

yaml
# GPU 温度过高
- alert: GPUHighTemperature
  expr: DCGM_FI_DEV_GPU_TEMP > 85
  for: 5m
  labels:
    severity: warning
  annotations:
    summary: "GPU {{ $labels.gpu }} 温度过高"

# KV Cache 接近用满
- alert: KVCacheAlmostFull
  expr: vllm:gpu_cache_usage_perc > 0.95
  for: 10m
  labels:
    severity: critical

# 请求排队超过阈值
- alert: VLLMHighQueueDepth
  expr: vllm:num_requests_waiting > 20
  for: 1m
  labels:
    severity: warning

# P99 TTFT 超过 SLA
- alert: HighP99TTFT
  expr: histogram_quantile(0.99, vllm:time_to_first_token_seconds_bucket) > 10
  for: 2m
  labels:
    severity: critical

# 单 Team 日消费异常
- alert: LLMDailyCostSpike
  expr: increase(litellm_spend_metric[1h]) / increase(litellm_spend_metric[1h] offset 1d) > 3
  for: 10m
  labels:
    severity: warning

# NCCL 错包(硬件故障信号)
- alert: NCCLErrorCount
  expr: increase(nccl_errors_total[5m]) > 0
  labels:
    severity: critical

实战要点#

  1. AI Gateway 是必须的,不是可选的:不到网关层做统一接入,多模型、多团队、成本统计、安全审计都是空谈。LiteLLM 是开源首选。

  2. 限流优先于扩容:遇到流量峰值先限流保护已有服务,等扩容完成再放开。直接扩容可能扩容还没完成服务已经被打挂。

  3. 熔断 fallback 链路要测试:fallback 到的模型可能更贵,不要兜底到比主模型贵得多的模型上。fallback 模型可能被打爆——监控 fallback 模型的 QPS。

  4. HPA 用 GPU 指标而非 CPU:LLM 推理的 CPU 使用率和实际负载关系弱。用 num_requests_waiting 或 GPU 利用率作扩缩指标。

  5. OpenTelemetry GenAI 语义约定是 2026 的对齐方向(多数属性仍 experimental、未 stable):新项目可观测设计直接对齐它,省去大量自定义 instrument 工作。六层属性覆盖系统/请求/Token/响应/成本/Agent 工具调用——但要注意"成本"属性并非官方约定,需用厂商自定义扩展。

  6. 成本指标是治理的基础:没有「谁花了多少钱」的数据,成本优化就是盲人摸象。按 Team/Model/Feature 维度拆分,配预算告警。

  7. Scale-to-Zero 要权衡冷启动:低频模型可以 scale-to-zero 省成本,但第一个请求会超时。keep-warm 1 副本是折中方案。

  8. 效果可观测不能省:只看延迟和成本不看质量,模型劣化发现不了。RAG 场景的幻觉检测、定期 benchmark 评测是在线质量保障的底线。

  9. 灰度必须可回滚:灰度期间保留老版本权重一直到新版本稳定至少 1 周。回滚要秒级见效(网关层切流量)。

  10. 审计日志要全:LLM 调用的 Prompt + Response + Token + Cost 全量记录,合规抽查时这是唯一凭据。


小结#

线上稳定性与可观测的核心能力矩阵:

text
AI Gateway(鉴权/路由/隔离/额度/审计)
稳定性(限流/熔断/fallback/超时/重试/灰度/回滚)
弹性伸缩(HPA(KEDA) / scale-to-zero / 冷启动 / GPU-aware 指标)
可观测(系统指标 + 成本指标 + 效果指标)
技术栈(OTel GenAI / DCGM / Prometheus / Grafana / Loki / Jaeger / Langfuse)

2026 年的关键认知:

  • OTel GenAI 语义约定是 LLM 可观测的对齐方向(多数属性仍 experimental、无官方 cost 属性),新项目可提前对齐
  • Scale-to-Zero让低频模型成本可控,但冷启动要预留优化
  • 效果可观测(质量/幻觉)是与传统 DevOps 可观测的最大区别
  • AI Gateway是 LLM 服务化的统一入口,不是可选组件

下一章进入 模型工程化与平台治理——Model Registry、Eval Pipeline、国内合规备案、内容安全。