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.hqwc.cn/news/589768.html

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

相关文章

搭建跨境电商电商独立站如何接入1688平台API接口|通过1688API接口采集商品通过链接搜索商品下单

接口设计|接口接入 对于mall项目中商品模块的接口设计,大家可以参考项目的Swagger接口文档,以Pms开头的接口就是商品模块对应的接口。 参数说明 通用参数说明 参数不要乱传,否则不管成功失败都会扣费url说明……d.cn/平台/API类型/ 平台&…

WEB 工程路径

WEB 工程路径 相对路径 使用相对路径来解决, 一个非常重要的规则:页面所有的相对路径,在默认情况下,都会参考当前浏览器地址栏的路径 http://ip:port/工程名/ 资源来进行跳转。 相对路径带来的问题 如上图,若在a.h…

黄锈水过滤器 卫生热水工业循环水色度水处理器厂家工作原理动画

​ 1:黄锈水处理器介绍 黄锈水处理器是一种专门用于处理“黄锈水”的设备,它采用机电一体化设计,安装方便,操作简单,且运行费用极低。这种处理器主要由数码射频发生器、射频换能器、活性过滤体三部分组成,…

MySQL的基本操作(超详细)

👨‍💻作者简介:👨🏻‍🎓告别,今天 📔高质量专栏 :☕java趣味之旅 📔(零基础)专栏:MSQL数据库 欢迎🙏点赞&…

execl产品排行分析

产品排行分析 1.原数据 2.透视表 选择日期--数据--组合 效果如下: 修改透视表排版: 3.提取数据 将需要分析的数据拷贝至新的表中: 4.排序 1996年度进行排序 效果 添加名次 效果 同理处理1997年度数据和排行 新增一列: 名次变…

源聚达科技:抖音开网店步骤难吗

在数字化浪潮的推动下,抖音平台不仅成为了人们娱乐休闲的好去处,更是许多创业者眼中的“金矿”。然而,对于初次尝试在抖音开设网店的朋友来说,难免会对开店流程感到疑惑。究竟开设一个抖音网店的难度如何呢?让我们一探究竟。 要明…

04 Python进阶:MySQL-PyMySQL

什么是 PyMySQL? PyMySQL 是一个用于 Python 的纯 Python MySQL 客户端库,提供了与 MySQL 数据库进行交互的功能。PyMySQL 允许 Python 开发人员连接到 MySQL 数据库服务器,并执行诸如查询、插入、更新和删除等数据库操作。 以下是 PyMySQL …

SSL证书有哪些种类?有免费的吗?

SSL证书主要有以下几种类型: 1. 域名验证型SSL证书 (DV SSL): - 仅对申请者的域名所有权进行验证,无需人工验证申请单位的真实身份。 - 审核快速,通常适用于个人网站、小型组织或各类加密应用。 2. 组织验证型SSL证书 (OV…

9.动态规划——4.最长公共子序列(动态规划类的算法题该如何解决?)

例题——最长公共子序列(一) 分析 设最长公共子序列 d p [ i ] [ j ] dp[i][j] dp[i][j]是 S 1 S_1 S1​的前 i i i个元素,是 S 2 S_2 S2​的前 j j j个元素,那么有: 若 S 1 [ i − 1 ] S 2 [ i − 1 ] S_1[i-1]S_2[i-1] S1​[i−1]S2​[…

E-魔法猫咪(遇到过的题,做个笔记)

题解: 来自学长们思路: 其中一种正解是写单调队列。限制队列内的数单调递增,方法为每当新来的数据比当前队尾数据小时队 尾出列,直到能够插入当前值,这保证了队头永远是最小值。因此总体思路是队尾不断插入新值的同时 …

ABAP Restful接口

文章目录 ABAP Restful接口代码 ABAP Restful接口 代码 METHOD if_http_extension~handle_request.TYPES: BEGIN OF parameter,name TYPE string,value TYPE string,END OF parameter.TYPES : BEGIN OF ty_material,werks TYPE marc-werks, "工厂matnr TYPE mara-matnr, …

GDPU Java 天码行空6

一、实验目的 1、理解设计模式的基本思想; 2、理解并掌握常用的几种设计模式; 3、根据需求编写简单工厂设计模式; 4、根据需求编写适配器设计模式; 二、实验内容和步骤 1. 简单工厂模式实现计算器 请用简单工厂模式设计并编码…