[NLP] 使用Llama.cpp和LangChain在CPU上使用大模型

一 准备工作

下面是构建这个应用程序时将使用的软件工具:

1.Llama-cpp-python

 下载llama-cpp, llama-cpp-python

[NLP] Llama2模型运行在Mac机器-CSDN博客

2、LangChain

LangChain是一个提供了一组广泛的集成和数据连接器,允许我们链接和编排不同的模块。可以常见聊天机器人、数据分析和文档问答等应用。

3、sentence-transformer

sentence-transformer提供了简单的方法来计算句子、文本和图像的嵌入。它能够计算100多种语言的嵌入。我们将在这个项目中使用开源的all-MiniLM-L6-v2模型。

4、FAISS

Facebook AI相似度搜索(FAISS)是一个为高效相似度搜索和密集向量聚类而设计的库。

给定一组嵌入,我们可以使用FAISS对它们进行索引,然后利用其强大的语义搜索算法在索引中搜索最相似的向量。

虽然它不是传统意义上的成熟的向量存储(如数据库管理系统),但它以一种优化的方式处理向量的存储,以实现有效的最近邻搜索。

二 LLM应用架构:以文档Q&A为例

假设我们想基于自己部署的Llama2模型,构建一个用于回答针对特定文档内容提问的聊天机器人。文档的内容可能属于特定领域或者特定组织内的文档,因此不属于任何Llama2进行预训练和微调的数据集。一个直觉的做法是in-context-learning:将文档作为Prompt提供给模型,从而模型能够根据所提供的Context进行回答。直接将文档作为Context可能遇到的问题是:

  • 文档的长度超出了模型的Context长度限制,原版Llama2的Context长度为4096个Tokens。
  • 对于较长的Context,模型可能会Lost in the Middle,无法准确从Context中获取关键信息。

因此,我们希望在构建Prompt时,只输入与用户的问题最相关的文档内容。

以下是构建文档Q&A应用的常用架构:

  • 文档处理与存储:将原始文本进行分块 (Splitting),并使用语言模型对每块文本进行embedding,得到文本的向量表示,最后将文本向量存储在支持相似性搜索的向量数据库中。
  • 用户询问和Prompt构建:根据用户输入的询问,使用相似性搜索在向量数据库中提取出与询问最相关的一些文档分块,并将用户询问+文档一起构建Prompt,随后输入LLM并得到回答。

三 实际使用

LangChain

在上节中描述了以文档Q&A为例的LLM应用Pipeline架构。LangChain是构建该类大模型应用的框架,其提供了模块化组件(例如上文图中的Document loader, Text splitter, Vector storage)的抽象和实现,并支持集成第三方的实现(例如可以使用不同第三方提供的Vector Storage服务)。通过LangChain可以将大模型与自定义的数据源结合起来构建Pipeline。

https://github.com/langchain-ai/langchain​github.com/langchain-ai/langchain

构建步骤

我们已经了解了各种组件,接下来让逐步介绍如何构建文档问答应用程序。

由于已经有许多教程了,所以我们不会深入到复杂和一般的文档问答组件的细节(例如,文本分块,矢量存储设置)。在本文中,我们将把重点放在开源LLM和CPU推理方面。

使用llama-cpp-python启动llama2 api服务

python3 -m llama_cpp.server --model TheBloke--Chinese-Alpaca-2-7B-GGUF/chinese-alpaca-2-7b.Q4_K_M.gguf   --n_gpu_layers 1INFO:     Started server process [63148]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://localhost:8000 (Press CTRL+C to quit)

使用LangChain调用本地部署的Llama2

下面的示例将使用LangChain的API调用本地部署的Llama2模型。

from langchain.chat_models import ChatOpenAIchat_model = ChatOpenAI(openai_api_key = "EMPTY", openai_api_base = "http://localhost:8000/v1", max_tokens=256)
  • 由于本地部署的llama-cpp-python提供了类OpenAI的API,因此可以直接使用ChatOpenAI接口,这将调用/v1/chat/completions API。
  • 由于并没有使用真正的OpenAI API,因此open_ai_key可以任意提供。openai_pi_base为模型API的Base URL。max_tokens限制了模型回答的长度。
from langchain.chat_models import ChatOpenAIchat_model = ChatOpenAI(openai_api_key = "EMPTY", openai_api_base = "http://localhost:8000/v1", max_tokens=256)from langchain.schema import AIMessage, HumanMessage, SystemMessagesystem_text = "You are a helpful assistant."
human_text1 = "What is the capital of France?"
assistant_text = "Paris."
human_text2 = "How about England?"messages = [SystemMessage(content=system_text), HumanMessage(content=human_text1), AIMessage(content=assistant_text), HumanMessage(content=human_text2)]chat_model.predict_messages(messages)

