llama.cpp库的Python绑定
项目描述
Python绑定llama.cpp
为@ggerganov的llama.cpp
库提供的简单Python绑定。本软件包提供
- 通过
ctypes
接口访问C API的底层访问。 - 用于文本补全的高级Python API
- 类似OpenAI的API
- 与LangChain兼容
- 与LlamaIndex兼容
- 兼容OpenAI的Web服务器
文档可在https://llama-cpp-python.readthedocs.io/en/latest找到。
安装
需求
- Python 3.8+
- C编译器
- Linux:gcc或clang
- Windows:Visual Studio或MinGW
- MacOS:Xcode
要安装包,运行
pip install llama-cpp-python
这将从源代码构建llama.cpp
并将其与Python包一起安装。
如果失败,请向pip install
添加--verbose
以查看完整的cmake构建日志。
预构建轮子(新)
还可以安装带有基本CPU支持的预构建轮子。
pip install llama-cpp-python \
--extra-index-url https://abetlen.github.io/llama-cpp-python/whl/cpu
安装配置
llama.cpp
支持多个硬件加速后端,以提高推理速度以及特定后端选项。有关完整列表,请参阅llama.cpp README。
所有llama.cpp
cmake构建选项都可以通过CMAKE_ARGS
环境变量或通过安装期间的--config-settings / -C
CLI标志设置。
环境变量
# 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
命令行界面 / requirements.txt
也可以通过pip install -C / --config-settings
命令来设置,并保存到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"
支持的后端
以下是一些常见的后端,它们的构建命令以及所需的任何附加环境变量。
OpenBLAS(CPU)
使用OpenBLAS安装时,在安装前设置GGML_BLAS
和GGML_BLAS_VENDOR
环境变量
CMAKE_ARGS="-DGGML_BLAS=ON -DGGML_BLAS_VENDOR=OpenBLAS" pip install llama-cpp-python
CUDA
要支持CUDA安装,在安装前设置GGML_CUDA=on
环境变量
CMAKE_ARGS="-DGGML_CUDA=on" pip install llama-cpp-python
预构建轮子(新)
还可以安装支持CUDA的预构建wheel。只要您的系统满足一些要求
- CUDA版本为12.1、12.2、12.3、12.4或12.5
- Python版本为3.10、3.11或3.12
pip install llama-cpp-python \
--extra-index-url https://abetlen.github.io/llama-cpp-python/whl/<cuda-version>
<cuda-version>
可以是以下之一
cu121
:CUDA 12.1cu122
:CUDA 12.2cu123
:CUDA 12.3cu124
:CUDA 12.4cu125
:CUDA 12.5
例如,要安装CUDA 12.1 wheel
pip install llama-cpp-python \
--extra-index-url https://abetlen.github.io/llama-cpp-python/whl/cu121
Metal
使用Metal(MPS)安装时,在安装前设置GGML_METAL=on
环境变量
CMAKE_ARGS="-DGGML_METAL=on" pip install llama-cpp-python
预构建轮子(新)
还可以安装支持Metal的预构建wheel。只要您的系统满足一些要求
- MacOS版本为11.0或更高
- Python版本为3.10、3.11或3.12
pip install llama-cpp-python \
--extra-index-url https://abetlen.github.io/llama-cpp-python/whl/metal
hipBLAS(ROCm)
要支持AMD显卡的hipBLAS / ROCm安装,在安装前设置GGML_HIPBLAS=on
环境变量
CMAKE_ARGS="-DGGML_HIPBLAS=on" pip install llama-cpp-python
Vulkan
要支持Vulkan安装,在安装前设置GGML_VULKAN=on
环境变量
CMAKE_ARGS="-DGGML_VULKAN=on" pip install llama-cpp-python
SYCL
要支持SYCL安装,在安装前设置GGML_SYCL=on
环境变量
source /opt/intel/oneapi/setvars.sh
CMAKE_ARGS="-DGGML_SYCL=on -DCMAKE_C_COMPILER=icx -DCMAKE_CXX_COMPILER=icpx" pip install llama-cpp-python
RPC
要支持RPC安装,在安装前设置GGML_RPC=on
环境变量
source /opt/intel/oneapi/setvars.sh
CMAKE_ARGS="-DGGML_RPC=on" pip install llama-cpp-python
Windows注意事项
错误:找不到'nmake'或'CMAKE_C_COMPILER'
如果您遇到找不到'nmake'
或CMAKE_C_COMPILER的问题,您可以将w64devkit解压如llama.cpp仓库中所述,并手动添加到CMAKE_ARGS中,然后再运行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"
请参阅上述说明,并将CMAKE_ARGS
设置为要使用的BLAS后端。
MacOS注意事项
详细的MacOS Metal GPU安装文档可在docs/install/macos.md中找到
M1 Mac性能问题
注意:如果您使用的是Apple Silicon(M1)Mac,请确保您已安装支持arm64架构的Python版本。例如
wget https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-MacOSX-arm64.sh
bash Miniforge3-MacOSX-arm64.sh
否则,在安装时将构建llama.cpp的x86版本,这将使Apple Silicon(M1)Mac上的性能慢10倍。
M系列Mac错误:(mach-o文件,但架构不兼容(有'x86_64',需要'arm64'))
尝试使用以下方法安装
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
升级和重新安装
要升级和重新构建llama-cpp-python
,请将--upgrade --force-reinstall --no-cache-dir
标志添加到pip install
命令中,以确保从源代码重新构建该包。
高级API
高级API通过Llama
类提供了一个简单的管理接口。
以下是一个使用高级API进行基本文本补全的简短示例
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)
默认情况下,llama-cpp-python
以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
}
}
文本补全可通过__call__
和create_completion
方法获得,这两个方法属于Llama
类。
从Hugging Face Hub拉取模型
您可以直接从Hugging Face下载Llama
模型,格式为gguf
,并使用from_pretrained
方法。要使用此功能,您需要安装huggingface-hub
包(pip install huggingface-hub
)。
llm = Llama.from_pretrained(
repo_id="Qwen/Qwen2-0.5B-Instruct-GGUF",
filename="*q8_0.gguf",
verbose=False
)
默认情况下,from_pretrained
将模型下载到Hugging Face缓存目录,您可以使用huggingface-cli
工具管理已安装的模型文件。
聊天完成
高级API还提供了一个简单的聊天完成接口。
聊天完成需要模型知道如何将消息格式化为单个提示。Llama类使用预注册的聊天格式(例如chatml
、llama-2
、gemma
等)或通过提供自定义聊天处理对象来实现。
模型将按照以下顺序优先级将消息格式化为单个提示:
- 如果提供了
chat_handler
,则使用它 - 如果提供了
chat_format
,则使用它 - 使用来自
gguf
模型元数据的tokenizer.chat_template
(大多数新模型应适用,旧模型可能没有此功能) - 否则,回退到
llama-2
聊天格式
设置verbose=True
以查看所选聊天格式。
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."
}
]
)
聊天完成通过Llama
类的create_chat_completion
方法提供。
为了与OpenAI API v1兼容,您可以使用create_chat_completion_openai_v1
方法,该方法将返回pydantic模型而不是dict。
JSON和JSON Schema模式
要使用create_chat_completion
中的response_format
参数将聊天响应限制为仅有效的JSON或特定的JSON Schema。
JSON模式
以下示例将响应限制为仅有效的JSON字符串。
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,
)
JSON Schema模式
要进一步将响应限制为特定的JSON Schema,请将schema添加到response_format
参数的schema
属性。
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,
)
函数调用
高级API支持与OpenAI兼容的函数和工具调用。这通过functionary
预训练模型聊天格式或通过通用的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"
}
}
)
Functionary v2
此模型集的各种gguf-转换文件可以在此处找到。Functionary能够智能地调用函数,并分析任何提供的函数输出以生成连贯的响应。所有v2模型的功能性都支持并行函数调用
。您可以在初始化Llama类时为chat_format
提供functionary-v1
或functionary-v2
。
由于llama.cpp和HuggingFace的tokenizers之间存在差异,因此需要为Functionary提供HF Tokenizer。可以初始化LlamaHFTokenizer
类并将其传递到Llama类中。这将覆盖Llama类中使用的默认llama.cpp tokenizer。tokenizer文件已包含在托管gguf文件的相应HF存储库中。
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")
)
注意:无需提供Functionary中使用的默认系统消息,因为它们会在Functionary聊天处理程序中自动添加。因此,消息应仅包含聊天消息和/或系统消息,这些消息为模型提供额外的上下文(例如:日期时间等)。
多模态模型
llama-cpp-python
支持llava1.5等模型,允许语言模型从文本和图像中读取信息。
以下是支持的多模态模型及其相应的聊天处理程序(Python API)和聊天格式(服务器API)。
模型 | LlamaChatHandler |
chat_format |
---|---|---|
llava-v1.5-7b | Llava15ChatHandler |
llava-1-5 |
llava-v1.5-13b | Llava15ChatHandler |
llava-1-5 |
llava-v1.6-34b | Llava16ChatHandler |
llava-1-6 |
moondream2 | MoondreamChatHandler |
moondream2 |
nanollava | NanollavaChatHandler |
nanollava |
llama-3-vision-alpha | Llama3VisionAlphaChatHandler |
llama-3-vision-alpha |
minicpm-v-2.6 | MiniCPMv26ChatHandler |
minicpm-v-2.6 |
您需要使用自定义聊天处理程序来加载剪辑模型并处理聊天消息和图像。
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" } }
]
}
]
)
您还可以使用 from_pretrained
方法从 Hugging Face Hub 中提取模型。
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"])
注意:多模态模型也支持工具调用和 JSON 模式。
加载本地图像
图像可以作为 base64 编码的数据 URI 传递。以下示例演示了如何执行此操作。
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
支持投机解码,这使得模型可以根据草案模型生成完成。
使用 LlamaPromptLookupDecoding
类使用投机解码最快。
只需在初始化 Llama
类时将此作为草案模型传递。
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.
)
嵌入
要生成文本嵌入,请使用 create_embedding
或 embed
。请注意,您必须在创建模型时将 embedding=True
传递给构造函数,以便这些操作正常工作。
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!"])
在 Transformer 风格的模型中,有两个主要的嵌入概念:token 级别和sequence 级别。sequence 级别嵌入是通过“聚合”token 级别嵌入生成的,通常是通过平均它们或使用第一个 token。
专门针对嵌入的模型通常默认返回 sequence 级别嵌入,每个输入字符串一个。非嵌入模型,如为文本生成设计的模型,通常仅返回 token 级别嵌入,每个序列中的每个 token 一个。因此,返回类型的维度对于 token 级别嵌入将高一个。
在某些情况下,您可以使用模型创建时的 pooling_type
标志来控制聚合行为。您可以使用 LLAMA_POOLING_TYPE_NONE
确保任何模型都从任何模型中获取 token 级别嵌入。目前无法将面向生成的模型转换为生成 sequence 级别嵌入,但您可以始终手动执行聚合。
调整上下文窗口
Llama 模型的上下文窗口决定了可以一次性处理的 token 的最大数量。默认情况下,此值为 512 个 token,但可以根据您的需求进行调整。
例如,如果您想处理更大的上下文,可以通过在初始化 Llama 对象时设置 n_ctx 参数来扩展上下文窗口
llm = Llama(model_path="./models/7B/llama-model.gguf", n_ctx=2048)
OpenAI 兼容的 Web 服务器
llama-cpp-python
提供了一个 Web 服务器,旨在作为 OpenAI API 的直接替代品。这允许您使用与 llama.cpp 兼容的任何 OpenAI 兼容客户端(语言库、服务等)。
要安装服务器包并开始
pip install 'llama-cpp-python[server]'
python3 -m llama_cpp.server --model models/7B/llama-model.gguf
类似于上面的硬件加速部分,您还可以使用以下方式安装具有 GPU(cuBLAS)支持
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
导航到 http://localhost:8000/docs 查看 OpenAPI 文档。
要绑定到 0.0.0.0
以启用远程连接,请使用 python3 -m llama_cpp.server --host 0.0.0.0
。同样,要更改端口(默认为 8000),请使用 --port
。
您可能还希望设置提示格式。对于 chatml,使用
python3 -m llama_cpp.server --model models/7B/llama-model.gguf --chat_format chatml
这将根据模型期望的格式对提示进行格式化。您可以在模型卡片中找到提示格式。有关可能选项,请参阅 llama_cpp/llama_chat_format.py 并查找以 "@" 开头的行。
如果您已安装 huggingface-hub
,您还可以使用 --hf_model_repo_id
标志从 Hugging Face Hub 加载模型。
python3 -m llama_cpp.server --hf_model_repo_id Qwen/Qwen2-0.5B-Instruct-GGUF --model '*q8_0.gguf'
Web 服务器功能
Docker 镜像
可以在 GHCR 上找到 Docker 镜像。要运行服务器
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
在 Termux 上运行 Docker(需要 root 权限) 是目前唯一已知的在手机上运行此软件的方法,请参阅 Termux 支持问题
低级 API
低级 API 是对由 llama.cpp
提供的 C API 的直接 ctypes
绑定。整个低级 API 可以在 llama_cpp/llama_cpp.py 中找到,并直接映射到 llama.h 中的 C API。
以下是一个简短示例,演示如何使用低级 API 对提示进行标记
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)
请查看 示例文件夹 以获取更多使用低级 API 的示例。
文档
文档可通过 https://llama-cpp-python.readthedocs.io/ 获取。如果您发现文档有任何问题,请提交问题或提交 PR。
开发
此软件包正在积极开发中,我欢迎任何贡献。
要开始,请克隆存储库并在可编辑/开发模式下安装软件包
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
您还可以通过在 vendor/llama.cpp
子模块中检出所需的提交来测试 llama.cpp
的特定提交,然后再次运行 make clean
和 pip install -e .
。对 llama.h
API 的任何更改都需要修改 llama_cpp/llama_cpp.py
文件以匹配新的 API(可能还需要在其他地方进行更改)。
常见问题解答 (FAQ)
是否有可用的预构建二进制文件/二进制轮子?
建议的安装方法是按照上述方法从源代码进行安装。这样做的原因是 llama.cpp
是根据您自己的系统特定的编译器优化构建的。使用预构建的二进制文件将需要禁用这些优化或支持每个平台的大量预构建二进制文件。
尽管如此,通过发行版以及一些社区提供的轮子,仍然有一些预构建的二进制文件可用。
将来,我希望能为常见平台提供预构建的二进制文件和轮子,并乐意接受该领域的任何有用贡献。这目前正在通过 #741 跟踪。
这与 llama.cpp
的其他 Python 绑定相比如何?
我最初编写这个软件包是为了自己的使用,目标是两个
- 提供一种简单的过程来安装
llama.cpp
并从 Python 访问llama.h
中的完整 C API - 提供一个高级 Python API,可以用作 OpenAI API 的直接替代品,以便现有应用程序可以轻松移植以使用
llama.cpp
对这个软件包的任何贡献和更改都将以此目标为依据。
许可证
此项目受 MIT 许可证的条款约束。