LLM:检索增强生成(RAG)

1 Embedding技术

  简单地说,嵌入(Embedding)思想可以视为一种尝试通过用向量来表示所有东西的“本质”的方法,其特性是“相近的事物”由相近的数表示。

1.1 文本向量(Text Embedding)

  在GPT中,文本嵌入(Text Embedding)是通过将输入文本中的每个词汇或词语转换为高维向量表示的方法。这些向量捕捉了词汇的语义信息,使得模型能够理解文本的含义并生成相关的输出。通过预训练的方式,GPT模型能够学习得到通用的文本表示,从而在各种自然语言处理任务中表现出色,包括文本生成、文本分类、问答等。

1.2 使用GPT进行Embedding

  目前OpenAI官方提供的3个文本向量模型为:

模型最大向量维度可否缩减维度
text-embedding-3-small1536
text-embedding-3-large3072
text-embedding-ada-0021536

text-embedding-3-smalltext-embedding-3-large可以通过embeddings.create中的dimensions参数调整输出的文本向量的维度。一般而言,文本向量维度越小搜索越快,而维度越大搜索越准。embeddings.create接口中的参数主要包括以下几个:

  • input: string或array。当为array时,其元素可以是字符串、整数或整数组成的array。整数会被视为一个token标记,整数组成的array会被视为一个完整的字符串。一个字符串输出一个embedding向量。
  • model: OpenAI提供的embedding模型。
  • dimension: embedding向量的维度;
  • encode-format: embedding向量的编码方式,float(默认值)或base64

具体代码举例如下(关于文本向量的相似度,GPT官方建议使用余弦相似度):

from openai import OpenAI
import os
from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv())  
client = OpenAI()
import numpy as np
from numpy.linalg import norm
def cos_sim(a, b):'''余弦距离 -- 值越接近1越相似'''return np.dot(a, b)/(norm(a)*norm(b))
def get_embeddings(texts, model="text-embedding-ada-002", dimensions=None):'''封装 OpenAI 的 Embedding 模型接口'''if model == "text-embedding-ada-002":dimensions = Noneif dimensions:data = client.embeddings.create(input=texts, model=model, dimensions=dimensions).dataelse:data = client.embeddings.create(input=texts, model=model).datareturn [x.embedding for x in data]if __name__=="__main__":vec1=np.reshape(get_embeddings(texts="你好啊")[0],(-1,1536))vec2=np.reshape(get_embeddings(texts="hello")[0],(1536,-1))print(cos_sim(vec1,vec2))

代码运行结果如下:

[[0.84943191]]

2 向量数据库

  向量数据库是一种特殊类型的数据库,专门用于存储和检索向量数据,是为了有效处理高维数据而设计的。这里要注意一点:向量数据库本身不生成向量,向量是由 Embedding 模型产生的。目前主流的向量数据库有多种:chroma、milvus等。这里以chroma为例简单介绍。

2.1 chroma安装

chroma的安装非常简单,在Python中直接使用pip install命令安装即可。具体如下:

pip install chromadb

2.2 chroma基本操作

chroma向量数据库中的集合(collection)保存一组相关文件,可以看作一个容器,用于存储和组织特定类别或主题的数据。与collection相关的操作包括以下内容:

  • 创建集合:create_collection
  • 删除集合:delete_collection
  • 获取集合:get_collection
  • 获取并创建集合:get_or_create_collection(最常用)

在collection中可以添加add、删除delect、修改modify、插入insert、更新update向量。

2.3 chroma添加向量及查找相似向量

def get_embeddings(texts, model="text-embedding-ada-002", dimensions=None):if model == "text-embedding-ada-002":dimensions = Noneif dimensions:data = client.embeddings.create(input=texts, model=model, dimensions=dimensions).dataelse:data = client.embeddings.create(input=texts, model=model).datareturn [x.embedding for x in data]chroma_client=chromadb.Client(Settings(allow_reset=True))
chroma_client.reset()
collection=chroma_client.get_or_create_collection(name="my_collection")documents=['hello','你吃早饭了吗?',"今天考了多少分?","侬好吗?"]
#向collection中添加向量
collection.add(embeddings=get_embeddings(documents),documents=documents,ids=["id1", "id2",'id3','id4'])
#查找与“你好”最相近的向量
results=collection.query(query_embeddings=get_embeddings(["你好"]),n_results=2)
print(results['documents'][0])