这里将演示如何使用LangChain构建一个简单的文档Q&A应用Pipeline:

  • Document Loading + Text Splitting
  • Text Embeddings + Vector Storage
  • Text Retrieval  + Query LLM

1 数据加载与处理 Document Loading + Text Splitting

本实验使用llama.cpp的README.md作为我们需要进行询问的文档。LangChain提供了一系列不同格式文档的Loader,包括用于加载Markdown文档的UnstructuredMarkdownLoader:

UnstructuredMarkdownLoader默认会将文档中的不同Elements(各级标题,正文等)组合起来,去掉了#等字符。

RecursiveCharacterTextSplitter是对常见文本进行Split的推荐选择:

RecursiveCharacterTextSplitter递归地在文本中寻找能够进行分割的字符(默认为["\n\n", "\n", " ", ""])。这将尽可能地保留完整的段落,句子和单词。

  • chunk_size: 文本进行Split后每个分块的最大长度,所有分块将在这个限制以内
  • chunk_overlap: 前后分块overlap的长度,overlap是为了保持前后两个分块之间的语义连续性
  • length_function: 度量文本长度的方法
from langchain.document_loaders import UnstructuredMarkdownLoaderloader = UnstructuredMarkdownLoader("./README.md")
text = loader.load()from langchain.text_splitter import RecursiveCharacterTextSplittertext_splitter = RecursiveCharacterTextSplitter(chunk_size = 2000,chunk_overlap  = 400,length_function = len,is_separator_regex = False
)
all_splits = text_splitter.split_documents(text)

2.矢量存储 Text Embeddings + Vector Storage

这一步的任务是:将文本分割成块,加载嵌入模型,然后通过FAISS 进行向量的存储

Vector Storage

这里以FAISS向量数据库作为示例, FAISS基于Facebook AI Similarity Search(Faiss)库 。

pip install faiss-cpu

from langchain.embeddings import HuggingFaceEmbeddings 
# Load embeddings model 
embeddings = HuggingFaceEmbeddings(model_name='sentence-transformers/all-MiniLM-L6-v2', model_kwargs={'device': 'cpu'}) from langchain.vectorstores import FAISS
vectorstore = FAISS.from_documents(all_splits, embeddings) 
vectorstore.save_local('vectorstore/db_faiss')#question = "How to run the program in interactive mode?"
#docs = vectorstore.similarity_search(question, k=1)

运行上面的Python脚本后,向量存储将被生成并保存在名为'vectorstore/db_faiss'的本地目录中,并为语义搜索和检索做好准备。

3.文本检索与LLM查询 Text Retrieval  + Query LLM

from langchain.llms import OpenAI
from langchain.chat_models import ChatOpenAI
from langchain.chains import RetrievalQAchat_model = ChatOpenAI(openai_api_key = "EMPTY", openai_api_base = "http://localhost:8000/v1", max_tokens=256)qa_chain = RetrievalQA.from_chain_type(chat_model, retriever=vectorstore.as_retriever(search_kwargs={"k": 1}))
qa_chain({"query": "How to run the program in interactive mode?"})

构造RetrievalQA需要提供一个LLM的实例,我们提供基于本地部署的Llama2构造的ChatOpenAI;还需要提供一个文本的Retriever,我们提供FAISS向量数据库作为一个Retriever,参数search_kwargs={"k":1}设置了Retriever提取的文档分块的数量,决定了最终Prompt包含的文档内容的数量,在这里我们设置为1。 向Chain中传入询问,即可得到LLM根据Retriever提取的文档做出的回答。

自定义RetrievalQA的Prompt:

from langchain.chains import RetrievalQA
from langchain.prompts import PromptTemplatetemplate = """Use the following pieces of context to answer the question at the end. 
If you don't know the answer, just say that you don't know, don't try to make up an answer. 
Use three sentences maximum and keep the answer as concise as possible. 
Always say "thanks for asking!" at the end of the answer. 
{context}
Question: {question}
Helpful Answer:"""
QA_CHAIN_PROMPT = PromptTemplate.from_template(template)qa_chain = RetrievalQA.from_chain_type(chat_model,retriever=vectorstore.as_retriever(search_kwargs={"k": 1}),chain_type_kwargs={"prompt": QA_CHAIN_PROMPT}
)
qa_chain({"query": "What is --interactive option used for?"})

