菜单

开发

相关源文件

本页面涵盖 llama.cpp 代码库的开发工作流程、测试框架和贡献指南。它包括有关构建系统、CI/CD 管道、测试基础设施和可重现开发环境的信息。有关使用 llama.cpp 应用程序的信息,请参阅 入门指南用户界面

构建系统架构

llama.cpp 项目使用 CMake 作为其构建系统,支持多种平台和硬件配置。构建系统支持使用各种优化级别、硬件加速功能和后端选项进行编译。

来源: .github/workflows/build.yml6-987 ggml/CMakeLists.txt1-362 ggml/src/CMakeLists.txt1-343 common/CMakeLists.txt1-145 examples/server/CMakeLists.txt1-51

关键构建选项

构建系统支持众多选项,可根据您的硬件和需求定制构建。以下是一些最重要的选项:

选项描述默认
LLAMA_NATIVE针对当前 CPU 进行优化ON(除非交叉编译)
LLAMA_METAL在 macOS 上启用 Metal 支持ON (macOS)
LLAMA_CUDA为 NVIDIA GPU 启用 CUDA 支持OFF
LLAMA_VULKAN启用 Vulkan 支持OFF
LLAMA_OPENMP启用 OpenMP 以进行多线程处理ON
LLAMA_AVX/AVX2/AVX512启用特定的 CPU 指令集可变
LLAMA_BLAS启用 BLAS 支持OFF (Apple 为 ON)
LLAMA_BUILD_SERVER构建 HTTP 服务器ON

来源: .github/workflows/build.yml36-988 ggml/CMakeLists.txt50-167

特定平台优化

构建系统会检测 CPU 架构,并根据可用的指令集启用相应的优化。

来源: ggml/src/ggml-cpu/CMakeLists.txt84-367 ggml/src/ggml-cpu/ggml-cpu.c89-106

GGML 同步

llama.cpp 将 GGML 张量库作为子模块维护,需要定期与上游 GGML 存储库同步以合并新功能和优化。

同步脚本

存储库提供了两个用于 GGML 同步的脚本:

简单同步 (sync-ggml.sh):

  • 从本地 GGML 存储库签出复制文件
  • 需要手动解决冲突
  • 适用于一次性同步

高级同步 (sync-ggml-am.sh):

  • 使用 git am 将单个 GGML commit 应用为补丁
  • 维护 commit 历史记录和归属信息
  • 处理来自 scripts/sync-ggml.last 的增量更新
  • 定期同步的首选方法

来源: scripts/sync-ggml.sh1-36 scripts/sync-ggml-am.sh1-203 scripts/sync-ggml.last1-2

同步流程详情

sync-ggml-am.sh 脚本遵循以下流程:

  1. 读取上次同步:解析 scripts/sync-ggml.last 以查找上次同步的 GGML commit。
  2. 生成补丁系列:使用 git format-patch 创建新 GGML commit 的补丁。
  3. 应用补丁:使用 git am 应用每个补丁,保留 commit 元数据。
  4. 处理冲突:提供手动解决冲突的说明(如果需要)。
  5. 更新跟踪:使用新的同步点更新 scripts/sync-ggml.last

使用示例

来源: scripts/sync-ggml-am.sh20-203

集成注意事项

同步 GGML 更改时:

  1. 兼容性测试:同步后运行完整的测试套件。
  2. 后端兼容性:验证所有后端是否仍能成功编译和运行。
  3. 性能回归:使用 ci/run.sh 检查性能回归。
  4. API 更改:如果 GGML API 已更改,则更新 llama.cpp 代码。
  5. 文档:如果公开了新的 GGML 功能,则更新文档。

在以下情况下,同步过程可能需要手动干预:

  • GGML 更改与 llama.cpp 特定修改冲突
  • 新的 GGML 功能需要 llama.cpp 中的集成工作
  • 后端实现需要针对新的 GGML 操作进行更新

来源: scripts/sync-ggml-am.sh9-200

测试框架

llama.cpp 包含一个全面的测试框架,以确保代码质量和功能。测试组织在 tests/ 目录下,可以使用 CTest 运行。

来源: tests/CMakeLists.txt1-156

运行测试

在构建项目后,可以使用 CTest 运行测试。

测试框架提供三个主要函数用于添加测试:

来源: tests/CMakeLists.txt3-81

测试组织

测试按标签和类别进行组织。

来源: tests/CMakeLists.txt84-183

可用的测试类别

类别测试名称目的
分词器test-tokenizer-0-* (bert-bge, command-r 等)词汇表和分词
语法test-grammar-parser, test-grammar-integration, test-grammar-llguidance结构化生成
后端test-backend-ops, test-quantize-fns, test-ropeGGML 操作
模型test-model-load-cancel, test-autorelease模型生命周期
实用工具test-chat, test-gguf, test-sampling核心功能
集成test-arg-parser, test-json-partial命令行和解析

来源: tests/CMakeLists.txt86-183

后端测试

test-backend-ops 可执行文件用于验证不同 GGML 后端之间的数值一致性。

此测试确保操作在 CPU、CUDA、Metal、Vulkan 或其他后端上运行时产生一致的结果。

来源: tests/CMakeLists.txt161

CI/CD 流水线

该项目使用多层 CI/CD 系统,结合 GitHub Actions 和自定义云端 CI 框架,以在各种平台和硬件配置上进行全面测试。

GitHub Actions 工作流

主 CI 工作流在 build.yml 中定义,它在每次 push 和 pull request 时运行,跨多个平台和配置执行构建。

来源: .github/workflows/build.yml24-1079

