6.12 AI 基础设施基础——GPU、CUDA 与模型服务

预计阅读时间:14 分钟

📖 目录

学习目标

学完本章后,你将能够:

  • 理解 GPU 的硬件架构和 CUDA 软件栈的层次关系
  • 在 Linux 上安装 NVIDIA 驱动并验证 GPU 可用性
  • 使用 NVIDIA Container Toolkit 让 Docker 容器访问 GPU
  • 部署 vLLM 和 Triton Inference Server 提供推理服务
  • 使用 nvidia-smi 和 DCGM 监控 GPU 健康状态和性能
  • 排查常见的 GPU/CUDA 错误和性能瓶颈

核心知识

  • GPU(Graphics Processing Unit)——最初为图形渲染设计的并行处理器,因大量 CUDA 核心适合矩阵运算,成为 AI 加速的核心硬件
  • CUDA(Compute Unified Device Architecture)——NVIDIA 的并行计算平台和编程模型,允许开发者用 C/C++ 直接调用 GPU 进行计算
  • cuDNN(CUDA Deep Neural Network Library)——NVIDIA 针对深度神经网络优化的 GPU 加速库,提供卷积、归一化、激活函数等高性能实现
  • NVIDIA Driver——操作系统与 GPU 硬件之间的通信层,包含内核模块(nvidia.ko)和用户空间库(libcuda.so)
  • NVIDIA Container Toolkit——在容器中暴露 GPU 设备文件的工具链,核心是 nvidia-container-runtime 和 nvidia-container-cli
  • vLLM——高性能 LLM 推理引擎,核心创新是 PagedAttention(分页显存管理),支持连续批处理和流式输出
  • Triton Inference Server——NVIDIA 官方的多模型推理服务框架,支持 TensorRT/ONNX/PyTorch 等多种后端
  • DCGM(Data Center GPU Manager)——NVIDIA 的数据中心 GPU 管理工具,提供比 nvidia-smi 更细粒度的遥测和健康检查

知识关联

  • 前置知识:了解 Linux 包管理(apt/yum)、Docker 基本用法(3.1:Docker 容器入门)、命令行基础
  • 后续影响:本章的 GPU 环境是运行 LLM 训练/推理、模型微调、生成式 AI 应用的硬件基础
  • 配套技术:nvidia-smi/DCGM 用于监控,可配合 Prometheus/Grafana 构建 GPU 仪表盘
  • 在整个体系中的位置:AI 基础设施的底层——GPU 硬件层 → 驱动/CUDA 层 → 容器运行时 → 推理框架 → 上层应用

原理讲解

1. GPU 硬件架构——从图形卡到 AI 加速器

GPU 与传统 CPU 的设计哲学截然不同:CPU 追求低延迟串行执行(几十个强大核心),GPU 追求高吞吐并行计算(数千个精简核心)。

维度CPUGPU
核心数量4-64 个数千个(如 A100 含 6912 个 CUDA 核心)
设计目标低延迟,单线程性能最大化高吞吐,大量线程同时执行
内存架构大容量 DDR(几十 GB)高带宽 HBM(几十 GB,带宽可达 2TB/s)
适合任务分支密集、延迟敏感的控制逻辑数据并行、计算密集的矩阵运算
典型功耗65-300W150-700W

NVIDIA GPU 内部以 SM(Streaming Multiprocessor) 为基本计算单元。每个 SM 包含一组 CUDA 核心、共享内存、寄存器文件和 warp 调度器。以 A100 为例:108 个 SM × 64 个 CUDA 核心/SM = 6912 CUDA 核心。GPU 在执行矩阵乘法(AI 推理的核心算力)时,数千个线程同时计算,做到"乘法比加法还快"的并行效果。

📝 CUDA 核心不是 CPU 核心 CUDA 核心是更轻量的 ALU(算术逻辑单元),不能独立运行完整指令线程。真正独立的执行单位是 SM。"核"的翻译容易产生误解。

2. CUDA 软件栈——从驱动到框架的四层结构

在 Linux 上运行 AI 模型,涉及从硬件到应用的完整软件栈:

组件作用
应用层vLLM / PyTorch / TensorFlow调用 cuBLAS/cuDNN 执行 AI 计算
加速库层cuBLAS / cuDNN / TensorRT封装底层 CUDA 调用,提供高度优化的矩阵运算
CUDA 运行时层CUDA Runtime API / Driver API管理 GPU 内存、启动 kernel、设备管理
驱动层NVIDIA Kernel Driver (nvidia.ko)OS 与 GPU 硬件的通信通道