结论

本文介绍了如何在MacBook Pro本地环境使用llama.cpp部署ggml量化格式的Llama2语言模型,并演示如何使用LangChain简单构造了一个文档Q&A应用。

References

[1] https://github.com/ggerganov/llama.cpp

[2] QA over Documents | ️ Langchain

在MacBook Pro部署Llama2语言模型并基于LangChain构建LLM应用 - 知乎 (zhihu.com)

使用GGML和LangChain在CPU上运行量化的llama2 - 知乎 (zhihu.com)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/183649.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[正式学习java②]——数组的基本使用,java内存图与内存分配

🌈键盘敲烂,年薪30万🌈 目录 一、数组的两种初始化方式 1.完整格式(静态初始化) 2.动态初始化 二、数组的遍历方式 三、数组的开辟与访问 四、数组的注意事项 1.数组直接打印打印的是地址值 2.数组在内存图中的位置 3.数组一旦开辟了…

【C语言】二分查找(含图解)

文章目录 1. 二分查找思想2. 代码实现2.1 未封装函数2.2 封装函数(使用while循环)2.3 封装函数(使用递归) 1. 二分查找思想 二分法:二分查找算法是一种在有序数组中查找某一特定元素的搜索算法,其思想就是…

预处理、编译、汇编、链接

或者一步条指令 gcc helloworld.c -o helloworld 1.预处理 宏替换去注释引入头文件 #之后的语句都是预处理语句&#xff0c; #include<iostream> 将该文件的内容拷贝到现有文件中&#xff0c;结果得到一个C程序&#xff0c;通常是以.i作为文件扩展名的。 2.编译 词…

【JAVA】我们该如何规避代码中可能出现的错误?(二)

个人主页&#xff1a;【&#x1f60a;个人主页】 系列专栏&#xff1a;【❤️初识JAVA】 文章目录 前言异常方法&#xff08;Throwable类&#xff09;Throwable类的方法 捕获异常多重捕获块 前言 异常是程序中的一些错误&#xff0c;但并不是所有的错误都是异常&#xff0c;并…

Pygame游戏实战四:打砖块

介绍模块 本游戏使用的是由Pycharm中的pygame模块来实现的&#xff0c;也可以在python中运行。通过Pygame制作一个打砖块&#xff0c;通过击打砖块来得到更多的分数&#xff0c;看看这个是你小时候玩的游戏吗&#xff1f; 最小开发框架 详情请看此文章&#xff1a;Pygame游戏…

Java 性能优化之直接使用成员变量 VS 拷贝副本

背景 刷到一个大佬的 CSDN 博客&#xff0c;仔细看了一下性能优化专栏。联想到我们的日常开发工作&#xff0c;由于业务比较简单&#xff0c;很容就忽略性能问题。但是&#xff0c;性能优化的一下常见思路&#xff0c;也早有耳闻。看了一个 Java 性能优化的方法 「减少操作指令…

APISpace 手机号码归属地API接口案例代码

1.手机号码归属地API产品介绍 APISpace 的 手机号码归属地API&#xff0c;提供全国移动、联通、电信等手机号码归属地查询&#xff0c;上亿条数据囊括最新的170、166、147等号段&#xff0c;更新及时、准确度高。 2.手机号码归属地API详解 2.1 接口请求 请求方式&#xff1a…

Nodejs的安装以及配置(node-v12.16.1-x64.msi)

Nodejs的安装以及配置 1、安装 node-v12.16.1-x64.msi点击安装&#xff0c;注意以下步骤 本文设置nodejs的安装的路径&#xff1a;D:\soft\nodejs 继续点击next&#xff0c;选中Add to PATH &#xff0c;旁边的英文告诉我们会把 环境变量 给我们配置好 当然也可以只选择 Nod…

虚拟机没有桥接模式--物理机WiFi不见了--注册表修复

我们知道虚拟机有三种模式&#xff1a; vmnet0 桥接模式&#xff1b;vmnet1 仅主机模式&#xff1b;vmnet8 NAT模式 我自己以前一直用的NAT模式&#xff0c;今天突然要用到桥接模式&#xff0c;发现无法切换... 我下面这个是后面弄好了的&#xff0c;最开始是没有显示桥接模式…

七月论文审稿GPT第2版:从Meta Nougat、GPT4审稿到Mistral、LongLora

