LLM 谷歌 AI

谷歌Gemma模型的C++推理引擎

适用于Google Gemma模型的轻量级独立C++推理引擎。

2024年2月27日
gemmacpp
分享

gemma.cpp 是一个轻量级、独立的 C++ 推理引擎,适用于 Google 的 Gemma 基础模型。

有关 Gemma 的更多信息,请参阅 ai.google.dev/gemma。模型权重、包括 gemma.cpp 的特定项目文件,可在 kaggle 上找到

这个项目适合谁?

现代 LLM 推理引擎是复杂的系统,通常具有超出传统神经网络运行态的定制功能。随之而来的是需要通过高级算法和低级计算的协同设计进行研究和创新。然而,面向部署的 C++ 推理运行态(并非为实验而设计)与以 Python 为中心的 ML 研究框架(通过编译抽象出低级计算)之间存在差距。

gemma.cpp 提供了 Gemma 2B 和 7B 模型的极简实现,注重简单性和直接性,而不是完全的通用性。这受到垂直集成模型实现(例如 ggmlllama.cllama.rs )的启发。

gemma.cpp 的目标是实验和研究用例。它旨在以最小的依赖性直接嵌入到其他项目中,并且还可以通过小型的约 2K 行代码核心实现(以及约 4K 行支持相关的实用代码)轻松修改。我们使用Google Highway Library 来利用便携式 SIMD 进行 CPU 推理。

对于面向生产的边缘部署,我们建议使用 JAX、Keras、PyTorch 和 Transformers 等 Python 框架的标准部署路径(此处为所有模型变体)。

欢迎社区贡献。该项目遵循 Google 的开源社区准则

目前正在dev分支上进行积极的开发。请使用dev分支而不是main,这样会更稳定。

快速开始

系统要求

在开始之前,您应该先安装:

在 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-it2b-pt7b-it7b-pt),反之亦然。重新看步骤 #3 并检查cmake用于构建gemma的命令对于您下载的权重是否正确。

将来我们将处理从编译时到运行时的模型格式处理,以简化这一过程。

在 Windows/Visual Studio 中构建的问题

目前,如果您使用的是 Windows,我们建议使用 WSL(适用于 Linux 的 Windows 子系统)进行构建。我们正在探索启用其他构建配置的选项,请参阅问题以进行积极讨论。

模型不响应指令并产生奇怪的输出

一个常见的问题是您使用的是预训练的模型,该模型未经过指令调整,因此不会响应指令。确保您使用的是指令调整模型 ( 2b-it-sfp2b-it7b-it-sfp7b-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 HuangJan Wassenberg 于 2023 年秋季启动,随后在 Phil Culliton、Paul Chang 和 Dan Cheng 的贡献下于 2024 年 2 月发布。

来自:https://github.com/google/gemma.cpp

更多文章

通过深度学习检测文件内容类型。

2024年2月26日 · 文件类型 AI
LLM标记化中常用的字节对编码(BPE)算法的最小、干净的代码。
2024年2月26日 · LLM
gitbutler
Git分支管理工具,从头开始构建,适合现代工作流程。
2024年2月23日 · git
sc
Stability AI出品的新一代文生图模型。
2024年2月22日 · AIGC AI