HiHuo
首页
博客
手册
工具
关于
首页
博客
手册
工具
关于
  • AI 基础设施深度教程

    • AI Infra 深度教程
    • GPU容器化

      • 01-GPU 架构基础
      • NVIDIA 容器运行时
      • GPU 共享与隔离
      • GPU 监控与调试
    • Kubernetes GPU调度

      • Device Plugin 机制深度解析
      • GPU 调度器实现
      • 拓扑感知调度
      • 弹性 GPU 调度
    • AI训练平台

      • 分布式训练框架
      • 训练任务调度
      • 模型存储与管理
      • 实验管理
      • 超参数优化
    • 推理服务

      • 推理引擎原理
      • 模型服务框架
      • 动态批处理
      • 推理优化技术
      • 多模型服务
    • 异构计算

      • 05-异构计算
      • 异构计算概述
      • GPU 虚拟化技术
      • NPU 与专用 AI 芯片
      • 设备拓扑感知调度
      • 算力池化与弹性调度
    • AI工作流引擎

      • 06-AI工作流引擎
      • AI 工作流引擎概述
      • Kubeflow Pipelines 深度实践
      • 03-Argo Workflows 深度实践
      • 04-数据版本管理
      • 05-实验跟踪与模型注册
    • MLOps实践

      • 07-MLOps实践
      • 01-MLOps 成熟度模型
      • 02-数据集工程
      • 03-Feature Store 特征存储
      • 04-模型评测体系
      • 05-模型安全与治理
    • AIOps实践

      • 08-AIOps实践
      • 01-AIOps概述与架构
      • 02-异常检测算法
      • 03-根因分析与告警聚合
      • 04-智能运维决策
      • 05-AIOps平台实战
    • 面试专题

      • 09-面试专题
      • 01-AI基础设施核心面试题
      • 02-大模型面试题
      • 03-系统设计面试题
    • CUDA编程与算子开发

      • 10-CUDA 编程与算子开发
      • 01-CUDA编程模型与内存层次
      • 02-高性能 Kernel 开发实战
      • 03-Tensor Core 与矩阵运算
      • 04-算子融合与优化技术
      • 05-Triton 编程入门
    • 通信与网络底层

      • 11-通信与网络底层
      • 01-NCCL 源码深度解析
      • 02-AllReduce 算法实现
      • 03-RDMA与InfiniBand原理
      • 04-网络拓扑与通信优化
      • 05-大规模集群网络架构
    • 框架源码解析

      • 12-框架源码解析
      • 01-PyTorch分布式源码解析
      • 02-DeepSpeed源码深度解析
      • 03-Megatron-LM源码解析
      • 04-vLLM推理引擎源码解析
      • 05-HuggingFace Transformers源码解析
    • 编译优化与图优化

      • 13-编译优化与图优化
      • 01-深度学习编译器概述
      • 02-TorchDynamo与torch.compile
      • 03-XLA编译器深度解析
      • 04-算子融合与Kernel优化
      • 05-自动调度与代码生成

01-GPU 架构基础

学习目标

  • 理解 GPU 与 CPU 的本质区别和各自适用场景
  • 掌握 NVIDIA GPU 的硬件架构(SM、CUDA Core、Tensor Core)
  • 深入理解 GPU 内存层次结构
  • 了解 CUDA 编程模型的核心概念
  • 为后续 GPU 容器化和调度打下基础

前置知识

  • 计算机组成原理基础
  • 基本的并行计算概念

一、为什么需要 GPU?

1.1 CPU vs GPU:设计哲学的差异