关键认知:驱动是唯一需要直接安装在宿主机上的组件。CUDA 工具链和加速库可以装在 Docker 容器内(通过 NVIDIA Container Toolkit 暴露驱动),这就是"驱动在宿主机、CUDA 在容器"的最佳实践。

3. nvidia-smi 指标解读——读懂 GPU 健康状态

nvidia-smi 是运维 GPU 服务器最常用的工具。理解每一列的真正含义比跑出数字更重要:

指标含义正常范围警示值
GPU-UtilGPU 计算核心利用率(非显存带宽利用率)0-100%持续 100% 不释放(死循环)
Memory-Usage已用显存 / 总显存模型大小 + 10-20% 余量>95%(OOM 风险)
TempGPU 核心温度30-80°C>85°C(降频阈值)
Pwr:Usage/Cap当前功耗 / 最大功耗30-100%接近但低于 Cap 正常
Volatile Uncorr. ECC无法纠正的显存错误计数0>0(显存可能损坏)
Persistence-M持久化模式(初始化状态保持)OnOff(首次调用慢)
⚠️ GPU-Util 不是显存利用率 GPU-Util 衡量的是计算核心繁忙程度。推理服务通常 GPU-Util 不高(显存带宽瓶颈),训练任务通常 GPU-Util 较高(计算瓶颈)。两指标都要看。

4. vLLM 推理架构——PagedAttention 与连续批处理

vLLM 是目前最流行的 LLM 推理引擎。它的两个核心创新让 GPU 显存利用率大幅提升:

PagedAttention:传统方案为每个请求的 KV Cache 预分配连续显存(类似内存碎片问题),PagedAttention 像操作系统的分页机制——将 KV Cache 分成固定大小的 block,按需分配、非连续存储,消除了内部碎片。

Continuous Batching:传统方案等一批请求全部完成后才切换下一批;Continuous Batching 在每个推理 step 后动态调度——已完成请求离开、新请求加入队列,最大化 GPU 利用。

5. 多卡并行——模型放不下单张卡时的三种切法

大模型(70B+)单卡放不下时,需要把模型或数据拆分到多张 GPU。三种主流并行方式对应三种"切法":

并行方式切什么通信需求典型场景
数据并行(DP)复制模型到每张卡,分片喂数据低(每 step 同步梯度)训练加速,卡数越多吞吐越高
张量并行(TP)把单层矩阵切成 N 块放到 N 张卡高(每层都要 AllReduce)推理+训练,模型必须能放进单节点
流水线并行(PP)按层切段:卡 0 跑第 1-20 层,卡 1 跑 21-40 层中(段间传输激活值)超大规模训练,跨节点扩展

vLLM 推理场景通常只涉及 张量并行--tensor-parallel-size),因为它对显存的改善最直接。注意两个反直觉点:

  • TP 不省总显存:7B 模型在 1 张 24G 卡上放不下时,切成 TP=2 每张卡各放一半模型权重(≈4GB)——但 KV Cache 也要按比例分配,总显存需求仍是"模型全部权重 + KV Cache"
  • TP 越高通信开销越大:TP=8 时每层 attention 都要跨卡通信,PCIe 带宽会成为瓶颈。同节点优先用 NVLink;跨节点做 TP 性能会显著下降
# vLLM 多卡启动(2 张 A100 跑 70B 模型)
docker run --gpus '"device=0,1"' \
  -p 8000:8000 -v /models:/models \
  vllm/vllm-openai:v0.6.0 \
  --model /models/Qwen2.5-70B-Instruct \
  --tensor-parallel-size 2 \
  --gpu-memory-utilization 0.9

# 显存放不下时的降级路径(按性价比排序):
# ① 量化:AWQ/GPTQ 4bit(显存减半,精度损失小)→ 首选
# ② 减小 max-model-len(限制 KV Cache 上限)
# ③ 减小 gpu-memory-utilization 并加 --swap-space(CPU offload,变慢)
# ④ 换更大显存卡 / 增加 TP 卡数

示例代码

NVIDIA 驱动安装与验证

# 检查 GPU 型号
lspci | grep -i nvidia
# 输出: NVIDIA Corporation GA102 [GeForce RTX 3080]

# 查看推荐驱动版本
ubuntu-drivers devices
# 输出:
# driver   : nvidia-driver-570 - third-party non-free recommended
# driver   : nvidia-driver-535 - third-party non-free

# 安装推荐驱动
apt update && apt install -y nvidia-driver-570
reboot

