Skip to content

05 - AI 行业 K8s 最佳实践

AI 工作负载 vs 传统 Web 工作负载

特性传统 Web 服务AI 训练/推理
生命周期长期运行训练是临时的,推理是长期的
资源类型CPU + 内存GPU + 大内存 + 高速存储 + 高速网络
成本相对低极高(GPU 按小时上百元)
弹性逐步扩缩训练前申请大量资源,完成后立即释放
数据量MB-GB 级TB-PB 级
容错无状态重启即可需要 Checkpoint 恢复

一、MLOps 平台架构

┌──────────────────────────────────────────────────────────────────┐
│                     ML Platform on K8s                           │
│                                                                  │
│  ┌───────────┐  ┌───────────┐  ┌───────────┐  ┌──────────────┐ │
│  │ Notebook  │  │ Training  │  │  Model    │  │  Inference   │ │
│  │ Server    │  │  Pipeline │  │  Registry │  │  Service     │ │
│  │           │  │           │  │           │  │              │ │
│  │ JupyterHub│  │ Kubeflow  │  │ MLflow /  │  │ TF Serving / │ │
│  │ on K8s   │  │ Pipelines │  │ ModelScope│  │ Triton /     │ │
│  │           │  │ / Argo    │  │           │  │ vLLM         │ │
│  └───────────┘  └───────────┘  └───────────┘  └──────────────┘ │
│        │              │              │              │            │
│        └──────────────┴──────────────┴──────────────┘            │
│                              │                                   │
│  ┌──────────────────────────────────────────────────────────┐   │
│  │                   K8s Cluster (ACK)                       │   │
│  │  GPU Node Pool │ CPU Node Pool │ Spot/抢占式 Node Pool    │   │
│  └──────────────────────────────────────────────────────────┘   │
│  ┌──────────────────────────────────────────────────────────┐   │
│  │  Storage: NAS (数据集) │ OSS (模型/日志) │ 云盘 (缓存)     │   │
│  └──────────────────────────────────────────────────────────┘   │
└──────────────────────────────────────────────────────────────────┘

二、GPU 资源管理最佳实践

节点池分层设计

yaml
# 节点池 1:GPU 训练池(按需/预留实例)
# - 大 GPU 规格(A100/V100)
# - 用于大规模训练
# - 标签: pool=gpu-training

# 节点池 2:GPU 推理池(按需实例)
# - 中等 GPU 规格(A10/T4)
# - 用于模型推理
# - 标签: pool=gpu-inference

# 节点池 3:GPU Spot 池(抢占式实例)
# - 低成本 GPU
# - 用于可容错的训练任务
# - 标签: pool=gpu-spot

# 节点池 4:CPU 池
# - 数据预处理、调度组件、监控等
# - 标签: pool=cpu

GPU 调度策略

yaml
# 训练任务:使用专用 GPU 节点
spec:
  nodeSelector:
    pool: gpu-training
  tolerations:
  - key: nvidia.com/gpu
    operator: Exists
    effect: NoSchedule
  containers:
  - name: train
    resources:
      limits:
        nvidia.com/gpu: 8    # 整机独占

---
# 推理任务:可以共享 GPU
spec:
  nodeSelector:
    pool: gpu-inference
  containers:
  - name: inference
    resources:
      limits:
        aliyun.com/gpu-mem: 8  # cGPU 共享 8GB 显存

GPU 监控

bash
# DCGM Exporter(NVIDIA 官方 GPU 监控)
helm install dcgm-exporter gpu-helm-charts/dcgm-exporter

# 关键指标
# DCGM_FI_DEV_GPU_UTIL     - GPU 利用率
# DCGM_FI_DEV_FB_USED      - 显存使用
# DCGM_FI_DEV_GPU_TEMP     - GPU 温度
# DCGM_FI_DEV_POWER_USAGE  - 功耗
yaml
# Grafana 告警示例
# GPU 利用率持续 30 分钟低于 10%(浪费资源)
expr: avg_over_time(DCGM_FI_DEV_GPU_UTIL[30m]) < 10
# GPU 显存使用率超过 95%(可能 OOM)
expr: DCGM_FI_DEV_FB_USED / DCGM_FI_DEV_FB_FREE > 0.95