┌────────────────────────────────────────────────────────────────────────┐
│                      CPU vs GPU 架构对比                                │
├────────────────────────────────────────────────────────────────────────┤
│                                                                        │
│   CPU (Central Processing Unit)                                        │
│   ┌─────────────────────────────────────────────────────────────────┐ │
│   │                                                                 │ │
│   │   设计目标:低延迟,处理复杂逻辑                                  │ │
│   │                                                                 │ │
│   │   ┌─────────────────────────────────────────────────────────┐  │ │
│   │   │  ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐               │  │ │
│   │   │  │ Core  │ │ Core  │ │ Core  │ │ Core  │               │  │ │
│   │   │  │  1    │ │  2    │ │  3    │ │  4    │  (4-64 核)    │  │ │
│   │   │  └───────┘ └───────┘ └───────┘ └───────┘               │  │ │
│   │   │                                                         │  │ │
│   │   │  ┌─────────────────────────────────────────────────┐   │  │ │
│   │   │  │              大容量缓存 (L1/L2/L3)               │   │  │ │
│   │   │  │              几十 MB                             │   │  │ │
│   │   │  └─────────────────────────────────────────────────┘   │  │ │
│   │   │                                                         │  │ │
│   │   │  ┌─────────────────────────────────────────────────┐   │  │ │
│   │   │  │              复杂控制逻辑                        │   │  │ │
│   │   │  │         分支预测、乱序执行、推测执行              │   │  │ │
│   │   │  └─────────────────────────────────────────────────┘   │  │ │
│   │   └─────────────────────────────────────────────────────────┘  │ │
│   │                                                                 │ │
│   │   特点:                                                        │ │
│   │   - 少量强大的核心                                               │ │
│   │   - 大缓存减少内存访问延迟                                       │ │
│   │   - 复杂控制逻辑处理分支和依赖                                   │ │
│   │   - 适合串行任务、复杂逻辑、操作系统                              │ │
│   │                                                                 │ │
│   └─────────────────────────────────────────────────────────────────┘ │
│                                                                        │
│   GPU (Graphics Processing Unit)                                       │
│   ┌─────────────────────────────────────────────────────────────────┐ │
│   │                                                                 │ │
│   │   设计目标:高吞吐量,处理大规模并行计算                          │ │
│   │                                                                 │ │
│   │   ┌─────────────────────────────────────────────────────────┐  │ │
│   │   │  ┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐     │  │ │
│   │   │  └─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘     │  │ │
│   │   │  ┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐     │  │ │
│   │   │  └─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘     │  │ │
│   │   │  ... (数千个小核心)                                    │  │ │
│   │   │  ┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐     │  │ │
│   │   │  └─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘     │  │ │
│   │   └─────────────────────────────────────────────────────────┘  │ │
│   │                                                                 │ │
│   │   ┌─────────────────────────────────────────────────────────┐  │ │
│   │   │              高带宽显存 (HBM/GDDR)                      │   │ │
│   │   │              几百 GB/s ~ 几 TB/s                        │   │ │
│   │   └─────────────────────────────────────────────────────────┘  │ │
│   │                                                                 │ │
│   │   特点:                                                        │ │
│   │   - 大量简单的核心 (数千个)                                      │ │
│   │   - 高带宽内存                                                  │ │
│   │   - 简单控制逻辑,SIMT 执行模式                                  │ │
│   │   - 适合矩阵运算、图像处理、深度学习                              │ │
│   │                                                                 │ │
│   └─────────────────────────────────────────────────────────────────┘ │
│                                                                        │
└────────────────────────────────────────────────────────────────────────┘

1.2 为什么 AI 需要 GPU?

深度学习的核心运算:矩阵乘法

神经网络前向传播: Y = W × X + b
- W: 权重矩阵 (可能是 [4096 × 4096])
- X: 输入向量/矩阵
- 需要大量的乘加运算

示例:一个简单的矩阵乘法 C = A × B
┌─────────────────────────────────────────────────────────────────────┐
│                                                                     │
│   A [M×K]  ×  B [K×N]  =  C [M×N]                                   │
│                                                                     │
│   计算 C[i][j] = Σ(A[i][k] × B[k][j])  for k = 0 to K-1            │
│                                                                     │
│   总运算量: M × N × K 次乘法 + M × N × K 次加法                     │
│                                                                     │
│   例如: [4096×4096] × [4096×4096]                                   │
│   = 4096 × 4096 × 4096 × 2 ≈ 1370 亿次运算                         │
│                                                                     │
│   CPU (单核 10 GFLOPS): 需要约 14 秒                                │
│   GPU (A100 312 TFLOPS): 需要约 0.0004 秒                           │
│                                                                     │
│   关键:矩阵乘法中每个元素的计算是独立的,天然并行!                   │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

二、NVIDIA GPU 硬件架构

2.1 GPU 架构层次

以 NVIDIA A100 (Ampere 架构) 为例:

┌────────────────────────────────────────────────────────────────────────┐
│                        NVIDIA A100 GPU 架构                            │
├────────────────────────────────────────────────────────────────────────┤
│                                                                        │
│   整体结构                                                              │
│   ┌─────────────────────────────────────────────────────────────────┐ │
│   │                                                                 │ │
│   │   ┌─────────────────────────────────────────────────────────┐  │ │
│   │   │                      GPC × 8                             │  │ │
│   │   │              (Graphics Processing Cluster)              │  │ │
│   │   │                                                         │  │ │
│   │   │   ┌─────────────────────────────────────────────────┐  │  │ │
│   │   │   │                   TPC × 2                        │  │  │ │
│   │   │   │          (Texture Processing Cluster)           │  │  │ │
│   │   │   │                                                  │  │  │ │
│   │   │   │   ┌─────────────────────────────────────────┐   │  │  │ │
│   │   │   │   │                SM                        │   │  │  │ │
│   │   │   │   │      (Streaming Multiprocessor)         │   │  │  │ │
│   │   │   │   │                                         │   │  │  │ │
│   │   │   │   │   ┌─────────┐ ┌─────────┐ ┌─────────┐  │   │  │  │ │
│   │   │   │   │   │  CUDA   │ │ Tensor  │ │  共享   │  │   │  │  │ │
│   │   │   │   │   │  Cores  │ │  Cores  │ │  内存   │  │   │  │  │ │
│   │   │   │   │   │  (64)   │ │  (4)    │ │ (192KB)│  │   │  │  │ │
│   │   │   │   │   └─────────┘ └─────────┘ └─────────┘  │   │  │  │ │
│   │   │   │   └─────────────────────────────────────────┘   │  │  │ │
│   │   │   └─────────────────────────────────────────────────┘  │  │ │
│   │   └─────────────────────────────────────────────────────────┘  │ │
│   │                                                                 │ │
│   │   A100 总计:                                                    │ │
│   │   - 8 GPC × 2 TPC × 1 SM = 108 SM (实际启用)                   │ │
│   │   - 108 × 64 = 6912 CUDA Cores                                 │ │
│   │   - 108 × 4 = 432 Tensor Cores (第三代)                        │ │
│   │   - 40GB 或 80GB HBM2e 显存                                    │ │
│   │   - 显存带宽: 2039 GB/s (80GB 版本)                            │ │
│   │                                                                 │ │
│   └─────────────────────────────────────────────────────────────────┘ │
│                                                                        │
└────────────────────────────────────────────────────────────────────────┘

