OnPrem.LLM:一个轻量级 Python 库,用于使用私有数据运行本地大型语言模型

一、介绍 OnPrem.LLM

OnPrem.LLM 是一个简单的 Python 库,用于使用非公开数据运行本地大型语言模型。它默认使用的 7B 参数模型,你也可以通过提供 use_larger=True 使用默认的 13B 模型。你还可以提供不同模型的 URL。OnPrem.LLM 主要受到 privateGPT 项目的启发,旨在帮助将本地 LLM 集成到实际应用程序中。

二、安装 OnPrem.LLM

在安装 OnPrem.LLM 前,需要先安装 PyTorchllama-cpp-python。建议使用虚拟环境来进行安装,可以参考以下2.1和2.2部门准备好包管理器和Python等基础环境。

2.1、Package Manager

要安装 PyTorch 二进制文件,您需要使用两个受支持的包管理器之一:Anaconda 或 pip。 Anaconda 是推荐的包管理器,因为它将在一个沙盒安装中为您提供所有 PyTorch 依赖项,包括 Python。

2.1.1、Anaconda

根据你实际的安装环境操作系统来选择对应的脚本安装 Anaconda,然后激活即可使用。

  • Linux 系统使用以下命令
curl -O https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
sh Miniconda3-latest-Linux-x86_64.sh
  • Intel Mac 系统使用以下命令
curl -O https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-x86_64.sh
sh Miniconda3-latest-MacOSX-x86_64.sh
  • M1 Mac 系统使用以下命令
curl -O https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-arm64.sh
sh Miniconda3-latest-MacOSX-arm64.sh
  • 使用以下命令激活conda环境:
source ~/.bashrc
  • 使用以下命令检查conda是否成功安装:
conda --version

如果conda成功安装,您将看到conda的版本号,我这里安装的是conda 23.5.2。

2.1.2、pip

如果您通过 Homebrew 或 Python 网站安装了 Python,则 pip 会随之安装。如果您安装了 Python 3.x,那么您将使用命令 pip3

提示:如果您只想使用命令 pip 而不是 pip3 ,则可以将 pip 符号链接到 pip3 二进制文件。

2.2、Python

建议您使用 Python 3.8 或更高版本,可以通过 Anaconda 包管理器(见下文)、Homebrew 或 Python 网站安装。

如果需要在Miniconda中安装特定版本的Python,可以使用以下命令:

conda create -n myenv python=3.11

这将创建一个名为myenv的环境,并在其中安装 Python 3.11 版本。您可以根据需要替换版本号。

如果使用的是 Mac/Linux,您可以使用以下命令激活虚拟环境:

conda activate myenv

在命令行前面如果看到 (myenv) 则说明 Python 的虚拟环境激活成功了,后续推出会话需要安装依赖也需要先激活到虚拟环境再进行操作。

(base) root@racknerd:/scalene# conda activate myenv
(myenv) root@racknerd:/scalene# pip --version
pip 23.2.1 from /root/miniconda3/envs/myenv/lib/python3.11/site-packages/pip (python 3.11)

2.3、PyTorch

PyTorch 在 macOS 10.15 (Catalina) 或更高版本上受支持。

2.3.1、Anaconda

要通过 Anaconda 安装 PyTorch,请使用以下 conda 命令:

conda install pytorch torchvision -c pytorch
2.3.2、pip

要通过 pip 安装 PyTorch,请使用以下命令,具体取决于您的 Python 版本:

# Python 3.x
pip3 install torch torchvision
2.3.3、Verification

为了确保 PyTorch 正确安装,我们可以通过运行示例 PyTorch 代码来验证安装。这里我们将构造一个随机初始化的张量。

import torch
x = torch.rand(5, 3)
print(x)

输出应该类似于:

tensor([[0.3380, 0.3845, 0.3217],
        [0.8337, 0.9050, 0.2650],
        [0.2979, 0.7141, 0.9069],
        [0.1449, 0.1132, 0.1375],
        [0.4675, 0.3947, 0.1426]])