其输出内容为:

[‘侬好吗?’, ‘hello’]

注意:chroma等其他向量数据库能快速定位相似变量,是因为这类数据库通常执行的是近似查找,而非精确查找。

3 检索增强生成

  检索增强生成(Retrieval-Augmented Generation, RAG)是一种结合了信息检索和自然语言生成的技术。其基本思想是利用信息检索的技术,从大规模语料库(存储在向量数据库)中检索出与当前任务相关的文本片段,并将这些文本片段作为输入提供给生成模型,以引导生成模型产生更准确、更相关的文本输出。其基本框架为:在这里插入图片描述

下面给出一个具体的代码案例:

from pdfminer.high_level import extract_pages
from pdfminer.layout import LTTextContainer
import re
import chromadb
from chromadb.config import Settings
from openai import OpenAI
from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv()) 
client=OpenAI()
#从pdf中提取文档
def extract_text_from_pdf(filename,page_numbers=None,min_line_length=5):paragaphs=[]full_text=''for i,page_layout in enumerate(extract_pages(filename)):if page_numbers and i not in page_numbers:continuefor element in page_layout:if isinstance(element,LTTextContainer):full_text+=element.get_text()+'\n'buffer=''for text in full_text.split('\n'):if len(text)>1 and bool(re.search(r'\b[A-Za-z]+\b',text)):buffer+=(' '+text) if not text.endswith('-') else text.strip('-')elif buffer:paragaphs.append(buffer.lstrip(' '))buffer=''if buffer:paragaphs.appen(buffer)return paragaphs
#定义embedding函数
def get_embeddings(texts, model="text-embedding-ada-002", dimensions=None):if model == "text-embedding-ada-002":dimensions = Noneif dimensions:data = client.embeddings.create(input=texts, model=model, dimensions=dimensions).dataelse:data = client.embeddings.create(input=texts, model=model).datareturn [x.embedding for x in data]
#修改prompt模版
def bulid_prompt(prompt_template, **kwargs):prompt=prompt_templatefor k,v in kwargs.items():if isinstance(v,str):val=velif isinstance(v,list) and all(isinstance(x,str) for x in v):val='\n'.join(v)else:val=str(v)prompt=prompt.replace(f"__{k.upper()}__",val)return prompt
#调用大模型
def get_completions(prompt,model='gpt-3.5-turbo'):response=client.chat.completions.create(model=model,messages=[{"role":"user","content":prompt}],temperature=0.5,)return response.choices[0].message.contentprompt_template = """
你是一个问答机器人。
你的任务是根据下述给定的已知信息回答用户问题。
确保你的回复完全依据下述已知信息。不要编造答案。
如果下述已知信息不足以回答用户的问题,请直接回复"我无法回答您的问题"。已知信息:
__INFO__用户问:
__QUERY__请用中文回答用户问题。
"""
class RAG_BOT():def __init__(self):chroma_client=chromadb.Client(Settings(allow_reset=True))self.collection=chroma_client.get_or_create_collection(name="my_collection")def add_documents(self,documents):self.collection.add(documents=documents,embeddings=get_embeddings(documents),ids=["id"+str(i) for i in range(len(documents))])def query(self,user_query,top_n=2):results=self.collection.query(query_embeddings=get_embeddings([user_query]),n_results=top_n)prompt=bulid_prompt(prompt_template,query=user_query,info=results['documents'])return get_completions(prompt)documents=extract_text_from_pdf('/Users/sherry/Downloads/llama2.pdf')rag_bot=RAG_BOT()
rag_bot.add_documents(documents)
print(rag_bot.query("llama2有多少参数?"))

