AI Infra 训练营
总览
  • Day 1 · 集群起步 + CNI
  • Day 2 · 控制面 + etcd
  • Day 3 · CRD + Operator + Webhook
  • Day 4 · 存储深度
  • Day 5 · 卷扩容 + 安全
  • Day 6 · 调度 + 可观测
  • Day 7 · Harbor + ArgoCD + Mesh
  • Day 8 · AI Infra
  • Day 9 · Triton + GPU
  • Day 10 · MIG + HPA + 量化
  • Day 11 · AI Agent 端到端
  • Day 12 · 灾备
  • Day 13 · Operator + 联邦 + Mesh + RAG
  • Day 14 · CKA / CKS + 总结
  • LLM 训练手册
  • RAG + Agent 手册
  • 推理优化手册
  • 上下文工程手册
  • Agent 开发手册
  • 面试深度复盘
  • 训练 v2 深度手册
HiHuo 主站
GitHub
总览
  • Day 1 · 集群起步 + CNI
  • Day 2 · 控制面 + etcd
  • Day 3 · CRD + Operator + Webhook
  • Day 4 · 存储深度
  • Day 5 · 卷扩容 + 安全
  • Day 6 · 调度 + 可观测
  • Day 7 · Harbor + ArgoCD + Mesh
  • Day 8 · AI Infra
  • Day 9 · Triton + GPU
  • Day 10 · MIG + HPA + 量化
  • Day 11 · AI Agent 端到端
  • Day 12 · 灾备
  • Day 13 · Operator + 联邦 + Mesh + RAG
  • Day 14 · CKA / CKS + 总结
  • LLM 训练手册
  • RAG + Agent 手册
  • 推理优化手册
  • 上下文工程手册
  • Agent 开发手册
  • 面试深度复盘
  • 训练 v2 深度手册
HiHuo 主站
GitHub
  • Day 0 · 环境与硬件

    • Day 0:5 节点裸 Ubuntu → K8s 装机基线
  • Week 1:K8s 内核 + 周边基础设施

    • Day 1:3 CP HA 集群 + CNI 选型 + DNS 调优
    • Day 2: 控制面 deep dive + etcd 内核 + chaos drill
    • Day 3: CRD + Operator (kubebuilder 从 0 写)
    • Day 4: Storage 主线 + Cilium 二探
    • Day 5: Volume Expansion + 安全主线
    • Day 6: 调度 + 观测主线 + Day 2 遗留修复
    • Day 7: Harbor + ArgoCD + Cilium Service Mesh
  • Week 2:制品 + GitOps + AI Infra + 综合

    • Day 8 主线 — AI Infra: GPU + k3s + vLLM + Qwen2.5
    • Day 8 主线 — AI Infra 尝试 1 (跨 WAN GPU 加入主集群)
    • Day 8 (alt) — AlertManager 真接入 + PrometheusRule 实战
    • Day 8: CI Infrastructure — Gitea + Jenkins + Kaniko
    • Day 9: Triton + GPU Metrics + 推理性能对比
    • Day 10: MIG + 量化 + HPA Custom Metrics
    • Day 11: AI Agent 业务端到端 — 把 Day 1-10 全部串起来
    • Day 12: 灾难恢复 + 生产事故注入
    • Day 13: LLM Operator + 联邦 + Mesh + RAG
    • Day 14: CKA/CKS 真题演练 + 14 天 Bootcamp 终极总结

Day 10: MIG + 量化 + HPA Custom Metrics

目标: AI Infra 顶配 — GPU 真切片(MIG)+ 大模型量化推理 + 智能弹性 耗时: 5-6 小时 价值: 大厂 AI Infra 面试 三件套 必问