三、分布式训练最佳实践

训练任务生命周期管理

代码提交 → 镜像构建 → 数据准备 → 训练启动 → 监控 → Checkpoint → 模型评估 → 模型注册

                           ┌────────┴────────┐
                           │                  │
                     训练成功              训练失败
                           │                  │
                      模型评估           自动重试/通知

                      模型注册

                      推理部署

Checkpoint 策略(关键!)

GPU 资源昂贵,断点续训是必须的:

python
# 训练代码中的 Checkpoint 最佳实践
import torch
import os

def save_checkpoint(model, optimizer, epoch, loss, path):
    """定期保存 Checkpoint 到共享存储"""
    torch.save({
        'epoch': epoch,
        'model_state_dict': model.state_dict(),
        'optimizer_state_dict': optimizer.state_dict(),
        'loss': loss,
        'rng_state': torch.random.get_rng_state(),
        'cuda_rng_state': torch.cuda.get_rng_state_all(),
    }, path)

def load_checkpoint(path, model, optimizer):
    """从 Checkpoint 恢复训练"""
    if os.path.exists(path):
        ckpt = torch.load(path)
        model.load_state_dict(ckpt['model_state_dict'])
        optimizer.load_state_dict(ckpt['optimizer_state_dict'])
        torch.random.set_rng_state(ckpt['rng_state'])
        torch.cuda.set_rng_state_all(ckpt['cuda_rng_state'])
        return ckpt['epoch'], ckpt['loss']
    return 0, float('inf')

# 训练循环中
for epoch in range(start_epoch, total_epochs):
    train_one_epoch(model, dataloader, optimizer)

    # 每 N 个 epoch 保存一次
    if epoch % save_interval == 0:
        save_checkpoint(model, optimizer, epoch, loss,
                       f'/output/checkpoint_epoch_{epoch}.pt')

    # 保留最新的 Checkpoint
    save_checkpoint(model, optimizer, epoch, loss,
                   '/output/checkpoint_latest.pt')
yaml
# PyTorchJob 配置:共享存储 + 自动恢复
spec:
  pytorchReplicaSpecs:
    Worker:
      replicas: 4
      restartPolicy: OnFailure  # 失败自动重启
      template:
        spec:
          containers:
          - name: train
            command:
            - python
            - train.py
            - --resume=/output/checkpoint_latest.pt  # 自动恢复
            volumeMounts:
            - name: data
              mountPath: /data
              readOnly: true
            - name: output
              mountPath: /output      # Checkpoint 存这里
          volumes:
          - name: data
            persistentVolumeClaim:
              claimName: training-data    # NAS RWX
          - name: output
            persistentVolumeClaim:
              claimName: training-output  # NAS RWX

通信优化

yaml
# 大规模训练通信优化
env:
# NCCL 优化
- name: NCCL_ALGO
  value: "Ring"               # Ring AllReduce(适合中等规模)
  # value: "Tree"             # Tree AllReduce(适合大规模)
- name: NCCL_IB_DISABLE
  value: "0"                  # 启用 InfiniBand/RoCE
- name: NCCL_NET_GDR_LEVEL
  value: "5"                  # GPU Direct RDMA(最高性能)
- name: NCCL_SOCKET_IFNAME
  value: "eth0"               # 指定网卡
- name: NCCL_DEBUG
  value: "WARN"               # 生产用 WARN,调试用 INFO

# PyTorch DataLoader 优化
- name: OMP_NUM_THREADS
  value: "4"

数据加载优化

