使用GGML和LangChain在CPU上运行量化的llama2

Meta AI 在本周二发布了最新一代开源大模型 Llama 2。对比于今年 2 月发布的 Llama 1,训练所用的 token 翻了一倍,已经达到了 2 万亿,对于使用大模型最重要的上下文长度限制,Llama 2 也翻了一倍。

在本文,我们将紧跟趋势介绍如何在本地CPU推理上运行量化版本的开源Llama 2。

量化快速入门

我们首先简单介绍一下量化的概念:

量化是一种减少用于表示数字或值的比特数的技术。由于量化减少了模型大小,因此它有利于在cpu或嵌入式系统等资源受限的设备上部署模型。

一种常用的方法是将模型权重从原始的16位浮点值量化为精度较低的8位整数值。

llm已经展示了出色的能力,但是它需要大量的CPU和内存,所以我们可以使用量化来压缩这些模型,以减少内存占用并加速计算推理,并且保持模型性能。我们将通过将权重存储在低精度数据类型中来降低模型参数的精度。

工具和数据

下图是我们将在这个项目中构建的文档知识问答应用程序的体系结构。

我们的测试文件是177页的曼联足球俱乐部2022年年报。

为了演示这个项目的量化结果,我们使用一个AMD Ryzen 5 5600X 6核处理器和16GB RAM (DDR4 3600)。

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

1、LangChain

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

2、C Transformers

C transformer是一个Python库,它为使用GGML库并在C/ c++中实现了Transformers模型。

为了解释这个事情我们首先要了解GGML:

GGML库是一个为机器学习设计的张量库,它的目标是使大型模型能够在高性能的消费级硬件上运行。这是通过整数量化支持和内置优化算法实现的。

也就是说,llm的GGML版本(二进制格式的量化模型)可以在cpu上高性能地运行。因为我们最终是使用Python的,所以还需要C Transformers库,它其实就是为GGML模型提供了Python API。

C transformer支持一组选定的开源模型,包括像Llama、GPT4All-J、MPT和Falcon等的流行模型。

3、sentence-transformer

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

4、FAISS

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

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

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

5、Poetry

Poetry用于设置虚拟环境和处理Python包管理。相比于venv,Poetry使依赖管理更加高效和无缝。这个不是只做参考,因为conda也可以。

开源LLM

开源LLM领域已经取得了巨大的进步,在HuggingFace的开放LLM排行榜上可以找到模型。为了紧跟时代,我们选择了最新的开源Llama-2-70B-Chat模型(GGML 8位):

1、Llama 2

它是C Transformers库支持的开源模型。根据LLM排行榜排名(截至2023年7月),在多个指标中表现最佳。在原来的Llama 模型设定的基准上有了巨大的改进。

2、模型尺寸:7B

LLM将主要用于总结文档块这一相对简单的任务。因此选择了7B模型,因为我们在技术上不需要过大的模型(例如65B及以上)来完成这项任务。

3、微调版:Llama-2-7B-Chat

lama-2- 7b基本模型是为文本补全而构建的,因此它缺乏在文档问答用例中实现最佳性能所需的微调。而lama-2 - 7b - chat模型是我们的理想候选,因为它是为对话和问答而设计的。该模型被许可(部分)用于商业用途。这是因为经过微调的模型lama-2- chat模型利用了公开可用的指令数据集和超过100万个人工注释。

4、8位量化

考虑到RAM被限制为16GB, 8位GGML版本是合适的,因为它只需要9.6GB的内存而原始的非量化16位模型需要约15gb的内存

8位格式也提供了与16位相当的响应质量,而其他更小的量化格式(即4位和5位)是可用的,但它们是以准确性和响应质量为代价的。

构建步骤指导

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

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

1、数据处理和矢量存储

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

 from langchain.vectorstores import FAISSfrom langchain.text_splitter import RecursiveCharacterTextSplitterfrom langchain.document_loaders import PyPDFLoader, DirectoryLoaderfrom langchain.embeddings import HuggingFaceEmbeddings# Load PDF file from data pathloader = DirectoryLoader('data/',glob="*.pdf",loader_cls=PyPDFLoader)documents = loader.load()# Split text from PDF into chunkstext_splitter = RecursiveCharacterTextSplitter(chunk_size=500,chunk_overlap=50)texts = text_splitter.split_documents(documents)# Load embeddings modelembeddings = HuggingFaceEmbeddings(model_name='sentence-transformers/all-MiniLM-L6-v2',model_kwargs={'device': 'cpu'})# Build and persist FAISS vector storevectorstore = FAISS.from_documents(texts, embeddings)vectorstore.save_local('vectorstore/db_faiss')

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

