前端也可以这样零基础入门Pinecone

假如你和我一样在准备24年的春招,在前端全栈外,再准备一些AI的内容是非常有必要的。24年是AI红利年,AIGC+各种岗位大厂机会会多些,同意的请点赞。也欢迎朋友们加我微信shunwuyu, 一起交流。

前言

向量数据库是构建LLM应用程序架构的关键组成部分,特别是当我们在构建RAG(检索增强生成)类应用的时候,本文我们一起来学习Pinecone。

我们将使用Pinecone来实现文本相似性搜索、图像相似性搜索、异常检测、推荐系统和混合搜索等... 马上就要能实现图搜图了,小激动的。

在传统的词汇搜索中,主要是字面或模式匹配,我们会用数据库的like查询或ElasticSearch。LLM降低了语义搜索的门槛, 我们可以根据keyword的语义来进行搜索。

自然语义是AIGC类应用的基础,它通过Embedding计算实现,Pinecone存储的就是Embedding向量。当我们将用户输入的keyword也Embedding,就可以和Pinecone里的向量进行cosine相似度计算,从而实现Semantic Search。

上图是一个Semantic Search的基本架构图。程序将Quora(问答社区) dataset (数据集),生成嵌入式向量(Embeding)后存入Pinecone。然后程序构建一个QAChain(LangChain),用户就可以向它提出上面的几个问题,得到回答。

  • 安装依赖
yaml 复制代码
# HuggingFace 数据集, 
!pip install datasets
# pinecone 向量数据库
!pip install pinecone-client
# 命令行工具
!pip install tqdm
  • 引入warning模块,忽略警告信息
arduino 复制代码
import warnings
warnings.filterwarnings('ignore')
  • 引入相关依赖
python 复制代码
# datasets 是由 HugggingFace 提供的数据库加载库,可以方便的加载社区的开源数据集,等下我们会用它加载 quora dataset
from datasets import load_dataset
# sentence_transformers是基于pytorch的句子嵌入计算
from sentence_transformers import SentenceTransformer
# pinecone 向量数据库  Pinecone是数据库实例, ServerlessSpec是云端存储
from pinecone import Pinecone, ServerlessSpec

import os 
import time
# 开源的深度学习框架
import torch
# tqdm 是命令行进度条,实时表达当前进展
from tqdm.auto import tqdm
  • 下载数据集,并截取其中的一个子集
ini 复制代码
# train的意思是训练子集中的一部分
dataset = load_dataset('quora', split='train[240000-290000]')
# 取其中五条
dataset[:5]
  • 添加问题
css 复制代码
# 准备问题空数组
questions = []
# 遍历dataset的questions 
for record in dataset['questions']:
    questions.extend(record['text'])
# list 表示有序的可变的数据集合,set去重
question = list(set(questions))
print('\n'.join(questions[:10]))
print('-'*50)
print(f'Number of questions: {len(questions)}')
  • 嵌入模型的加载
bash 复制代码
# 查看gpu 能力,如果支持,则gpu 计算,这里数据集不大, 用cpu也行
device = 'cuda' if torch.cuda.is_available() else 'cpu'
if device != 'cuda':
    print('Sorry no cuda')
# 以前用的是OpenAI, 这里使用的是SentenceTransformer,模型是all-MiniLM-L6-v2
# `all-MiniLM-L6-v2` 是一个基于Hugging Face的Sentence Transformers库中的预训练模型
model = SentenceTransformer('all-MiniLM-L6-v2', device=device)

这里我们没有用gpu能力,下载进度表表示all-MiniLM-L6-v2模型文件的下载

  • 尝试一下嵌入
ini 复制代码
# 问题
query = 'Which city is the most populated in the world?'
# 编码 即嵌入
xq = model.encode(query)
# 将句子编码为一个384维的向量
xq.shape
scss 复制代码
(384,)
  • 实例化pinecone
ini 复制代码
# 实例化pinecone
pinecone=Pinecone(api_key='515c9a29-ebf3-4b0b-ab55-e67e50cf31cc')
# pinecone里的索引,可以相像为mysql里的table
INDEX_NAME = "dl-ai"
# pinecone.list_index() 会返回我们的index列表  
if INDEX_NAME in (index.name for index in pinecone.list_index()):
    # 如果已经创建就删除
    pinecone.delete_index(INDEX_NAME)