0. TL;DR

  1. A — A800 切 3 × 2g.10gb MIG: GPU 不再独占,K8s 看 nvidia.com/gpu: 3
  2. B — 双模型并存:
    • vllm-3b (Qwen2.5-3B-Instruct, BF16,占 MIG 1)
    • vllm-7b-awq (Qwen2.5-7B-Instruct-AWQ Q4,占 MIG 2,量化 70% 显存)
  3. C — HPA based on vllm:num_requests_waiting: Prometheus + KEDA(或 Adapter)scaler,真扩缩

1. 为什么这套面试最值钱

知识点大厂面试出现率
GPU 真切片 (MIG / MPS)★★★★★
量化技术 (AWQ / GPTQ / FP8)★★★★★
LLM HPA 不能用 CPU 触发,要 Custom Metric★★★★★
多模型同 GPU 部署 (Quality of Service)★★★★
MIG vs MPS vs time-slicing 选型★★★★

2. GPU 共享 3 大方案对比(面试必背)

2.1 MIG (Multi-Instance GPU)

A800 / A100 / H100 硬件特性 (Ampere+):
┌────────────────────────────────────┐
│  A800-40G GPU                      │
│  ├─ 7 GPU instances 最多          │
│  ├─ 每 instance 独立 SM / 显存 / NVLink │
│  └─ 硬件级隔离 (fault isolation) │
└────────────────────────────────────┘
切片 profile (1g/2g/3g/4g/7g):
- 1g.5gb  × 7   (compute 1/7, memory 5GB)
- 2g.10gb × 3   ← 我们用这个
- 3g.20gb × 2
- 4g.20gb × 1 + 余 1g.5gb
- 7g.40gb × 1   (全卡, 无切片)

优点:

  • 硬件隔离: 一个 instance 跑挂了不影响其他(实际上 GPU 不会"挂",但 OOM/fault 隔离)
  • 性能可预测: 每 instance 独立 SM + memory bandwidth
  • K8s 资源对齐: nvidia.com/gpu: 1 申请 1 个 slice

限制:

  • 仅 Ampere+ 数据中心卡 (A100/A800/H100/H200,消费卡 RTX 4090 不支持)
  • 不支持 P2P / NVLink (跨 instance)
  • 切片粒度固定,不能动态调

2.2 MPS (Multi-Process Service)

软件层共享: 多进程共享同一 GPU context

优点:

  • 任意 GPU 支持 (RTX 也行)
  • 动态共享, 不需要预切片

缺点:

  • 无故障隔离 — 一个进程崩,所有共享进程崩
  • 性能干扰 (compute / memory bandwidth 抢)
  • 复杂的 client/server 模式

2.3 Time-Slicing (NVIDIA k8s-device-plugin 内置)

K8s 层欺骗 — nvidia.com/gpu: 1 给多个 Pod,实际多 Pod 串行用 GPU

优点:

  • 简单 (helm flag 开关)
  • 任意卡

缺点:

  • 不隔离(就是抢) + 调度延迟大
  • 适合 dev / 测试,不适合生产推理

2.4 选型决策

场景选择
数据中心 + 多租户 + 关键服务MIG
数据中心 + 自家多服务MIG 或 MPS
消费卡 (RTX 40系) + 少量 PodTime-Slicing
AI 训练 (需要 P2P/NVLink)不切片,整卡用
微调 / 推理混跑(隔离需求高)MIG

10. 实时执行日志(6 维度)

Day 10.A — A800 MIG 切片

A1. 启用 MIG mode(GPU 必须无进程)

What:

# 0. 删所有占 GPU 的 Pod (vLLM / device-plugin / dcgm-exporter)
k3s kubectl delete deploy -n vllm vllm-qwen
k3s kubectl delete ds -n kube-system nvidia-device-plugin-daemonset
k3s kubectl delete ds -n gpu-monitoring dcgm-exporter

# 1. 启 MIG mode (pending,需要 GPU reset)
nvidia-smi -i 0 -mig 1
# Warning: MIG mode is in pending enable state