2、设置提示模板

我们使用lama-2 - 7b - chat模型,所以需要使用的提示模板。

一些chat的模板在这里不起作用,因为我们的Llama 2模型没有针对这种会话界面进行专门优化。所以我们需要使用更加直接的模板,例如:

 qa_template = """Use the following pieces of information to answer the user's question.If you don't know the answer, just say that you don't know, don't try to make up an answer.Context: {context}Question: {question}Only return the helpful answer below and nothing else.Helpful answer:"""

需要注意的是,相对较小的LLM(如7B),对格式特别敏感。当改变提示模板的空白和缩进时,可能得到了稍微不同的输出。

3、下载lama-2 - 7b - chat GGML二进制文件

由于我们将在本地运行LLM,所以需要下载量化的lama-2 - 7b - chat模型的二进制文件。

我们可以通过访问TheBloke的Llama-2-7B-Chat GGML页面来实现,然后下载名为Llama-2-7B-Chat .ggmlv3.q8_0.bin的GGML 8位量化文件。

下载的是8位量化模型的bin文件可以保存在合适的项目子文件夹中,如/models。

这个页面还显示了每种量化格式的更多信息和详细信息:

4、LangChain集成

我们将利用C transformer和LangChain进行集成。也就是说将在LangChain中使用CTransformers LLM包装器,它为GGML模型提供了一个统一的接口。

 from langchain.llms import CTransformers# Local CTransformers wrapper for Llama-2-7B-Chatllm = CTransformers(model='models/llama-2-7b-chat.ggmlv3.q8_0.bin', # Location of downloaded GGML modelmodel_type='llama', # Model type Llamaconfig={'max_new_tokens': 256,'temperature': 0.01})

这里就可以为LLM定义大量配置设置,例如最大令牌、最高k值、温度和重复惩罚等等,这些参数在我们以前的文章已经介绍过了。

这里我将温度设置为0.01而不是0,因为设置成0时,得到了奇怪的响应。

5、构建并初始化RetrievalQA

准备好提示模板和C Transformers LLM后,我们还需要编写了三个函数来构建LangChain RetrievalQA对象,该对象使我们能够执行文档问答。

 from langchain import PromptTemplatefrom langchain.chains import RetrievalQAfrom langchain.embeddings import HuggingFaceEmbeddingsfrom langchain.vectorstores import FAISS# Wrap prompt template in a PromptTemplate objectdef set_qa_prompt():prompt = PromptTemplate(template=qa_template,input_variables=['context', 'question'])return prompt# Build RetrievalQA objectdef build_retrieval_qa(llm, prompt, vectordb):dbqa = RetrievalQA.from_chain_type(llm=llm,chain_type='stuff',retriever=vectordb.as_retriever(search_kwargs={'k':2}),return_source_documents=True,chain_type_kwargs={'prompt': prompt})return dbqa# Instantiate QA objectdef setup_dbqa():embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2",model_kwargs={'device': 'cpu'})vectordb = FAISS.load_local('vectorstore/db_faiss', embeddings)qa_prompt = set_qa_prompt()dbqa = build_retrieval_qa(llm, qa_prompt, vectordb)return dbqa

6、代码整合

最后一步就是是将前面的组件组合到main.py脚本中。使用argparse模块是因为我们将从命令行将用户查询传递到应用程序中。

这里为了评估CPU推理的速度,还使用了timeit模块。

 import argparseimport timeitif __name__ == "__main__":parser = argparse.ArgumentParser()parser.add_argument('input', type=str)args = parser.parse_args()start = timeit.default_timer() # Start timer# Setup QA objectdbqa = setup_dbqa()# Parse input from argparse into QA objectresponse = dbqa({'query': args.input})end = timeit.default_timer() # End timer# Print document QA responseprint(f'\nAnswer: {response["result"]}')print('='*50) # Formatting separator# Process source documents for better displaysource_docs = response['source_documents']for i, doc in enumerate(source_docs):print(f'\nSource Document {i+1}\n')print(f'Source Text: {doc.page_content}')print(f'Document Name: {doc.metadata["source"]}')print(f'Page Number: {doc.metadata["page"]}\n')print('='* 50) # Formatting separator# Display time taken for CPU inferenceprint(f"Time to retrieve response: {end - start}")