# 验证驱动
nvidia-smi
# 输出:
# +-----------------------------------------------------------------------------+
# | NVIDIA-SMI 550.xx    Driver Version: 550.xx    CUDA Version: 12.4          |
# |-------------------------------+----------------------+----------------------+
# | GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
# | Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
# |   0  GeForce RTX 3080    Off  | 00000000:01:00.0  On |                  N/A |
# | 30%   65°C    P0    120W / 320W|   2048MiB / 10240MiB |     45%      Default |
# +-------------------------------+----------------------+----------------------+

NVIDIA Container Toolkit 配置

# 安装 NVIDIA Container Toolkit
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
curl -sL https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
  sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list

apt update && apt install -y nvidia-container-toolkit
systemctl restart docker

# 验证 GPU 在容器中可访问
docker run --gpus all nvidia/cuda:12.4-runtime-ubuntu22.04 nvidia-smi

# 指定特定 GPU
docker run --gpus '"device=0"' nvidia/cuda:12.4-runtime-ubuntu22.04 nvidia-smi

# 检查 nvidia-container-cli 是否正常工作
nvidia-ctk cdi list
# 输出: nvidia.com/gpu=0  (列出可用 GPU)

vLLM 推理服务部署

# 启动 vLLM(Docker)
docker run --gpus all \
  -p 8000:8000 \
  -v /path/to/models:/models \
  vllm/vllm-openai:v0.6.0 \
  --model /models/Qwen2.5-7B-Instruct \
  --tensor-parallel-size 1 \
  --gpu-memory-utilization 0.9 \
  --max-model-len 8192

# 调用推理接口(兼容 OpenAI API)
curl http://localhost:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "Qwen2.5-7B-Instruct",
    "messages": [{"role": "user", "content": "用文言文写一段 Linux 的简介"}],
    "temperature": 0.7,
    "max_tokens": 512
  }'

GPU 监控——nvidia-smi 与 DCGM

# 实时监控
watch -n 1 nvidia-smi

# 详细指标(DCGM)
apt install -y datacenter-gpu-manager
dcgmi group -c all
dcgmi dmon -e 1001,1002,1003,1004
# 输出: GPU 温度、功耗、显存带宽利用率

# Prometheus GPU Exporter(容器化)
docker run -d --gpus all --restart unless-stopped \
  -p 9835:9835 \
  nvidia/dcgm-exporter:latest
# Prometheus 抓取: http://localhost:9835/metrics
# 关键指标: DCGM_FI_DEV_GPU_UTIL, DCGM_FI_DEV_MEM_COPY_UTIL, DCGM_FI_DEV_POWER_USAGE

Triton Inference Server 配置

# docker-compose.yml
services:
  triton:
    image: nvcr.io/nvidia/tritonserver:24.06-py3
    command: tritonserver --model-repository=/models --http-port=8000 --grpc-port=8001
    ports:
      - "8000:8000"
      - "8001:8001"
    volumes:
      - ./models:/models
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [gpu]

GPU 故障排查流程——从现象到根因

# 场景:模型推理突然报错或变慢,按以下顺序排查

# 第一步:确认 GPU 还在不在(驱动层面)
nvidia-smi
# 失败 → 驱动问题:dmesg | grep -i nvidia 查内核报错,重启或重装驱动
# 成功 → 看 Perf 列:P0(全速)/ P2-P3(降频)/ P8(空闲)

# 第二步:确认硬件健康(温度/功耗/ECC)
nvidia-smi -q -d TEMPERATURE,POWER,ECC
# 温度 > 85°C → 散热问题(清灰/机房空调/降功耗 nvidia-smi -pl 250)
# Uncorr ECC > 0 → 显存损坏,申请换卡

# 第三步:确认是"算不动"还是"等数据"(计算 vs 带宽)
nvidia-smi --query-gpu=utilization.gpu,utilization.memory --format=csv
# gpu 高 + memory 低 → 计算密集,正常(如训练)
# gpu 低 + memory 高 → 显存带宽瓶颈(如长序列推理)
# 两者都低 → 进程在等 CPU/磁盘/网络(数据加载慢、单请求串行)

# 第四步:确认进程与显存占用
nvidia-smi --query-compute-apps=pid,used_memory --format=csv
fuser -v /dev/nvidia0    # 谁占用了 GPU 0
# 显存碎片化:重启推理服务进程是最快的清理手段

# 第五步:核对日志与配置
# 推理服务日志中找 CUDA OOM / NCCL timeout / DRIVER version mismatch
# NCCL timeout → 多卡通信异常:检查 NVLink 状态(nvidia-smi nvlink -s)