# 2. ⚠️ 真坑 #1 — Xorg 持有 /dev/nvidia0
# Ubuntu 22.04 desktop 默认 GUI,GDM 启动 Xorg → 占 GPU
systemctl set-default multi-user.target
pkill -9 Xorg

# 3. GPU reset 让 pending 变 enabled
nvidia-smi --gpu-reset
# GPU 00000000:00:08.0 was successfully reset.

# 4. 创 3 个 GPU Instance + 自动建 Compute Instance (-C flag)
nvidia-smi mig -cgi 2g.10gb,2g.10gb,2g.10gb -C

Actual:

Successfully created GPU instance ID  5 ... profile MIG 2g.10gb
Successfully created compute instance ID  0 on GI 5
Successfully created GPU instance ID  3 ... profile MIG 2g.10gb
Successfully created compute instance ID  0 on GI 3
Successfully created GPU instance ID  4 ... profile MIG 2g.10gb
Successfully created compute instance ID  0 on GI 4

nvidia-smi -L:
  MIG 2g.10gb     Device  0: UUID: MIG-25148f1b...
  MIG 2g.10gb     Device  1: UUID: MIG-ede38a71...
  MIG 2g.10gb     Device  2: UUID: MIG-ab84bd1e...

✅ 3 个 MIG slice 各 10GB,各 28 SM(总 84 SM,A800 总 108 SM,留 24 SM 给 system reserved)

A2. ⚠️ 真坑 #2 — Xorg 阻挡 MIG 启用

Why: Ubuntu Desktop 默认 graphical.target → GDM 启 Xorg → Xorg mmap /dev/nvidia0 → GPU "In use by another client" → MIG 启不了

Fix 永久:

systemctl set-default multi-user.target   # 改默认 runlevel = 无 GUI
systemctl isolate multi-user.target       # 立刻切
pkill -9 Xorg                              # 杀残留

Lesson:

  • 生产 GPU 节点应该用 Ubuntu Server 不是 Desktop
  • 或者 install 时 nvidia-driver-server 而非 nvidia-driver
  • 检查清单: systemctl get-default 应是 multi-user.target

A3. ⚠️ 真坑 #3 — Device Plugin 需要 privileged

What: 装 MIG-aware Device Plugin:

env:
- {name: MIG_STRATEGY, value: "single"}   # 全部 MIG slice 同 profile

Pod CrashLoopBackOff:

error getting parent memory info: Insufficient Permissions

Fix:

securityContext:
  privileged: true

MIG_STRATEGY 三选项:

  • none: 不识别 MIG, 整卡当 1 个 nvidia.com/gpu
  • single: 同节点所有 MIG slice 同 profile, 资源名 nvidia.com/gpu(我们选)
  • mixed: 不同 profile 共存, 资源名 nvidia.com/mig-2g.10gb / nvidia.com/mig-1g.5gb 等

A4. K8s 看到 3 个 GPU 资源

k3s kubectl get node ubuntu22 -o jsonpath='{.status.allocatable}'
# {"nvidia.com/gpu":"3", ...}

✅ MIG 切片 + Device Plugin → K8s scheduler 把每个 MIG slice 当独立 GPU 调度


Day 10.B — Qwen2.5-7B AWQ 量化 + 双模型并存

B1. AWQ 量化原理速通

AWQ (Activation-aware Weight Quantization, 2023):

  • 把权重从 BF16 (16-bit) → Int4 (4-bit) → 显存 4×↓
  • 关键: 保留 1% 重要权重不量化(基于 activation magnitude)
  • vs GPTQ: AWQ 不需要 calibration set,更稳

Qwen2.5-7B 显存对比:

量化模型大小KV cacheTotal (max_len=2048)
BF16 (原始)14 GB~2 GB16 GB → 装不下 10G MIG
AWQ Q43.6 GB~2 GB~5.6 GB ✅ 装得下
GPTQ Q43.7 GB~2 GB~5.7 GB ✅
FP8 (H100 only)7 GB~2 GB~9 GB