2.2 SM (Streaming Multiprocessor) 详解

SM 是 GPU 的核心计算单元,理解 SM 结构是理解 GPU 性能的关键:

┌────────────────────────────────────────────────────────────────────────┐
│                      SM 内部结构 (Ampere 架构)                          │
├────────────────────────────────────────────────────────────────────────┤
│                                                                        │
│   ┌─────────────────────────────────────────────────────────────────┐ │
│   │                         SM (一个)                                │ │
│   │                                                                 │ │
│   │   ┌─────────────────────────────────────────────────────────┐  │ │
│   │   │                 Sub-partition × 4                        │  │ │
│   │   │                                                         │  │ │
│   │   │   ┌─────────────────────────────────────────────────┐  │  │ │
│   │   │   │   每个 Sub-partition 包含:                       │  │  │ │
│   │   │   │                                                  │  │  │ │
│   │   │   │   ┌──────────────────────────────────────────┐  │  │  │ │
│   │   │   │   │   Warp Scheduler × 1                      │  │  │  │ │
│   │   │   │   │   负责调度 warp (32个线程一组)             │  │  │  │ │
│   │   │   │   └──────────────────────────────────────────┘  │  │  │ │
│   │   │   │                                                  │  │  │ │
│   │   │   │   ┌──────────────────────────────────────────┐  │  │  │ │
│   │   │   │   │   CUDA Cores × 16                         │  │  │  │ │
│   │   │   │   │   INT32 + FP32 运算                       │  │  │  │ │
│   │   │   │   └──────────────────────────────────────────┘  │  │  │ │
│   │   │   │                                                  │  │  │ │
│   │   │   │   ┌──────────────────────────────────────────┐  │  │  │ │
│   │   │   │   │   Tensor Core × 1                         │  │  │  │ │
│   │   │   │   │   矩阵运算加速                             │  │  │  │ │
│   │   │   │   └──────────────────────────────────────────┘  │  │  │ │
│   │   │   │                                                  │  │  │ │
│   │   │   │   ┌──────────────────────────────────────────┐  │  │  │ │
│   │   │   │   │   Register File (16384 × 32-bit)          │  │  │  │ │
│   │   │   │   │   寄存器文件                               │  │  │  │ │
│   │   │   │   └──────────────────────────────────────────┘  │  │  │ │
│   │   │   │                                                  │  │  │ │
│   │   │   └─────────────────────────────────────────────────┘  │  │ │
│   │   └─────────────────────────────────────────────────────────┘  │ │
│   │                                                                 │ │
│   │   共享资源 (整个 SM):                                           │ │
│   │   ┌─────────────────────────────────────────────────────────┐  │ │
│   │   │   L1 Cache / Shared Memory: 192 KB (可配置比例)          │  │ │
│   │   │   Texture Cache                                          │  │ │
│   │   │   Constant Cache                                         │  │ │
│   │   └─────────────────────────────────────────────────────────┘  │ │
│   │                                                                 │ │
│   └─────────────────────────────────────────────────────────────────┘ │
│                                                                        │
│   SM 总计:                                                             │
│   - 4 × 16 = 64 CUDA Cores                                            │
│   - 4 × 1 = 4 Tensor Cores                                            │
│   - 4 × 16384 = 65536 个 32-bit 寄存器                                │
│   - 最多同时执行 2048 个线程 (64 warps)                                │
│                                                                        │
└────────────────────────────────────────────────────────────────────────┘

2.3 CUDA Core vs Tensor Core