常见错误

错误原因解决方案
nvidia-smi: command not found驱动未安装或 PATH 未包含apt install nvidia-driver-* 或检查 /usr/lib/nvidia-*/bin
NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver驱动加载失败或内核升级后驱动未重编译重启;或 modprobe nvidia,必要时重装驱动
docker: Error response from daemon: could not select device driver "" with capabilities: [[gpu]]NVIDIA Container Toolkit 未安装或 docker 未重启apt install nvidia-container-toolkit && systemctl restart docker
CUDA 版本不兼容(应用要求 CUDA 12.x 但宿主机只装了 11.x)宿主机只装驱动,容器内 CUDA 版本可以不同宿主机只需驱动版本 >= 容器 CUDA 的最低驱动需求;检查 nvidia-smi 的 CUDA Version 字段
CUDA out of memory模型 + KV Cache + 框架开销超过显存总量减小 --max-model-len、减小 --gpu-memory-utilization、使用量化(4bit/8bit)
Volatile Uncorr. ECC 计数 > 0显存出现不可纠正的硬件错误运行 nvidia-smi -q -d ECC 确认错误位置;联系云厂商换卡或申请 RMA
GPU-Util 持续 0% 但推理慢显存带宽瓶颈或数据传输(PCIe 带宽不足)检查 nvidia-smiMem Copy Util;换用更高带宽的 GPU 型号

最佳实践

#实践说明
1宿主机只装驱动,CUDA 走容器驱动是唯一必须装在宿主机上的组件。CUDA 工具链、cuDNN、PyTorch 都放 Docker 镜像,环境隔离、版本管理灵活
2开启 Persistence Modenvidia-smi -pm 1 保持 GPU 初始化状态,避免每次调用 nvidia-smi 时重新初始化
3推理时留 10-15% 显存余量--gpu-memory-utilization 设为 0.85-0.9,给内核、驱动和框架临时分配留空间
4监控 Volatile ECC 计数器定期检查 nvidia-smi -q -d ECC,>=0 时换卡,避免推理结果被显存错误污染
5tensor-parallel-size = GPU 数量多卡推理时设置 TP = 卡数,注意显存总量 > 模型大小 × 卡数
6使用 DCGM Exporter 接入 Prometheus生产环境不要只靠 nvidia-smi,用 dcgm-exporter 指标构建 Grafana 仪表盘
7内核升级后重装驱动Linux 内核升级后 NVIDIA 内核模块需要重新编译。建议 apt 安装(自动处理 DKMS)而非 .run 包

练习题

  1. (概念)解释 GPU 和 CPU 在架构设计上的根本差异。为什么 GPU 适合 AI 推理而 CPU 不适合?
  2. (概念)"驱动在宿主机、CUDA 在容器"是什么意思?这样做的好处是什么?
  3. (概念)解释 vLLM 的 PagedAttention 如何提高显存利用率。
  4. (实操)在 Linux 上安装 NVIDIA 驱动,运行 nvidia-smi 并记录输出的 GPU 型号、驱动版本、CUDA 版本、显存总量。
  5. (实操)部署 NVIDIA Container Toolkit,运行 docker run --gpus all nvidia/cuda:12.4-runtime-ubuntu22.04 nvidia-smi 验证容器内 GPU 可用。
  6. (实操)使用 Docker 部署 vLLM(任意支持的小模型如 Qwen2.5-7B),通过 curl 调用 /v1/chat/completions 接口完成一次对话。
  7. (探究 🔍)查看 nvidia-smi -q -d ECC 的输出,确认你的 GPU 是否有 ECC 内存和当前错误计数。
  8. (探究 🔍)在容器内外分别运行 nvidia-smi,对比输出差异。思考:为什么 nvidia-smi 命令本身在容器内也能工作?