示例查询

现在是时候对我们的应用程序进行测试了。我们用以下命令询问阿迪达斯(曼联的全球技术赞助商)应支付的最低保证金额:

 python main.py "How much is the minimum guarantee payable by adidas?"

结果如下:

我们成功地获得了正确响应(即£7.5亿),以及语义上与查询相似的相关文档块。

从启动应用程序并生成响应的总时间为31秒,这是相当不错的,因为这只是在AMD Ryzen 5600X(中低档的消费级CPU)上本地运行它。并且在gpu上运行LLM推理(例如,直接在HuggingFace上运行)也需要两位数的时间,所以在CPU上量化运行的结果是非常不错的。

作者:Kenneth Leung

相关资源

https://avoid.overfit.cn/post/9df8822ed2854176b68585226485ee0f

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

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

相关文章

【Linux】Linux服务器连接百度网盘:实现上传下载

【Linux】Linux服务器连接百度网盘:实现上传下载 文章目录 【Linux】Linux服务器连接百度网盘:实现上传下载1. 前言2. 具体过程2.1 pip 安装所需包2.2 认证(第一次连接需要认证)2.3 下载所需文件或者目录2.4 其他指令使用2.5 注意…

node.js 爬虫图片下载

主程序文件 app.js 运行主程序前需要先安装使用到的模块: npm install superagent --save axios要安装指定版,安装最新版会报错:npm install axios0.19.2 --save const {default: axios} require(axios); const fs require(fs); const superagent r…

Java导出数据到Excel