┌────────────────────────────────────────────────────────────────────────┐
│                    CUDA Core vs Tensor Core                            │
├────────────────────────────────────────────────────────────────────────┤
│                                                                        │
│   CUDA Core (通用计算核心)                                              │
│   ┌─────────────────────────────────────────────────────────────────┐ │
│   │                                                                 │ │
│   │   功能: 标量浮点/整数运算                                        │ │
│   │                                                                 │ │
│   │   每个时钟周期执行:                                              │ │
│   │   - 1 次 FP32 乘加 (FMA) 或                                     │ │
│   │   - 1 次 INT32 运算                                             │ │
│   │                                                                 │ │
│   │   适用场景:                                                      │ │
│   │   - 通用 GPU 计算                                                │ │
│   │   - 图形渲染                                                     │ │
│   │   - 不规则计算模式                                               │ │
│   │                                                                 │ │
│   │   A100 FP32 性能: 19.5 TFLOPS                                   │ │
│   │                                                                 │ │
│   └─────────────────────────────────────────────────────────────────┘ │
│                                                                        │
│   Tensor Core (张量计算核心)                                           │
│   ┌─────────────────────────────────────────────────────────────────┐ │
│   │                                                                 │ │
│   │   功能: 矩阵乘加运算 (Matrix Multiply-Accumulate)                │ │
│   │                                                                 │ │
│   │   每个时钟周期执行:                                              │ │
│   │   D = A × B + C                                                 │ │
│   │   其中 A, B, C, D 是小矩阵 (如 4×4×4)                           │ │
│   │                                                                 │ │
│   │   ┌─────────────────────────────────────────────────────────┐  │ │
│   │   │                                                         │  │ │
│   │   │   [A]      ×    [B]      +    [C]      =    [D]        │  │ │
│   │   │   4×4           4×4           4×4           4×4         │  │ │
│   │   │                                                         │  │ │
│   │   │   一次操作完成 4×4×4×2 = 128 次运算!                    │  │ │
│   │   │                                                         │  │ │
│   │   └─────────────────────────────────────────────────────────┘  │ │
│   │                                                                 │ │
│   │   支持的数据类型:                                                │ │
│   │   - FP16 (Half): 312 TFLOPS                                    │ │
│   │   - BF16 (Bfloat16): 312 TFLOPS                                │ │
│   │   - TF32 (TensorFloat-32): 156 TFLOPS                          │ │
│   │   - FP64 (Double): 19.5 TFLOPS                                 │ │
│   │   - INT8: 624 TOPS                                             │ │
│   │   - INT4: 1248 TOPS                                            │ │
│   │                                                                 │ │
│   │   适用场景:                                                      │ │
│   │   - 深度学习训练/推理                                            │ │
│   │   - 矩阵密集型计算                                               │ │
│   │                                                                 │ │
│   └─────────────────────────────────────────────────────────────────┘ │
│                                                                        │
│   性能对比 (A100):                                                     │
│   ┌─────────────────────────────────────────────────────────────────┐ │
│   │                                                                 │ │
│   │   CUDA Core FP32:     19.5 TFLOPS                              │ │
│   │   Tensor Core FP16:   312 TFLOPS   (16× faster!)               │ │
│   │                                                                 │ │
│   │   这就是为什么深度学习使用混合精度训练如此重要!                   │ │
│   │                                                                 │ │
│   └─────────────────────────────────────────────────────────────────┘ │
│                                                                        │
└────────────────────────────────────────────────────────────────────────┘

2.4 GPU 型号演进

┌────────────────────────────────────────────────────────────────────────┐
│                    NVIDIA 数据中心 GPU 演进                            │
├────────────────────────────────────────────────────────────────────────┤
│                                                                        │
│   架构代际:                                                             │
│                                                                        │
│   Pascal (2016)     →  Volta (2017)    →  Turing (2018)               │
│   P100                  V100               T4                          │
│   │                     │                  │                           │
│   └─────────────────────┼──────────────────┘                           │
│                         ↓                                              │
│                    Ampere (2020)    →  Hopper (2022)    →  Blackwell  │
│                    A100                 H100                 B100/B200 │
│                                                              (2024)    │
│                                                                        │
│   关键参数对比:                                                         │
│   ┌─────────────┬────────┬────────┬────────┬────────┬────────┐        │
│   │   型号      │  V100  │  A100  │  H100  │  H200  │  B200  │        │
│   ├─────────────┼────────┼────────┼────────┼────────┼────────┤        │
│   │ 架构        │ Volta  │ Ampere │ Hopper │ Hopper │Blackwell│       │
│   │ 显存        │ 32GB   │ 80GB   │ 80GB   │ 141GB  │ 192GB  │        │
│   │ 显存类型    │ HBM2   │ HBM2e  │ HBM3   │ HBM3e  │ HBM3e  │        │
│   │ 带宽        │ 900GB/s│2039GB/s│3350GB/s│4800GB/s│8000GB/s│        │
│   │ FP16 Tensor │ 125T   │ 312T   │ 1979T  │ 1979T  │ 4500T  │        │
│   │ 互联        │ NVLink2│ NVLink3│ NVLink4│ NVLink4│ NVLink5│        │
│   │ TDP         │ 300W   │ 400W   │ 700W   │ 700W   │ 1000W  │        │
│   └─────────────┴────────┴────────┴────────┴────────┴────────┘        │
│                                                                        │
│   选型建议:                                                             │
│   - 推理服务: T4 (性价比), L4 (新一代)                                 │
│   - 中小规模训练: A100 40GB                                            │
│   - 大模型训练: A100 80GB, H100, H200                                  │
│   - 超大模型: H100/H200 集群 + NVLink                                  │
│                                                                        │
└────────────────────────────────────────────────────────────────────────┘

三、GPU 内存层次结构

3.1 内存层次概览

