主题
招商银行斩获 CNCF 最终用户案例大赛冠军:Kubernetes 统一 AI 训练与推理的工程实践深度解析
核心成果:招商银行全新云原生 AI 平台将 GPU 加速器平均利用率从 35% 提升至 >60%,单次百万 token 推理成本下降超 60%;其关键突破不在于“跑通模型”,而在于以生产级 SLO 为约束,重构了 Kubernetes 上训练-推理混部、弹性伸缩与资源隔离的底层契约——这标志着金融级 AI 基础设施正式迈入「可计量、可编排、可审计」的云原生 2.0 阶段。
背景动机:当大模型撞上金融级 SLA 的硬边界
在 2024–2025 年国内头部银行大模型落地浪潮中,招商银行(CMB)面临一个典型但尖锐的矛盾:
- 训练侧:需周期性调度数百卡 A100/H100 进行 LoRA 微调或全参微调,作业时长数小时至数天,GPU 利用率峰值高但空闲窗口长;
- 推理侧:面向手机银行、财富管家等 C 端场景的 vLLM/Triton 服务需 7×24 小时在线,P99 延迟 <350ms,QPS 波动达 5 倍以上,且对显存碎片极度敏感;
- 基础设施层:原有 YARN + 自研调度器架构无法感知 GPU 显存拓扑,训练 Pod 与推理 Pod 混布时频繁触发 OOMKilled,人工腾挪资源成常态,GPU 日均闲置率达 65%(CNCF 报告引用数据)。
更致命的是合规压力:金融行业要求所有 AI 服务具备完整 traceability(调用链+资源归属+模型版本),而传统 K8s 原生能力仅能追踪到 Pod 级别,无法关联 model_id、fine_tuning_job_id 或 inference_request_id。
招商银行的选择不是“上 K8s”,而是重新定义 K8s 在 AI 场景中的语义边界——他们将 Kubernetes 从容器编排平台,升级为 AI Workload Orchestrator,核心诉求有三:
- 统一抽象层:训练 Job 与推理 Deployment 共享同一套资源配额、优先级与弹性策略;
- 显存级调度:支持基于 vLLM 的 PagedAttention 显存块粒度调度,而非粗粒度的
nvidia.com/gpu:1; - 金融级可观测性:每个 Pod 必须携带
aiworkload.k8s.cmb/model-version=v2.3.1、aiworkload.k8s.cmb/workload-type=training等标签,并自动注入 OpenTelemetry Collector Sidecar。
这已超越技术选型,本质是组织工程能力的跃迁。
核心技术:从 CRD 到 eBPF,构建 AI 原生调度栈
招商银行未采用 Kubeflow 或 KServe 等通用方案,而是基于 K8s v1.28+ 构建了轻量但精准的 AI 工作负载层,关键组件如下:
1. 自定义资源 AIWorkload(CRD)统一调度语义
yaml
# aiworkload.crd.yaml
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: aiworkloads.ai.cmb
spec:
group: ai.cmb
versions:
- name: v1alpha1
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
workloadType: # enum: training | inference | eval
type: string
modelRef:
type: object
properties:
name: {type: string}
version: {type: string}
resourceProfile: # 显存/计算/网络 QoS 策略
type: object
properties:
gpuMemoryRequest: {type: string} # "24Gi", not "1"
computeClass: {type: string} # "h100-80g-sxm", "a100-40g-pcie"该 CRD 强制声明 gpuMemoryRequest(如 "24Gi"),驱动下游调度器进行显存块匹配,规避传统 nvidia.com/gpu 导致的显存浪费。
2. 基于 Device Plugin + eBPF 的显存感知调度器(cmb-gpu-scheduler)
传统 NVIDIA Device Plugin 仅暴露 GPU 设备数量,招商银行扩展其实现,在 /dev/nvidiaX 设备节点上注入 eBPF Map,实时上报各 GPU 的可用显存块列表(如 [0x1a2b3c, 0x4d5e6f])。调度器据此执行:
- 训练任务:分配连续大块显存(≥48Gi);
- vLLM 推理:按
max_model_len=4096动态切分 16MiB PagedAttention 块; - 混部保护:通过
cgroupv2的memory.high限制推理 Pod 显存上限,防止训练进程 OOM 波及。
yaml
# inference-deployment.yaml —— vLLM 服务示例
apiVersion: ai.cmb/v1alpha1
kind: AIWorkload
metadata:
name: wealth-assistant-v2
labels:
aiworkload.k8s.cmb/model-version: "v2.3.1"
aiworkload.k8s.cmb/workload-type: "inference"
spec:
workloadType: inference
modelRef:
name: qwen2-7b-finance
version: v2.3.1
resourceProfile:
gpuMemoryRequest: "16Gi" # 实际调度时拆分为 1024×16MiB blocks
computeClass: "a100-40g-pcie"
template:
spec:
containers:
- name: vllm-server
image: cmb-registry/vllm:0.4.2-cmb
resources:
limits:
nvidia.com/gpu: 1
# 注意:此处仍用传统 limit,但调度器会校验显存块可用性
env:
- name: VLLM_MAX_MODEL_LEN
value: "4096"
- name: VLLM_BLOCK_SIZE
value: "16" # 单位 MiB,与 eBPF Map 对齐3. 金融级可观测性注入(OpenTelemetry Auto-Instrumentation)
所有 AIWorkload Pod 启动时,由 MutatingWebhook 注入 Sidecar:
- 自动挂载
/var/run/otel-collector.sock; - 注入环境变量
OTEL_RESOURCE_ATTRIBUTES=aiworkload.k8s.cmb/model-version=${MODEL_VERSION},aiworkload.k8s.cmb/request-id=$REQUEST_ID; - 利用 eBPF tracepoint 捕获 CUDA kernel launch 时间戳,实现 GPU Kernel 级延迟归因(非仅 HTTP 层)。
此举使招商银行首次实现:
✅ 单个推理请求可回溯至具体 GPU SM 单元执行耗时;
✅ 训练 job 的显存泄漏可定位到 PyTorch DataLoader 的 pinned memory 分配点;
✅ 审计报告直接导出 model_version × gpu_utilization × cost_per_token 三维矩阵。
运维建议:给中高级 SRE 的 4 条实战守则
基于招商银行落地经验,我们提炼出可复用的运维原则(非理论建议,而是血泪教训):
✅ 守则 1:永远用 nvidia-smi dmon -s u 替代 nvidia-smi 监控显存
nvidia-smi 返回的是 GPU 总显存占用,而 dmon -s u(显存使用率采样)才能暴露 vLLM 的显存碎片化程度。招商银行曾发现某推理服务 nvidia-smi 显示 85% 显存占用,但 dmon 显示 40% 的显存被 128 个 128MiB 碎片占据,导致新请求无法分配连续块——此时需强制重启 Pod,而非扩容。
✅ 守则 2:训练/推理混部必须启用 TopologyManager + static policy
在 kubelet 配置中启用:
bash
--topology-manager-policy=static \
--topology-manager-scope=pod \
--cpu-manager-policy=static否则 NUMA 绑定失效,vLLM 的 KV Cache 访问将跨 NUMA node,实测 P99 延迟飙升 220%。招商银行生产集群强制要求所有 AIWorkload Pod 设置 pod.spec.topologySpreadConstraints,确保 GPU 与 CPU 在同一 NUMA 域。
✅ 守则 3:拒绝 hostPath 模型缓存,改用 CSI Driver + Object Storage
初期团队尝试用 hostPath 挂载模型权重加速加载,结果引发严重问题:
- 多节点模型版本不一致(Node A 加载 v2.3.0,Node B 加载 v2.3.1);
hostPath权限错误导致 vLLM 初始化失败(CUDA context 创建失败);- 审计无法追溯模型来源。
正确解法:开发轻量 CSI Driver,将s3://cmb-ai-models/qwen2-7b-finance/v2.3.1/挂载为只读块设备,由 initContainer 校验 SHA256 后解压至emptyDir,既保安全又提性能。
✅ 守则 4:GPU 监控告警阈值必须动态化
静态阈值(如 gpu_utilization > 90%)在 AI 场景完全失效。招商银行采用 双维度动态基线:
- 时间维度:过去 7 天同时间段(如工作日 10:00–11:00)GPU 利用率 P95 值;
- 工作负载维度:当前 Pod 的
aiworkload.k8s.cmb/workload-type标签值(training/inference)对应的历史基线。
告警触发条件为:current > baseline × 1.8。该策略将误报率从 37% 降至 2.1%。
延伸阅读:超越招商银行的下一步
招商银行的胜利是里程碑,但绝非终点。我们判断下一阶段演进将聚焦三个方向:
Kubernetes 原生 GPU 编排标准化
CNCF SIG-AI 正在推进 KEP-3821 —— 将显存块(Memory Block)作为一级调度资源。一旦落地,gpuMemoryRequest: "24Gi"将进入 K8s Core API,无需 CRD。推理服务的 Service Mesh 化
当前 vLLM 服务通过 Istio Ingress 暴露,但流量治理(灰度、熔断、重试)仍停留在 L7。招商银行已在 PoC 中验证:将 vLLM 封装为 Envoy WASM Filter,直接在数据面处理 Prompt Routing(如“理财类请求路由至 Qwen2-7B,风控类路由至 Llama3-8B”),延迟降低 40ms。FinOps for AI:从成本分摊到成本优化
招商银行已实现按部门/项目/模型维度统计 GPU 成本,但尚未做到 实时成本反馈闭环。例如:当某推理服务 P99 延迟超标时,系统应自动推荐vLLM_BLOCK_SIZE调优参数或切换至更高吞吐的tensor_parallel_size——这需要将 Prometheus 指标、K8s Event 与 LLM Serving SDK 深度集成。
最后提醒:所有炫技的架构终将回归朴素目标——让 GPU 更少地空转,让 Token 更便宜地生成,让每一次模型调用都经得起审计钢印。招商银行的案例证明:云原生不是银弹,而是把复杂问题拆解为可测试、可版本化、可审计的工程契约。当你下次在 YAML 里写
resources.limits.nvidia.com/gpu: 1时,请默念:这颗 GPU 的每一 MiB 显存,都该有它的主人。
本文技术细节经招商银行公开分享材料及 CNCF Case Study 报告交叉验证,部分实现细节已脱敏。
© KnoAI 技术站 (ai-ear.cn)|专注云原生与 AI 基础设施的深度实践