llama.cpp
Ligações simples de Python para a biblioteca llama.cpp
de @ggerganov . Este pacote fornece:
ctypes
.A documentação está disponível em https://llama-cpp-python.readthedocs.io/en/latest.
Requisitos:
Para instalar o pacote, execute:
pip install llama-cpp-python
Isso também criará llama.cpp
a partir do código-fonte e o instalará junto com este pacote python.
Se isso falhar, adicione --verbose
à pip install
veja o log de compilação completo do cmake.
Roda pré-construída (nova)
Também é possível instalar uma roda pré-construída com suporte básico de CPU.
pip install llama-cpp-python
--extra-index-url https://abetlen.github.io/llama-cpp-python/whl/cpu
llama.cpp
oferece suporte a vários back-ends de aceleração de hardware para acelerar a inferência, bem como opções específicas de back-end. Consulte o README llama.cpp para obter uma lista completa.
Todas as opções de compilação do cmake llama.cpp
podem ser definidas por meio da variável de ambiente CMAKE_ARGS
ou por meio do sinalizador --config-settings / -C
cli durante a instalação.
# Linux and Mac
CMAKE_ARGS= " -DGGML_BLAS=ON -DGGML_BLAS_VENDOR=OpenBLAS "
pip install llama-cpp-python
# Windows
$ env: CMAKE_ARGS = " -DGGML_BLAS=ON -DGGML_BLAS_VENDOR=OpenBLAS "
pip install llama - cpp - python
Eles também podem ser definidos por meio do comando pip install -C / --config-settings
e salvos em um arquivo requirements.txt
:
pip install --upgrade pip # ensure pip is up to date
pip install llama-cpp-python
-C cmake.args= " -DGGML_BLAS=ON;-DGGML_BLAS_VENDOR=OpenBLAS "
# requirements.txt
llama-cpp-python -C cmake.args="-DGGML_BLAS=ON;-DGGML_BLAS_VENDOR=OpenBLAS"
Abaixo estão alguns back-ends comuns, seus comandos de construção e quaisquer variáveis de ambiente adicionais necessárias.
Para instalar com OpenBLAS, defina as variáveis de ambiente GGML_BLAS
e GGML_BLAS_VENDOR
antes de instalar:
CMAKE_ARGS= " -DGGML_BLAS=ON -DGGML_BLAS_VENDOR=OpenBLAS " pip install llama-cpp-python
Para instalar com suporte CUDA, defina a variável de ambiente GGML_CUDA=on
antes de instalar:
CMAKE_ARGS= " -DGGML_CUDA=on " pip install llama-cpp-python
Roda pré-construída (nova)
Também é possível instalar uma roda pré-construída com suporte CUDA. Contanto que seu sistema atenda a alguns requisitos:
pip install llama-cpp-python
--extra-index-url https://abetlen.github.io/llama-cpp-python/whl/ < cuda-version >
Onde <cuda-version>
é um dos seguintes:
cu121
: CUDA 12.1cu122
: CUDA 12.2cu123
: CUDA 12.3cu124
: CUDA 12.4cu125
: CUDA 12.5Por exemplo, para instalar a roda CUDA 12.1:
pip install llama-cpp-python
--extra-index-url https://abetlen.github.io/llama-cpp-python/whl/cu121
Para instalar com Metal (MPS), defina a variável de ambiente GGML_METAL=on
antes de instalar:
CMAKE_ARGS= " -DGGML_METAL=on " pip install llama-cpp-python
Roda pré-construída (nova)
Também é possível instalar uma roda pré-construída com suporte metálico. Contanto que seu sistema atenda a alguns requisitos:
pip install llama-cpp-python
--extra-index-url https://abetlen.github.io/llama-cpp-python/whl/metal
Para instalar com suporte hipBLAS/ROCm para placas AMD, defina a variável de ambiente GGML_HIPBLAS=on
antes de instalar:
CMAKE_ARGS= " -DGGML_HIPBLAS=on " pip install llama-cpp-python
Para instalar com suporte Vulkan, defina a variável de ambiente GGML_VULKAN=on
antes de instalar:
CMAKE_ARGS= " -DGGML_VULKAN=on " pip install llama-cpp-python
Para instalar com suporte SYCL, defina a variável de ambiente GGML_SYCL=on
antes de instalar:
source /opt/intel/oneapi/setvars.sh
CMAKE_ARGS= " -DGGML_SYCL=on -DCMAKE_C_COMPILER=icx -DCMAKE_CXX_COMPILER=icpx " pip install llama-cpp-python
Para instalar com suporte RPC, defina a variável de ambiente GGML_RPC=on
antes de instalar:
source /opt/intel/oneapi/setvars.sh
CMAKE_ARGS= " -DGGML_RPC=on " pip install llama-cpp-python
Se você tiver problemas em que ele reclama, não consegue encontrar 'nmake'
'?'
ou CMAKE_C_COMPILER, você pode extrair w64devkit conforme mencionado no repositório llama.cpp e adicioná-los manualmente ao CMAKE_ARGS antes de executar pip
install:
$env:CMAKE_GENERATOR = "MinGW Makefiles"
$env:CMAKE_ARGS = "-DGGML_OPENBLAS=on -DCMAKE_C_COMPILER=C: /w64devkit/bin/gcc.exe -DCMAKE_CXX_COMPILER=C: /w64devkit/bin/g++.exe"
Veja as instruções acima e defina CMAKE_ARGS
para o backend BLAS que você deseja usar.
A documentação detalhada de instalação da GPU MacOS Metal está disponível em docs/install/macos.md
Nota: Se você estiver usando Apple Silicon (M1) Mac, certifique-se de ter instalado uma versão do Python que suporte a arquitetura arm64. Por exemplo:
wget https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-MacOSX-arm64.sh
bash Miniforge3-MacOSX-arm64.sh
Caso contrário, durante a instalação, a versão llama.cpp x86 será construída, que será 10x mais lenta no Apple Silicon (M1) Mac.
Tente instalar com
CMAKE_ARGS= " -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_APPLE_SILICON_PROCESSOR=arm64 -DGGML_METAL=on " pip install --upgrade --verbose --force-reinstall --no-cache-dir llama-cpp-python
Para atualizar e reconstruir llama-cpp-python
adicione os sinalizadores --upgrade --force-reinstall --no-cache-dir
ao comando pip install
para garantir que o pacote seja reconstruído a partir da fonte.
Referência de API
A API de alto nível fornece uma interface gerenciada simples por meio da classe Llama
.
Abaixo está um pequeno exemplo que demonstra como usar a API de alto nível para completar texto básico:
from llama_cpp import Llama
llm = Llama (
model_path = "./models/7B/llama-model.gguf" ,
# n_gpu_layers=-1, # Uncomment to use GPU acceleration
# seed=1337, # Uncomment to set a specific seed
# n_ctx=2048, # Uncomment to increase the context window
)
output = llm (
"Q: Name the planets in the solar system? A: " , # Prompt
max_tokens = 32 , # Generate up to 32 tokens, set to None to generate up to the end of the context window
stop = [ "Q:" , " n " ], # Stop generating just before the model would generate a new question
echo = True # Echo the prompt back in the output
) # Generate a completion, can also call create_completion
print ( output )
Por padrão, llama-cpp-python
gera conclusões em um formato compatível com OpenAI:
{
"id" : "cmpl-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" ,
"object" : "text_completion" ,
"created" : 1679561337 ,
"model" : "./models/7B/llama-model.gguf" ,
"choices" : [
{
"text" : "Q: Name the planets in the solar system? A: Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune and Pluto." ,
"index" : 0 ,
"logprobs" : None ,
"finish_reason" : "stop"
}
],
"usage" : {
"prompt_tokens" : 14 ,
"completion_tokens" : 28 ,
"total_tokens" : 42
}
}
A conclusão do texto está disponível através dos métodos __call__
e create_completion
da classe Llama
.
Você pode baixar modelos Llama
no formato gguf
diretamente do Hugging Face usando o método from_pretrained
. Você precisará instalar o pacote huggingface-hub
para usar esse recurso ( pip install huggingface-hub
).
llm = Llama . from_pretrained (
repo_id = "Qwen/Qwen2-0.5B-Instruct-GGUF" ,
filename = "*q8_0.gguf" ,
verbose = False
)
Por padrão, from_pretrained
baixará o modelo para o diretório de cache huggingface, você poderá então gerenciar os arquivos de modelo instalados com a ferramenta huggingface-cli
.
A API de alto nível também fornece uma interface simples para conclusão do chat.
A conclusão do chat requer que o modelo saiba como formatar as mensagens em um único prompt. A classe Llama
faz isso usando formatos de chat pré-registrados (ou seja, chatml
, llama-2
, gemma
, etc) ou fornecendo um objeto manipulador de chat personalizado.
O modelo formatará as mensagens em um único prompt usando a seguinte ordem de precedência:
chat_handler
se fornecidochat_format
se fornecidotokenizer.chat_template
dos metadados do modelo gguf
(deve funcionar para a maioria dos modelos novos, modelos mais antigos podem não ter isso)llama-2
Defina verbose=True
para ver o formato de chat selecionado.
from llama_cpp import Llama
llm = Llama (
model_path = "path/to/llama-2/llama-model.gguf" ,
chat_format = "llama-2"
)
llm . create_chat_completion (
messages = [
{ "role" : "system" , "content" : "You are an assistant who perfectly describes images." },
{
"role" : "user" ,
"content" : "Describe this image in detail please."
}
]
)
A conclusão do chat está disponível através do método create_chat_completion
da classe Llama
.
Para compatibilidade da API OpenAI v1, você usa o método create_chat_completion_openai_v1
que retornará modelos pydantic em vez de dictos.
Para restringir as respostas do chat apenas a JSON válido ou a um esquema JSON específico, use o argumento response_format
em create_chat_completion
.
O exemplo a seguir restringirá a resposta apenas a strings JSON válidas.
from llama_cpp import Llama
llm = Llama ( model_path = "path/to/model.gguf" , chat_format = "chatml" )
llm . create_chat_completion (
messages = [
{
"role" : "system" ,
"content" : "You are a helpful assistant that outputs in JSON." ,
},
{ "role" : "user" , "content" : "Who won the world series in 2020" },
],
response_format = {
"type" : "json_object" ,
},
temperature = 0.7 ,
)
Para restringir ainda mais a resposta a um esquema JSON específico, adicione o esquema à propriedade schema
do argumento response_format
.
from llama_cpp import Llama
llm = Llama ( model_path = "path/to/model.gguf" , chat_format = "chatml" )
llm . create_chat_completion (
messages = [
{
"role" : "system" ,
"content" : "You are a helpful assistant that outputs in JSON." ,
},
{ "role" : "user" , "content" : "Who won the world series in 2020" },
],
response_format = {
"type" : "json_object" ,
"schema" : {
"type" : "object" ,
"properties" : { "team_name" : { "type" : "string" }},
"required" : [ "team_name" ],
},
},
temperature = 0.7 ,
)
A API de alto nível oferece suporte a funções e chamadas de ferramentas compatíveis com OpenAI. Isso é possível por meio do formato de bate-papo de modelos pré-treinados functionary
ou por meio do formato de bate chatml-function-calling
.
from llama_cpp import Llama
llm = Llama ( model_path = "path/to/chatml/llama-model.gguf" , chat_format = "chatml-function-calling" )
llm . create_chat_completion (
messages = [
{
"role" : "system" ,
"content" : "A chat between a curious user and an artificial intelligence assistant. The assistant gives helpful, detailed, and polite answers to the user's questions. The assistant calls functions with appropriate input when necessary"
},
{
"role" : "user" ,
"content" : "Extract Jason is 25 years old"
}
],
tools = [{
"type" : "function" ,
"function" : {
"name" : "UserDetail" ,
"parameters" : {
"type" : "object" ,
"title" : "UserDetail" ,
"properties" : {
"name" : {
"title" : "Name" ,
"type" : "string"
},
"age" : {
"title" : "Age" ,
"type" : "integer"
}
},
"required" : [ "name" , "age" ]
}
}
}],
tool_choice = {
"type" : "function" ,
"function" : {
"name" : "UserDetail"
}
}
)
Os vários arquivos convertidos em gguf para este conjunto de modelos podem ser encontrados aqui. O Functionary é capaz de chamar funções de forma inteligente e também analisar quaisquer saídas de função fornecidas para gerar respostas coerentes. Todos os modelos v2 de funções suportam chamadas de funções paralelas . Você pode fornecer functionary-v1
ou functionary-v2
para chat_format
ao inicializar a classe Llama.
Devido a discrepâncias entre llama.cpp e os tokenizers do HuggingFace, é necessário fornecer o Tokenizer HF para o funcionário. A classe LlamaHFTokenizer
pode ser inicializada e passada para a classe Llama. Isso substituirá o tokenizer llama.cpp padrão usado na classe Llama. Os arquivos tokenizer já estão incluídos nos respectivos repositórios HF que hospedam os arquivos gguf.
from llama_cpp import Llama
from llama_cpp . llama_tokenizer import LlamaHFTokenizer
llm = Llama . from_pretrained (
repo_id = "meetkai/functionary-small-v2.2-GGUF" ,
filename = "functionary-small-v2.2.q4_0.gguf" ,
chat_format = "functionary-v2" ,
tokenizer = LlamaHFTokenizer . from_pretrained ( "meetkai/functionary-small-v2.2-GGUF" )
)
NOTA : Não há necessidade de fornecer as mensagens padrão do sistema usadas no Functionary, pois elas são adicionadas automaticamente no manipulador de bate-papo do Functionary. Assim, as mensagens devem conter apenas as mensagens de chat e/ou mensagens do sistema que fornecem contexto adicional para o modelo (ex: datahora, etc.).
llama-cpp-python
suporta como llava1.5 que permite que o modelo de linguagem leia informações de texto e imagens.
Abaixo estão os modelos multimodais suportados e seus respectivos manipuladores de chat (API Python) e formatos de chat (API de servidor).
Modelo | LlamaChatHandler | chat_format |
---|---|---|
lhava-v1.5-7b | Llava15ChatHandler | llava-1-5 |
lhava-v1.5-13b | Llava15ChatHandler | llava-1-5 |
lhava-v1.6-34b | Llava16ChatHandler | llava-1-6 |
moondream2 | MoondreamChatHandler | moondream2 |
nanolava | NanollavaChatHandler | nanollava |
lhama-3-visão-alfa | Llama3VisionAlphaChatHandler | llama-3-vision-alpha |
minicpm-v-2.6 | MiniCPMv26ChatHandler | minicpm-v-2.6 |
Em seguida, você precisará usar um manipulador de chat personalizado para carregar o modelo de clipe e processar as mensagens e imagens do chat.
from llama_cpp import Llama
from llama_cpp . llama_chat_format import Llava15ChatHandler
chat_handler = Llava15ChatHandler ( clip_model_path = "path/to/llava/mmproj.bin" )
llm = Llama (
model_path = "./path/to/llava/llama-model.gguf" ,
chat_handler = chat_handler ,
n_ctx = 2048 , # n_ctx should be increased to accommodate the image embedding
)
llm . create_chat_completion (
messages = [
{ "role" : "system" , "content" : "You are an assistant who perfectly describes images." },
{
"role" : "user" ,
"content" : [
{ "type" : "text" , "text" : "What's in this image?" },
{ "type" : "image_url" , "image_url" : { "url" : "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg" } }
]
}
]
)
Você também pode extrair o modelo do Hugging Face Hub usando o método from_pretrained
.
from llama_cpp import Llama
from llama_cpp . llama_chat_format import MoondreamChatHandler
chat_handler = MoondreamChatHandler . from_pretrained (
repo_id = "vikhyatk/moondream2" ,
filename = "*mmproj*" ,
)
llm = Llama . from_pretrained (
repo_id = "vikhyatk/moondream2" ,
filename = "*text-model*" ,
chat_handler = chat_handler ,
n_ctx = 2048 , # n_ctx should be increased to accommodate the image embedding
)
response = llm . create_chat_completion (
messages = [
{
"role" : "user" ,
"content" : [
{ "type" : "text" , "text" : "What's in this image?" },
{ "type" : "image_url" , "image_url" : { "url" : "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg" } }
]
}
]
)
print ( response [ "choices" ][ 0 ][ "text" ])
Nota : Os modelos multimodais também suportam chamada de ferramenta e modo JSON.
As imagens podem ser passadas como URIs de dados codificados em base64. O exemplo a seguir demonstra como fazer isso.
import base64
def image_to_base64_data_uri ( file_path ):
with open ( file_path , "rb" ) as img_file :
base64_data = base64 . b64encode ( img_file . read ()). decode ( 'utf-8' )
return f"data:image/png;base64, { base64_data } "
# Replace 'file_path.png' with the actual path to your PNG file
file_path = 'file_path.png'
data_uri = image_to_base64_data_uri ( file_path )
messages = [
{ "role" : "system" , "content" : "You are an assistant who perfectly describes images." },
{
"role" : "user" ,
"content" : [
{ "type" : "image_url" , "image_url" : { "url" : data_uri }},
{ "type" : "text" , "text" : "Describe this image in detail please." }
]
}
]
llama-cpp-python
suporta decodificação especulativa que permite ao modelo gerar conclusões com base em um modelo de rascunho.
A maneira mais rápida de usar a decodificação especulativa é por meio da classe LlamaPromptLookupDecoding
.
Basta passar isso como um modelo de rascunho para a classe Llama
durante a inicialização.
from llama_cpp import Llama
from llama_cpp . llama_speculative import LlamaPromptLookupDecoding
llama = Llama (
model_path = "path/to/model.gguf" ,
draft_model = LlamaPromptLookupDecoding ( num_pred_tokens = 10 ) # num_pred_tokens is the number of tokens to predict 10 is the default and generally good for gpu, 2 performs better for cpu-only machines.
)
Para gerar embeddings de texto, use create_embedding
ou embed
. Observe que você deve passar embedding=True
ao construtor na criação do modelo para que funcionem corretamente.
import llama_cpp
llm = llama_cpp . Llama ( model_path = "path/to/model.gguf" , embedding = True )
embeddings = llm . create_embedding ( "Hello, world!" )
# or create multiple embeddings at once
embeddings = llm . create_embedding ([ "Hello, world!" , "Goodbye, world!" ])
Existem duas noções principais de incorporação em um modelo estilo Transformer: nível de token e nível de sequência . Os embeddings em nível de sequência são produzidos "agrupando" os embeddings em nível de token, geralmente calculando a média deles ou usando o primeiro token.
Modelos que são explicitamente voltados para embeddings geralmente retornarão embeddings em nível de sequência por padrão, um para cada string de entrada. Modelos sem incorporação, como aqueles projetados para geração de texto, normalmente retornarão apenas incorporações em nível de token, uma para cada token em cada sequência. Assim, a dimensionalidade do tipo de retorno será maior para incorporações em nível de token.
É possível controlar o comportamento do pool em alguns casos usando o sinalizador pooling_type
na criação do modelo. Você pode garantir incorporações em nível de token de qualquer modelo usando LLAMA_POOLING_TYPE_NONE
. O inverso, atualmente não é possível obter um modelo orientado à geração para gerar incorporações em nível de sequência, mas você sempre pode fazer o pool manualmente.
A janela de contexto dos modelos Llama determina o número máximo de tokens que podem ser processados de uma só vez. Por padrão, isso é definido como 512 tokens, mas pode ser ajustado com base em seus requisitos.
Por exemplo, se quiser trabalhar com contextos maiores, você pode expandir a janela de contexto definindo o parâmetro n_ctx ao inicializar o objeto Llama:
llm = Llama ( model_path = "./models/7B/llama-model.gguf" , n_ctx = 2048 )
llama-cpp-python
oferece um servidor web que visa atuar como um substituto imediato para a API OpenAI. Isso permite que você use modelos compatíveis com llama.cpp com qualquer cliente compatível com OpenAI (bibliotecas de idiomas, serviços, etc.).
Para instalar o pacote do servidor e começar:
pip install ' llama-cpp-python[server] '
python3 -m llama_cpp.server --model models/7B/llama-model.gguf
Semelhante à seção de aceleração de hardware acima, você também pode instalar com suporte a GPU (cuBLAS) assim:
CMAKE_ARGS= " -DGGML_CUDA=on " FORCE_CMAKE=1 pip install ' llama-cpp-python[server] '
python3 -m llama_cpp.server --model models/7B/llama-model.gguf --n_gpu_layers 35
Navegue até http://localhost:8000/docs para ver a documentação do OpenAPI.
Para vincular a 0.0.0.0
para habilitar conexões remotas, use python3 -m llama_cpp.server --host 0.0.0.0
. Da mesma forma, para alterar a porta (o padrão é 8000), use --port
.
Você provavelmente também deseja definir o formato do prompt. Para chatml, use
python3 -m llama_cpp.server --model models/7B/llama-model.gguf --chat_format chatml
Isso formatará o prompt de acordo com o que o modelo espera. Você pode encontrar o formato do prompt no cartão do modelo. Para opções possíveis, consulte llama_cpp/llama_chat_format.py e procure por linhas que começam com "@register_chat_format".
Se você tiver huggingface-hub
instalado, também poderá usar o sinalizador --hf_model_repo_id
para carregar um modelo do Hugging Face Hub.
python3 -m llama_cpp.server --hf_model_repo_id Qwen/Qwen2-0.5B-Instruct-GGUF --model ' *q8_0.gguf '
Uma imagem Docker está disponível no GHCR. Para executar o servidor:
docker run --rm -it -p 8000:8000 -v /path/to/models:/models -e MODEL=/models/llama-model.gguf ghcr.io/abetlen/llama-cpp-python:latest
Docker no termux (requer root) é atualmente a única maneira conhecida de executar isso em telefones, consulte o problema de suporte do termux
Referência de API
A API de baixo nível é uma ligação direta ctypes
à API C fornecida por llama.cpp
. Toda a API de baixo nível pode ser encontrada em llama_cpp/llama_cpp.py e espelha diretamente a API C em llama.h.
Abaixo está um pequeno exemplo que demonstra como usar a API de baixo nível para tokenizar um prompt:
import llama_cpp
import ctypes
llama_cpp . llama_backend_init ( False ) # Must be called once at the start of each program
params = llama_cpp . llama_context_default_params ()
# use bytes for char * params
model = llama_cpp . llama_load_model_from_file ( b"./models/7b/llama-model.gguf" , params )
ctx = llama_cpp . llama_new_context_with_model ( model , params )
max_tokens = params . n_ctx
# use ctypes arrays for array params
tokens = ( llama_cpp . llama_token * int ( max_tokens ))()
n_tokens = llama_cpp . llama_tokenize ( ctx , b"Q: Name the planets in the solar system? A: " , tokens , max_tokens , llama_cpp . c_bool ( True ))
llama_cpp . llama_free ( ctx )
Confira a pasta de exemplos para mais exemplos de uso da API de baixo nível.
A documentação está disponível em https://llama-cpp-python.readthedocs.io/. Se você encontrar algum problema com a documentação, abra um problema ou envie um PR.
Este pacote está em desenvolvimento ativo e agradeço quaisquer contribuições.
Para começar, clone o repositório e instale o pacote em modo editável/desenvolvimento:
git clone --recurse-submodules https://github.com/abetlen/llama-cpp-python.git
cd llama-cpp-python
# Upgrade pip (required for editable mode)
pip install --upgrade pip
# Install with pip
pip install -e .
# if you want to use the fastapi / openapi server
pip install -e .[server]
# to install all optional dependencies
pip install -e .[all]
# to clear the local build cache
make clean
Você também pode testar commits específicos de llama.cpp
verificando o commit desejado no submódulo vendor/llama.cpp
e executando make clean
e pip install -e .
de novo. Quaisquer alterações na API llama.h
exigirão alterações no arquivo llama_cpp/llama_cpp.py
para corresponder à nova API (alterações adicionais podem ser necessárias em outro lugar).