Tutorial do Gemma para C++ (gemma.cpp)

gemma.cpp é uma implementação leve do ambiente de execução de inferência de C++ puro do modelo Gemma.

Para saber mais sobre o Gemma, consulte o card do modelo. Os pesos do modelo, incluindo artefatos específicos do gemma.cpp, estão disponíveis no Kaggle (em inglês).

A quem este projeto é direcionado?

Os mecanismos de inferência LLM modernos são sistemas sofisticados, geralmente com recursos personalizados que se estendem além dos ambientes de execução tradicionais de redes neurais. Isso verá oportunidades de pesquisa e inovação pelo co-design de algoritmos de alto nível e computação de baixo nível. No entanto, há uma lacuna entre os ambientes de execução de inferência C++ orientados à implantação, que não são projetados para experimentação, e os frameworks de pesquisa de ML centrados em Python, que abstraem compilação de baixo nível por meio da compilação.

O gemma.cpp oferece uma implementação minimalista dos modelos Gemma 2B e 7B, com foco na simplicidade e no direcionamento, em vez da generalidade total. Isso é inspirado em implementações de modelo C++ integrados verticalmente, como ggml, llama.c e llama.rs (links em inglês).

O gemma.cpp é voltado a casos de uso de experimentação e pesquisa, em especial a exploração do espaço de design dos algoritmos de inferência da CPU e dos algoritmos de inferência usando um chip portátil pela biblioteca Google Highway. Ela se destina a ser simples de incorporar em outros projetos com dependências mínimas e também facilmente modificável com uma pequena implementação de núcleo de LoC de aproximadamente 2 mil (junto com aproximadamente 4 mil de LoC de utilitários de suporte).

Para implantações de borda orientadas para produção, recomendamos caminhos de implantação padrão usando frameworks do Python maduros como JAX, Keras, PyTorch e Transformers (todas as variações de modelo aqui).

Contribuições da comunidade, sejam grandes ou pequenas, são bem-vindas. Esse projeto segue as diretrizes da comunidade de código aberto do Google.

Guia de início rápido

Para concluir este guia de início rápido, clone ou faça o download de gemma.cpp.

Requisitos do sistema

Antes de começar, você precisa ter instalado:

Etapa 1: obter pesos do modelo e tokenizador do Kaggle

Visite a página do modelo da gemma no Kaggle (em inglês) e selecione "Variações do modelo".

O menu suspenso . On this tab, theVariação do Gemma C++ inclui as opções abaixo. As opções de pesos bfloat16 têm maior fidelidade, enquanto pesos de ponto flutuante de 8 bits permitem uma inferência mais rápida.

Modelos 2B ajustados (it) e pré-treinados (pt):

Nome do modelo Descrição
2b-it 2 bilhões de modelos ajustados por instrução de parâmetros, bfloat16
2b-it-sfp 2 bilhões de modelos ajustados por instrução de parâmetros, ponto flutuante comutado de 8 bits
2b-pt 2 bilhões de modelos pré-treinados de parâmetros, bfloat16
2b-pt-sfp 2 bilhões de modelos pré-treinados de parâmetros, ponto flutuante comutado de 8 bits

7 bilhões de modelos ajustados por instrução (it) e pré-treinados (pt):

Nome do modelo Descrição
7b-it 7 bilhões de modelos ajustados por instrução de parâmetros, bfloat16
7b-it-sfp Modelo ajustado por instrução de 7 bilhões de parâmetros, ponto flutuante comutado de 8 bits
7b-pt 7 bilhões de modelos pré-treinados de parâmetros, bfloat16
7b-pt-sfp 7 bilhões de modelos pré-treinados de parâmetros, ponto flutuante comutado de 8 bits

OBSERVAÇÃO: recomendamos começar com 2b-it-sfp para começar.

Etapa 2: extrair arquivos

Depois de preencher o formulário de consentimento, o download deve prosseguir para recuperar um arquivo .tar archive.tar.gz. Extraia arquivos de archive.tar.gz (isso pode levar alguns minutos):