点击查看答案
  1. CPU 少量强核,侧重低延迟串行计算;GPU 大量弱核,侧重高吞吐并行计算。AI 推理本质是矩阵乘法的并行计算,GPU 可同时处理数千线程,CPU 受限于核数。
  2. NVIDIA 驱动(内核模块 nvidia.ko + libcuda.so)装在宿主机上直接管理 GPU 硬件。容器内通过 NVIDIA Container Toolkit 将 nvidia 设备挂载进去,无需在容器内装驱动。好处:容器镜像更小、驱动版本由宿主机统一管理、多容器共享 GPU 资源。
  3. 传统 KV Cache 预分配连续显存导致碎片和浪费。PagedAttention 将 KV Cache 分页管理(类似虚拟内存),按需分配页,消除内部碎片,支持 page sharing(同一 prompt 的多条请求共享 prefix 页),显存利用率从 ~40% 提升到 ~95%。
  4. nvidia-smi 输出示例:GPU 0: NVIDIA A100-SXM4-80GB, Driver 550.54.15, CUDA 12.4, Memory 81920 MiB。
  5. 容器内 nvidia-smi 应看到与宿主机相同的 GPU 信息(驱动版本、GPU 型号)。区别:容器无法看到 process name。
  6. vLLM Docker 启动后 POST {"model":"Qwen2.5-7B","messages":[{"role":"user","content":"Hello"}]}/v1/chat/completions,返回 id/choices/usage 等字段。
  7. ECC 开启时 Current 和 Pending 错误计数应为 0。非零表示有可纠正或不可纠正的显存错误,需联系云服务商换卡。
  8. nvidia-smi 本身不是 GPU 程序——它通过 libnvidia-ml.so 访问 NVML 库,NVIDIA Container Toolkit 将 /usr/lib/x86_64-linux-gnu/libnvidia-ml.so 挂载进容器,所以容器内也能调用。

学习检查点

学完本章后,请检验自己是否掌握以下内容:

检查项自测问题验证方法
概念理解能用自己的话解释 AI 基础设施的 GPU 调度和模型服务架构尝试向他人讲解
命令操作能不查文档完成 NVIDIA GPU Operator 安装和模型部署在终端实际执行
原理掌握能说出 GPU 共享、显存管理和模型推理优化原理画出流程图
故障排查能独立排查 GPU 资源不足或模型服务 OOM 的问题模拟故障并修复
最佳实践能说明为什么需要为 AI 工作负载配置专用节点池对比不同方案

本章总结

GPU 是 AI 时代最核心的计算硬件。在 Linux 上运行 AI 推理的完整路径:

  • 硬件层——NVIDIA GPU(CUDA 核心 + HBM 显存),通过 PCIe 与主机通信
  • 驱动层——NVIDIA 驱动(nvidia.ko + libcuda.so),唯一需要装在宿主机上的组件
  • 容器运行时层——NVIDIA Container Toolkit,让 Docker 暴露 GPU 设备到容器
  • 推理框架层——vLLM(PagedAttention + Continuous Batching)或 Triton Inference Server
  • 监控层——nvidia-smi(即时)、DCGM Exporter + Prometheus(持续)

速查表

操作命令
查看 GPU 状态nvidia-smi
实时监控watch -n 1 nvidia-smi
查看 ECC 错误nvidia-smi -q -d ECC
持久化模式nvidia-smi -pm 1
设置最大功耗nvidia-smi -pl 250
DCGM 详细监控dcgmi dmon -e 1001,1002,1003,1004
DCGM Prometheus 导出docker run -d --gpus all -p 9835:9835 nvidia/dcgm-exporter

下一步:掌握本章的 GPU 基础设施后,可以继续学习模型微调(LoRA/QLoRA)、多机多卡推理部署、以及 GPU 虚拟化/分片技术。

延伸阅读

常见问题

NVIDIA 驱动装完 nvidia-smi 找不到 GPU?
① 检查硬件检测:lspci | grep -i nvidia;② 确认驱动版本匹配 GPU 型号(nvidia-smi 与驱动版本对应);③ 检查 secure boot 禁用(UEFI 安全启动会拦截未签名模块);④ 检查内核模块加载:lsmod | grep nvidia;⑤ dmesg | grep nvidia 查看内核错误信息。Ubuntu 推荐用 apt install nvidia-driver-xxx(官方驱动仓库)而非下载 .run 文件。
CUDA 容器运行时怎么配置 Docker?
安装 nvidia-container-toolkit 包,配置 Docker 运行时后重启 docker 服务。运行 GPU 容器:docker run --rm --gpus all nvidia/cuda:12.2-runtime-ubuntu22.04 nvidia-smi。--gpus 参数选择特定 GPU。
vLLM 推理服务的性能调优参数有哪些?
核心参数:--max-model-len(最大上下文长度,越长显存占用越大)、--gpu-memory-utilization(GPU 显存利用率,默认 0.9)、--tensor-parallel-size(多 GPU 张量并行)、--pipeline-parallel-size(流水线并行)、--max-num-seqs(最大并发请求数)、--quantization(模型量化方式:awq/gptq/squeezellm)、--dtype(半精度:bfloat16/float16)。
↑ 回到顶部