┌────────────────────────────────────────────────────────────────────────┐
│                       GPU 内存层次结构                                  │
├────────────────────────────────────────────────────────────────────────┤
│                                                                        │
│   访问速度 (快 → 慢)                                                    │
│   ┌─────────────────────────────────────────────────────────────────┐ │
│   │                                                                 │ │
│   │   Level 1: 寄存器 (Register)                                    │ │
│   │   ┌─────────────────────────────────────────────────────────┐  │ │
│   │   │   位置: SM 内部,每个线程私有                            │  │ │
│   │   │   大小: 每个 SM 约 256KB (A100)                          │  │ │
│   │   │   延迟: 1 cycle                                          │  │ │
│   │   │   带宽: ~20 TB/s (有效)                                  │  │ │
│   │   └─────────────────────────────────────────────────────────┘  │ │
│   │                         ↓                                       │ │
│   │   Level 2: 共享内存 / L1 Cache                                  │ │
│   │   ┌─────────────────────────────────────────────────────────┐  │ │
│   │   │   位置: SM 内部,同一 Block 内线程共享                    │  │ │
│   │   │   大小: 每个 SM 192KB (可配置)                           │  │ │
│   │   │   延迟: ~20-30 cycles                                    │  │ │
│   │   │   带宽: ~19 TB/s                                         │  │ │
│   │   └─────────────────────────────────────────────────────────┘  │ │
│   │                         ↓                                       │ │
│   │   Level 3: L2 Cache                                             │ │
│   │   ┌─────────────────────────────────────────────────────────┐  │ │
│   │   │   位置: 全局,所有 SM 共享                               │  │ │
│   │   │   大小: 40MB (A100)                                      │  │ │
│   │   │   延迟: ~200 cycles                                      │  │ │
│   │   │   带宽: ~5 TB/s                                          │  │ │
│   │   └─────────────────────────────────────────────────────────┘  │ │
│   │                         ↓                                       │ │
│   │   Level 4: 全局内存 / 显存 (Global Memory / VRAM)               │ │
│   │   ┌─────────────────────────────────────────────────────────┐  │ │
│   │   │   位置: GPU 芯片外部 (HBM/GDDR)                          │  │ │
│   │   │   大小: 40GB/80GB (A100)                                 │  │ │
│   │   │   延迟: ~400-600 cycles                                  │  │ │
│   │   │   带宽: 2039 GB/s (A100 80GB)                            │  │ │
│   │   └─────────────────────────────────────────────────────────┘  │ │
│   │                         ↓                                       │ │
│   │   Level 5: 主机内存 (通过 PCIe/NVLink)                          │ │
│   │   ┌─────────────────────────────────────────────────────────┐  │ │
│   │   │   位置: CPU 内存                                         │  │ │
│   │   │   大小: 取决于主机配置                                   │  │ │
│   │   │   延迟: 数万 cycles                                      │  │ │
│   │   │   带宽: PCIe 4.0 x16 ~32 GB/s                           │  │ │
│   │   │         NVLink 3.0 ~600 GB/s (A100)                      │  │ │
│   │   └─────────────────────────────────────────────────────────┘  │ │
│   │                                                                 │ │
│   └─────────────────────────────────────────────────────────────────┘ │
│                                                                        │
└────────────────────────────────────────────────────────────────────────┘

3.2 显存 (Global Memory) 详解

┌────────────────────────────────────────────────────────────────────────┐
│                          GPU 显存详解                                   │
├────────────────────────────────────────────────────────────────────────┤
│                                                                        │
│   显存类型:                                                             │
│   ┌─────────────────────────────────────────────────────────────────┐ │
│   │                                                                 │ │
│   │   GDDR (Graphics DDR)                                           │ │
│   │   - 成本较低                                                    │ │
│   │   - 带宽相对较低                                                 │ │
│   │   - 用于消费级 GPU (RTX 系列)                                   │ │
│   │   - 例: RTX 4090 使用 GDDR6X, 1008 GB/s                        │ │
│   │                                                                 │ │
│   │   HBM (High Bandwidth Memory)                                   │ │
│   │   - 成本高                                                      │ │
│   │   - 超高带宽 (堆叠芯片 + 硅中介层)                               │ │
│   │   - 用于数据中心 GPU                                            │ │
│   │   - 例: A100 使用 HBM2e, 2039 GB/s                             │ │
│   │   - 例: H100 使用 HBM3, 3350 GB/s                              │ │
│   │                                                                 │ │
│   └─────────────────────────────────────────────────────────────────┘ │
│                                                                        │
│   显存管理:                                                             │
│   ┌─────────────────────────────────────────────────────────────────┐ │
│   │                                                                 │ │
│   │   显存分配 = 模型参数 + 梯度 + 优化器状态 + 激活值 + 临时缓冲    │ │
│   │                                                                 │ │
│   │   示例: 训练 7B 参数模型 (FP16)                                 │ │
│   │   ┌─────────────────────────────────────────────────────────┐  │ │
│   │   │   模型参数:    7B × 2 bytes = 14 GB                      │  │ │
│   │   │   梯度:        7B × 2 bytes = 14 GB                      │  │ │
│   │   │   优化器状态:  7B × 8 bytes = 56 GB (Adam)               │  │ │
│   │   │   激活值:      取决于 batch size 和序列长度               │  │ │
│   │   │   ─────────────────────────────                          │  │ │
│   │   │   最少需要:    ~84 GB (单卡无法训练!)                     │  │ │
│   │   └─────────────────────────────────────────────────────────┘  │ │
│   │                                                                 │ │
│   │   显存优化技术:                                                  │ │
│   │   - 混合精度训练 (FP16/BF16)                                    │ │
│   │   - 梯度检查点 (Gradient Checkpointing)                         │ │
│   │   - ZeRO (Zero Redundancy Optimizer)                            │ │
│   │   - 模型并行 / 张量并行                                          │ │
│   │                                                                 │ │
│   └─────────────────────────────────────────────────────────────────┘ │
│                                                                        │
└────────────────────────────────────────────────────────────────────────┘

3.3 查看 GPU 内存使用