tar -xf archive.tar.gz

Isso produz um arquivo com pesos de modelo, como 2b-it-sfp.sbs, e um arquivo tokenizador (tokenizer.spm). Mova esses arquivos para um local de diretório conveniente (por exemplo, o diretório build/ desse repositório).

Etapa 3: criar

O sistema de build usa o CMake. Para gerar o ambiente de execução de inferência da gemma, crie um diretório de build e gere os arquivos de build usando cmake no diretório do projeto de nível superior:

(cd build && cmake ..)

Em seguida, execute make para criar o executável ./gemma:

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

Por exemplo, make -j 8 gemma. Se a operação for bem-sucedida, você terá um executável gemma no diretório build/.

Etapa 4: executar

Agora é possível executar gemma de dentro do diretório build/.

gemma tem os seguintes argumentos obrigatórios:

Argumento Descrição Valor de exemplo
--model O tipo de modelo. 2b-it, 2b-pt, 7b-it, 7b-pt, ... (confira acima)
--compressed_weights O arquivo de pesos compactado. 2b-it-sfp.sbs, ... (ver acima)
--tokenizer O nome de arquivo do tokenizador. tokenizer.spm

gemma é invocado como:

./gemma \
--tokenizer [tokenizer file] \
--compressed_weights [compressed weights file] \
--model [2b-it or 2b-pt or 7b-it or 7b-pt]

Exemplo de invocação para a configuração a seguir:

  • Arquivo de pesos compactado 2b-it-sfp.sbs (modelo ajustado por instrução 2B, ponto flutuante comutado de 8 bits).
  • Arquivo tokenizer.spm do tokenizador.
./gemma \
--tokenizer tokenizer.spm \
--compressed_weights 2b-it-sfp.sbs \
--model 2b-it

Uso

gemma tem diferentes modos de uso, controlados pela flag de verbosidade.

Todos os modos de uso são interativos, acionando a geração de texto na entrada de nova linha.

Verbosidade Modo de uso Detalhes
--verbosity 0 Mínimo Mostra apenas a saída de geração. Adequado como ferramenta de CLI.
--verbosity 1 Padrão interface padrão do terminal voltada para o usuário.
--verbosity 2 Detalhado Mostra mais informações sobre o desenvolvedor e a depuração.

App de terminal interativo

Por padrão, o nível de detalhes é definido como 1, mostrando uma interface interativa baseada no terminal quando gemma é invocado com os argumentos necessários:

$ ./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 (%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.

...

Uso como ferramenta de linha de comando

Para usar o executável gemma como uma ferramenta de linha de comando, pode ser útil criar um alias para gemma.cpp com argumentos totalmente especificados:

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"

Substitua os caminhos acima pelos seus próprios caminhos para os caminhos do modelo e do tokenizador do download.

Confira um exemplo de solicitação de gemma com uma entrada truncada (usando um alias gemma2b, como definido acima):

cat configs.h | tail -35 | tr '\n' ' ' | xargs -0 echo "What does this C++ code do: " | gemma2b

OBSERVAÇÃO: o uso da CLI de gemma.cpp é experimental e precisa considerar as limitações de tamanho do contexto.

A saída do comando acima será semelhante a esta:

$ 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**:

*   `seq_len`: Stores the length of the sequence to be processed. It's set to 7168.
*   `vocab_size`: Stores the size of the vocabulary, which is 256128.
*   `n_layers`: Number of layers in the deep learning model. It's set to 28.
*   `dim_model`: Dimension of the model's internal representation. It's set to 3072.
*   `dim_ffw_hidden`: Dimension of the feedforward and recurrent layers' hidden representations. It's set to 16 * 3072 / 2.

**ConfigGemma2B**:

*   `seq_len`: Stores the length of the sequence to be processed. It's also set to 7168.
*   `vocab_size`: Size of the vocabulary, which is 256128.
*   `n_layers`: Number of layers in the deep learning model. It's set to 18.
*   `dim_model`: Dimension of the model's internal representation. It's set to 2048.
*   `dim_ffw_hidden`: 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.