前言 如此前这篇文章《学术论文GPT的源码解读与微调&#xff1a;从chatpaper、gpt_academic到七月论文审稿GPT》中的第三部分所述&#xff0c;对于论文的摘要/总结、对话、翻译、语法检查而言&#xff0c;市面上的学术论文GPT的效果虽暂未有多好&#xff0c;可至少还过得去&am…

【C++干货铺】内存管理new和delete

个人主页点击直达&#xff1a;小白不是程序媛 C系列专栏&#xff1a;C干货铺 代码仓库&#xff1a;Gitee 目录 C语言中动态内存管理方式 malloc/calloc/realloc的区别&#xff1f; C内存管理的方式 内置类型 自定义类型 operator new 和 operator delete 函数 operato…

MCU测试科普|如何进行MCU芯片测试,具体流程是什么?

MCU芯片测试系统是一种专门用于检测MCU芯片性能和质量的综合性设备。它通常由硬件和软件两部分组成&#xff0c;硬件包括测试仪器、适配器、测试夹具等&#xff0c;用于连接被测MCU芯片和测试机&#xff0c;实现高效高精度的测试。软件部分通常包括测试程序、测试管理软件等&am…

maven 上传本地jar包到nexus

maven上传命令 mvn deploy:deploy-file -DgroupIdcom.microsoft.sqlserver -DartifactIdsqljdbc4 -Dversion4.0 -Dpackagingjar -DfileC:\java\top-sdk-java-1.0.1-lib\lib\bcprov-jdk16-1.46.jar -Durlhttp://ip:port/repository/maven-releases/ -DrepositoryIdsnapshot…

【文生图】Stable Diffusion XL 1.0模型Full Fine-tuning指南(U-Net全参微调)

文章目录 前言重要教程链接以海报生成微调为例总体流程数据获取POSTER-TEXTAutoPosterCGL-DatasetPKU PosterLayoutPosterT80KMovie & TV Series & Anime Posters 数据清洗与标注模型训练模型评估生成图片样例宠物包商品海报护肤精华商品海报 一些TipsMata&#xff1a;…

MySQL的备份恢复

数据备份的重要性 1.生产环境中&#xff0c;数据的安全至关重要 任何数据的丢失都会导致非常严重的后果。 2.数据为什么会丢失 &#xff1a;程序操作&#xff0c;运算错误&#xff0c;磁盘故障&#xff0c;不可预期的事件&#xff08;地震&#xff0c;海啸&#xff09;&#x…

独立云厂商市场份额第一 | 云轴科技ZStack位居IDC云系统软件市场报告第一梯队

近日&#xff0c;全球IT市场研究和咨询公司IDC发布《中国云系统软件市场跟踪报告2023H1》报告&#xff0c;报告显示2023年上半年中国云系统软件整体市场规模达到24.08亿元&#xff0c;同比增长16.4%。其中&#xff0c;云轴科技ZStack 作为产品化的云基础软件提供商&#xff0c;…

怎么在相册里去水印?三种方法教你去除

当你查看相册时&#xff0c;有时可能会注意到一些照片上有水印&#xff0c;这可能会让人感到不满,不管你是想保存这些照片还是与他人分享&#xff0c;水印往往会影响图片的观赏效果&#xff0c;不过别担心我将向你介绍一些简单的方法&#xff0c;帮助你在相册中轻松去除这些水印…

浅谈前端自定义VectorGrid矢量瓦片样式

目录 前言 一、VectorGrid相关API介绍 1、VectorGrid 2、 LayerStyles样式详解 二、样式自动配置 1、页面定义 2、地图及PBF瓦片引入 3、矢量瓦片样式定义 4、鼠标事件交互 三、最终效果 1、自定义样式展示 2、鼠标交互 总结 前言 在上一篇博客中&#xff0c;详细讲…

6大场景,玩转ChatGPT!

文章目录 一、故事叙述提问举例 二、产品描述提问举例 三、报告撰写提问举例 四、邮件和信件撰写提问举例 五、新间稿和公告撰写提问举例 六、学术论文和专业文章撰写提问举例 本文是在GPT3.5版本下演示的 我们知道AI技术不仅能够自动生成文章和内容&#xff0c;还可以根据我们…

Postman接口测试工具,提高SpringBoot开发效率

文章目录 &#x1f33a;工具—postman⭐作用&#x1f3f3;️‍&#x1f308;安装&#x1f388;创建工作空间 &#x1f384;简单参数⭐原始方式&#x1f388;我们建立springboot项目&#xff0c;输入下面的代码&#x1f388;运行 ⭐SpringBoot方式 &#x1f384;实体参数&#x…