# 使用 nvidia-smi 查看
$ nvidia-smi
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 535.104.05   Driver Version: 535.104.05   CUDA Version: 12.2    |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  NVIDIA A100-SXM...  On   | 00000000:07:00.0 Off |                    0 |
| N/A   32C    P0    52W / 400W |    412MiB / 81920MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+

# 详细内存信息
$ nvidia-smi --query-gpu=memory.total,memory.used,memory.free --format=csv
memory.total [MiB], memory.used [MiB], memory.free [MiB]
81920 MiB, 412 MiB, 81508 MiB

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

# 查看进程级显存使用
$ nvidia-smi pmon -s m
# gpu    pid    type    sm   mem   enc   dec   command
#   0   1234     C       0    12     0     0   python

四、CUDA 编程模型基础

4.1 核心概念

┌────────────────────────────────────────────────────────────────────────┐
│                      CUDA 编程模型核心概念                              │
├────────────────────────────────────────────────────────────────────────┤
│                                                                        │
│   线程层次结构:                                                         │
│   ┌─────────────────────────────────────────────────────────────────┐ │
│   │                                                                 │ │
│   │   Grid (网格)                                                    │ │
│   │   ┌─────────────────────────────────────────────────────────┐  │ │
│   │   │                                                         │  │ │
│   │   │   Block 0        Block 1        Block 2       ...       │  │ │
│   │   │   ┌─────────┐   ┌─────────┐   ┌─────────┐              │  │ │
│   │   │   │ Thread  │   │ Thread  │   │ Thread  │              │  │ │
│   │   │   │  0,1,2  │   │  0,1,2  │   │  0,1,2  │              │  │ │
│   │   │   │  ...    │   │  ...    │   │  ...    │              │  │ │
│   │   │   │  n-1    │   │  n-1    │   │  n-1    │              │  │ │
│   │   │   └─────────┘   └─────────┘   └─────────┘              │  │ │
│   │   │                                                         │  │ │
│   │   └─────────────────────────────────────────────────────────┘  │ │
│   │                                                                 │ │
│   │   Grid: 一次 kernel 启动产生的所有线程                          │ │
│   │   Block: 线程块,同一 Block 内线程可以同步和共享内存             │ │
│   │   Thread: 最小执行单元                                          │ │
│   │   Warp: 32 个连续线程,GPU 实际调度单位                         │ │
│   │                                                                 │ │
│   └─────────────────────────────────────────────────────────────────┘ │
│                                                                        │
│   硬件映射:                                                             │
│   ┌─────────────────────────────────────────────────────────────────┐ │
│   │                                                                 │ │
│   │   Grid        →  整个 GPU                                       │ │
│   │   Block       →  SM (一个 Block 在一个 SM 上执行)               │ │
│   │   Warp (32)   →  CUDA Cores (并行执行)                          │ │
│   │   Thread      →  单个 CUDA Core                                 │ │
│   │                                                                 │ │
│   │   一个 SM 可以同时执行多个 Block (受资源限制)                   │ │
│   │   一个 Block 内的线程共享 SM 的共享内存                          │ │
│   │                                                                 │ │
│   └─────────────────────────────────────────────────────────────────┘ │
│                                                                        │
│   SIMT (Single Instruction, Multiple Threads):                         │
│   ┌─────────────────────────────────────────────────────────────────┐ │
│   │                                                                 │ │
│   │   同一 Warp 内的 32 个线程执行相同指令                          │ │
│   │   但操作不同的数据 (不同的寄存器/内存地址)                       │ │
│   │                                                                 │ │
│   │   Warp [Thread 0, Thread 1, ... Thread 31]                     │ │
│   │         ↓         ↓              ↓                              │ │
│   │      ADD R1,R2  ADD R1,R2  ...  ADD R1,R2  (同一指令)          │ │
│   │      Data[0]    Data[1]   ...   Data[31]  (不同数据)           │ │
│   │                                                                 │ │
│   │   分支发散 (Branch Divergence):                                 │ │
│   │   如果 Warp 内线程走不同分支,会串行执行,降低效率               │ │
│   │                                                                 │ │
│   └─────────────────────────────────────────────────────────────────┘ │
│                                                                        │
└────────────────────────────────────────────────────────────────────────┘

4.2 简单 CUDA 程序示例

// vector_add.cu - 向量加法示例

#include <cuda_runtime.h>
#include <stdio.h>

// GPU Kernel: 在 GPU 上执行的函数
__global__ void vectorAdd(float *a, float *b, float *c, int n) {
    // 计算全局线程索引
    int idx = blockIdx.x * blockDim.x + threadIdx.x;

    // 边界检查
    if (idx < n) {
        c[idx] = a[idx] + b[idx];
    }
}