# 创建索引
pinecone.create_index(
    name=INDEX_NAME, 
    # 维度 
    dimension=model.get_sentence_embedding_dimension(),
    # cosine 计算相似度
    metric='cosine',
    # serverless 的云服务 aws 亚马逊云  地区是 美国西部(俄勒冈)
    spec=ServerlessSpec(cloud='aws',region='us-west-2')
)
# 获得index 
index = pinecone.Index(INDEX_NAME)
打印index
index
  • 数据节片
ini 复制代码
# 一次处理200个数据
batch_size=200
# 向量上限为10000
vector_limit=10000
# 切片操作,要提取的数据是vector_limit
questions = question[:vector_limit]
  • 上传数据
ini 复制代码
# tqdm 是进度条工具, 下图显示进度条到60%, 已处理30批数据
# range 接受三个参数, 分别是起始位置,结束值, 迭代值 总共要迭代10000/200 = 50
for i in tqdm(range(0, len(questions), batch_size)):
    # 当前最后一条 i的值for 时也会增加 0 200 400....
    # min 最后一页如果< batch_size 那就取len(questions)
    i_end = min(i+batch_size, len(questions))
    # 列表推导式  ids 的值 是 ['0', '1', '2', ....]
    ids = [str(x) for x in range(i, i_end)]
    # 数据放在metadatas中, 每一项的结构都是text:text
    metadatas=[{'text': text} for text in questions[i:i_end]]
    # 基于SentenceTransformer embedding 
    xc = model.encode(questions[i:i_end])
    #`zip` 是 Python 内置函数,用于将多个可迭代对象(如列表、元组或其他序列)的元素打包成一个个元组,并返回一个 zip 对象
    records=zip(ids, xc, metadatas)
    # 添加数据
    index.upset(vectors=records)

pinecone 里存放的是一个将ids数组、嵌入向量和metadatas 打包后的元组。从下图看,已经存好了。

我们要理解下这边为啥会花那么多时间, 一是数量量比较大,二是每次都要进行模型的运行,如果显卡好,就会快很多。我这里花了3分16秒。

  • 打印查询内容
diff 复制代码
index.describe_index_stats()

存成功后,index的状态数据如下:

  • 检索器
python 复制代码
def run_query(query):
  embedding = model.encode(query).tolist()
  results = index.query(vector=embedding, top_k=10, include_metadata=True, include_value=False)
  for result in results['matches']:
    print(f"{round(result['score'], 2)}:{result['metadata']['text']}")

这里我们定义了run_query函数, 根据输入调用index上的query方法,得到结果。

  • 查询
scss 复制代码
run_query("which city has the higest population in the world?")

总结

pinecone 的基本流程跑通了,结合huggingface,完美。

参考资料

相关推荐
AI_NEW_COME8 分钟前
构建全方位大健康零售帮助中心:提升服务与体验
大数据·人工智能
IT古董14 分钟前
【机器学习】机器学习的基本分类-强化学习-Actor-Critic 方法
人工智能·机器学习·分类
martian66514 分钟前
【人工智能数学基础】——深入详解贝叶斯理论:掌握贝叶斯定理及其在分类和预测中的应用
人工智能·数学·分类·数据挖掘·贝叶斯
mingo_敏15 分钟前
深度学习中的并行策略概述:2 Data Parallelism
人工智能·深度学习
終不似少年遊*1 小时前
美国加州房价数据分析01
人工智能·python·机器学习·数据挖掘·数据分析·回归算法
区块链小八歌1 小时前
链原生 Web3 AI 网络 Chainbase 推出 AVS 主网, 拓展 EigenLayer AVS 场景
人工智能
禾高网络1 小时前
租赁小程序成品|租赁系统搭建核心功能
java·人工智能·小程序
湫ccc2 小时前
《Opencv》基础操作详解(3)
人工智能·opencv·计算机视觉
Jack_pirate3 小时前
深度学习中的特征到底是什么?
人工智能·深度学习
微凉的衣柜3 小时前
微软在AI时代的战略布局和挑战
人工智能·深度学习·microsoft