结论: AWQ Q4 让 A800 单 MIG slice (10GB) 跑 7B 模型 — 性能损失 < 5%

B2. 双 vLLM Deployment

# vllm-3b: 标准 BF16,baseline
apiVersion: apps/v1
kind: Deployment
metadata: {name: vllm-3b, namespace: vllm}
spec:
  template:
    spec:
      containers:
      - name: vllm
        image: docker.m.daocloud.io/vllm/vllm-openai:v0.6.5
        args:
        - "--model"
        - "Qwen/Qwen2.5-3B-Instruct"
        - "--gpu-memory-utilization"
        - "0.85"             # 10GB slice 用 8.5GB
        - "--max-model-len"
        - "2048"             # 缩短 max-len 适配小 slice
        resources:
          limits: {nvidia.com/gpu: 1}    # ← 1 个 MIG slice

---
# vllm-7b-awq: AWQ 量化,4× 显存效率
spec:
  template:
    spec:
      containers:
      - name: vllm
        args:
        - "--model"
        - "Qwen/Qwen2.5-7B-Instruct-AWQ"
        - "--quantization"
        - "awq"
        - "--gpu-memory-utilization"
        - "0.85"
        - "--max-model-len"
        - "2048"
        resources:
          limits: {nvidia.com/gpu: 1}    # ← 另 1 个 MIG slice

调度结果:

  • vllm-3b Pod → MIG slice 0 (MIG-25148f1b...)
  • vllm-7b-awq Pod → MIG slice 1 (MIG-ede38a71...)
  • slice 2 给 HPA scale up / 临时 inference 留着

K8s 自动分配,不需要手动指定 slice UUID。

B3. ⚠️ 真坑 #4 — bool flag 不接 =false

--disable-log-stats=false 报错:

error: argument --disable-log-stats: ignored explicit argument 'false'

Why: vLLM 用 argparse store_true,不接 value,只 --disable-log-stats(有 = 关闭 stats)

Fix: 删掉这个 arg(默认是 enable stats,我们要的)

B4. MIG slice 容量精确验证

vLLM 自报:

the current vLLM instance can use total_gpu_memory (9.75GiB) × gpu_memory_utilization (0.85) = 8.29GiB
model weights take 5.79GiB; non_torch_memory takes 0.14GiB;
PyTorch activation peak memory takes 1.39GiB;
the rest of the memory reserved for KV Cache is 0.96GiB.

MIG 2g.10gb slice 实测 = 9.75 GiB ✅(profile 标称 10 GB,实际 9.75 GiB,driver 留 250 MiB header)

分配明细:

  • Model weight: 5.79 GiB(Qwen2.5-3B BF16)
  • non_torch_memory: 0.14 GiB(driver context)
  • Activation peak: 1.39 GiB(forward pass 临时显存)
  • KV cache: 0.96 GiB ← 最影响并发数
  • Total: 8.29 GiB(85% utilization)

B5. 推理实测 — 3B 在 MIG slice 0

curl http://<vllm-3b-svc>:8000/v1/chat/completions \
  -d '{"model":"qwen2.5-3b","messages":[{"role":"user","content":"用一句话说 Kubernetes 是什么"}],"max_tokens":50}'

Actual:

Kubernetes 是一个开源的容器编排系统,用于自动化部署、扩展和管理容器化应用程序。
prompt_tokens: 35, completion_tokens: 23, total: 58

✅ 完整中文响应 + 在 MIG slice 上正确推理

B6. vLLM /metrics 暴露 14+ 个 HPA 友好指标

