Skip to content

GGML 后端与硬件抽象 — 练习

练习 1:查看编译时可用的后端

阅读 CMakeLists.txt 中的后端选项,列出所有 GGML_* 开头的选项及其含义。

参考答案

主要后端选项:

  • GGML_CUDA=ON — NVIDIA GPU (CUDA)
  • GGML_METAL=ON — Apple GPU (Metal)
  • GGML_VULKAN=ON — 跨平台 GPU (Vulkan)
  • GGML_OPENCL=ON — OpenCL GPU
  • GGML_BLAS=ON — BLAS 加速 (OpenBLAS, MKL)
  • GGML_HIP=ON — AMD GPU (ROCm/HIP)
  • GGML_SYCL=ON — Intel GPU (SYCL)
  • GGML_RPC=ON — 远程过程调用后端

练习 2:追踪 buffer 分配流程

llama_init_from_model 开始,追踪 tensor 是如何分配到设备内存的。提示:关注 ggml_backend_alloc_ctx_tensors 的调用路径。

参考答案

流程:

  1. llama_init_from_model() 创建 context
  2. 内部调用 llama_context::init()
  3. 使用 ggml_backend_alloc_ctx_tensors(backend, ctx) 将模型权重张量分配到后端 buffer
  4. 后端根据自己的内存管理策略分配设备内存
  5. CPU 后端使用 malloc/mmap
  6. CUDA 后端使用 cudaMalloc
  7. Metal 后端使用 [MTLDevice newBufferWithBytes:] 或映射共享内存

练习 3:对比 CPU 和 GPU kernel

ggml-cpu/ggml-cuda/ggml-metal/ 中找到矩阵乘法的实现,对比它们的实现策略。

参考答案

CPU 矩阵乘法:

  • 按行分块,利用 SIMD 指令并行计算
  • 使用 cache-friendly 的分块策略
  • 量化矩阵乘法使用查表 + 累加

CUDA 矩阵乘法 (mmq.cuh):

  • 每个 thread block 处理输出矩阵的一个 tile
  • 利用 shared memory 缓存输入 tile
  • warp-level 矩阵乘法指令
  • 针对不同量化类型有专门 kernel

Metal 矩阵乘法 (ggml-metal.metal):

  • threadgroup 共享内存缓存
  • SIMD group 矩阵操作
  • 利用 Apple GPU 的统一内存特性减少拷贝

拓展挑战

  • 阅读一个量化矩阵乘法 kernel(如 Q4_0),理解 block-level 反量化过程
  • 对比同一模型在 CPU-only 和 GPU 后端上的推理速度
  • 理解 Scheduler 如何处理跨后端的 tensor 依赖