Skip to content

CPU + GPU:为什么 AI 平台工程本质上是一个异构基础设施问题

“AI 工作负载从来不是‘GPU-only’的端到端流程——它是 CPU、GPU、内存带宽、存储 I/O、网络延迟与调度策略在毫秒级协同下的交响。忽视 CPU 层的瓶颈,等于用 100 张 H100 去跑一个被 kubectl top node 显示为 98% CPU wait 的 vLLM Pod。”
—— 来自 CNCF Blog 2026 年深度观察,亦是我们过去 18 个月在 3 家头部大模型平台落地验证后的第一性原理结论。

背景动机:当“GPU is all you need”叙事开始崩塌

2023–2024 年,AI 基础设施圈弥漫着一种乐观的简化主义:“只要堆够 GPU,一切皆可训、皆可推”。Kubernetes 集群被快速打标为 nvidia.com/gpu: 8,Helm Chart 默认启用 resources.limits.nvidia.com/gpu: 4,SRE 团队甚至将 GPU 节点池命名为 ai-gpu-prod——仿佛 CPU、内存、本地 NVMe、RDMA 网络只是 GPU 的静态陪衬。

但现实很快给出了反例:

  • 某金融风控大模型推理服务(vLLM + LoRA)在 A100-80G 上 P99 延迟突增至 2.3s,nvidia-smi 显示 GPU 利用率仅 35%,而 kubectl top pod 显示其 sidecar data-loader 容器 CPU 使用率达 12/12 cores;
  • 某多模态训练 Pipeline 在 PyTorch DDP 启动阶段卡死 47 秒,strace -p $(pgrep -f "torch.distributed") 显示大量 futex 等待,最终定位为 CPU 核心间 NUMA 不均衡 + /dev/shm 容量不足(默认 64MB,实际需 2GB);
  • 某 RAG 服务在 QPS > 800 后出现 Connection reset by peerss -s 显示 tcp_tw_count 爆表,根源却是 Istio sidecar(Envoy)因 CPU 配额不足无法及时 recycle TIME_WAIT socket。

这些都不是 GPU 显存或算力不足的问题——它们是CPU 子系统、内核参数、cgroup v2 限制、NUMA 拓扑感知调度、共享内存配置与网络栈协同失效的综合症候群。AI 平台工程的真正挑战,早已从“如何让 GPU 跑起来”,跃迁至“如何让 CPU/GPU/IO/NIC 在 Kubernetes 的抽象层下不失真地协同”。

核心技术:构建真正异构感知的 K8s AI 工作负载

1. CPU 亲和性 ≠ 简单绑核:NUMA-aware + CFS bandwidth 控制

GPU 计算密集型 Pod 必须绑定到与 GPU 同一 NUMA node 的 CPU cores,否则跨 NUMA 访存将带来 40–60% 带宽衰减(实测 A100+EPYC 9654 场景)。但 spec.affinity.nodeAffinity 仅解决节点级调度,Pod 级 CPU 绑定需组合使用 cpuset.cpus + topology.kubernetes.io/zone

以下 YAML 展示一个 vLLM 推理 Pod 的生产级 CPU/GPU 协同配置:

yaml
apiVersion: v1
kind: Pod
metadata:
  name: vllm-prod-01
  annotations:
    # 启用 cgroup v2 + memory.low 防止 OOM kill 影响 GPU 进程
    container.apparmor.security.beta.kubernetes.io/vllm: runtime/default
spec:
  nodeName: gpu-node-07  # 已通过 NodeLabel + DevicePlugin 确保该节点有 A100-80G
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: topology.kubernetes.io/zone
            operator: In
            values: ["zone-a"]  # 与 GPU 所在 zone 一致
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values: ["vllm-data-loader"]
        topologyKey: topology.kubernetes.io/zone
  containers:
  - name: vllm
    image: ghcr.io/vllm-project/vllm:v0.4.3
    resources:
      limits:
        nvidia.com/gpu: 4
        cpu: 24
        memory: 128Gi
      requests:
        nvidia.com/gpu: 4
        cpu: 24
        memory: 128Gi
    # 关键:显式指定 cpuset,且与 GPU NUMA node 对齐
    volumeMounts:
    - name: dev-shm
      mountPath: /dev/shm
  volumes:
  - name: dev-shm
    emptyDir:
      medium: Memory
      sizeLimit: 4Gi  # 必须显式设为 ≥2Gi,vLLM 的 PagedAttention 重度依赖
  # 启用 RuntimeClass 实现 cgroup v2 + unified hierarchy
  runtimeClassName: nvidia-cgroups-v2

配套的 RuntimeClass(需提前部署):

yaml
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
  name: nvidia-cgroups-v2
handler: nvidia-container-runtime
overhead:
  cpu: 500m
  memory: 2Gi
# 启用 cgroup v2 特性开关
scheduling:
  nodeSelector:
    kubernetes.io/os: linux
    feature.node.kubernetes.io/runtime-cgroup-driver-cgroupfs: "false"  # 强制 systemd driver

技术判断cpuset.cpus 不能仅靠 kubelet --cpu-manager-policy=static 自动分配——它无法感知 GPU 的 NUMA node。必须通过 topology.kubernetes.io/zone + nodeAffinity 锁定物理拓扑,再配合 RuntimeClass 强制 cgroup v2,才能实现真正的异构协同。

2. GPU 共享 ≠ 时间片切分:MIG + vGPU 的运维真相