┌──────────────────────────────────────────────────────────┐
│  数据管道设计                                             │
│                                                          │
│  OSS (海量原始数据)                                       │
│       │ 预处理 Job                                       │
│       ▼                                                  │
│  NAS (处理后的训练数据)                                    │
│       │ 训练 Pod 直接读取                                 │
│       ▼                                                  │
│  本地 SSD 缓存 (热数据)                                   │
│       │ 极速读取                                         │
│       ▼                                                  │
│  GPU 显存                                                │
└──────────────────────────────────────────────────────────┘
yaml
# 数据缓存策略:使用 emptyDir (SSD) 做本地缓存
spec:
  initContainers:
  - name: data-cache
    image: busybox
    command: ["cp", "-r", "/data/hot-subset", "/cache/"]
    volumeMounts:
    - name: data
      mountPath: /data
    - name: cache
      mountPath: /cache
  containers:
  - name: train
    volumeMounts:
    - name: cache
      mountPath: /fast-data     # 训练读取本地缓存
  volumes:
  - name: data
    persistentVolumeClaim:
      claimName: training-data
  - name: cache
    emptyDir:
      sizeLimit: 100Gi         # 本地 SSD 缓存

四、模型推理最佳实践

推理框架选择

框架特点适用场景
vLLM高性能 LLM 推理,PagedAttention大语言模型
TritonNVIDIA 出品,多框架支持通用模型推理
TF ServingTensorFlow 模型TF 生态
TorchServePyTorch 模型PyTorch 生态
Ollama简单易用的 LLM 运行小规模/本地

vLLM 部署示例

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: llm-inference
spec:
  replicas: 2
  selector:
    matchLabels:
      app: llm-inference
  template:
    metadata:
      labels:
        app: llm-inference
    spec:
      nodeSelector:
        pool: gpu-inference
      tolerations:
      - key: nvidia.com/gpu
        operator: Exists
        effect: NoSchedule
      containers:
      - name: vllm
        image: vllm/vllm-openai:latest
        command:
        - python
        - -m
        - vllm.entrypoints.openai.api_server
        - --model=/models/Qwen2-7B
        - --tensor-parallel-size=1
        - --max-model-len=4096
        - --gpu-memory-utilization=0.9
        ports:
        - containerPort: 8000
        resources:
          limits:
            nvidia.com/gpu: 1
        volumeMounts:
        - name: models
          mountPath: /models
        readinessProbe:
          httpGet:
            path: /health
            port: 8000
          initialDelaySeconds: 120    # 模型加载需要时间
          periodSeconds: 10
        livenessProbe:
          httpGet:
            path: /health
            port: 8000
          initialDelaySeconds: 180
          periodSeconds: 30
      volumes:
      - name: models
        persistentVolumeClaim:
          claimName: model-store
---
apiVersion: v1
kind: Service
metadata:
  name: llm-inference
spec:
  selector:
    app: llm-inference
  ports:
  - port: 8000
    targetPort: 8000
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: llm-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: llm-inference
  minReplicas: 1
  maxReplicas: 8
  metrics:
  - type: Pods
    pods:
      metric:
        name: gpu_utilization     # 自定义 GPU 指标
      target:
        type: AverageValue
        averageValue: "70"        # GPU 利用率超过 70% 扩容

推理服务优化

yaml
# 1. 模型预加载(initContainer 预热)
initContainers:
- name: model-warmup
  image: curlimages/curl
  command: ["curl", "-X", "POST", "http://localhost:8000/v1/completions",
            "-d", '{"model":"Qwen2-7B","prompt":"Hello","max_tokens":1}']

# 2. 请求队列和限流
# 通过 Ingress annotation 限制
annotations:
  nginx.ingress.kubernetes.io/limit-rps: "50"
  nginx.ingress.kubernetes.io/limit-connections: "20"

# 3. 自动扩缩容
# 基于自定义 GPU 利用率指标
# 需要 Prometheus Adapter 将 GPU 指标暴露为 K8s metrics

五、AI 平台成本优化

成本分布(典型 AI 团队)

GPU 计算: 60-70% ← 最大优化空间
存储: 15-20%
网络: 5-10%
CPU/管理: 5-10%

优化策略