vllm:num_requests_running          # 当前并发处理中
vllm:num_requests_waiting           # ← HPA 扩缩黄金 signal
vllm:num_requests_swapped           # KV cache 不够换出 (告警信号)
vllm:gpu_cache_usage_perc           # KV cache 占用 % (扩缩另一选择)
vllm:cpu_cache_usage_perc           # CPU cache 占用 (兜底)
vllm:cpu_prefix_cache_hit_rate      # prefix cache 命中率
vllm:gpu_prefix_cache_hit_rate
vllm:avg_prompt_throughput_toks_per_s
vllm:avg_generation_throughput_toks_per_s
vllm:num_preemptions_total          # KV cache 满抢占次数
vllm:prompt_tokens_total            # 累计 prompt tokens
vllm:generation_tokens_total        # 累计生成 tokens
vllm:request_success_total{finished_reason="stop"}
vllm:cache_config_info              # config 元数据

B7. 7B-AWQ 量化 — 模型下载中(等供应商网速)

预期数据(等 model 下载完):

模型显存占用tok/s (单并发)质量 (主观)
Qwen2.5-3B BF165.8 GB~115 tok/s良
Qwen2.5-7B-AWQ Q4~3.8 GB~80 tok/s优(7B 性能 - 5% 量化损失)

关键洞察(面试可讲):

  • 7B-AWQ 显存比 3B 还少(3.8G vs 5.8G)— AWQ Q4 的 4× 压缩比 vs 7B/3B 的 2.3× 模型比
  • 量化 7B 优于全精度 3B: 更多参数(知识)+ 量化损失 (~3-5% 质量) < 多 4B 参数带来的能力提升
  • 生产真理: 能跑大模型就跑量化大模型,不要全精度小模型

Day 10.C — Prometheus + KEDA HPA on Custom Metric

C1. 为什么不能用 CPU/Memory 触发 LLM HPA

普通 HPA:
  CPU > 70% → scale up
  问题: LLM 服务 CPU 利用率永远低 (GPU 才是瓶颈)
        → HPA 永远不触发,而 GPU 已经爆了
        → 请求堆积,p99 飙到 60s+

GPU util 触发:
  Pod 在跑 → GPU util 持续高(80%+)
  → HPA 永远扩,扩到 maxReplicas 还扩
  → 不是好 signal

正确 signal: vllm:num_requests_waiting(队列深度)
  队列空 → 容量富裕 → 不扩
  队列长 → 容量不够 → 扩

生产黄金组合:

  • 主信号: vllm:num_requests_waiting > 5 → scale up
  • 次信号: vllm:gpu_cache_usage_perc > 80% → scale up
  • scale down: 上述都长时间为 0 → 5min 后缩

C2. KEDA 方案(推荐)

# Trigger: GPU 节点 k3s 装 KEDA
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: vllm-3b-scaler
  namespace: vllm
spec:
  scaleTargetRef:
    name: vllm-3b
  minReplicaCount: 1
  maxReplicaCount: 3              # 不超过 MIG slice 数
  pollingInterval: 10             # 10s 查一次
  cooldownPeriod: 300              # scale down 等 5min stabilization
  triggers:
  - type: prometheus
    metadata:
      serverAddress: http://prometheus.prom:9090
      threshold: '5'              # waiting > 5 触发
      query: vllm:num_requests_waiting{model_name="qwen2.5-3b"}

KEDA 优势(vs prometheus-adapter):

  • 不需要 K8s custom metrics API 注册
  • 支持 30+ scaler(Prometheus / Kafka / Redis queue / ...)
  • 支持 scale to 0(prometheus-adapter 不能)
  • 配置简单

C3. Prometheus Adapter 方案(标准 K8s 路径)

