​ Python 绑定llama.cpp​ github页面

​ Python 绑定llama.cpp​ github页面

Python 绑定

@ggerganov 库的 简单 Python 绑定。此包提供:

  • 通过接口对 C API 进行低级访问ctypes
  • 用于文本完成的高级 Python API
  • 类似 OpenAI 的 API
  • OpenAI 兼容的 Web 服务器

文档可在上找到。

安装

要求:

  • Python 3.8+
  • C 编译器
  • Linux:gcc 或 clang
  • Windows:Visual Studio 或 MinGW
  • MacOS:Xcode

要安装该包,请运行:  pip install llama-cpp-python

这也llama.cpp将从源代码构建并将其与这个 python 包一起安装。

如果失败,请添加--verbosepip install查看完整的 cmake 构建日志。

预制车轮(新)

还可以安装具有基本 CPU 支持的预制轮子。  pip install llama-cpp-python \ --extra-index-url https://abetlen.github.io/llama-cpp-python/whl/cpu

安装配置

llama.cpp支持多种硬件加速后端以加速推理以及后端特定选项。请参阅以获取完整列表。

所有llama.cppcmake 构建选项都可以在安装期间通过CMAKE_ARGS环境变量或cli 标志进行设置。--config-settings / -C

环境变量  # 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

CLI/要求.txt

支持的后端

以下是一些常见的后端、它们的构建命令以及所需的任何其他环境变量。

OpenBLAS(CPU)

要使用 OpenBLAS 安装,请在安装之前设置GGML_BLASGGML_BLAS_VENDOR环境变量:  CMAKE_ARGS="-DGGML_BLAS=ON -DGGML_BLAS_VENDOR=OpenBLAS" pip install llama-cpp-python

通用计算架构

要安装 CUDA 支持,请GGML_CUDA=on在安装前设置环境变量:  CMAKE_ARGS="-DGGML_CUDA=on" pip install llama-cpp-python

预制车轮(新)

也可以安装预先构建的具有 CUDA 支持的轮子。只要您的系统满足一些要求:

  • CUDA 版本为 12.1、12.2、12.3 或 12.4
  • 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.1
  • cu122:CUDA 12.2
  • cu123:CUDA 12.3
  • cu124:CUDA 12.4

例如,要安装 CUDA 12.1 轮子:  pip install llama-cpp-python \ --extra-index-url https://abetlen.github.io/llama-cpp-python/whl/cu121

金属

要使用 Metal(MPS)安装,请GGML_METAL=on在安装前设置环境变量:  CMAKE_ARGS="-DGGML_METAL=on" pip install llama-cpp-python

预制车轮(新)

也可以安装带有 Metal 支持的预制轮子。只要您的系统满足一些要求:

  • 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 支持,请GGML_VULKAN=on在安装前设置环境变量:  CMAKE_ARGS="-DGGML_VULKAN=on" pip install llama-cpp-python

新加坡联合通讯社

要安装 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 ,并在运行安装之前将其手动添加到 CMAKE_ARGS pip:  $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 安装文档可在

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 通过类提供了简单的托管接口。

下面是一个简短的示例,演示如何使用高级 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 } }

文本完成可以通过类的和方法实现。

从 Hugging Face Hub 提取模型

您可以使用该方法直接从 Hugging Face 下载 格式Llama的模型。您需要安装该软件包才能使用此功能()。ggufhuggingface-hubpip install huggingface-hub  llm = Llama.from_pretrained( repo_id="Qwen/Qwen2-0.5B-Instruct-GGUF", filename="*q8_0.gguf", verbose=False )

默认情况下会将模型下载到huggingface缓存目录,然后您可以使用该工具管理已安装的模型文件。

聊天完成

高级 API 还提供了用于聊天完成的简单接口。

聊天完成要求模型知道如何将消息格式化为单个提示。该类Llama使用预先注册的聊天格式(即chatmlllama-2gemma等)或通过提供自定义聊天处理程序对象来实现这一点。

该模型将按照以下优先顺序将消息格式化为单个提示:

  • 使用chat_handlerif 提供
  • 使用chat_formatif 提供
  • 使用tokenizer.chat_template来自gguf模型的元数据(应该适用于大多数新模型,旧模型可能没有这个)
  • 否则,恢复到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." } ] )

聊天完成可以通过类的方法实现。

为了与 OpenAI API v1 兼容,您可以使用返回 pydantic 模型而不是字典的方法。

JSON 和 JSON Schema 模式

要将聊天响应限制为仅有效的 JSON 或特定的 JSON 模式,请使用response_format中的参数。

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 模式

为了将响应进一步限制到特定的 JSON 模式,请将该模式添加到参数schema的属性中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, )

函数调用

高级 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" } } )

职能 v2

此组模型的各种 gguf 转换文件可找到。Functionary 能够智能地调用函数,还可以分析任何提供的函数输出以生成连贯的响应。functionary 的所有 v2 模型都支持并行函数调用。您可以在初始化 Llama 类时为提供或functionary-v1functionary-v2chat_format

由于 llama.cpp 与 HuggingFace 的 tokenizer 之间存在差异,因此需要为 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)。

模型LlamaChatHandlerchat_format
Llava15ChatHandlerllava-1-5
Llava15ChatHandlerllava-1-5
Llava16ChatHandlerllava-1-6
MoondreamChatHandlermoondream2
NanollavaChatHandlernanollava
Llama3VisionAlphaChatHandlerllama-3-vision-alpha