NVIDIA MIG(Multi-Instance GPU)在 K8s 中常被误用为“逻辑 GPU 分片”。但 MIG 是物理硬件切分,每个 MIG instance 独占 L2 cache、显存控制器、计算单元。若在单卡上创建 7 个 MIG instance(如 A100-80G → 7×10G),则每个 instance 的 FP16 算力仅为全卡的 ~1/7,但PCIe 带宽、NVLink、显存带宽仍被 7 个 instance 共享竞争

生产建议:

  • 训练场景禁用 MIG:DDP 多进程需全卡显存 & NVLink 低延迟,MIG 反而引入跨 instance 通信开销;
  • 推理场景慎用 MIG:仅当模型显存 ≤10G 且 batch_size 极小(<4)时收益明显;否则优先用 vLLM 的 PagedAttention + continuous batching;
  • 替代方案:nvidia-device-plugin + k8s-device-plugin 支持 nvidia.com/gpu.memory: 20Gi(基于 MIG 的 memory-aware scheduling),但需配合 nvidia-smi -L 动态发现可用 MIG instance。

3. 数据加载:CPU 成为最大隐性瓶颈

vLLM 的 AsyncLLMEngine 默认启动 4 个 DataLoader 线程,但若未挂载高性能本地 NVMe(而非 NFS/CephFS),或未设置 O_DIRECT,则 CPU 将持续处于 io_wait。我们在线上观测到:当 kubectl top node 显示 cpu-wait > 60%,即使 GPU 利用率 <20%,P99 延迟也飙升 300%。

解决方案 YAML 片段:

yaml
# 在 StatefulSet 中显式挂载 NVMe 直通设备
volumeDevices:
- name: nvme-data
  devicePath: /dev/nvme0n1p1
volumes:
- name: nvme-data
  persistentVolumeClaim:
    claimName: pvc-nvme-gpu-07

并在容器内初始化脚本中执行:

bash
# 禁用 ext4 journal(推理场景无需事务一致性)
tune2fs -o journal=none /dev/nvme0n1p1
# 设置 I/O scheduler 为 none(NVMe 原生支持 MQ-DEADLINE)
echo none > /sys/block/nvme0n1/queue/scheduler
# mount with direct I/O flags
mount -o noatime,nodiratime,dax /dev/nvme0n1p1 /data

运维建议:面向异构基础设施的 SRE 清单

维度生产必须项检查命令示例
NUMA 拓扑所有 GPU 节点运行 numactl --hardware,确认 GPU PCI bus 与 CPU cores 同 nodelspci -vv -s $(nvidia-smi -q | grep "Bus Id" | head -1 | awk '{print $4}') | grep NUMA
共享内存/dev/shm sizeLimit ≥ 2Gi for vLLM; ≥ 4Gi for multi-GPU trainingdf -h /dev/shmkubectl exec -it <pod> -- ls -lh /dev/shm
cgroup v2kubelet 必须启用 --cgroup-driver=systemd + --cgroups-per-qos=trueps aux | grep kubelet | grep cgroupcat /proc/1/cgroup | head -1
网络栈net.ipv4.tcp_tw_reuse=1, net.core.somaxconn=65535, net.ipv4.ip_local_port_range="1024 65535"`sysctl -a | grep -E "(tw_reuse
GPU 监控部署 dcgm-exporter + Prometheus,必须采集 DCGM_FI_DEV_GPU_UTIL, DCGM_FI_DEV_MEM_COPY_UTIL, DCGM_FI_DEV_PCIE_TX_BYTES`curl http://dcgm-exporter:9400/metrics | grep -E "(gpu_util

⚠️ 关键提醒:不要信任 nvidia-smi dmon 的默认采样间隔(2s)。生产环境请将 dcgm-exporter--collectors 显式设为 --collectors=dcgm_gpu_util,dcgm_gpu_mem_copy_util,dcgm_gpu_pcie_tx_bytes,并调高 Prometheus 抓取频率至 1s——PCIe 带宽毛刺往往在 500ms 级别发生。

延伸阅读

  • 📘 CNCF TAG-AI 白皮书 v2.1:首次明确定义 “Heterogeneous Orchestration Layer” 架构层级,提出 TopologyAwareScheduler + DeviceProfile CRD 标准。
  • 📚 Kubernetes Enhancement Proposal KEP-3982:Topology Manager v2 正式进入 Beta,支持 CPU/GPU/NVMe/SmartNIC 多设备拓扑联合约束。
  • 🛠️ 开源工具推荐:
    • gpu-operator v24.9+:原生支持 MIG profile hot-reload 与 nvidia-dcgm-exporter 一键部署;
    • kube-hunter 插件 --ai-mode:自动扫描 NUMA 错配、/dev/shm 不足、cgroup v1 遗留等 AI 特征风险;
    • vLLM Bench:提供 --enable-chunked-prefill --gpu-memory-utilization 0.9 等真实负载压测模板,比 nvidia-smi 更早暴露 CPU 瓶颈。

AI 平台工程没有银弹。它是一场在 Linux 内核、GPU 固件、Kubernetes 调度器与大模型框架之间持续校准的精密平衡术。当你下次再看到 nvidia-smi 显示 GPU 利用率低迷时,请先敲入 kubectl top node --sort-by=cpu-wait——因为真正的敌人,往往藏在 GPU 的阴影之外。

—— KnoAI 技术站|深耕 K8s 异构调度一线 · 2026.09