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

Created at: 2024-02-13 12:36:03
Language: C++
License: Apache-2.0

gemma.cpp

gemma.cpp 是 Gemma 的轻量级独立C++推理引擎 来自 Google 的基础模型。

有关 Gemma 的其他信息,请参阅 ai.google.dev/gemma。模型重量,包括gemma.cpp 特定工件,可在 卡格尔

这个项目是为谁准备的?

现代 LLM 推理引擎是复杂的系统,通常具有定制功能 超越传统神经网络运行时的功能。有了这个 通过高水平的共同设计带来研究和创新的机会 算法和低级计算。但是,两者之间存在差距 面向部署的 C++ 推理运行时,不是为 实验,以及以 Python 为中心的 ML 研究框架,这些框架抽象出来 通过编译进行低级计算。

gemma.cpp 提供了 Gemma 2B 和 7B 模型的极简实现, 注重简单性和直接性,而不是完全的笼统性。这是 灵感来自垂直集成的模型实现,例如 GGMLLlama.Cllama.rs

gemma.cpp针对实验和研究用例。它的目的是 直接嵌入到其他项目中,依赖性最小,而且 通过小型 ~2K LoC 内核实现(以及 ~4K LoC)轻松修改 支持公用事业)。我们使用 Google 高速公路图书馆可以利用 用于 CPU 推理的便携式 SIMD。

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

欢迎大大小小的社区贡献。这个项目遵循谷歌的开源社区 准则

目前,主动开发是在 dev 分支上完成的。请打开拉 针对 dev 分支而不是 main 的请求,后者旨在更多 稳定。

快速上手

系统要求

在开始之前,你应该已经安装:

在 Windows 上本机生成需要 Visual Studio 2012 生成工具,其中包含 可选的 Clang/LLVM C++ 前端 ()。这可以从 使用 Winget 的命令行:

clang-cl

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 获取模型权重和分词器

访问 Gemma 模型页面 Kaggle 并选择 。在此选项卡上,下拉列表包含以下选项。 注意 bfloat16 权重的保真度更高,而 8 位切换浮点数 权重可以加快推理速度。通常,我们建议从检查点开始。

Model Variations |> Gemma C++
Variation
-sfp

2B 指令调整 () 和预训练 () 模型:

it
pt

型号名称 描述
2b-it
20亿参数指令调优模型,bfloat16
2b-it-sfp
20亿参数指令调优模型,8位开关浮点
2b-pt
20亿参数预训练模型,bfloat16
2b-pt-sfp
20亿参数预训练模型,8位开关浮点

7B 指令调整 () 和预训练 () 模型:

it
pt

型号名称 描述
7b-it
70亿参数指令调优模型,bfloat16
7b-it-sfp
70亿参数指令调优模型,8位开关浮点
7b-pt
70亿参数预训练模型,bfloat16
7b-pt-sfp
70亿参数预训练模型,8位开关浮点

[!注意] 重要提示:我们强烈建议从模型开始 启动并运行。

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 推理 运行时,创建一个构建目录,并使用从顶级项目目录生成构建文件。对于 8 位开关浮点 权重 (SFP),运行 CMake,不带任何选项:

cmake

类 Unix 平台

cmake -B build

或者,如果你下载了 bfloat16 权重(名称中没有的任何型号), 与其像上面那样在没有选项的情况下运行 CMake,不如使用 WEIGHT_TYPE 运行 设置为高速公路类型 (这将在将来简化,我们建议使用权重 而不是 bfloat16 以获得更快的推理):

-sfp
hwy::bfloat16_t
-sfp

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]

替换为一个数字 - 的编号 系统上可用的内核是一种合理的启发式方法。例如,将使用 4 个线程构建。如果命令是 可用,可以作为合理的默认值使用 用于线程数。

[number of parallel threads to use]
make -j4 gemma
nproc
make -j$(nproc) gemma

如果不确定标志的正确值,则可以直接运行,它仍应生成可执行文件。

-j
make gemma
./gemma

[!注] 在适用于 Linux 的 Windows 子系统 (WSL) 上,用户应设置 并行线程到 1。使用较大的数字可能会导致错误。

如果生成成功,则现在目录中应该有一个可执行文件。

gemma
build/

窗户

# Configure `build` directory
cmake --preset windows

# Build project using Visual Studio Build Tools
cmake --build --preset windows -j [number of parallel threads to use]

如果生成成功,则现在目录中应该有一个可执行文件。

gemma.exe
build/

第 4 步:运行

你现在可以从目录内部运行。

gemma
build/

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 指令调谐模型,8 位) 切换浮点)。
    2b-it-sfp.sbs
  • Tokenizer 文件。
    tokenizer.spm
./gemma \
--tokenizer tokenizer.spm \
--compressed_weights 2b-it-sfp.sbs \
--model 2b-it

疑难解答和常见问题解答

运行 ./gemma 失败,并显示“无法读取缓存gating_ein_0(错误 294)...”

最常见的问题是使用错误的权重类型构建,并尝试使用默认切换浮点 (sfp) 加载权重 (, , , ),反之亦然。反思 步骤#3并检查用于构建的命令是否正确 你下载的权重。

cmake
gemma
bfloat16
2b-it
2b-pt
7b-it
7b-pt
cmake
gemma

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

在 Windows/Visual Studio 中生成时出现问题

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

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

一个常见的问题是你使用的是预先训练的模型,而事实并非如此 指令调整,因此不响应指令。确保你是 使用指令优化模型 (, , , ) 而不是预训练模型(任何带有后缀的模型)。

2b-it-sfp
2b-it
7b-it-sfp
7b-it
-pt

如何将微调转换为 .sbs 压缩模型文件?

我们正在开发一个 python 脚本,将标准模型格式转换为 , 并希望在下周左右提供它。遵循此 更新问题

.sbs

用法

gemma
具有不同的使用模式,由 verbosity 标志控制。

目前所有使用模式都是交互式的,在 换行符输入。

冗长 使用方式
--verbosity 0
极小 仅打印生成输出。适合作为 CLI 工具。
--verbosity 1
违约 标准面向用户的终端 UI。
--verbosity 2
详细 显示其他开发人员和调试信息。

交互式终端应用程序

默认情况下,详细程度设置为 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.cpp创建别名,并完全指定参数:

gemma

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

[!注] CLI 对 gemma.cpp 的使用是实验性的,应采用上下文长度 考虑到限制。

上述命令的输出应如下所示:

$ 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纳入你自己的项目的最简单方法是引入 gemma.cpp和依赖项。你可以将以下内容添加到你的 CMakeLists.txt:

FetchContent

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

[!注] 如果你在自己的项目中使用gemma.cpp,请执行以下步骤 在上一节中,构建库是由 自动完成的,可以跳过此部分。

FetchContent
cmake

首先,运行:

cmake

cmake -B build

然后,使用目标运行:

make
libgemma

cd build
make -j [number of parallel threads to use] libgemma

如果此操作成功,则目录中现在应该有一个库文件。在 Unix 平台上,文件名为 。

libgemma
build/
libgemma.a

致谢和联系方式

gemma.cpp 由 Austin HuangJan Wassenberg 于 2023 年秋季启动,随后于 2024 年 2 月发布 感谢 Phil Culliton、Paul Chang 和 Dan Zheng 的贡献。

这不是官方支持的 Google 产品。