2.4、llama-cpp-python

llama-cpp-python 是 llama.cpp 的 Python 绑定。它支持许多LLM的推理,可以在 HuggingFace 上访问。

注意:新版本的 llama-cpp-python 使用 GGUF 模型文件

从版本 0.1.79 开始,模型格式已从 ggmlv3 更改为 gguf 。旧模型文件可以使用 llama.cpp 中的 convert-llama-ggmlv3-to-gguf.py 脚本进行转换

要将现有的 GGML 模型转换为 GGUF,您可以在 llama.cpp 中运行以下命令:

python ./convert-llama-ggmlv3-to-gguf.py --eps 1e-5 --input models/openorca-platypus2-13b.ggmlv3.q4_0.bin --output models/openorca-platypus2-13b.gguf.q4_0.bin
2.4.1、仅CPU安装

从源代码构建 llama.cpp 。这是推荐的安装方法,因为它可以确保 llama.cpp 是使用适合您的系统的可用优化构建的。

pip install llama-cpp-python

如果您之前通过 pip 安装了 llama-cpp-python 并希望升级版本或使用不同的编译器选项重建软件包,请添加以下标志以确保正确重建软件包:

pip install llama-cpp-python --force-reinstall --upgrade --no-cache-dir

注意:如果您使用的是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.ccp x86 版本,该版本在 Apple Silicon (M1) Mac 上速度会慢 10 倍。

2.4.2、使用硬件加速安装

lama.cpp 支持多个 BLAS 后端以加快处理速度。使用 FORCE_CMAKE=1 环境变量强制使用 cmake 并为所需的 BLAS 后端安装 pip 包(源代码)。

安装具有 cuBLAS 支持的 llama-cpp-python,请在安装前设置 LLAMA_CUBLAS=on 环境变量:

CMAKE_ARGS="-DLLAMA_CUBLAS=on" pip install llama-cpp-python

重要提示:如果您已经安装了该软件包的仅限 CPU 版本,则需要从头开始重新安装。以下步骤描述了安装和使用具有 cuBLAS 支持的 llama-cpp-python ,并且可用于 Linux 和 Google Colab 等上的 GPU 加速:

CMAKE_ARGS="-DLLAMA_CUBLAS=on" FORCE_CMAKE=1 pip install -q --upgrade --force-reinstall llama-cpp-python --no-cache-dir

要使用 OpenBLAS 安装,请在安装前设置 LLAMA_BLAS and LLAMA_BLAS_VENDOR 环境变量:

CMAKE_ARGS="-DLLAMA_BLAS=ON -DLLAMA_BLAS_VENDOR=OpenBLAS" pip install llama-cpp-python

要使用 CLBlast 进行安装,请在安装前设置 LLAMA_CLBLAST=on环境变量:

CMAKE_ARGS="-DLLAMA_CLBLAST=on" pip install llama-cpp-python

要使用 Metal (MPS) 进行安装,请在安装前设置 LLAMA_METAL=on 环境变量:

CMAKE_ARGS="-DLLAMA_METAL=on" pip install llama-cpp-python

要安装 AMD 卡的 hipBLAS / ROCm 支持,请在安装前设置 LLAMA_HIPBLAS=on 环境变量:

CMAKE_ARGS="-DLLAMA_HIPBLAS=on" pip install llama-cpp-python
2.4.3、在CentOS系统安装失败

问题:ERROR: Could not build wheels for llama-cpp-python, which is required to install pyproject.toml-based projects