其输出结果为:

根据已知信息,Llama 2 模型有三个变种,参数量分别为 7B、13B 和 70B。

参考资料

  1. https://zhuanlan.zhihu.com/p/647646322
  2. https://guangzhengli.com/blog/zh/vector-database/
  3. https://blog.csdn.net/shebao3333/article/details/130593519

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

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

相关文章

vsphere高可用实验

实验要求: 部署高可用集群,在2个EXSI主机上,将该虚拟机断电。这台虚拟机会在另一台主机上自动起来 实验环境要求: 2台EXSI,一台ISCSI,一台vcenter,在一台EXSI上安装一台虚拟机,要求…

《富爸爸穷爸爸》笔记

每个孩子都需要得到更多的、不同的教育,他们得知道真实生活中的游戏规则,各种不同的规则当我们作为父母建议自己的孩子“去学校,好好学习,找份好工作”时,我们常常只是出于文化习惯才这么做的,大家都认为这…

【chrome扩展】简 Tab (SimpTab)‘每日一句名言’样式

背景:最初参考“每日诗词”发现总是那几句,可以更换API接口完成“每日一句名言” 声明:本人不会ajax及ccs样式,非专业人士,借助CHATGPT代码生成完成。请友善交流。 每一句名言API: "https://api.xygeng.cn/open…

Linux的学习之路:4、权限

一、Linux权限的概念 权限我们都熟悉,最常见的就是在看电视时需要vip这个就是权限,然后在Linux就是有两个权限,就是管理员也就是超级用户和普通的用户 命令:su [用户名] 功能:切换用户。 例如,要从root用户…

jdk api之WriteAbortedException基础、应用、实战

博主18年的互联网软件开发经验,从一名程序员小白逐步成为了一名架构师,我想通过平台将经验分享给大家,因此博主每天会在各个大牛网站点赞量超高的博客等寻找该技术栈的资料结合自己的经验,晚上进行用心精简、整理、总结、定稿&…

WPF中通过自定义Panel实现控件拖动

背景 看到趋时软件的公众号文章(WPF自定义Panel:让拖拽变得更简单),发现可以不通过Drag的方法来实现ListBox控件的拖动,而是通过对控件的坐标相加减去实现控件的位移等判断,因此根据文章里面的代码,边理解边…

Day80:服务攻防-中间件安全HW2023-WPS分析WeblogicJettyJenkinsCVE

目录 中间件-Jetty-CVE&信息泄漏 CVE-2021-34429(信息泄露) CVE-2021-28169(信息泄露) 中间件-Jenkins-CVE&RCE执行 cve_2017_1000353 CVE-2018-1000861 cve_2019_1003000 中间件-Weblogic-CVE&反序列化&RCE 应用金山WPS-HW2023-RCE&复现&上线…

代码随想录第30天|51. N皇后

51. N皇后 51. N 皇后 - 力扣(LeetCode) 代码随想录 (programmercarl.com) 这就是传说中的N皇后? 回溯算法安排!| LeetCode:51.N皇后_哔哩哔哩_bilibili 按照国际象棋的规则,皇后可以攻击与之处在同一行…

element-ui empty 组件源码分享

今日简单分享 empty 组件的源码实现,主要从以下三个方面: 1、empty 组件页面结构 2、empty 组件属性 3、empty 组件 slot 一、empty 组件页面结构 二、empty 组件属性 2.1 image 属性,图片地址,类型 string,无默认…

notepad++主题One Dark

<?xml version"1.0" encoding"Windows-1252" ?> <!--// # Style Name: One Dark for Notepad (Npp-1-Dark) # Author: https://60ss.github.io # Description: A close replica of the Atom "One Dark" syntax theme in Notepad. # L…

代码随想录阅读笔记-二叉树【二叉搜索树中的搜索】

