跳转至

高级部署:从单机到集群

本章面向已经能启动模型服务,但需要处理多 GPU、多节点、滚动升级、弹性和故障隔离的场景。先证明单机不能满足目标,再引入集群复杂度。

对 PCIe、NVLink、NVSwitch、NUMA、RDMA、InfiniBand、RoCE 或 NCCL 不熟悉时,先阅读硬件、显存与互连术语,再回到本章选择并行和拓扑。

复杂度阶梯

层级 形态 何时升级 新增故障面
L0 单进程单卡 模型能放下,开发或极低流量 进程、显存、模型文件
L1 单机多副本 单卡能放下,需要更高吞吐或隔离 负载均衡、队列、显存争用
L2 单机多卡并行 模型单卡放不下 GPU 拓扑、集合通信、切分
L3 多机单模型 单节点显存或计算仍不足 网络、节点同步、编排和恢复
L4 多模型共享集群 多团队、多版本、弹性需求 调度、租户、配额、碎片和升级
L5 多区域混合路由 容灾、地域和数据边界 一致性、跨区成本、策略审计

每上升一级,都应写明低一级为什么不能满足质量、时延、吞吐、容量或治理目标。

并行策略决策

单卡副本优先

模型能放入单卡时,优先每卡一个独立副本。请求不经过跨卡通信,单卡故障只损失部分容量,滚动升级也可以逐副本完成。

Tensor Parallel

TP 把同一层矩阵分散到多卡,适合单卡放不下或需要缩短单请求计算时间。卡间每层都有通信,最好限制在同一 NVLink/NVSwitch 域。跨慢速 PCIe 或跨节点使用 TP 前必须实测。

Pipeline Parallel

PP 把不同层分给不同阶段,适合单节点放不下或跨节点切分。小批量和交互流量容易产生 pipeline bubble;它更关注容量,不一定降低单请求时延。

Data Parallel

DP 让每个副本拥有完整模型,最适合扩大独立请求吞吐。网关应按副本队列长度或预计 token 工作量调度,而不是简单轮询。

Expert Parallel

EP 将 MoE 专家分散到设备。通信模式取决于 token 路由,负载可能不均匀。总参数决定权重驻留,激活参数不能直接转换为卡数。

问题 推荐起点
8B 模型、8 张卡、追求吞吐 8 个单卡副本
70B 权重单卡放不下、同机 4/8 卡高速互联 TP 4 或 TP 8
单节点仍放不下超大模型 PP/TP 组合或专用多节点 recipe
MoE 跨大量 GPU 按官方引擎支持评估 EP + TP/DP
短请求与长请求混合 分池部署,避免长请求阻塞交互池

生产参考架构

                   +-> admission / quota / auth
Client -> Gateway -+-> request classifier -> short-prompt pool
                   |                      -> long-context pool
                   |                      -> batch pool
                   +-> model alias -> versioned deployment

Control plane: registry + deployment controller + eval gate + rollout policy
Data plane:    inference pods + tokenizer workers + cache + tool/RAG services
Evidence:      traces + metrics + audit + cost ledger + raw eval artifacts

控制面决定“什么版本可以接多少流量”,数据面只处理已授权请求。不要让业务客户端直接拼出具体 Pod 地址或模型 revision。

模型制品分发

权重加载常常比容器启动慢得多。常见方案:

方式 优点 风险与适用范围
每节点本地 NVMe 预热 加载快,运行时不依赖网络存储 占空间,需要分发与一致性检查
共享并行文件系统 集中管理,适合大集群 启动风暴可能压垮元数据或带宽
对象存储拉取到本地缓存 成本和容量弹性好 首次启动慢,必须校验 hash 和断点续传
权重放入容器镜像 制品不可变 镜像巨大,分发与扫描成本高,通常不推荐超大模型

推荐把模型 manifest 与权重分开:manifest 固定仓库、revision、文件 hash、Tokenizer、chat template、量化格式和许可证;节点缓存按 hash 命中。服务就绪前检查全部文件,不能在首个用户请求中边下载边加载。

Kubernetes 基线

下面展示控制点,不是可以直接用于所有引擎的完整清单:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: llm-serve-v17
spec:
  replicas: 2
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 0
      maxSurge: 1
  template:
    metadata:
      labels:
        app: llm-serve
        model-version: v17
    spec:
      terminationGracePeriodSeconds: 120
      containers:
        - name: server
          image: registry.example/llm-server@sha256:<digest>
          args: ["--model", "/models/current", "--max-model-len", "8192"]
          resources:
            limits:
              nvidia.com/gpu: 1
          startupProbe:
            httpGet: {path: /health/ready, port: 8000}
            periodSeconds: 10
            failureThreshold: 90
          readinessProbe:
            httpGet: {path: /health/ready, port: 8000}
            periodSeconds: 5
          livenessProbe:
            httpGet: {path: /health/live, port: 8000}
            periodSeconds: 15