解决:gcc 版本需要 升级到 11 版本(https://github.com/imartinez/privateGPT/issues/644)

# 删除已安装的 gcc 
yum remove gcc 
yum remove gdb
# 安装 scl-utils
yum install scl-utils 
yum install centos-release-scl
# find devtoolset-11
yum list all --enablerepo='centos-sclo-rh' | grep "devtoolset"
# 安装 devtoolset-11-toolchain 工具集
yum install -y devtoolset-11-toolchain
# 把下面的指令添加到 /etc/profile 文件尾部
PATH=$PATH:/opt/rh/devtoolset-11/root/usr/bin 
export PATH 
sudo scl enable devtoolset-11 bash
# 查看 gcc version and gcc11 is installed successfully.
gcc --version
# 再次尝试安装
pip install llama-cpp-python==0.1.50

2.5、OnPrem

安装 PyTorch 并安装 llama-cpp-python 后,您可以使用以下命令安装 OnPrem.LLM:

pip install onprem

三、快速开始

默认情况下,下载并使用 7B 参数模型。如果是 use_larger=True ,则使用 13B 参数。您还可以向 LLM 提供您选择的 LLM 的 URL(有关示例,请参阅下面的代码生成部分)。从 v0.0.20 开始,OnPrem.LLM 支持较新的 GGUF 格式。

from onprem import LLM

llm = LLM()

如果在尝试下载模型时收到 SSL 错误,可以设置 ssl_verify=False

from onprem import LLM

LLM.download_model(url, ssl_verify=False)

四、离线部署

在联网环境下通过调用 LLM.download_model 方法将模型文件下载到 /onprem_data ,然后将下载的模型权重文件传输到离线机器上的同一位置。

对于 ingestask 方法,还需要下载并传输嵌入模型文件:

from sentence_transformers import SentenceTransformer
model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2')
model.save('/some/folder')

some/folder 文件夹复制到离线计算机,并通过 embedding_model_name 参数提供 LLM 的路径。

五、应用案例

5.1、使用提示词解决问题

5.1.1、信息提取
prompt = """Extract the Name, Position, and Company from the following sentences.  Here are some examples.
[Text]: Fred is a serial entrepreneur. Co-founder and CEO of Platform.sh, he previously co-founded Commerce Guys, a leading Drupal ecommerce provider. His mission is to guarantee that as we continue on an ambitious journey to profoundly transform how cloud computing is used and perceived, we keep our feet well on the ground continuing the rapid growth we have enjoyed up until now. 
[Name]: Fred
[Position]: Co-founder and CEO
[Company]: Platform.sh
###
[Text]: Microsoft (the word being a portmanteau of "microcomputer software") was founded by Bill Gates on April 4, 1975, to develop and sell BASIC interpreters for the Altair 8800. Steve Ballmer replaced Gates as CEO in 2000, and later envisioned a "devices and services" strategy.
[Name]:  Steve Ballmer
[Position]: CEO
[Company]: Microsoft
###
[Text]: Franck Riboud was born on 7 November 1955 in Lyon. He is the son of Antoine Riboud, the previous CEO, who transformed the former European glassmaker BSN Group into a leading player in the food industry. He is the CEO at Danone.
[Name]:  Franck Riboud
[Position]: CEO
[Company]: Danone
###
[Text]: David Melvin is an investment and financial services professional at CITIC CLSA with over 30 years’ experience in investment banking and private equity. He is currently a Senior Adviser of CITIC CLSA.
"""
saved_output = llm.prompt(prompt)

[Name]: David Melvin

[Position]: Senior Adviser

[Company]: CITIC CLSA

5.1.2、语法纠正
prompt = """Correct the grammar and spelling in the supplied sentences.  Here are some examples.
[Sentence]:
I love goin to the beach.
[Correction]: I love going to the beach.
[Sentence]:
Let me hav it!
[Correction]: Let me have it!
[Sentence]:
It have too many drawbacks.
[Correction]: It has too many drawbacks.
[Sentence]:
I do not wan to go
[Correction]:"""
saved_output = llm.prompt(prompt)

I don't want to go.

5.1.3、情感分类
prompt = """Classify each sentence as either positive, negative, or neutral.  Here are some examples.
[Sentence]: I love going to the beach.
[[Classification]: Positive
[Sentence]: It is 10am right now.
[Classification]: Neutral
[Sentence]: I just got fired from my job.
[Classification]: Negative
[Sentence]: The reactivity of  your team has been amazing, thanks!
[Classification]:"""

saved_output = llm.prompt(prompt)

Positive

5.1.4、释义和总结
prompt = """Paraphrase the following text delimited by triple backticks. 
```After a war lasting 20 years, following the decision taken first by President Trump and then by President Biden to withdraw American troops, Kabul, the capital of Afghanistan, fell within a few hours to the Taliban, without resistance.```
"""
saved_output = llm.prompt(prompt)

Paraphrase: After two decades of war in Afghanistan, with President Trump and later President Biden announcing their plans to withdraw American troops, Kabul, the Afghan capital, quickly fell into the hands of the Taliban without any resistance from local authorities or security forces.

5.1.5、少样本答案提取
prompt = """Answer the Question based on the Context.  Here are some examples.
[Context]: 
NLP Cloud was founded in 2021 when the team realized there was no easy way to reliably leverage Natural Language Processing in production.
Question: When was NLP Cloud founded?
[Answer]: 
2021
###
[Context]:
NLP Cloud developed their API by mid-2020 and they added many pre-trained open-source models since then.
[Question]: 
What did NLP Cloud develop?
[Answer]:
API
###
[Context]:
All plans can be stopped anytime. You only pay for the time you used the service. In case of a downgrade, you will get a discount on your next invoice.
[Question]:
When can plans be stopped?
[Answer]:
Anytime
###
[Context]:
The main challenge with GPT-J is memory consumption. Using a GPU plan is recommended.
[Question]:
Which plan is recommended for GPT-J?
Answer:"""
saved_output = llm.prompt(prompt)

GPU Plan

5.1.6、生成产品描述
prompt = """Generate a Sentence from the Keywords. Here are some examples.
[Keywords]:
shoes, women, $59
[Sentence]:
Beautiful shoes for women at the price of $59.
###
[Keywords]:
trousers, men, $69
[Sentence]:
Modern trousers for men, for $69 only.
###
[Keywords]:
gloves, winter, $19
[Sentence]: 
Amazingly hot gloves for cold winters, at $19.
###
[Keywords]: 
t-shirt, men, $39
[Sentence]:"""
saved_output = llm.prompt(prompt)

A stylish and comfortable t-shirt for men, for just $39.

5.1.7、起草电子邮件
prompt = """Generate an email introducing Tesla to shareholders."""
saved_output = llm.prompt(prompt)

Subject: Introducing Tesla, the future of transportation Dear Shareholder, I am writing to introduce you to Tesla, the leading manufacturer of electric vehicles (EVs) and energy storage products. Tesla has been at the forefront of innovating EV technology since its inception in 2003. With a history of creating breakthrough products such as the Tesla Model S, Tesla Powerwall, and Solar Roof, it is clear that Tesla's mission is to create a better future through sustainable transportation and energy solutions. Tesla has experienced rapid growth in recent years, with its stock price increasing by 475% since January 2016. This growth can be attributed to several factors, including the increase in global interest in sustainability and environmental issues, as well as Tesla's continuous innovation and success in the EV market. Overall, Tesla is a company that not only produces cutting-edge products but also has a strong commitment to sustainability and innovation. As a shareholder of Tesla, I encourage you to take advantage of this opportunity to invest in the future of transportation and energy storage solutions with Tesla. Thank you for your continued support of Tesla.

5.2、通过RAG与文档对话

在这个示例中,我们将展示如何使用OnPrem.LLM来进行检索增强生成或RAG(Retrieval-Augmented Generation)。

首先,我们需要确保使用GPU加速推理。为此,我们使用NVIDIA Titan V GPU,并且有适度的12GB VRAM。请确保您已经按照文档中所述安装了支持CUBLAS的llama-cpp-python库。

接下来,在提供LLM参数时,您只需添加ngpulayers参数即可启用GPU加速响应。

另外,我们还可以通过将use_larger参数设置为True来使用稍大的默认模型。

这样,您就可以利用OnPrem.LLM进行检索增强生成,并在具备GPU加速的环境中获得更好的性能和效果。

from onprem import LLM
import tempfile

vectordb_path = tempfile.mkdtemp()

llm = LLM(use_larger=True, n_gpu_layers=35, vectordb_path=vectordb_path)

# 加载文件
llm.ingest("./sample_data/")
5.2.1、对加载的文件进行提问
# 对加载的文件进行提问
result = llm.ask("What is ktrain?")
5.2.2、查询文档答案来源

答案存储在 results['answer'] 中。从向量存储中检索到的用于生成答案的文档存储在上面的 results['source_documents'] 中。

print(result["source_documents"][0])
5.2.3、与上传的文档聊天

LLM.ask 不同, LLM.chat 方法保留会话记忆,但代价是更大的上下文和对 LLM 的额外调用。

result = llm.chat("What is ktrain?")

result = llm.chat("Does it support image classification?")

print(result["answer"])

5.3、代码生成

我们将通过提供 URL 并采用该模型所需的特定提示格式来使用 CodeUp LLM。

from onprem import LLM
from IPython.display import Markdown as md

url = "https://huggingface.co/TheBloke/CodeUp-Llama-2-13B-Chat-HF-GGUF/resolve/main/codeup-llama-2-13b-chat-hf.Q4_K_M.gguf"
llm = LLM(url, n_gpu_layers=35)

template = """
Below is an instruction that describes a task. Write a response that appropriately completes the request.

### Instruction:
{prompt}

### Response:"""

answer = llm.prompt(
    "Write a Python script that returns all file paths from a folder recursively.",
    prompt_template=template,
)

md(answer)

5.4、语义相似度

OnPrem.LLM 中的底层矢量数据库可用于检测文本片段之间的语义相似性。

import os, tempfile
from onprem import LLM

vectordb_path = tempfile.mkdtemp()
llm = LLM(
    embedding_model_name="sentence-transformers/nli-mpnet-base-v2",
    embedding_encode_kwargs={"normalize_embeddings": True},
    vectordb_path=vectordb_path,
)

data = [  # from txtai
    "US tops 5 million confirmed virus cases",
    "Canada's last fully intact ice shelf has suddenly collapsed, forming a Manhattan-sized iceberg",
    "Beijing mobilises invasion craft along coast as Taiwan tensions escalate",
    "The National Park Service warns against sacrificing slower friends in a bear attack",
    "Maine man wins $1M from $25 lottery ticket",
    "Make huge profits without work, earn up to $100,000 a day",
]
source_folder = tempfile.mkdtemp()
for i, d in enumerate(data):
    filename = os.path.join(source_folder, f"doc{i}.txt")
    with open(filename, "w") as f:
        f.write(d)

llm.ingest(source_folder, chunk_size=500, chunk_overlap=0)

在这里,我们获得对底层向量存储的引用并直接查询它以找到最佳语义匹配。

db = llm.load_ingester().get_db()
for query in (
    "feel good story",
    "climate change",
    "public health story",
    "war",
    "wildlife",
    "asia",
    "lucky",
    "dishonest junk",
):
    docs = db.similarity_search(query)
    print(f"{query} : {docs[0].page_content}")

Google Colab:

https://github.com/Crossme0809/frenzyTechAI/blob/main/onprem/OnPremLLMQuickStart_1007.ipynb

六、OnPrem 内置Web应用

OnPrem.LLM 包含一个内置 Web 应用程序,可轻松访问和使用 LLM。安装 OnPrem.LLM 后,您可以按照以下步骤准备 Web 应用程序并启动它:

第 1 步:使用 Python API 提取一些文档:
from onprem import LLM
llm = LLM()
llm.ingest('/your/folder/of/documents')
第 2 步:启动 Web 应用程序:
# 命令行运行
onprem --port 8000

然后,在 Web 浏览器中输入 localhost:8000 (如果在远程服务器上运行,则输入 :8000 )以访问该应用程序:

OnPrem.LLM:一个轻量级 Python 库,用于使用私有数据运行本地大型语言模型_第1张图片

OnPrem.LLM:一个轻量级 Python 库,用于使用私有数据运行本地大型语言模型_第2张图片

Web 应用程序是通过 Streamlit: pip install streamlit 实现的。如果尚未安装, onprem 命令将要求您安装它。以下是有关 onprem 命令的更多信息:

$:~/projects/github/onprem$ onprem --help
usage: onprem [-h] [-p PORT] [-a ADDRESS] [-v]

Start the OnPrem.LLM web app
Example: onprem --port 8000

optional arguments:
  -h, --help            show this help message and exit
  -p PORT, --port PORT  Port to use; default is 8501
  -a ADDRESS, --address ADDRESS
                        Address to bind; default is 0.0.0.0
  -v, --version         Print a version

该应用程序要求用户主目录的 onprem_data 文件夹中存在名为 webapp.yml 的文件。此文件存储 Web 应用程序使用的信息,例如要使用的模型。如果不存在,则会为您创建一个默认的,如下所示:

# 默认YAML配置
llm:
  # 模型url(或先前下载的模型文件名)
  model_url: https://huggingface.co/TheBloke/WizardLM-13B-V1.2-GGUF/resolve/main/wizardlm-13b-v1.2.Q4_K_M.gguf
  # number of layers offloaded to GPU
  n_gpu_layers: 32
  # 向量数据库文件夹路径
  vectordb_path: {datadir}/vectordb
  # 模型下载文件夹的路径
  model_download_path: {datadir}
  # LLM. ask和LLM.chat使用的源文件数量
  rag_num_source_docs: 6
  # LLM. ask/LLM.chat考虑的源的最小相似性分数
  rag_score_threshold: 0.0
  # verbosity of Llama.cpp
  verbose: TRUE
prompt:
  # prompt_template与LLM.提示词一起使用(例如,用于接受系统提示词的模型)
  prompt_template:
ui:
  # 应用名称
  title: OnPrem.LLM
  # “与您的文档对话”屏幕中的副标题
  rag_title:
  # 包含将在下面插入的内容的markdown文件的路径rag_title
  rag_text_path:
  # 包含原始文档的文件夹路径(即您提供给LLM. ingest的文件夹的绝对路径)
  rag_source_path:
  # 基本url(留空,除非您运行自己的单独Web服务器来提供源文档)
  rag_base_url:

您可以根据您的要求编辑该文件。 llm 部分中的变量会自动传递给 onprem.LLM 构造函数,而构造函数又将额外的 **kwargs 传递给 llama-cpp-python 。例如,您可以在 llm 部分中添加 temperature 变量来调整 Web 应用程序中模型的温度(例如,接近 0.0 的较低值可实现更具确定性的输出,较高的值可实现更稳定的输出)以获得更多创意)。

自动创建的 YAML 文件中的默认模型是 13B 参数模型。如果这对您的系统来说太大且太慢,您可以编辑上面的 model_url 以使用速度更快的 7B 参数模型或 3B 参数模型,但会牺牲一些性能。当然,您也可以编辑 model_url 以使用更大的模型。任何 GGUF 格式的模型都可以使用。

如果你对这篇文章感兴趣,而且你想要了解更多关于AI领域的实战技巧,可以关注「技术狂潮AI」公众号。在这里,你可以看到最新最热的AIGC领域的干货文章和案例实战教程。

你可能感兴趣的:(LLM应用实战,AI应用实战,AI工具实战,本地模型部署,OnPrem,语言模型)