int main() {
    int n = 1000000;  // 100万个元素
    size_t size = n * sizeof(float);

    // 分配主机内存
    float *h_a = (float*)malloc(size);
    float *h_b = (float*)malloc(size);
    float *h_c = (float*)malloc(size);

    // 初始化数据
    for (int i = 0; i < n; i++) {
        h_a[i] = i;
        h_b[i] = i * 2;
    }

    // 分配 GPU 显存
    float *d_a, *d_b, *d_c;
    cudaMalloc(&d_a, size);
    cudaMalloc(&d_b, size);
    cudaMalloc(&d_c, size);

    // 复制数据: 主机 → GPU
    cudaMemcpy(d_a, h_a, size, cudaMemcpyHostToDevice);
    cudaMemcpy(d_b, h_b, size, cudaMemcpyHostToDevice);

    // 配置执行参数
    int threadsPerBlock = 256;
    int blocksPerGrid = (n + threadsPerBlock - 1) / threadsPerBlock;

    // 启动 Kernel
    vectorAdd<<<blocksPerGrid, threadsPerBlock>>>(d_a, d_b, d_c, n);

    // 复制结果: GPU → 主机
    cudaMemcpy(h_c, d_c, size, cudaMemcpyDeviceToHost);

    // 验证结果
    for (int i = 0; i < 10; i++) {
        printf("c[%d] = %f\n", i, h_c[i]);
    }

    // 清理资源
    cudaFree(d_a);
    cudaFree(d_b);
    cudaFree(d_c);
    free(h_a);
    free(h_b);
    free(h_c);

    return 0;
}

// 编译运行:
// nvcc vector_add.cu -o vector_add
// ./vector_add

4.3 内存访问模式

┌────────────────────────────────────────────────────────────────────────┐
│                      GPU 内存访问优化                                   │
├────────────────────────────────────────────────────────────────────────┤
│                                                                        │
│   合并访问 (Coalesced Access) - 高效                                    │
│   ┌─────────────────────────────────────────────────────────────────┐ │
│   │                                                                 │ │
│   │   Thread 0   Thread 1   Thread 2   Thread 3   ...               │ │
│   │      ↓          ↓          ↓          ↓                         │ │
│   │   ┌────┬────┬────┬────┬────┬────┬────┬────┐                    │ │
│   │   │ 0  │ 1  │ 2  │ 3  │ 4  │ 5  │ 6  │ 7  │  Global Memory    │ │
│   │   └────┴────┴────┴────┴────┴────┴────┴────┘                    │ │
│   │                                                                 │ │
│   │   线程访问连续内存地址,可以合并成一次内存事务                    │ │
│   │   带宽利用率高                                                   │ │
│   │                                                                 │ │
│   │   代码示例 (好):                                                 │ │
│   │   data[threadIdx.x]  // 连续访问                                │ │
│   │                                                                 │ │
│   └─────────────────────────────────────────────────────────────────┘ │
│                                                                        │
│   非合并访问 (Strided/Random Access) - 低效                            │
│   ┌─────────────────────────────────────────────────────────────────┐ │
│   │                                                                 │ │
│   │   Thread 0   Thread 1   Thread 2   Thread 3                     │ │
│   │      ↓          ↓          ↓          ↓                         │ │
│   │   ┌────┬────┬────┬────┬────┬────┬────┬────┐                    │ │
│   │   │ 0  │    │ 2  │    │ 4  │    │ 6  │    │  Global Memory    │ │
│   │   └────┴────┴────┴────┴────┴────┴────┴────┘                    │ │
│   │                                                                 │ │
│   │   跨步访问,每次只利用部分内存事务                               │ │
│   │   带宽浪费                                                       │ │
│   │                                                                 │ │
│   │   代码示例 (差):                                                 │ │
│   │   data[threadIdx.x * 2]  // 跨步访问                            │ │
│   │                                                                 │ │
│   └─────────────────────────────────────────────────────────────────┘ │
│                                                                        │
│   使用共享内存优化:                                                     │
│   ┌─────────────────────────────────────────────────────────────────┐ │
│   │                                                                 │ │
│   │   1. 从全局内存合并读取到共享内存                                │ │
│   │   2. __syncthreads() 同步                                       │ │
│   │   3. 从共享内存以任意模式访问 (无 bank conflict 时高效)          │ │
│   │   4. 写回全局内存时再次合并                                      │ │
│   │                                                                 │ │
│   └─────────────────────────────────────────────────────────────────┘ │
│                                                                        │
└────────────────────────────────────────────────────────────────────────┘

五、GPU 性能指标

5.1 关键性能指标