然后,您需要使用自定义聊天处理程序来加载剪辑模型并处理聊天消息和图像。  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" } } ] } ] )

您还可以使用该方法从 Hugging Face Hub 中拉出模型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"])

:多模态模型还支持工具调用和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. )

嵌入

要生成文本嵌入,请使用或。请注意,必须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 风格模型中的嵌入有两个主要概念:标记级别序列级别。序列级别嵌入是通过将标记级别嵌入“池化”在一起而生成的,通常通过对它们进行平均或使用第一个标记。

专门针对嵌入的模型通常会默认返回序列级嵌入,每个输入字符串一个。非嵌入模型(例如为文本生成设计的模型)通常只返回标记级嵌入,每个序列中的每个标记一个。因此,对于标记级嵌入,返回类型的维度将高一个。

在某些情况下,可以使用pooling_type模型创建时的标志来控制池化行为。您可以使用 确保任何模型的标记级别嵌入LLAMA_POOLING_TYPE_NONE。相反,目前无法让面向生成的模型产生序列级别嵌入,但您始终可以手动进行池化。

调整上下文窗口

Llama 模型的上下文窗口决定了一次可以处理的最大令牌数。默认情况下,该值设置为 512 个令牌,但可以根据您的要求进行调整。

例如,如果您想使用更大的上下文,您可以在初始化 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

导航到查看 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

这将根据模型的期望格式化提示。您可以在模型卡中找到提示格式。有关可能的选项,请参阅并查找以“@register_chat_format”开头的行。

如果您已经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 映像

上有可用的 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

是唯一已知的在手机上运行它的方法,请参阅

低级 API

低级 API 直接绑定到 提供的 C API llama.cpp。整个低级 API 可以在中的 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 的更多示例。

文档

文档可通过获取。如果您发现文档存在任何问题,请打开问题或提交 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

llama.cpp您还可以通过签出vendor/llama.cpp子模块中所需的提交,然后再次运行make clean并测试特定的提交pip install -e .。API 中的任何更改都llama.h将需要更改llama_cpp/llama_cpp.py文件以匹配新 API(其他地方可能需要进行其他更改)。

常问问题

是否有可用的预建二进制文件/二进制轮?

建议的安装方法是如上所述从源代码安装。这样做的原因是它是llama.cpp使用特定于您的系统的编译器优化构建的。使用预构建的二进制文件需要禁用这些优化或支持每个平台的大量预构建二进制文件。

话虽如此,还是有一些通过发布版本提供的预先构建的二进制文件以及一些社区提供的轮子。

将来,我希望为常见平台提供预构建的二进制文件和轮子,我很乐意接受这方面的任何有用贡献。目前正在

这与其他 Python 绑定相比如何llama.cpp

我最初编写这个包是为了自己使用,有两个目的:

  • 提供一个简单的过程来安装和访问Pythonllama.cpp中的完整 C APIllama.h
  • 提供可作为 OpenAI API 替代品的高级 Python API,以便现有应用程序可以轻松移植使用llama.cpp

对此软件包的任何贡献和更改都将以这些目标为目标。

执照

该项目是根据 MIT 许可条款授权的。

Read more

深入理解 Proxy 和 Object.defineProperty

在JavaScript中,对象是一种核心的数据结构,而对对象的操作也是开发中经常遇到的任务。在这个过程中,我们经常会使用到两个重要的特性:Proxy和Object.defineProperty。这两者都允许我们在对象上进行拦截和自定义操作,但它们在实现方式、应用场景和灵活性等方面存在一些显著的区别。本文将深入比较Proxy和Object.defineProperty,包括它们的基本概念、使用示例以及适用场景,以帮助读者更好地理解和运用这两个特性。 1. Object.defineProperty 1.1 基本概念 Object.defineProperty 是 ECMAScript 5 引入的一个方法,用于直接在对象上定义新属性或修改已有属性。它的基本语法如下: javascript 代码解读复制代码Object.defineProperty(obj, prop, descriptor); 其中,obj是目标对象,prop是要定义或修改的属性名,descriptor是一个描述符对象,用于定义属性的特性。 1.2 使用示例 javascript 代码解读复制代码//

By Ne0inhk

Proxy 和 Object.defineProperty 的区别

Proxy 和 Object.defineProperty 是 JavaScript 中两个不同的特性,它们的作用也不完全相同。 Object.defineProperty 允许你在一个对象上定义一个新属性或者修改一个已有属性。通过这个方法你可以精确地定义属性的特征,比如它是否可写、可枚举、可配置等。该方法的使用场景通常是需要在一个对象上创建一个属性,然后控制这个属性的行为。 Proxy 也可以用来代理一个对象,但是相比于 Object.defineProperty,它提供了更加强大的功能。使用 Proxy 可以截获并重定义对象的基本操作,比如访问属性、赋值、函数调用等等。在这些操作被执行之前,可以通过拦截器函数对这些操作进行拦截和修改。因此,通过 Proxy,你可以完全重写一个对象的默认行为。该方法的使用场景通常是需要对一个对象的行为进行定制化,或者需要在对象上添加额外的功能。 对比 以下是 Proxy 和 Object.defineProperty 的一些区别对比: 方面ProxyObject.defineProperty语法使用 new Proxy(target,

By Ne0inhk