Skip to content

rafaelcaires/node-llama-cpp

Repository files navigation

node-llama-cpp

Fork enxuto de withcatai/node-llama-cpp v3.18.1, mantido apenas com o necessário para rodar o Gemma 4 dentro do servidor gemma-llama.

A lib upstream é genérica e suporta dezenas de arquiteturas, downloaders, embeddings, ranking, infill e templates de projeto. Nosso uso é bem mais estreito: carregar um único .gguf Gemma e expor via API OpenAI-compatível. Este fork remove o que não usamos, aplica os patches necessários para a build atual e publica os binários prontos por plataforma como GitHub Releases.

Diferenças em relação ao upstream

Removido (não usado pelo gemma-llama)

  • CLI: comandos chat, complete, infill, init, pull, debug, inspect. Mantidos apenas postinstall e source (build/download/clear) para o pipeline de compilação nativa.
  • Templates de projeto (templates/ — scaffolds Electron/Node, ~390 KB).
  • Avaliadores não usados: LlamaEmbedding, LlamaEmbeddingContext, LlamaRankingContext, token predictors (speculative decoding).
  • Model downloader: createModelDownloader, resolveModelFile (consumimos GGUF de path local).
  • Métodos públicos de LlamaModel: createEmbeddingContext, createRankingContext.
  • Outros: experimentalChunkDocument, docs/, test/, assets/, scripts/, eslint.config.js, vitest.config.ts, dependências e devDependências relacionadas.

Mantido (necessário ou acoplado ao core)

  • Núcleo de inferência: LlamaModel, LlamaContext, LlamaChatSession, LlamaChat, LlamaCompletion, LlamaSampler.
  • Gramáticas: LlamaGrammar, LlamaJsonSchemaGrammar, utils/gbnfJson/ — não dá para remover sem reescrever metade do LlamaChat/LlamaSampler.
  • Todos os chat wrappers: Gemma, General, Empty, Llama2/3/3.1/3.2, Mistral, Qwen, DeepSeek, Functionary, Falcon, Alpaca, ChatML, Harmony, Seed, Jinja/Template. O resolveChatWrapper usa todos para detecção automática a partir da metadata GGUF — remover quebra a resolução de templates.
  • bindings/, gguf/, ChatWrapper.ts, utils/LlamaText.ts.

Patches C++ aplicados direto na source

  1. llama/CMakeLists.txt: target_link_libraries(${PROJECT_NAME} "llama-common") (era "common", quebrava com a versão atual do llama.cpp).
  2. llama/addon/addon.cpp: static std::atomic_bool loaded{false}; (sintaxe correta de inicialização para C++20 atomic).

Pipeline de empacotamento

A versão neste repositório (3.18.1-gemma.1) é distribuída como GitHub Release com um .tgz por plataforma. O workflow .github/workflows/pack.yml faz tudo:

  1. Roda em paralelo nos runners windows-latest, ubuntu-latest, macos-14 (arm64).
  2. Em cada plataforma: npm install --ignore-scriptsnpm run build → compila o binding nativo via cmake-js (download da source do llama.cpp + build).
  3. Remove o postinstall do package.json (binário já está embutido) e adiciona sufixo de plataforma na versão.
  4. Faz prune de tudo que não é runtime: llama/llama.cpp/, llama/addon/, llama/cmake/, llama/toolchains/, llama/xpack/, llama/CMakeLists.txt etc. Sobra só llama/localBuilds/<plataforma>/...node + llama/binariesGithubRelease.json.
  5. npm pack → upload do .tgz como artifact.
  6. Job release baixa os 3 artifacts, cria/atualiza a release v3.18.1-gemma.1 e anexa todos os .tgz.

Disparar manualmente

gh workflow run pack.yml
gh run watch

Ou pela UI: Actions → Pack per platform → Run workflow → main.

Tarballs gerados

Arquivo Plataforma alvo Aceleração
node-llama-cpp-3.18.1-gemma.1-win-x64.tgz Windows x64 CPU
node-llama-cpp-3.18.1-gemma.1-linux-x64.tgz Linux x64 CPU
node-llama-cpp-3.18.1-gemma.1-mac-arm64-metal.tgz macOS arm64 (Apple Silicon) Metal

Atenção: cada tarball é específico de uma plataforma. Instalar o .tgz de Windows num Mac não funciona — o .node embutido é incompatível.

Como consumir no gemma-llama

Opção 1 — URL direto da release (recomendado)

// package.json
{
  "dependencies": {
    "node-llama-cpp": "https://github.com/rafaelcaires/node-llama-cpp/releases/download/v3.18.1-gemma.1/node-llama-cpp-3.18.1-gemma.1-mac-arm64-metal.tgz"
  }
}

Funciona para repo público. Para repo privado, npm precisa de auth (token) ou use a opção 2.

Opção 2 — Tarball local

gh release download v3.18.1-gemma.1 -p '*mac-arm64-metal.tgz' -D packages/
// package.json
{
  "dependencies": {
    "node-llama-cpp": "file:packages/node-llama-cpp-3.18.1-gemma.1-mac-arm64-metal.tgz"
  }
}

Em ambas as opções, npm install no gemma-llama apenas descompacta — não recompila, porque o postinstall foi removido do tarball pelo workflow.

Build local (opcional)

Para gerar um .tgz no seu Mac sem CI:

cd /Users/rafaelcaires/Dev/02_WEB/node-llama-cpp
npm install                 # roda postinstall: compila o .node localmente
npm run build               # tsc
npm pack                    # gera node-llama-cpp-3.18.1-gemma.1.tgz na raiz

O .tgz resultante inclui o postinstall (porque você não passou pelo workflow), então será recompilado em qualquer máquina onde for instalado. Para um tarball "binary-baked" como os da release, use o workflow.

Estrutura

src/                  # fonte TypeScript (já enxuta)
  bindings/           # ponte para o addon C++ (Llama, getLlama)
  evaluator/          # LlamaModel, LlamaContext, LlamaChat, LlamaChatSession, ...
  chatWrappers/       # detectores de template (Gemma + restante para fallback)
  gguf/               # leitor de metadata GGUF
  cli/                # CLI mínima: postinstall + source build/download/clear
  utils/              # LlamaText, gbnfJson, helpers
llama/                # build do addon C++
  CMakeLists.txt      # já com patch llama-common aplicado
  addon/              # código C++ do binding (já com patch atomic_bool)
  cmake/              # módulos cmake
  toolchains/         # toolchains cross-compile
.github/workflows/
  pack.yml            # nosso pipeline (matriz Win/Linux/Mac + release)
  build.yml           # upstream — não dispara em main
  test.yml            # upstream — não dispara em main
  prLint.yml          # upstream — só em PRs

Atualizar o fork (sync com upstream)

git remote add upstream https://github.com/withcatai/node-llama-cpp.git
git fetch upstream
git merge upstream/master         # resolva conflitos em CMakeLists.txt e addon.cpp;
                                  # se os patches já não forem necessários, remova do nosso código

Depois bumpe version em package.json (ex: 3.19.0-gemma.1), commit, push, e o workflow gera novas releases automaticamente.

Licença

MIT — herdada do upstream withcatai/node-llama-cpp.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors