gemma.cpp 是一个轻量级、独立的 C++ 推理引擎,适用于 Google 的 Gemma 基础模型。
有关 Gemma 的更多信息,请参阅 ai.google.dev/gemma。模型权重、包括 gemma.cpp 的特定项目文件,可在 kaggle 上找到。
这个项目适合谁?
现代 LLM 推理引擎是复杂的系统,通常具有超出传统神经网络运行态的定制功能。随之而来的是需要通过高级算法和低级计算的协同设计进行研究和创新。然而,面向部署的 C++ 推理运行态(并非为实验而设计)与以 Python 为中心的 ML 研究框架(通过编译抽象出低级计算)之间存在差距。
gemma.cpp 提供了 Gemma 2B 和 7B 模型的极简实现,注重简单性和直接性,而不是完全的通用性。这受到垂直集成模型实现(例如 ggml、 llama.c和 llama.rs )的启发。
gemma.cpp 的目标是实验和研究用例。它旨在以最小的依赖性直接嵌入到其他项目中,并且还可以通过小型的约 2K 行代码核心实现(以及约 4K 行支持相关的实用代码)轻松修改。我们使用Google Highway Library 来利用便携式 SIMD 进行 CPU 推理。
对于面向生产的边缘部署,我们建议使用 JAX、Keras、PyTorch 和 Transformers 等 Python 框架的标准部署路径(此处为所有模型变体)。
欢迎社区贡献。该项目遵循 Google 的开源社区准则。
目前正在dev
分支上进行积极的开发。请使用dev
分支而不是main
,这样会更稳定。
快速开始
系统要求
在开始之前,您应该先安装:
- CMake
- Clang C++编译器,至少支持C++17
tar
用于从 Kaggle 中提取档案
在 Windows 上进行本机构建需要带有可选 Clang/LLVM C++ 前端 ( clang-cl
) 的 Visual Studio 2012 构建工具。可以使用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 获取模型权重和标记器
访问Kaggle 上的 Gemma 模型页面并选择Model Variations |> Gemma C++
。在此选项卡上,Variation
下拉列表包含以下选项。请注意,bfloat16 权重具有更高的保真度,而 8 位交换浮点权重可实现更快的推理。一般来说,我们建议从 -sfp
检查点开始。
2B 指令调整highway ( it
) 和预训练 ( pt
) 模型:
模型名称 | 描述 |
---|---|
2b-it | 20 亿参数指令调整模型,bfloat16 |
2b-it-sfp | 20亿参数指令调整模型,8位交换 float |
2b-pt | 20亿参数预训练模型,bfloat16 |
2b-pt-sfp | 20亿参数预训练模型,8位交换 float |
7B 指令调整 ( it
) 和预训练 ( pt
) 模型:
模型名称 | 描述 |
---|---|
7b-it | 70 亿参数指令调整模型,bfloat16 |
7b-it-sfp | 70 亿参数指令调整模型,8 位交换 float |
7b-pt | 70亿参数预训练模型,bfloat16 |
7b-pt-sfp | 70亿参数预训练模型,8位交换 float |
重要提示:我们强烈建议从2b-it-sfp
模型开始。
第 2 步:提取文件
填写同意书后,下载会继续并检索 tar 存档文件archive.tar.gz
。解压文件archive.tar.gz
(这可能需要几分钟):
tar -xf archive.tar.gz
这应该会生成一个包含模型权重的文件如2b-it-sfp.sbs
和一个标记器文件 ( tokenizer.spm
)。您可能希望将这些文件移动到方便的目录位置(例如此存储库中的build/
目录)。
第 3 步:构建
构建系统使用CMake。要构建 gemma 推理运行框架,请创建一个build
目录并使用cmake
从顶级项目目录生成构建文件。对于 8 位交换浮点权重 (sfp),不带任何选项运行 cmake:
类 Unix 平台
cmake -B build
或者,如果您下载了 bfloat16 权重(名称中没有-sfp
的任何模型),则不要像上面那样运行没有选项的 cmake,而是在 WEIGHT_TYPE 设置为 高速公路hwy::bfloat16_t
类型的情况下运行 cmake(这将在将来得到简化,我们建议使用-sfp
权重而不是 bfloat16来更快的推理):
cmake -B build -DWEIGHT_TYPE=hwy::bfloat16_t
运行适合您权重的上述cmake
调用后,您可以进入build/
目录并运行make
以构建 ./gemma
可执行文件:
# Configure `build` directory cmake --preset make # Build project using 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
可执行文件。
注意:在 Windows Subsystem for Linux (WSL) 上,用户应将并行线程数设置为 1。使用较大的数字可能会导致错误。
如果构建成功,目录build/
中现在应该有一个gemma
可执行文件。
Windows
# Configure `build` directory cmake --preset windows # Build project using Visual Studio Build Tools cmake --build --preset windows -j [number of parallel threads to use]
如果构建成功,目录build/
中现在应该有一个gemma.exe
可执行文件。
第四步:运行
您现在可以从build/
目录内部运行gemma
。
gemma
具有以下必需的参数:
参数 | 描述 | 示例值 |
---|---|---|
--model | 模型类型 | 2b-it,2b-pt,7b-it,7b-pt, ... (见上面) |
--compressed_weights | 压缩的权重文件 | 2b-it-sfp.sbs, ... (见上面) |
--tokenizer | 标记器文件 | tokenizer.spm |
gemma
调用方法如下:
./gemma \ --tokenizer [tokenizer file] \ --compressed_weights [compressed weights file] \ --model [2b-it or 2b-pt or 7b-it or 7b-pt or ...]
加入以下配置的调用示例:
- 压缩权重文件
2b-it-sfp.sbs
(2B 指令调整模型,8 位交换浮点)。 - 标记器文件
tokenizer.spm
。
./gemma \ --tokenizer tokenizer.spm \ --compressed_weights 2b-it-sfp.sbs \ --model 2b-it
故障排除和常见问题解答
运行./gemma
失败并显示“Failed to read cache gating_ein_0 (error 294) ...”
最常见的问题是cmake
使用错误的权重类型构建,gemma
尝试使用默认的交换浮点 (sfp) 加载bfloat16
权重 ( 2b-it
、2b-pt
、7b-it
、 7b-pt
),反之亦然。重新看步骤 #3 并检查cmake
用于构建gemma
的命令对于您下载的权重是否正确。
将来我们将处理从编译时到运行时的模型格式处理,以简化这一过程。
在 Windows/Visual Studio 中构建的问题
目前,如果您使用的是 Windows,我们建议使用 WSL(适用于 Linux 的 Windows 子系统)进行构建。我们正在探索启用其他构建配置的选项,请参阅问题以进行积极讨论。
模型不响应指令并产生奇怪的输出
一个常见的问题是您使用的是预训练的模型,该模型未经过指令调整,因此不会响应指令。确保您使用的是指令调整模型 ( 2b-it-sfp
、2b-it
、7b-it-sfp
、7b-it
),而不是预训练的模型(任何带有-pt
后缀的模型)。
如何将微调转换为.sbs
压缩模型文件?
我们正在开发一个 python 脚本,将标准模型格式转换为.sbs
,并希望在下周左右推出。请关注此问题以获取更新。
用法
gemma
有不同的使用模式,由verbosity
标志控制。
目前所有使用模式都是交互式的,在输入换行时触发文本生成。
详细显示程度 | 使用模式 | 细节 |
---|---|---|
--verbosity 0 | 最小 | 仅打印生成输出。适合作为 CLI 工具。 |
--verbosity 1 | 默认 | 标准面向用户的终端 UI。 |
--verbosity 2 | 详细 | 显示额外的开发和调试信息。 |
互动终端应用程序
默认情况下,verbosity
设置为 1,gemma
调用时将显示基于终端的交互界面:
$ ./gemma [...] __ _ ___ _ __ ___ _ __ ___ __ _ ___ _ __ _ __ / _` |/ _ \ '_ ` _ \| '_ ` _ \ / _` | / __| '_ \| '_ \ | (_| | __/ | | | | | | | | | | (_| || (__| |_) | |_) | \__, |\___|_| |_| |_|_| |_| |_|\__,_(_)___| .__/| .__/ __/ | | | | | |___/ |_| |_| tokenizer : tokenizer.spm compressed_weights : 2b-it-sfp.sbs model : 2b-it weights : [no path specified] max_tokens : 3072 max_generated_tokens : 2048 *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 --compressed_weights ~/gemma.cpp/build/2b-it-sfp.sbs --model 2b-it --verbosity 0"
将上述路径替换为您自己的模型路径和下载的标记器路径。
下面是使用截断的输入文件来提示gemma
的示例(使用上面定义的别名gemma2b
):
cat configs.h | tail -35 | tr '\n' ' ' | xargs -0 echo "What does this C++ code do: " | gemma2b
注意:gemma.cpp 的 CLI 使用是实验性的,应考虑上下文长度限制。
上述命令的输出应如下所示:
$ cat configs.h | tail -35 | tr '\n' ' ' | xargs -0 echo "What does this C++ code do: " | gemma2b [ Reading prompt ] ...................................................................................................................................................................................................................................................................................................................................................................................................................................................................................... The code defines two C++ structs, `ConfigGemma7B` and `ConfigGemma2B`, which are used for configuring a deep learning model. **ConfigGemma7B**: * `kSeqLen`: Stores the length of the sequence to be processed. It's set to 7168. * `kVocabSize`: Stores the size of the vocabulary, which is 256128. * `kLayers`: Number of layers in the deep learning model. It's set to 28. * `kModelDim`: Dimension of the model's internal representation. It's set to 3072. * `kFFHiddenDim`: Dimension of the feedforward and recurrent layers' hidden representations. It's set to 16 * 3072 / 2. **ConfigGemma2B**: * `kSeqLen`: Stores the length of the sequence to be processed. It's also set to 7168. * `kVocabSize`: Size of the vocabulary, which is 256128. * `kLayers`: Number of layers in the deep learning model. It's set to 18. * `kModelDim`: Dimension of the model's internal representation. It's set to 2048. * `kFFHiddenDim`: Dimension of the feedforward and recurrent layers' hidden representations. It's set to 16 * 2048 / 2. These structs are used to configure a deep learning model with specific parameters for either Gemma7B or Gemma2B architecture.
将 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 da250571a45826b21eebbddc1e50d0c1137dee5f) 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 调用来构建libgemma
目标而不是gemma
.
注意:如果您按照上一节中的FetchContent
步骤在自己的项目中使用 gemma.cpp,则构建库会由cmake
自动完成,可以跳过本节。
首先,运行cmake
:
cmake -B build
然后,用libgemma
做为目标运行make
:
cd build make -j [number of parallel threads to use] libgemma
如果成功,build/
目录中现在应该有一个libgemma
库文件。在 Unix 平台上,文件名为libgemma.a
.
致谢和联系方式
gemma.cpp 由 Austin Huang 和 Jan Wassenberg 于 2023 年秋季启动,随后在 Phil Culliton、Paul Chang 和 Dan Cheng 的贡献下于 2024 年 2 月发布。