菜单

CUDA 后端

相关源文件

本文档涵盖了 GGML 的 CUDA 后端实现,该后端为张量操作和神经网络推理提供 NVIDIA GPU 加速。CUDA 后端支持各种量化数据类型、多 GPU 配置以及使用 CUDA 核心和 Tensor Cores 的优化矩阵运算。

有关其他 GPU 后端的信息,请参阅 Metal 后端Vulkan 后端SYCL 后端。有关通用后端架构概念,请参阅 后端

架构概述

CUDA 后端是一个模块化系统,它与 GGML 的后端抽象层进行接口,同时为张量操作提供优化的 CUDA 实现。

CUDA 后端架构

来源:ggml/src/ggml-cuda/ggml-cuda.cu1-830 ggml/src/ggml-cuda/common.cuh1-830

关键组件和关系

来源:ggml/src/ggml-cuda/ggml-cuda.cu758-829 ggml/src/ggml-cuda/common.cuh630-648

设备管理

CUDA 后端通过 ggml_cuda_device_info 结构管理多个 GPU 设备,并提供设备发现和配置功能。

设备初始化和检测

后端通过 ggml_cuda_init() 初始化设备,该函数

  • 使用 cudaGetDeviceCount() 检测可用的 CUDA 设备
  • 查询设备属性,包括计算能力、内存和多处理器数量
  • 确定每个设备的虚拟内存管理 (VMM) 支持
  • 根据设备内存计算默认张量分割比例

跟踪的关键设备属性包括:

  • cc:计算能力
  • nsm:流式多处理器数量
  • smpb/smpbo:每个块的共享内存
  • vmm:虚拟内存管理支持
  • warp_size:每个 warp 的线程数(NVIDIA 为 32,AMD 为 64)

来源:ggml/src/ggml-cuda/ggml-cuda.cu176-291

多厂商支持

该后端通过头文件抽象厂商差异,将 CUDA API 映射到等效的厂商 API

厂商标题目标硬件
NVIDIAvendors/cuda.hCUDA GPU
AMDvendors/hip.hROCm/HIP GPU
摩尔线程vendors/musa.hMUSA GPU

来源:ggml/src/ggml-cuda/vendors/cuda.h1-16 ggml/src/ggml-cuda/vendors/hip.h1-244 ggml/src/ggml-cuda/vendors/musa.h1-141

内存管理

CUDA 后端实现了复杂的内存管理,支持内存池、虚拟内存和高效的分配策略。

内存池架构

来源:ggml/src/ggml-cuda/ggml-cuda.cu300-515

虚拟内存管理

对于支持 VMM 的设备,后端使用 ggml_cuda_pool_vmm,它提供了:

  • 虚拟地址空间:高达 32GB 的虚拟内存(CUDA_POOL_VMM_MAX_SIZE
  • 按需分配:使用 cuMemCreate() 按需分配物理内存
  • 粒度对齐:分配与设备特定的粒度对齐
  • 顺序释放:内存必须按照分配的相反顺序释放

来源:ggml/src/ggml-cuda/ggml-cuda.cu398-505

Split Buffer 支持

该后端通过 ggml_backend_cuda_split_buffer_type 支持将大型张量分割到多个设备上

  • 张量按行分割到可用设备上
  • 每个设备部分独立分配
  • 行边界根据量化要求进行对齐
  • 同步事件协调多设备操作

来源:ggml/src/ggml-cuda/ggml-cuda.cu763-928

矩阵运算

CUDA 后端实现了优化的矩阵运算,支持量化和标准数据类型以及多种算法变体。

矩阵乘法流水线

来源:ggml/src/ggml-cuda/mmq.cu270-324 ggml/src/ggml-cuda/mmq.cuh12-19

量化矩阵运算

mmq.cuhmmq.cu 文件实现了量化类型(MMQ)的矩阵乘法,支持:

支持的量化类型:

  • Q4_0, Q4_1:4 位量化
  • Q5_0, Q5_1:5 位量化
  • Q8_0:8 位量化
  • Q2_KQ6_K:K 量化变体
  • IQ*:整数量化变体

关键参数:

  • MMQ_ITER_K:迭代大小(256)
  • MMQ_NWARPS:Warp 数量(8)
  • MMQ_DP4A_MAX_BATCH_SIZE:DP4A 内核的最大批处理大小(64)

来源:ggml/src/ggml-cuda/mmq.cuh12-15 ggml/src/ggml-cuda/mmq.cu6-66

矩阵向量运算

后端通过两种实现提供优化的矩阵向量乘法

  1. 标准类型mmv.cu):适用于 floathalfnv_bfloat16
  2. 量化类型mmvq.cu):适用于量化数据类型

两种实现都支持:

  • 多通道和多样本批处理
  • MoE 模型可选的行 ID 间接寻址
  • 硬件特定优化(warp 大小、block 大小)

来源:ggml/src/ggml-cuda/mmv.cu5-101 ggml/src/ggml-cuda/mmvq.cu137-224

量化支持

CUDA 后端提供了全面的量化支持,以减少内存使用并提高推理速度。

量化数据布局

来源:ggml/src/ggml-cuda/mmq.cuh27-48 ggml/src/ggml-cuda/mmq.cuh50-84

动态量化

quantize.cu 文件实现了计算过程中的即时量化

  • Q8_1 量化:将浮点输入转换为 8 位量化格式
  • Warp 级规约:使用 warp shuffle 操作进行高效的统计计算
  • 多种布局:根据源量化类型支持不同的尺度/总和排列

量化过程

  1. 计算 warp 间的最大绝对值
  2. 计算量化尺度(d = amax / 127
  3. 量化值并存储尺度/总和

来源: ggml/src/ggml-cuda/quantize.cu4-146

性能优化

算法选择

后端使用 ggml_cuda_should_use_mmq() 根据以下因素在 cuBLAS 和自定义 MMQ 内核之间进行选择

  • 量化类型支持
  • 计算能力(旧 GPU 需要 DP4A)
  • 批处理大小阈值
  • 硬件特定优化

来源: ggml/src/ggml-cuda/mmq.cu270-324

硬件特定功能

后端利用了各种硬件功能

  • Tensor Cores:FP16 矩阵乘法加速
  • DP4A 指令:4路 8位 点积加速
  • Warp Shuffle:高效的 Warp 内通信
  • 共享内存:高带宽的片上存储器,用于存储块
  • 异步复制:重叠数据移动(Ampere+)

来源: ggml/src/ggml-cuda/common.cuh226-262 ggml/src/ggml-cuda/mma.cuh1-16

错误处理和调试

后端通过以下方式提供全面的错误处理

  • CUDA_CHECK 宏:CUDA API 调用的自动错误检查
  • 设备代码验证NO_DEVICE_CODE 用于不支持的架构
  • 资源管理:析构函数中的 RAII 风格清理
  • 详细日志:设备功能和配置报告

来源: ggml/src/ggml-cuda/common.cuh135-146 ggml/src/ggml-cuda/ggml-cuda.cu66-76