┌────────────────────────────────────────────────────────────────────────┐
│                       GPU 性能指标详解                                  │
├────────────────────────────────────────────────────────────────────────┤
│                                                                        │
│   1. 算力 (FLOPS - Floating Point Operations Per Second)               │
│   ┌─────────────────────────────────────────────────────────────────┐ │
│   │                                                                 │ │
│   │   TFLOPS = 核心数 × 时钟频率 × 每周期运算数 × 2 (FMA)           │ │
│   │                                                                 │ │
│   │   A100 FP32: 6912 cores × 1.41 GHz × 2 = 19.5 TFLOPS           │ │
│   │   A100 FP16 Tensor: 312 TFLOPS (Tensor Core 加速)               │ │
│   │                                                                 │ │
│   │   注意: 理论峰值 vs 实际性能,通常能达到 60-80%                  │ │
│   │                                                                 │ │
│   └─────────────────────────────────────────────────────────────────┘ │
│                                                                        │
│   2. 显存带宽 (Memory Bandwidth)                                        │
│   ┌─────────────────────────────────────────────────────────────────┐ │
│   │                                                                 │ │
│   │   决定数据搬运速度                                               │ │
│   │                                                                 │ │
│   │   A100 80GB: 2039 GB/s                                         │ │
│   │   H100 80GB: 3350 GB/s                                         │ │
│   │                                                                 │ │
│   │   很多深度学习任务是内存带宽受限 (Memory Bound) 而非计算受限      │ │
│   │                                                                 │ │
│   └─────────────────────────────────────────────────────────────────┘ │
│                                                                        │
│   3. 算术强度 (Arithmetic Intensity)                                   │
│   ┌─────────────────────────────────────────────────────────────────┐ │
│   │                                                                 │ │
│   │   AI = 运算次数 / 内存访问字节数 (FLOP/Byte)                    │ │
│   │                                                                 │ │
│   │   A100 平衡点:                                                  │ │
│   │   FP32: 19.5 TFLOPS / 2039 GB/s ≈ 9.6 FLOP/Byte                │ │
│   │   FP16: 312 TFLOPS / 2039 GB/s ≈ 153 FLOP/Byte                 │ │
│   │                                                                 │ │
│   │   如果实际 AI < 平衡点 → 内存带宽瓶颈                           │ │
│   │   如果实际 AI > 平衡点 → 计算能力瓶颈                           │ │
│   │                                                                 │ │
│   │   矩阵乘法 (N×N): AI ≈ N/12 → N 越大越能发挥计算能力            │ │
│   │                                                                 │ │
│   └─────────────────────────────────────────────────────────────────┘ │
│                                                                        │
│   4. GPU 利用率 (GPU Utilization)                                      │
│   ┌─────────────────────────────────────────────────────────────────┐ │
│   │                                                                 │ │
│   │   SM 利用率: SM 忙碌的时间比例                                  │ │
│   │   显存利用率: 显存使用量 / 总显存                               │ │
│   │                                                                 │ │
│   │   nvidia-smi 显示的 GPU-Util:                                   │ │
│   │   - 0%: GPU 空闲                                                │ │
│   │   - 100%: 至少一个 kernel 在执行                                │ │
│   │   - 注意: 100% 不代表性能最优,可能只是一直在等内存              │ │
│   │                                                                 │ │
│   └─────────────────────────────────────────────────────────────────┘ │
│                                                                        │
└────────────────────────────────────────────────────────────────────────┘

5.2 性能分析工具

# 1. nvidia-smi 基础监控
nvidia-smi dmon -s pucm  # 持续监控功耗、利用率、时钟、内存

# 2. NVIDIA Nsight Systems - 系统级性能分析
nsys profile -o report python train.py
nsys stats report.nsys-rep

# 3. NVIDIA Nsight Compute - Kernel 级性能分析
ncu --set full python train.py

# 4. PyTorch Profiler
import torch.profiler as profiler

with profiler.profile(
    activities=[
        profiler.ProfilerActivity.CPU,
        profiler.ProfilerActivity.CUDA,
    ],
    record_shapes=True,
    profile_memory=True,
    with_stack=True,
) as prof:
    model(input)

print(prof.key_averages().table(sort_by="cuda_time_total", row_limit=10))

# 5. DCGM (Data Center GPU Manager)
dcgmi dmon -e 155,156,203,204  # 监控 SM 活跃度、内存带宽等

六、面试要点

6.1 高频问题

Q1: GPU 为什么比 CPU 更适合深度学习?

1. 架构差异:
   - GPU 有数千个小核心,适合并行计算
   - CPU 有少量大核心,适合复杂逻辑

2. 深度学习特点:
   - 核心运算是矩阵乘法,天然并行
   - 数据量大,需要高带宽
   - 计算模式规则,不需要复杂分支预测

3. 专用硬件:
   - Tensor Core 针对矩阵运算优化
   - 高带宽显存 (HBM)

Q2: CUDA Core 和 Tensor Core 的区别?

CUDA Core:
- 通用标量运算 (FP32/INT32)
- 每周期 1 次 FMA
- 适合通用 GPU 计算

Tensor Core:
- 矩阵乘加运算 (4×4×4)
- 每周期 128 次运算
- 支持 FP16/BF16/TF32/INT8
- 专为深度学习设计

A100 性能对比:
- CUDA Core FP32: 19.5 TFLOPS
- Tensor Core FP16: 312 TFLOPS (16倍)

Q3: 什么是显存带宽瓶颈?如何判断?

判断方法:
1. 计算算术强度 AI = FLOPS / Memory Access
2. 对比 GPU 平衡点
3. 使用 profiler 分析

A100 平衡点:
- FP32: 9.6 FLOP/Byte
- FP16: 153 FLOP/Byte

如果 AI 低于平衡点,说明是带宽瓶颈
典型带宽瓶颈场景: Embedding 查表、小 batch 推理

Q4: 如何估算模型显存占用?

训练显存 = 模型参数 + 梯度 + 优化器状态 + 激活值

示例 (7B 模型, FP16):
- 参数: 7B × 2B = 14 GB
- 梯度: 7B × 2B = 14 GB
- Adam 状态: 7B × 8B = 56 GB (FP32 一阶二阶动量)
- 激活值: 取决于 batch size

优化手段:
- 混合精度 (FP16/BF16)
- 梯度检查点
- ZeRO 优化器
- 模型/张量并行

相关链接

  • 02-NVIDIA容器运行时 - GPU 容器化实现
  • 03-GPU共享与隔离 - MIG/vGPU
  • NVIDIA 官方文档
  • CUDA C++ Programming Guide

下一步:了解如何在容器中使用 GPU - NVIDIA 容器运行时!

Next
NVIDIA 容器运行时