高级部署:从单机到集群¶
本章面向已经能启动模型服务,但需要处理多 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 分钟,等队列爆满才扩容已经太晚。可组合定时预扩容、最小热副本、预测性容量和溢出到备用池。缩容前停止接新请求并等待在途生成完成或达到总时限。
灰度与滚动升级¶
- 新版本先完成离线质量、安全和性能门禁。
- 启动独立 revision,预加载权重并运行业务 readiness 样本。
- 镜像 0% 流量或重放脱敏请求,验证日志、成本和稳定性。
- 按 1% -> 5% -> 25% -> 50% -> 100% 扩流,每级有最短观察窗口。
- 同时比较任务通过率、严重错误、TTFT、TPOT、失败率和每成功任务成本。
- 任何硬门槛触发时,模型别名立即回指旧版本;新版本保留现场供排查。
不要在同一次发布中同时升级模型、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 的价值来自共享资源、自动化发布、隔离和规模化运维;它不会自动解决显存估算、模型质量、长冷启动或错误的容量策略。