本地 CI 系统

存储库包含 ci/run.sh,用于运行全面的本地测试,这些测试镜像云 CI 环境。

来源:ci/run.sh1-1024 ci/README.md1-69

特定平台的 CI 作业

CI 系统为每个平台测试多种配置

平台作业名称主要功能
macOS ARM64macOS-latest-cmake-arm64Metal, BF16, RPC
macOS x64macOS-latest-cmake-x64禁用 Metal, RPC
Ubuntu CPUubuntu-cpu-cmakex64/ARM64 矩阵, curl 测试
Ubuntu CUDAubuntu-latest-cmake-cudaNVIDIA 容器, CUDA 12.6
Ubuntu Vulkanubuntu-22-cmake-vulkanVulkan SDK, Mesa 驱动
Ubuntu SYCLubuntu-22-cmake-syclIntel oneAPI, FP16 变体
Windowswindows-latest-cmake多架构, OpenMP

来源:.github/workflows/build.yml25-1079

云 CI 框架

项目使用了一个托管在 https://github.com/ggml-org/ci 的自定义 CI 框架,该框架监控 master 分支并在专用的云实例上执行更重的负载。

  • 在 master 分支提交时自动触发
  • 可以通过将 ggml-ci 关键字添加到提交消息中手动触发
  • 提供对包括 GPU 和 Apple Silicon 在内的各种硬件架构的访问
  • 执行与本地测试相同的 ci/run.sh 脚本

来源:ci/README.md3-13

可复现构建

项目支持多种方法来创建可重现的开发环境和构建。

Docker 镜像

预构建的 Docker 镜像适用于各种配置

Docker 使用示例

来源:docs/docker.md8-127

Nix Flakes

该存储库包含 Nix flake 支持,用于可重现的开发环境

Nix 提供具有固定依赖项的封闭式构建,确保跨不同机器和跨时间的可重现结果。

本地 CI 测试

在提交更改之前,请在本地运行完整的 CI 套件,以便尽早发现问题

本地 CI 脚本下载测试模型,构建项目,并运行与云 CI 环境匹配的全面基准测试。

来源:ci/README.md15-32 ci/run.sh23-32

贡献指南

开发工作流

  1. 设置环境:使用 Docker、Nix 或本地设置及必需的依赖项
  2. 运行本地 CI:执行 ci/run.sh 来验证您的环境是否正常工作
  3. 进行更改:遵循现有的代码模式并保持跨平台兼容性
  4. 测试更改:在提交前运行相关的测试套件和本地 CI
  5. 提交 PR:创建带有清晰更改描述的拉取请求

代码规范

  • 语言:核心库为 C++17,GGML 后端实现为 C
  • 可移植性:代码必须能在 Windows、macOS、Linux、iOS、Android 上运行
  • 性能:留意性能影响,尤其是在热路径中
  • 测试:使用 llama_build_and_test 框架为新功能添加测试

后端开发

添加新的 GGML 后端时

  1. 遵循 ggml/src/ggml-{backend}/ 中的模式
  2. 在后端接口中实现所需操作
  3. ggml/src/ggml-{backend}/CMakeLists.txt 中添加 CMake 配置
  4. 使用 test-backend-ops 添加测试以验证数值精度
  5. 更新 CI 配置以测试新后端

来源:tests/CMakeLists.txt161 ggml/src/ggml-sycl/CMakeLists.txt1-190

构建系统细节

编译器优化

构建系统根据检测到的架构包含许多特定于编译器的优化。这些优化对于 llama.cpp 的性能至关重要。

来源:ggml/src/CMakeLists.txt1-343 ggml/cmake/common.cmake

后端支持

构建系统支持多种后端以实现硬件加速

后端标志描述
CPULLAMA_CPU基本 CPU 支持(始终启用)
CUDALLAMA_CUDA通过 CUDA 支持 NVIDIA GPU
MetalLLAMA_METAL通过 Metal 支持 Apple GPU
VulkanLLAMA_VULKAN通过 Vulkan 实现跨平台 GPU 支持
HIPLLAMA_HIP通过 HIP 支持 AMD GPU
SYCLLLAMA_SYCL通过 SYCL 支持 Intel GPU
OpenCLLLAMA_OPENCL通过 OpenCL 实现跨平台 GPU 支持
BLASLLAMA_BLAS基础线性代数程序支持

来源:ggml/CMakeLists.txt144-206 ggml/src/CMakeLists.txt283-312

交叉编译

构建系统支持交叉编译到各种目标

  1. 从 macOS 主机编译的 **iOS** 和 **tvOS** 目标
  2. 从 x86_64 主机编译的 **ARM64** 目标
  3. **Windows ARM64** 构建

每个目标都有特定的 CMake 选项和编译器标志,以启用正确的交叉编译。CI 工作流包含用于验证交叉编译是否正常工作的作业。

来源:.github/workflows/build.yml607-707 .github/workflows/build.yml826-833

开发者工具和实用程序

提供了几个实用函数和宏来辅助开发

  1. 测试函数

    • llama_test - 从现有可执行文件创建测试
    • llama_target_and_test - 一步构建并创建测试
  2. 构建助手函数

    • ggml_add_backend - 添加 GGML 后端
    • ggml_add_backend_library - 添加后端库
    • ggml_add_cpu_backend_variant - 添加 CPU 后端变体
  3. 调试工具

    • 用于检测内存和线程问题的 Sanitizer 构建
    • 调试日志设施
    • 性能测量实用程序

来源:tests/CMakeLists.txt3-68 ggml/src/CMakeLists.txt220-281