google/gemma.cpp

GitHub: google/gemma.cpp

这是一个轻量级的 C++ 推理引擎,专门用于在 CPU 上高效运行 Google 的 Gemma 大语言模型及 PaliGemma 多模态模型。

Stars: 6844 | Forks: 617

# gemma.cpp gemma.cpp 是一个轻量级、独立的 C++ 推理引擎,用于 Google 的 Gemma 基础模型。 有关 Gemma 的更多信息,请参阅 [ai.google.dev/gemma](https://ai.google.dev/gemma)。模型权重,包括 gemma.cpp 特有的构件,可在 [Kaggle 上获取](https://www.kaggle.com/models/google/gemma-2)。 ## 这个项目适合谁? 现代 LLM 推理引擎是复杂的系统,通常具有超越传统神经网络运行时的定制能力。这带来了通过高层算法和底层计算的协同设计进行研究和创新的机会。然而,面向部署的 C++ 推理运行时(并非为实验而设计)与以 Python 为中心的 ML 研究框架(通过编译抽象掉底层计算)之间存在差距。 gemma.cpp 提供了 Gemma-2、Gemma-3 和 PaliGemma-2 模型的极简实现,专注于简单性和直接性,而非完全的通用性。这受到了垂直集成模型实现的启发,例如 [ggml](https://github.com/ggerganov/ggml), [llama.c](https://github.com/karpathy/llama2.c), 和 [llama.rs](https://github.com/srush/llama2.rs)。 gemma.cpp 面向实验和研究用例。它旨在以最少的依赖轻松嵌入到其他项目中,并且由于核心实现较小(约 2K LoC,以及约 4K LoC 的支持工具),因此易于修改。我们使用 [Google Highway](https://github.com/google/highway) 库来利用可移植的 SIMD 进行 CPU 推理。 对于面向生产的边缘部署,我们推荐使用 Python 框架(如 JAX、Keras、PyTorch 和 Transformers)的标准部署路径([此处包含所有模型变体](https://www.kaggle.com/models/google/gemma))。 ## 包含什么内容? - LLM - 仅限 CPU 的推理:Gemma 2-3, PaliGemma 2。 - 支持带 TopK 和 temperature 的采样。 - 用于 Gemma 研究的反向传播 (VJP) 和 Adam 优化器。 - 优化 - 混合精度 (fp8, bf16, fp32, fp64 bit) GEMM: - 为 BF16 指令设计,可以高效模拟它们。 - 自动运行时自动调优,每个矩阵形状 7 个参数。 - 直接集成到 GEMM 中的权重压缩: - 具有 2..3 个尾数位的自定义 fp8 格式;张量缩放。 - 还有 bf16, f32 和非均匀 4 位 (NUQ);易于添加新格式。 - 基础设施 - SIMD:通过 Highway 的单一实现。在运行时选择 ISA。 - 张量并行:感知 CCX、多插槽线程池。 - 磁盘 I/O:内存映射或并行读取(启发式,用户可覆盖)。 - 具有前向/向后兼容元数据序列化的自定义格式。 - 从 Safetensors 进行模型转换,尚未开源。 - 可移植性:支持 Linux, Windows/OS X。CMake/Bazel。“任意”CPU。 - 前端 - 用于单查询和批量推理的带流式传输的 C++ API。 - 基本的交互式命令行应用。 - 基本的 Python 绑定 (pybind11)。 ## 快速开始 ### 系统要求 在开始之前,您应该已经安装了: - [CMake](https://cmake.org/) - [Clang C++ 编译器](https://clang.llvm.org/get_started.html),至少支持 C++17。 - 用于从 Kaggle 提取档案的 `tar`。 在 Windows 上本机构建需要 Visual Studio 2012 Build Tools 和可选的 Clang/LLVM C++ 前端 (`clang-cl`)。这可以通过命令行使用 [`winget`](https://learn.microsoft.com/en-us/windows/package-manager/winget/) 安装: ``` winget install --id Kitware.CMake winget install --id Microsoft.VisualStudio.2022.BuildTools --force --override "--passive --wait --add Microsoft.VisualStudio.Workload.VCTools;installRecommended --add Microsoft.VisualStudio.Component.VC.Llvm.Clang --add Microsoft.VisualStudio.Component.VC.Llvm.ClangToolset" ``` ### 步骤 1:从 Kaggle 或 Hugging Face Hub 获取模型权重和分词器 访问 [Gemma-2 的 Kaggle 页面](https://www.kaggle.com/models/google/gemma-2/gemmaCpp) 并选择 `Model Variations |> Gemma C++`。 在此选项卡上,`Variation` 下拉菜单包含以下选项。请注意,bfloat16 权重保真度更高,而 8 位交换浮点权重可实现更快的推理。通常,我们建议从 `-sfp` 检查点开始。 Gemma 2 模型命名为 `gemma2-2b-it` (2B) 和 `9b-it` 或 `27b-it`。请参阅 `configs.cc` 中的 `ModelPrefix` 函数。 ### 步骤 2:提取文件 填写同意书后,下载应继续检索一个 tar 档案文件 `archive.tar.gz`。从 `archive.tar.gz` 中提取文件(这可能需要几分钟): ``` tar -xf archive.tar.gz ``` 这应该会生成一个包含模型权重的文件,例如 `2b-it-sfp.sbs` 和 一个分词器文件 (`tokenizer.spm`)。您可能希望将这些文件移动到 方便的目录位置(例如本仓库中的 `build/` 目录)。 ### 步骤 3:构建 构建系统使用 [CMake](https://cmake.org/)。要构建 gemma 推理 运行时,请创建一个构建目录并从顶级项目目录使用 `cmake` 生成构建文件。请注意,如果您之前运行过 `cmake` 并正在 使用不同的设置重新运行,请务必使用 `rm -rf build/*` 删除 `build/` 目录中的所有文件。 #### 类 Unix 平台 ``` cmake -B build ``` 运行 `cmake` 后,您可以进入 `build/` 目录并运行 `make` 来 构建 `./gemma` 可执行文件: ``` # 配置 `build` 目录 cmake --preset make # 使用 make 构建项目 cmake --build --preset make -j [number of parallel threads to use] ``` 将 `[number of parallel threads to use]` 替换为一个数字 - 系统上可用的核心数是一个合理的启发式值。例如,`make -j4 gemma` 将使用 4 个线程进行构建。如果 `nproc` 命令可用,您可以使用 `make -j$(nproc) gemma` 作为线程数的合理默认值。 如果您不确定 `-j` 标志的正确值,您可以简单地运行 `make gemma`,它仍然应该构建 `./gemma` 可执行文件。 如果构建成功,您现在应该在 `build/` 目录中有一个 `gemma` 可执行文件。 #### Windows ``` # 配置 `build` 目录 cmake --preset windows # 使用 Visual Studio Build Tools 构建项目 cmake --build --preset windows -j [number of parallel threads to use] ``` 如果构建成功,您现在应该在 `build/` 目录中有一个 `gemma.exe` 可执行文件。 #### Bazel ``` bazel build -c opt --cxxopt=-std=c++20 :gemma ``` 如果构建成功,您现在应该在 `bazel-bin/` 目录中有一个 `gemma` 可执行文件。 #### Make 如果您更喜欢 Makefiles,@jart 在这里提供了一个: https://github.com/jart/gemma3/blob/main/Makefile ### 步骤 4:运行 您现在可以从 `build/` 目录内部运行 `gemma`。 `gemma` 具有以下必需参数: 参数 | 描述 | 示例值 ------------- | ---------------------------- | --------------- `--weights` | 压缩权重文件。 | `2b-it-sfp.sbs` `--tokenizer` | 分词器文件。 | `tokenizer.spm` 以下配置的示例调用: - 权重文件 `gemma2-2b-it-sfp.sbs` (Gemma2 2B 指令微调模型, 8 位交换浮点)。 - 分词器文件 `tokenizer.spm`(对于在 2025-05-06 之后创建的单格式权重文件,或由 migrate_weights.cc 输出的文件,可以省略)。 ``` ./gemma \ --tokenizer tokenizer.spm --weights gemma2-2b-it-sfp.sbs ``` ### PaliGemma 视觉语言模型 此仓库包含 PaliGemma 2 VLM 的一个版本 ([论文](https://arxiv.org/abs/2412.03555))。我们在这里提供了 PaliGemma 2 模型的 C++ 实现。 要使用此仓库中包含的 PaliGemma 版本,请按照上述步骤 3 中的说明构建 gemma 二进制文件。从 [Kaggle](https://www.kaggle.com/models/google/paligemma-2/gemmaCpp/paligemma2-3b-mix-224) 下载压缩权重和分词器 并按如下方式运行二进制文件: ``` ./gemma \ --tokenizer paligemma_tokenizer.model \ --weights paligemma2-3b-mix-224-sfp.sbs \ --image_file paligemma/testdata/image.ppm ``` 请注意,图像读取代码非常基础,以避免目前依赖图像处理库。我们目前仅支持读取二进制 PPM (P6)。 因此,请使用像 `convert` 这样的工具先将您的图像转换为该格式,例如 `convert image.jpeg -resize 224x224^ image.ppm` (由于图像无论如何都会被调整大小以进行处理,我们可以在此阶段进行调整以加快加载速度。) 与图像的交互(使用 mix-224 检查点)可能看起来像这样: ``` > Describe the image briefly A large building with two towers in the middle of a city. > What type of building is it? church > What color is the church? gray > caption image A large building with two towers stands tall on the water's edge. The building has a brown roof and a window on the side. A tree stands in front of the building, and a flag waves proudly from its top. The water is calm and blue, reflecting the sky above. A bridge crosses the water, and a red and white boat rests on its surface. The building has a window on the side, and a flag on top. A tall tree stands in front of the building, and a window on the building is visible from the water. The water is green, and the sky is blue. ``` ### 迁移到单文件格式 现在有一种新的权重文件格式,它是一个可以直接包含分词器(和模型类型)的文件。提供了一个将 从多文件格式迁移到单文件格式的工具。 ``` io/migrate_weights \ --tokenizer .../tokenizer.spm --weights .../gemma2-2b-it-sfp.sbs \ --output_weights .../gemma2-2b-it-sfp-single.sbs ``` 迁移后,您可以像这样省略分词器参数: ``` ./gemma --weights .../gemma2-2b-it-sfp-single.sbs ``` ### 故障排除和常见问题 **在 Windows / Visual Studio 中构建遇到问题** 目前,如果您使用的是 Windows,我们建议在 WSL (Windows Subsystem for Linux) 中构建。我们正在探索启用其他构建 配置的选项,请参阅 issues 以获取活跃讨论。 **模型不响应指令并产生奇怪的输出** 一个常见问题是您使用的是预训练模型,该模型未经过 指令微调,因此不响应指令。请确保您使用的是指令微调模型 (`gemma2-2b-it-sfp`) 而不是预训练 模型(任何带有 `-pt` 后缀的模型)。 **支持哪些序列长度?** 请参阅 `configs.cc` 和 `InferenceArgs.seq_len` 中的 `max_seq_len`。对于大于 1B 的 Gemma 3 模型,这通常是 32K,但如果 RAM 足够,128K 也可以工作。请注意,由于注意力的二次成本,长序列会很慢。 **如何将我的微调模型转换为 `.sbs` 压缩模型文件?** 对于 PaliGemma 2 检查点,您可以使用 python/convert_from_safetensors.py 从 safetensors 格式转换(已通过 bazel 构建测试)。对于适配器 模型,您可能需要调用 merge_and_unload() 将适配器 模型转换为单文件格式,然后再进行转换。 以下是使用压缩库的 bazel 构建来使用它的方法,假设本地安装了 (venv) torch, numpy, safetensors, absl-py 等: ``` bazel build //compression/python:compression BAZEL_OUTPUT_DIR="${PWD}/bazel-bin/compression" python3 -c "import site; print(site.getsitepackages())" # 在此处使用您的 sites-packages 文件: ln -s $BAZEL_OUTPUT_DIR [...]/site-packages/compression python3 python/convert_from_safetensors.py --load_path [...].safetensors.index.json ``` **有哪些简单的方法可以让模型运行得更快?** 1. 确保您使用的是 8 位交换浮点 `-sfp` 模型。 它们的大小是 bf16 的一半,因此使用的内存带宽和缓存 空间更少。 2. 由于自动调优,第二次尤其是第三次查询会更快。 3. 如果您使用的是笔记本电脑,请确保电源模式设置为最大化性能 并且省电模式是**关闭**的。对于大多数笔记本电脑,如果计算机未插入电源,省电模式会 自动激活。 4. 关闭其他未使用的 CPU 密集型应用程序。 5. 在 Mac 上,根据我们的经验,随着性能 核心的启动,我们会观察到速度的“预热”提升。 我们也在致力于算法和优化方法以实现更快的 推理,敬请期待。 ## 用法 `gemma` 有不同的使用模式,由详细程度标志控制。 所有使用模式目前都是交互式的,在换行输入时触发文本生成。 | 详细程度 | 使用模式 | 详情 | | --------------- | ---------- | --------------------------------------------- | | `--verbosity 0` | 最小化 | 仅打印生成输出。适合作为 CLI 工具。 | | `--verbosity 1` | 默认 | 标准的用户面向终端 UI。 | | `--verbosity 2` | 详细 | 显示额外的开发人员和调试信息。 | ### 交互式终端应用 默认情况下,详细程度设置为 1,当调用 `gemma` 时会启动一个基于终端的交互式 界面: ``` $ ./gemma [...] __ _ ___ _ __ ___ _ __ ___ __ _ ___ _ __ _ __ / _` |/ _ \ '_ ` _ \| '_ ` _ \ / _` | / __| '_ \| '_ \ | (_| | __/ | | | | | | | | | | (_| || (__| |_) | |_) | \__, |\___|_| |_| |_|_| |_| |_|\__,_(_)___| .__/| .__/ __/ | | | | | |___/ |_| |_| ... *Usage* Enter an instruction and press enter (%C reset conversation, %Q quits). *Examples* - Write an email to grandma thanking her for the cookies. - What are some historical attractions to visit around Massachusetts? - Compute the nth fibonacci number in javascript. - Write a standup comedy bit about WebGPU programming. > What are some outdoorsy places to visit around Boston? [ Reading prompt ] ..................... **Boston Harbor and Islands:** * **Boston Harbor Islands National and State Park:** Explore pristine beaches, wildlife, and maritime history. * **Charles River Esplanade:** Enjoy scenic views of the harbor and city skyline. * **Boston Harbor Cruise Company:** Take a relaxing harbor cruise and admire the city from a different perspective. * **Seaport Village:** Visit a charming waterfront area with shops, restaurants, and a seaport museum. **Forest and Nature:** * **Forest Park:** Hike through a scenic forest with diverse wildlife. * **Quabbin Reservoir:** Enjoy boating, fishing, and hiking in a scenic setting. * **Mount Forest:** Explore a mountain with breathtaking views of the city and surrounding landscape. ... ``` ### 作为命令行工具使用 要将 `gemma` 可执行文件用作命令行工具,为 gemma.cpp 创建一个完全指定参数的别名可能会有用: ``` alias gemma2b="~/gemma.cpp/build/gemma -- --tokenizer ~/gemma.cpp/build/tokenizer.spm --weights ~/gemma.cpp/build/gemma2-2b-it-sfp.sbs --verbosity 0" ``` 将上述路径替换为您自己的模型和分词器路径 来自下载。 这是一个使用截断的输入 文件提示 `gemma` 的示例(使用上面定义的 `gemma2b` 别名): ``` cat configs.h | tail -n 35 | tr '\n' ' ' | xargs -0 echo "What does this C++ code do: " | gemma2b ``` 上述命令的输出应如下所示: ``` [ Reading prompt ] [...] This C++ code snippet defines a set of **constants** used in a large language model (LLM) implementation, likely related to the **attention mechanism**. Let's break down the code: [...] ``` ### 将 gemma.cpp 作为库合并到您的项目中 将 gemma.cpp 合并到您自己的项目中的最简单方法是使用 `FetchContent` 引入 gemma.cpp 和依赖项。您可以将以下内容添加到 您的 CMakeLists.txt: ``` include(FetchContent) FetchContent_Declare(sentencepiece GIT_REPOSITORY https://github.com/google/sentencepiece GIT_TAG 53de76561cfc149d3c01037f0595669ad32a5e7c) FetchContent_MakeAvailable(sentencepiece) FetchContent_Declare(gemma GIT_REPOSITORY https://github.com/google/gemma.cpp GIT_TAG origin/main) FetchContent_MakeAvailable(gemma) FetchContent_Declare(highway GIT_REPOSITORY https://github.com/google/highway.git GIT_TAG 2a16a50ff61071bb25ddef0ce35d92b0e2b9c579) FetchContent_MakeAvailable(highway) ``` 请注意,对于 gemma.cpp 的 `GIT_TAG`,如果您想固定库版本,可以将 `origin/main` 替换为特定的 提交哈希。 定义可执行文件后(将您的可执行文件名称替换为 下面的 `[Executable Name]`): ``` target_link_libraries([Executable Name] libgemma hwy hwy_contrib sentencepiece) FetchContent_GetProperties(gemma) FetchContent_GetProperties(sentencepiece) target_include_directories([Executable Name] PRIVATE ${gemma_SOURCE_DIR}) target_include_directories([Executable Name] PRIVATE ${sentencepiece_SOURCE_DIR}) ``` ### 将 gemma.cpp 构建为库 gemma.cpp 也可以用作您自己项目中的库依赖项。 可以通过修改 make 调用来构建共享库构件,以构建 `gemma` 目标而不是 `gemma`。 首先,运行 `cmake`: ``` cmake -B build ``` 然后,使用 `libgemma` 目标运行 `make`: ``` cd build make -j [number of parallel threads to use] libgemma ``` 如果成功,您现在应该在 `build/` 目录中有一个 `libgemma` 库文件。在 Unix 平台上,文件名为 `libgemma.a`。 ## 使用 gemma.cpp 的独立项目 一些使用 gemma.cpp 的独立项目: - [gemma-cpp-python - Python 绑定](https://github.com/namtranase/gemma-cpp-python) - [lua-cgemma - Lua 绑定](https://github.com/ufownl/lua-cgemma) - [Godot 引擎演示项目](https://github.com/Rliop913/Gemma-godot-demo-project) 如果您希望将您的项目包含在内,请随时联系或 提交 PR 以编辑 `README.md`。 ## 致谢和联系方式 gemma.cpp 于 2023 年秋季由 [Austin Huang](mailto:austinvhuang@google.com) 和 [Jan Wassenberg](mailto:janwas@google.com) 启动,并于 2024 年 2 月发布,感谢 Phil Culliton、Paul Chang 和 Dan Zheng 的贡献。 Griffin 支持于 2024 年 4 月实施,感谢 Andrey Mikhaylov、Eugene Kliuchnikov、Jan Wassenberg、Jyrki Alakuijala、Lode Vandevenne、Luca Versari、Martin Bruse、Phil Culliton、Sami Boukortt、Thomas Fischbacher 和 Zoltan Szabadka 的贡献。它已于 2025-09 移除。 Gemma-2 支持于 2024 年 6 月/7 月实施,并在多人的帮助下完成。 PaliGemma 支持于 2024 年 9 月实施,感谢 Daniel Keysers 的贡献。 [Jan Wassenberg](mailto:janwas@google.com) 自最初发布以来持续贡献了许多 改进,包括效率方面的重大提升。 这不是一个受官方支持的 Google 产品。
标签:Apex, Bash脚本, C++, CPU推理, DNS解析, Google Gemma, Google Highway, LangChain, LLM, PaliGemma, SIMD, Temperature采样, TopK采样, Unmanaged PE, 多模态, 大模型, 开源项目, 推理引擎, 数据擦除, 机器学习, 模型部署, 深度学习, 独立运行, 研究工具, 轻量级, 边缘计算, 逆向工具, 量化, 高性能计算