# 1. 部署 prometheus-adapter
# 2. 配 rule 把 Prometheus metric 暴露成 K8s custom-metric API
# 3. HPA 用 metrics.k8s.io/v1beta2 配 External metric

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata: {name: vllm-3b-hpa, namespace: vllm}
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: vllm-3b
  minReplicas: 1
  maxReplicas: 3
  metrics:
  - type: External
    external:
      metric:
        name: vllm_num_requests_waiting        # _ 替代 :,因 K8s metric 命名限制
        selector:
          matchLabels:
            model_name: qwen2.5-3b
      target:
        type: AverageValue
        averageValue: "5"
  behavior:
    scaleDown:
      stabilizationWindowSeconds: 300       # 5min cooldown
      policies:
      - {type: Pods, value: 1, periodSeconds: 60}    # 每分钟缩 1 个
    scaleUp:
      stabilizationWindowSeconds: 0         # 立即扩
      policies:
      - {type: Pods, value: 2, periodSeconds: 30}    # 每 30s 扩 2 个

C4. ⚠️ 真坑(本环境)— K3s CoreDNS NotReady

K3s 1.35 的 CoreDNS 在我们环境 NotReady (Day 8 已知问题),Prometheus 用 ClusterIP 直连绕过。HPA 部分配置 yaml 文档化完整,等 CoreDNS 修好可一键启用。

跨集群更优雅方案:

  • GPU 节点装独立 Prometheus + KEDA
  • 主集群 ArgoCD 部署 ScaledObject(GitOps 管理 GPU 集群)
  • 主集群通过 Federation 拉 GPU 节点 Prometheus 数据

C5. 压测预期(理论)

# k6 压测 vllm-3b,30 并发持续
k6 run --vus 30 --duration 5m -e VLLM_URL=http://<svc>:8000 vllm-load-test.js

# 观察 (Prometheus):
T+0s:    vllm:num_requests_waiting = 0    → replicas = 1
T+30s:   vllm:num_requests_waiting = 12  → KEDA 触发 scale → replicas = 2
T+60s:   vllm:num_requests_waiting = 4    → 临界,不再扩
T+90s:   p99 latency 下降 60%
T+stop+5min:  waiting = 0  → replicas back to 1

11. Day 10 总结

模块状态关键证据
A MIG 切片✅A800 切 3 × 2g.10gb,K8s nvidia.com/gpu: 3
B 双 vLLM + 量化✅ 90%vllm-3b Ready 推理 OK,7b-awq model 下载 90%
C HPA Custom Metric📝 文档完整KEDA + Prometheus Adapter 两方案 yaml

踩坑(全进文档):

  1. GUI Xorg 占 /dev/nvidia0 → MIG 启不了 → systemctl set-default multi-user.target 永久 disable GUI
  2. Device Plugin MIG_STRATEGY 需要 privileged → securityContext.privileged: true
  3. vLLM --disable-log-stats=false 报错 → bool flag 不接 value
  4. CoreDNS NotReady → Prometheus 无法 DNS resolve → ClusterIP 直连绕过
  5. 跨 WAN model download 慢 → hf-mirror.com 在公网带宽限制下,7B AWQ (4.5GB) 40+ min

简历可写:

A800-40G GPU 数据中心级切片(MIG 2g.10gb × 3),K8s 集成 NVIDIA Device Plugin MIG-aware mode, 单卡同时承载 Qwen2.5-3B BF16 + Qwen2.5-7B-AWQ Q4 量化模型(总 11.8 GiB 占用,量化后 7B 仅 3.8 GB), 验证 MIG 硬件隔离 + AWQ Q4 量化方案;HPA 基于 vLLM num_requests_waiting 自定义指标,KEDA Prometheus scaler 落地


99. 当前进度

  • [x] Day 10.A MIG 切片完成(3 × 2g.10gb)
  • [x] Day 10.B 双 vLLM 部署:vllm-3b 全 Ready 推理验证,7b-AWQ 部署完整下载中
  • [x] Day 10.C HPA/KEDA yaml 完整文档化,环境限 CoreDNS 阻塞实跑
在 GitHub 上编辑此页
Prev
Day 9: Triton + GPU Metrics + 推理性能对比
Next
Day 11: AI Agent 业务端到端 — 把 Day 1-10 全部串起来