embedding和向量数据库(pinecone)

news/2024/12/29 1:44:51/

embedding和向量数据库(pinecone)

玩了这么久的gpt,大家多少都会发现使用过程中有一些尴尬的点:
LLM的训练数据是有ddl的,无法获取到最新的一些信息
LLM不知道答案,开始放飞自我,出现hallucination
想应用化(客服什么的),但某些数据是不通用的,需要自己投喂
如果是一个普通用户在使用,当然是关系不大。但是如果是想将其集成然后应用化,那么这些case总是不靠谱的。微调模型(fine-tuning)成本太大,效果不一定理想。

官方还提供了一种方式,简单来说就是:

我们自己有数据集(一些边缘case的答案和时效性都可维护),先存起来
当用户输入prompt之后,先去我们的数据集中查
如果找到其中一些相关的内容,就把内容和prompt重新组合成一个新的prompt,再丢给LLM进行交流
这样最大的好处就是省token,如果我们直接进行信息投喂,token很容易就爆了(中文占得还贼多)。然后的话这样也可以对LLM进行一个成本不大的微调
这种方式就是embedding
embedding
开头其实没怎么强调embedding的概念,因为个人感觉先知道为啥用和怎么用之后,后续理解概念可能会更简单。

embedding 中文翻译是“嵌入”,在⾃然语⾔处理和机器学习领域,"embeddings"是指将单词、短语或⽂本等离散变量转换成连续向量空间的过程。这个向量空间通常被称为嵌⼊空间(embedding space),⽽⽣成的向量则称为嵌⼊向量(embedding vector)或向量嵌⼊(vector embedding)。

刚开始看有点懵,其实我们上面的核心问题就是:怎么在我们的数据集中检索到和prompt相似的内容?

平常生活中我们是如何判断两个人像不像的呢,肯定会从很多维度去对比:

粗粒度一点:外貌、性格、性别、年龄等;
细粒度一点:头发长短、单双眼皮、做事是否认真等
同样的,如何对比两段内容是不是相近的呢?当然也是从两段内容的不同维度去对比

但机器不理解内容可以从什么维度去对比呀,所以就先需要把内容转换为多维空间中的连续向量,这样两段内容就可以进行相似性判断了:距离越近,相似程度越高,距离越远,相似程度越低:

我们可以调用openAI的api来生成内容对应的embedding vectors,好用且实惠:

python调用embedding的API也很简单:

import os
import openai
openai.api_key = os.getenv("OPENAI_API_KEY")
openai.Embedding.create(model="text-embedding-ada-002",input="需要转为embedding vectors的内容"
)

向量数据库
那么这些向量存放在哪以及怎么对向量的管理和检索怎么进行呢?这就是向量数据库的职责,相比于关系型数据库,向量数据库更擅长进行相似性的搜索,以及在数据存储量上也存在优势。

向量数据库可能每个人用的都不一样,我使用的是pinecone,其他还有Milvus、Zilliz啥的,没用过就不介绍了(主要是pingcone免费版申请直接就秒过了)

pinecone官网:https://www.pinecone.io/

pinecone文档:Python Client

进去之后免费版需要申请,不过应该挺好过。付费版好像是70刀一个月

创建索引

索引名称:符合规范即可

特征维度:就是向量的数组长度,openAi将内容转成向量之后的长度是1536,所以我配置的是1536

度量距离指标:就是上面说的计算向量之间距离的方式,三种方式的差异如下:

创建索引完成之后等待一会就好了,然后就可以本地环境安装依赖,对着文档crud了:

