Appearance
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 GPUGGML_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 的调用路径。
参考答案
流程:
llama_init_from_model()创建 context- 内部调用
llama_context::init() - 使用
ggml_backend_alloc_ctx_tensors(backend, ctx)将模型权重张量分配到后端 buffer - 后端根据自己的内存管理策略分配设备内存
- CPU 后端使用
malloc/mmap - CUDA 后端使用
cudaMalloc - 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 依赖