策略节约方法
Spot/抢占式实例60-90%训练任务 + Checkpoint 容错
GPU 利用率提升20-50%cGPU 共享 / 在离线混部 / 时间片调度
训练效率优化间接混合精度(FP16/BF16)、梯度累积、优化数据加载
及时释放资源直接训练完成后自动缩容节点(Cluster Autoscaler)
模型蒸馏/量化推理成本降 50-80%大模型 → 小模型 / INT8 量化
按需购买30-60%预留实例券用于稳定负载

抢占式实例 + Checkpoint 方案

yaml
# 抢占式节点池配置(阿里云)
# ACK 控制台 → 节点池 → 创建
# 实例类型选择"抢占式实例"
# 开启"补偿型实例"(被回收时自动创建新节点)

# 训练 Job 配置
apiVersion: kubeflow.org/v1
kind: PyTorchJob
metadata:
  name: spot-training
spec:
  pytorchReplicaSpecs:
    Worker:
      replicas: 4
      restartPolicy: OnFailure
      template:
        spec:
          nodeSelector:
            pool: gpu-spot           # 使用 Spot 节点池
          tolerations:
          - key: china.alibabacloud.com/spot
            operator: Exists
          containers:
          - name: train
            command:
            - python
            - train.py
            - --checkpoint-interval=300  # 每 5 分钟保存一次
            - --resume=auto              # 自动从最新 Checkpoint 恢复

六、Kubeflow 全家桶

Kubeflow 是 Google 开源的 ML 平台,在 K8s 上提供完整 ML 工作流:

组件功能
Kubeflow Notebooks在线 Jupyter 环境
Kubeflow PipelinesML 工作流编排(DAG)
Training Operator分布式训练(PyTorchJob/TFJob)
KServe模型推理服务
Katib超参数调优(AutoML)

简化安装(只装需要的组件)

bash
# 只安装 Training Operator(分布式训练)
kubectl apply -k "github.com/kubeflow/training-operator/manifests/overlays/standalone"

# 只安装 KServe(推理服务)
kubectl apply -f https://github.com/kserve/kserve/releases/latest/download/kserve.yaml

# 安装 Kubeflow Pipelines
kubectl apply -k "github.com/kubeflow/pipelines/manifests/kustomize/cluster-scoped-resources"
kubectl apply -k "github.com/kubeflow/pipelines/manifests/kustomize/env/dev"

七、实际案例:完整 AI 训练到部署流程

┌─────────────────────────────────────────────────────┐
│  1. 开发阶段                                         │
│     Jupyter Notebook (K8s Pod + GPU)                 │
│     实验 → 确认模型和超参                              │
├─────────────────────────────────────────────────────┤
│  2. 训练阶段                                         │
│     PyTorchJob (4 Worker × 4 GPU = 16 GPU)          │
│     数据: NAS → 本地缓存 → GPU                       │
│     Checkpoint: 每 1000 步保存到 NAS                 │
│     监控: GPU 利用率 + 训练 loss + TensorBoard       │
├─────────────────────────────────────────────────────┤
│  3. 评估阶段                                         │
│     K8s Job: 在测试集上评估模型                       │
│     对比指标 → 决定是否上线                           │
├─────────────────────────────────────────────────────┤
│  4. 注册阶段                                         │
│     模型推送到 OSS / Model Registry                  │
│     记录模型版本、指标、超参                           │
├─────────────────────────────────────────────────────┤
│  5. 部署阶段                                         │
│     Deployment + HPA (GPU 指标扩缩容)                │
│     灰度发布: 10% → 50% → 100%                      │
│     推理优化: 量化 / TensorRT / vLLM                 │
├─────────────────────────────────────────────────────┤
│  6. 监控阶段                                         │
│     延迟 P99 < 200ms                                │
│     GPU 利用率 > 60%                                 │
│     模型效果监控 (数据漂移检测)                       │
└─────────────────────────────────────────────────────┘

下一步

06 - AI 机器人初创公司 K8s 落地方案