题目 给定二叉搜索树&#xff08;BST&#xff09;的根节点和一个值。 你需要在BST中找到节点值等于给定值的节点。 返回以该节点为根的子树。 如果节点不存在&#xff0c;则返回 NULL。 例如&#xff0c; 在上述示例中&#xff0c;如果要找的值是 5&#xff0c;但因为没有节点…

禁用@RabbitAutoConfiguration后 @RabbitListener注解失效

最近遇到一个问题,我的@RabbitListener注解失效了,原因是底层组件原因 @SpringBootApplication(exclude = org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration.class)在排除掉自动配置之后,在代码里声明queue和exchange其实是不会自动被创建的,需要自己…

【放假第1天】采购季倒计时 2G 50/年,4G 618/3年 云服务器选购攻略 阿里云 腾讯云 京东云对比 搭建网站、数据分析

更新日期&#xff1a;4月4日&#xff08;阿里云价格回调&#xff0c;京东云采购季持续进行&#xff09; 本文纯原创&#xff0c;侵权必究 【云服务器推荐】价格对比&#xff01;阿里云 京东云 腾讯云 选购指南视频截图 《最新对比表》已更新在文章头部—腾讯云文档&#xff…

Matlab学习书籍分享

一、什么是Matlab​​&#xff1f; Matlab是一种用于数值计算、科学计算、工程设计和数据分析的高级编程语言。它提供了丰富的数学函数库&#xff0c;支持矩阵运算、信号处理、图像处理、机器学习等多种应用领域。Matlab还具有强大的图形界面&#xff0c;可以方便地进行数据可…

突破编程_C++_查找算法(红黑树查找)

1 算法题 &#xff1a;使用红黑树的数据结构在无序数组中查找指定元素 1.1 题目含义 这个题目要求实现一个红黑树&#xff08;Red-Black Tree&#xff09;&#xff0c;这是一种自平衡的二叉查找树&#xff0c;它通过颜色和一系列的调整规则来确保树的大致平衡&#xff0c;从而…

uni-app 实现仿微信界面【我的+首页聊天列表+长按菜单功能+添加菜单功能】+ 附源码

目录 【微信首页聊天列表】界面 【我的】界面 源代码&#xff1a; 文后附完整代码&#xff0c;支持一键导入 HBuilderX 示例体验 【微信首页聊天列表】界面 仿造【微信首页聊天列表 长按菜单功能 右上角添加按钮弹窗功能】&#xff0c;使用 uni-app 开发&#xff0c; 一…

深入浅出 -- 系统架构之微服务架构选型参考图

技术选型架构图 是一个用于展示项目中所采用的各种技术和组件之间关系的图表。 它通常包括以下几个部分&#xff1a; 1. 项目名称和描述&#xff1a;简要介绍项目的背景和目标。 2. 技术栈&#xff1a;列出项目中使用的主要技术和工具&#xff0c;如编程语言、框架、数据库…

[xboard]real6410-5.2 移植kernel网络驱动

文章目录 硬件电路 核心板,使用DM9000A [图片] 软件配置 问题1 / # / # ifconfig ifconfig: /proc/net/dev: No such file or directory ifconfig: socket: Function not implemented 参考https://blog.csdn.net/u011011827/article/details/115479707 问题2 / # ifconfig i…

Spring Boot程序中@JsonIgnoreProperties与@JsonIgnore的基本使用

问题由来&#xff1a; springboot项目中定义了很多类&#xff0c;我们在rest返回中直接返回或者在返回对象中使用这些类&#xff0c;spring已经使用jackson自动帮我们完成这些的to json。但是有时候自动转的json内容太多&#xff0c;或者格式不符合我们的期望&#xff0c;因此需…

JVM专题——类文件加载

本文部分内容节选自Java Guide和《深入理解Java虚拟机》, Java Guide地址: https://javaguide.cn/java/jvm/class-loading-process.html &#x1f680; 基础&#xff08;上&#xff09; → &#x1f680; 基础&#xff08;中&#xff09; → &#x1f680;基础&#xff08;下&a…