Java导出数据到Excel分3步处理 1、构建Workbook 数据 2、设置Workbook 格式 3、导出到Excel 1、构建Workbook 数据 public static void buildData(Workbook wb, List<Person> list) {Sheet sheetName wb.createSheet("sheetName");Row row sheetName.creat…

每日一题8.2 2536

2536. 子矩阵元素加 1 给你一个正整数 n &#xff0c;表示最初有一个 n x n 、下标从 0 开始的整数矩阵 mat &#xff0c;矩阵中填满了 0 。 另给你一个二维整数数组 query 。针对每个查询 query[i] [row1i, col1i, row2i, col2i] &#xff0c;请你执行下述操作&#xff1a;…

NAS私有云存储 - 搭建Nextcloud私有云盘并公网远程访问

文章目录 摘要视频教程1. 环境搭建2. 测试局域网访问3. 内网穿透3.1 ubuntu本地安装cpolar3.2 创建隧道3.3 测试公网访问 4 配置固定http公网地址4.1 保留一个二级子域名4.1 配置固定二级子域名4.3 测试访问公网固定二级子域名 摘要 Nextcloud,它是ownCloud的一个分支,是一个文…

【数据结构】单链表

&#x1f525;博客主页&#xff1a;小王又困了 &#x1f4da;系列专栏&#xff1a;数据结构 &#x1f31f;人之为学&#xff0c;不日近则日退 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 目录 一、什么是链表 1.1链表的概念及结构 1.2单链表的结构 二、链表的实现 …

[JavaScript游戏开发] 2D二维地图绘制、人物移动、障碍检测

系列文章目录 第一章 2D二维地图绘制、人物移动、障碍检测 第二章 跟随人物二维动态地图绘制、自动寻径、小地图显示(人物红点显示) 第三章 绘制冰宫宝藏地图、人物鼠标点击移动、障碍检测 第四章 绘制Q版地图、键盘上下左右地图场景切换 文章目录 系列文章目录前言一、列计划…

SpringBoot中间件—ORM(Mybatis)框架实现

目录 定义 需求背景 方案设计 代码展示 UML图 实现细节 测试验证 总结 源码地址&#xff08;已开源&#xff09;&#xff1a;https://gitee.com/sizhaohe/mini-mybatis.git 跟着源码及下述UML图来理解上手会更快&#xff0c;拒绝浮躁&#xff0c;沉下心来搞 定义&#x…

最新版本mac版Idea 激活Jerbel实现热部署

1.环境准备 1.安装docker desktop 客户端创建本地服务 2.创建guid 3.随便准备一个正确格式的邮箱 2.具体操作 1.通过提供的镜像直接搭建本地服务 docker pull qierkang/golang-reverseproxy docker run -d -p 8888:8888 qierkang/golang-reverseproxy2.guid 通过如下网址直…

干掉 “重复代码”,这三种方式绝了!

来源&#xff1a;我是程序汪 软件工程师和码农最大的区别就是平时写代码时习惯问题&#xff0c;码农很喜欢写重复代码而软件工程师会利用各种技巧去干掉重复的冗余代码。 业务同学抱怨业务开发没有技术含量&#xff0c;用不到设计模式、Java 高级特性、OOP&#xff0c;平时写…

2.2 身份鉴别与访问控制

数据参考&#xff1a;CISP官方 目录 身份鉴别基础基于实体所知的鉴别基于实体所有的鉴别基于实体特征的鉴别访问控制基础访问控制模型 一、身份鉴别基础 1、身份鉴别的概念 标识 实体身份的一种计算机表达每个实体与计算机内部的一个身份表达绑定信息系统在执行操作时&a…

AI 绘画Stable Diffusion 研究(二)sd模型ControlNet1.1 介绍与安装

部署包作者:秋葉aaaki 免责声明: 本安装包及启动器免费提供 无任何盈利目的 大家好&#xff0c;我是风雨无阻。 众所周知&#xff0c;StableDiffusion 是非常强大的AI绘图工具&#xff0c;需要详细了解StableDiffusion的朋友&#xff0c;可查看我之前的这篇文章&#xff1a; …

剑指offer48.最长不含重复字符的子字符串

我一开始的想法是创建一个大小为26的int数组&#xff0c;下标为0对应的是‘a&#xff0c;25对应的是’z&#xff0c;然后一开始都赋为-1&#xff0c;用一个for循环从头遍历这个字符串&#xff0c;通过char c s.charAt(i)获得字符&#xff0c;然后c-97&#xff0c;就是它对应的…

新抗原预测的计算工作流程

参考文献&#xff1a;Xie N, Shen G, Gao W, Huang Z, Huang C, Fu L. Neoantigens: promising targets for cancer therapy. Signal Transduct Target Ther. 2023 Jan 6;8(1):9. doi: 10.1038/s41392-022-01270-x. PMID: 36604431; PMCID: PMC9816309. 文章目录 *新抗原预测的…

小程序开发趋势:探索人工智能在小程序中的应用

第一章&#xff1a;引言 小程序开发近年来取得了快速的发展&#xff0c;成为了移动应用开发的重要一环。随着人工智能技术的飞速发展&#xff0c;越来越多的企业开始探索如何将人工智能应用于小程序开发中&#xff0c;为用户提供更智能、便捷的服务。本文将带您一起探索人工智能…

uniapp uview文件上传的文件不是文件流,该如何处理?用了uni.chooseImage预览功能要如何做

在使用uniapp开发&#xff0c;运用的ui是用uview&#xff0c;这边需要做一个身份认证&#xff0c;如下图 使用的是uview的u-upload组件&#xff0c;可是这个组件传给后端的不是文件流 后端接口需要的是文件流格式&#xff0c;后面使用了uniapp的选择图片或者拍照的api&#x…

针对高可靠性和高性能优化的1200V硅碳化物沟道MOSFET

目录 标题&#xff1a;1200V SiC Trench-MOSFET Optimized for High Reliability and High Performance摘要信息解释研究了什么文章创新点文章的研究方法文章的结论 标题&#xff1a;1200V SiC Trench-MOSFET Optimized for High Reliability and High Performance 摘要 本文详…

Android系统源码 目录结构

前言&#xff1a;Android官方在线看源码地址 https://cs.android.com/ 1.Android系统架构 Android系统架构分为五层&#xff0c;从上到下依次是应用层、应用框架层、系统运行库层、硬件抽象层和Linux内核层。 AOSP 架构 AOSP 的软件堆栈包含以下层&#xff1a; 图 1. AOSP …

MFC、Qt、WPF?该用哪个?

MFC、Qt和WPF都是流行的框架和工具&#xff0c;用于开发图形用户界面&#xff08;GUI&#xff09;应用程序。选择哪个框架取决于你的具体需求和偏好。MFC&#xff08;Microsoft Foundation Class&#xff09;是微软提供的框架&#xff0c;使用C编写&#xff0c;主要用于Windows…

51单片机学习--蜂鸣器播放音乐

由原理图可知&#xff0c;蜂鸣器BEEP与P1_5 相关&#xff0c;但其实这个原理图有错&#xff0c;实测接的是P2_5 下面这个代码就是以500HZ的频率响500ms的例子 sbit Buzzer P2^5;unsigned char KeyNum; unsigned int i;void main() {while(1){KeyNum Key();if(KeyNum){for(i …