startupProbe 要覆盖最坏模型加载时间;readinessProbe 在服务无法接新请求时摘流;livenessProbe 只判断进程是否需要重启。若三者使用同一深度推理请求,负载高时可能触发重启风暴。

官方参考:Kubernetes GPU 调度、NVIDIA GPU Operator。

多 GPU Pod 与拓扑

一个 TP=8 的 Pod 通常请求 8 张 GPU,但“拿到 8 张卡”不代表拓扑理想。部署时记录:

  • GPU 的物理编号、NVLink/NVSwitch 连接和 NUMA 节点。
  • Pod 是否独占节点,其他工作负载是否争抢 CPU、内存或 PCIe。
  • NCCL 环境、网络接口、RDMA 和实际 all-reduce 带宽。
  • 跨节点任务是否需要 gang scheduling,避免只启动部分 worker 后长期等待。
  • 任一 worker 失败时,整个模型组如何摘流、重建和恢复缓存。

使用 nvidia-smi topo -m 查看单机拓扑;多节点用 NCCL tests 或引擎官方基准验证通信,而不是只用 ping。

调度与准入控制

LLM 请求的工作量差异巨大。队列至少估算:

prefill_work ~= input_tokens
decode_work  ~= expected_output_tokens
memory_work  ~= active_tokens x KV bytes per token

准入控制在接收前检查租户配额、最大 token、当前队列和显存水位。超过安全线时返回明确的 429/503 与重试建议,或者路由到降级池;不要无限排队直到所有请求一起超时。

长短请求隔离

  • 交互池:短输入、短输出,优化 TTFT 和 P95。
  • 长上下文池:限制并发,预留更大 KV Cache。
  • Batch 池:接受排队,优化总吞吐和成本。
  • 高风险池:固定强模型、严格日志和人工审批。

自动扩缩容

CPU 利用率通常不能代表推理压力。更合适的信号包括:待处理请求、排队时间、运行中序列、活跃 KV token、TTFT SLO 违反率和预计 token 工作量。

扩容策略要考虑模型冷启动:若启动需要 10 分钟,等队列爆满才扩容已经太晚。可组合定时预扩容、最小热副本、预测性容量和溢出到备用池。缩容前停止接新请求并等待在途生成完成或达到总时限。

灰度与滚动升级

  1. 新版本先完成离线质量、安全和性能门禁。
  2. 启动独立 revision,预加载权重并运行业务 readiness 样本。
  3. 镜像 0% 流量或重放脱敏请求,验证日志、成本和稳定性。
  4. 按 1% -> 5% -> 25% -> 50% -> 100% 扩流,每级有最短观察窗口。
  5. 同时比较任务通过率、严重错误、TTFT、TPOT、失败率和每成功任务成本。
  6. 任何硬门槛触发时,模型别名立即回指旧版本;新版本保留现场供排查。

不要在同一次发布中同时升级模型、Tokenizer、引擎、CUDA 和驱动。基础设施大版本变更应与模型行为变更分离。

Adapter 与多模型服务

动态加载 LoRA 可以减少基础权重重复,但会增加 adapter 生命周期、缓存、租户隔离和版本组合。必须记录每个请求使用的 base revision 与 adapter revision,并限制可加载数量、来源和显存占用。

多模型共卡适合低流量小模型;高负载时容易显存碎片和相互干扰。关键模型优先独占 GPU 或独立 MIG 实例,并用真实混合流量测试 noisy neighbor。

多区域与混合云

跨区域设计先确定数据是否允许移动,再谈容灾:

  • 区域内保持无状态入口和至少两个故障域。
  • 会话状态、RAG 索引和工具写入需要明确一致性和恢复点。
  • 模型版本与安全策略跨区一致,密钥和审计按区域管理。
  • 故障切换前验证备用区域容量,不把“有部署”误认为“可承载峰值”。
  • 外部 API 降级到私有模型时,明确能力差异和用户提示。

集群验收矩阵

测试 操作 期望结果
单 Pod 终止 删除一个推理 Pod 摘流,无新增失败,容量告警合理
单节点故障 停止节点或隔离网络 模型组重建,流量受控降级
权重缓存未命中 清空新节点缓存后扩容 启动时间可预期,hash 校验通过
上游限流 模拟 429 有界退避,不形成重试风暴
超长请求 超过 token 上限 在网关快速拒绝,不占用 GPU
峰值流量 目标峰值 1.5 倍 在准入保护下维持 SLO 或明确限流
灰度回归 注入严重错误样本 自动或人工停止扩流并回滚
区域切换 禁用主入口 备用容量、数据与审计符合预期

什么时候不要上 Kubernetes

如果只有一个模型、1 到 2 台服务器、稳定用户群,systemd 或 Docker Compose 加成熟监控可能更可靠。Kubernetes 的价值来自共享资源、自动化发布、隔离和规模化运维;它不会自动解决显存估算、模型质量、长冷启动或错误的容量策略。

高级部署完成定义:不是多节点成功生成一次,而是版本能灰度、容量能保护、故障能隔离、权重能验证、成本能归属,并且运维团队完成过真实回滚。

官方参考