pip3 install pinecone-client
术语
Index:是Pinecone中向量数据的最高层组织单位。它接受和存储向量,服务于对其包含的向量的查询,并对它的内容进行其他向量操作。每个索引至少运行在一个pod上
Pod:用于运行 Pinecone 服务的预配置硬件单元。每个索引在一个或多个 pod 上运行。通常,更多的 pod 意味着更多的存储容量、更低的延迟和更高的吞吐量。您还可以创建不同大小的 pod
Collections:集合是索引的静态副本。它是一组向量和元数据的不可查询表示。您可以从索引创建集合,也可以从集合创建新索引。这个新索引可以不同于原始源索引:新索引可以有不同数量的 pod、不同的 pod 类型或不同的相似性度量
Demo实现(python)
因为不管是pinecone还是后续要写的Langchain,python的支持程度目前都更好,所以demo是用python(不过语法和js都差不多,代码逻辑也很简单,一眼就懂)

import openai
import pineconeopenai.api_key = "Your key"
pinecone.init(api_key="Your key",  environment="Your env")# 提示词
prompt="2022年卡塔尔世界杯的冠军是?"# 与LLM交流
completion = openai.ChatCompletion.create(model="gpt-3.5-turbo",messages=[{"role": "user", "content": prompt}]
)print("User: ", prompt)
print("AI: ", completion.choices[0].message.content)

AI肯定是不知道的:

然后我们在根目录新建 data/question_bank.txt作为我们测试的知识库,内容是:

已知2022年卡塔尔世界杯冠军是阿根廷
然后按照下面的逻辑:

初始化索引
获取txt文件中的数据
调用openAI的embedding接口生成embedding vectors
将embedding vectors保存到pinecone中,同时需要保存元数据
将propmt也调用openAI的embedding接口生成embedding vectors
去pinecone的索引中去检索,是否有相似的内容
将相似内容和prompt重新构造成一份新的prompt_final,丢给GPT

import openai
import pineconeopenai.api_key = "Your key"
pinecone.init(api_key="Your key",environment="Your env")# 提示词
prompt="2022卡塔尔世界杯的冠军是?"# 初始化索引
active_indexes = pinecone.list_indexes()
index = pinecone.Index(active_indexes[0])
print("****************** 初始化索引:Done ******************")# 获取知识库内容
file = open('data/question_bank.txt', 'r')
content = file.read()
file.close()
print("****************** 知识库获取:Done ******************")# 生成知识库embedding vector
data_embedding_res = openai.Embedding.create(model="text-embedding-ada-002",input=content
)
print("****************** 生成知识库embedding vector:Done ******************")# 更新知识库向量以及对应的元数据
upsertRes = index.upsert([("q1", data_embedding_res['data'][0]['embedding'], { "data": content })
])
print("****************** 更新知识库向量以及对应的元数据:Done ******************")# 生成问题embedding vector
promt_embedding_res = openai.Embedding.create(model="text-embedding-ada-002",input=prompt
)
print("****************** 生成问题embedding vector:Done ******************")# 从知识库中检索相关内容
# 返回的数据格式如下:
# {
#   'matches': [{
#     'id': 'q1',
#     'metadata': {'data': '2022年卡塔尔世界杯的冠军是卡塔尔'},
#     'score': 0.952013373,
#     'values': []
#   }],
#   'namespace': ''
# }
prompt_res = index.query(promt_embedding_res['data'][0]['embedding'],top_k=5,include_metadata=True
)
print("****************** 从知识库中检索相关内容:Done ******************")# 重新构造prompts
contexts = [item['metadata']['data'] for item in prompt_res['matches']]
prompt_final = "\n\n"+"\n\n---\n\n".join(contexts)+"\n\n-----\n\n"+prompt
print("****************** 重新构造prompts:Done ******************")# 与LLM交流
completion = openai.ChatCompletion.create(model="gpt-3.5-turbo",messages=[{"role": "user", "content": prompt_final}]
)print("User: ", prompt)
print("AI: ", completion.choices[0].message.content)

由于GPT知道了你给他的信息,所以自然也就能正确地给出answer了:

总结
上述的demo中没涉及到的还有:

知识库大了需要切片上传
需要考虑token

不过这些模块都被Langchain很好地拆分并集成了,所以等Langchain了解的差不多,还需要重新完善一下,这是一个openai的embedding的demo,可以参考一下:

https://github.com/openai/openai-cookbook/blob/main/examples/Obtain_dataset.ipynb

该说不说最近接触的这些知识对于我来说,着实有点太新鲜,加上也暂时还没在生产环境中用上哈哈,目前琢磨的不算透彻的,效率也贼低,不过总算是打开了扇窗户吧

后续得尝试着用在项目中,不然闭门造车也着实没意义


http://www.ppmy.cn/news/852997.html

相关文章

Linux rpm命令详解

rpm -aq|grep yum|xargs rpm -e --nodeps #卸载所有yum相关包 rpm常见命令参数 用法: rpm [选项...] -a&#xff1a;查询所有套件&#xff1b; -b<完成阶段><套件档>或-t <完成阶段><套件档>&#xff1a;设置包装套件的完成阶段&#xff0c;并…

苹果开发者_苹果iOS14.2/iPadOS开发者预览版下载-苹果iOS14.2/iPadOS开发者预览版Beta4固件大全下载 v1.0...

苹果开发者预览版是一款可以帮助你更新最新的苹果系统的软件&#xff0c;很多人用习惯了苹果系统感觉改不过来了&#xff0c;其实习惯这个事情&#xff0c;突然的转变对于很多人来说都会有点不习惯&#xff0c;在这里你可以自己更新一个苹果的最新系统&#xff0c;虽然这个系统…

Mac 防还原系统(设置固件密码)

分享一个给Mac设备设置固件密码的方法&#xff0c;一起来看看具体步骤吧。 1.OS X用户可以在开机的时候按住Option键&#xff0c;进入Recovery HD。注意&#xff0c;Recovery HD是OS X系统自带的急救模式&#xff0c;主要用于重装系统与修复磁盘等操作&#xff0c;删除了会有…

简单提取iOS13的ipsw固件的内置壁纸(或文件)

1.先百度下“TransMac”,下载并安装。 没看到官方网站&#xff0c;就点第一个下载就好了 2.在下载安装的同时&#xff0c;将下载的ipsw文件的后缀ipsw改成rar,然后进行解压&#xff0c;得到下面文件夹里的东西。 其中有3个后缀为dmg的文件&#xff0c;找到大小最大的那个&#…

airpods版本号_苹果更新 AirPods Pro 固件

原标题&#xff1a;苹果更新 AirPods Pro 固件 今日凌晨&#xff0c;苹果为 AirPods Pro 进行了固件升级&#xff0c;版本号由之前的 2C54/2B588 更新至 2D15。对于此次固件更新的内容仍未知&#xff0c;但有部分 AirPods Pro 用户一直抱怨前一个固件版本 2C54/2B588 的主动降噪…

「更新方法」iOS16.4更新方法及固件下载

苹果于2023年3月28日&#xff0c;正式推送了iOS 16.4、iPadOS 16.4、macOS Ventura 13.3、tvOS 16.4、watchOS 9.4等正式版更新。 至于如何更新有需要的小伙伴可以看下这篇文章。 https://mp.weixin.qq.com/s?__bizMzkyNDIzMDE3Ng&mid2247484710&idx1&sne806de391…

在苹果Mac上如何设置固件密码?

要保护MAC上数据&#xff0c;可以设置用户账户密码来阻止未经授权的用户登录。您还以使用FileVault来加密启动磁盘&#xff0c;这样在没有正确密码的情况下未经授权的用户就无法读取存储在MAC上的数据。 如果设置了固件密码&#xff0c;那么不知道这个密码的用户无法从指定启动…

不需要苹果官方支持,可重置MAC系统固件密码

安全研究人员fG!发现了一种可以重置iMac和MacBook固件密码的方法&#xff0c;并且不需要苹果公司官方的在线支持。这两款电脑都可以让用户设置一个固件密码&#xff0c;其目的是以防他人未经授权对核心设备设置进行更改。 苹果官方解锁密码 凡是密码&#xff0c;都有忘记的可能…