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

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

前言

向量数据库是构建LLM应用程序架构的关键组成部分,前端也可以这样零基础入门Pinecone - 掘金 (juejin.cn)介绍了Pinecone的基本用法。本文我们一起来使用Pinecone,构建检索增强生成系统(RAG)。

RAG

RAG全称是Retrieval-Augmented Generation,即检索增强生成。我们将Wikipedia的文章做为数据集,Embedding后存入Pinecone,再构建检索器,实现搜索。我们这里将Wikipedia的知识库提供给大模型,未来也可以把企业的私有知识库提供给LLM, 增强了LLM的检索能力,即Retrieval-Augmented。 在实现检索的同时,我们会调用OpenAI对文章内容进行总结(summarization),完成生成功能。即Generation。

我们将使用Pinecone与OpenAI构建一个经典的检索增强生成(RAG)应用。

代码

引入库及准备工作

  • 引入warnings

将会过滤掉项目中的一些警告信息,让输入更干净

arduino 复制代码
import warnings
warnings.filterwarnings['ignore']
  • 安装依赖
yaml 复制代码
# HuggingFace 数据集, 
!pip install datasets 
# pinecone 向量数据库 
!pip install pinecone-client
# 命令行工具 
!pip install tqdm
!pip install openai
  • 引入依赖库
python 复制代码
# 用于生成总结
from openai import OpenAI
# 向量数据库、pinecone 支持serverless 云服务
from pinecone import Pinecone, ServerlessSpec
# 命令行显示增强,进度条、详细信息等
from tqdm.auto import tqdm
# Abstract Syntax Tree   
import ast 
import os
# 数据处理和分析
import pandas as pd 

除了上篇文章那些核心库外, 这里还使用到了pandas,用来做数据处理和分析。

  • 实例化pinecone 连接数据库
ini 复制代码
# 创建实例  api_key 到后台取
pinecone = Pinecone(api_key="")
INDEX_NAME = 'dl-ai2'
# 如果存在, 先删除, 否则创建
# pinecone list_indexes方法会返回所有的index, 可以把index 想象成mysql 里的table
if INDEX_NAME in [index.name for index in pinecone.list_indexes()]:
    pinecone.delete_index(INDEX_NAME)
pinecone.create_index(
    # index名字
    name=INDEX_NAME,
    # openai 的向量维度是1536 上个例子用的是HuggingFace托管的免费模型 维度是384
    dimension=1536,
    # 相似度是通过 cosine 来计算
    metric='cosine',
    # 亚马逊的美国西部2区
    spec=-ServerlessSpec(cloud='aws', region='us-west-2')
)
# pinecone Index 方法可以返回相应的索引
index = pinecone.Index(INDEX_NAME)
  • 下载wikipedia数据,
python 复制代码
# wget 下载   -q  quiet 不显示下载进度条和详细信息
# - O 表示下载到哪个文件
!wget -q -O lesson2-wiki.csv.zip https://www.dropbox.com/scl/fi/yxzmsrv2sgl249zcspeqb/lesson2-wiki.csv.zip?rlkey=paehnoxjl3s5x53d1bedt4pmc&dl=0%22
# 解压缩
!unzip lesson2-wiki.csv.zip

这里是直接使用命令行工具wget下载dropbox里的zip文件,格式是csv,并重命名为lesson2-wiki.csv.zip。 因为是zip格式的文件,所以我们再使用unzip命令解压文件

  • 导入并创建数据集,pandas最擅长
ini 复制代码
# 导入wiki.csv文件  df DataFrame的意思 
# 从文件到数据集 pd可以直接加载csv文件
df = pd.read_csv('wiki.csv')
#  默认显示前五行数据, 用于测试是否加载成功。
df.head()

df 是一个Table行列式数据结构,id是唯一ID, metadata是媒体信息, vaues 是嵌入向量。

  • 上传到pinecone
ini 复制代码
# 数据容器
prepped=[]
# iterrows 可以遍历的每一行,
# df.shape 返回DataFrame 行列的数组, [0] 即总行数
# tqdm需要两个参数, 第一个是描述符, 第二个参数是总数
for i, row in tqdm(df.iterrows(), total=df.shape[0]):
    # metadata是一个JSON, ast.literal_eval 函数会将原JSON字符串数据转成JSON对象,如果转不了,就会失败, 确保符合pinecone的类型
    meta = ast.literal_eval(row['metadata'])
    preped.append({
        'id': row['id'],
        # 和metadata一样, 
        'values': ast.literal_eval(row['values']),
        'metadata':meta
    })
    # 每到200个, 添加一次
    if len(prepped) >= 200:
        index.upsert(prepped)
        prepped = []

本以为下载的csv格式数据,id,metadata,values都齐整,可以直接存, 为了数据完整性,我们还是过了一遍,学到了。index.upsert(prepped)是pinecone的存数据接口,每次存200条, 数据有点大,需要花些时间...

  • 查看index存放结果
diff 复制代码
index.describe_index_stats()

刚刚存入数据的pinecone index, 向量维度是1536(OpenAI), 总向量数量是1万条。

  • 准备OpenAI, 并编写Embedding功能函数
ini 复制代码
openai_client=OpenAI(api_key='')
# 使用的是text-embedding-ada-002  嵌入专用模型
def get_embeddings(articles, model="text-embedding-ada-002"):
    return openai_client.embeddings.create(input=articles, model=model)
  • 提出问题进行检索
ini 复制代码
query = 'what is the berlin wall?'
# 算嵌入向量
embed = get_embeddings(query)
# 查询
res = index.query(vector=embed.data[0].embedding, top_k=3, include_metadata=True, include_value=False)
# 列表推导式 拿出metadata 里的text 这里是明文
text = [r['metadata']['text'] for r in res['matches']]
# 将数组变成字符串, 用换行拼接
print('\n'.join(text))
  • 做总结生成
ini 复制代码
# 如果将问题标题做成占位符, 那这就是Prompt
# 写一篇关于这个问题的文章, 后面还会将刚刚查出来的文章放到后面
query = "write an article titled:what is the berlin wall?"
# 生成向量
embed = get_embeddings([query])
# 查询三条结果
res = index.query(vector=embed.data[0].embedding, top_k=3, include_metadata=True, include_value=False)
# 使用行列式将每条的文本取出
contexts = [
    x['metadata']['text'] for x in res['matches']
]

prompt_start - [
    "Answer the question based on the context below.\n\n" + 
    "Context:\n"
]
prompt_end=(
    f"\n\nQuestion: {query}\nAnswer:"
)
prompt = (
    prompt_start + "\n\n----\n\n".join(contexts) + 
    prompt_end
)
  • 将其发送给OpenAI来生成
ini 复制代码
# 调用的是completions 接口, 进行生成
res = openai_client.completions.create(
    # 模型是gpt-3.5-turbo-instruct 更擅长文本生成
    model="gpt-3.5-turbo-instruct",
    # 提示语
    prompt=prompt,
    # 0 表示很严谨
    temperature=0,
    # 最大tokens 减少费用
    max_tokens=636,
    # 返回一条内容
    top_p=1,
    frequency_penalty=0,
    presence_penalty=0,
    stop=None
)
print('-' * 80)
print(res.choices[0].text)

总结

  • 本文使用wget 直接下载wikipedia知识库,上篇用的是Hugging Face的datasets
  • pandas 加载并处理数据, 非常方便
  • 将问题通过封装好的get_embedd方法,先得到嵌入向量, 再在pinecone中做cosine相似度查询
  • openai 有很多模型, 比如最近的GPT-4, 多模态的dalle, 本文向量嵌入用的是text-embedding-ada-002, 文本生成用的是gpt-3.5-turbo-instruct。
  • prompt 设计, 头尾固定, 中间插入不同问题的index返回, 交给openai的completions接口生成
  • RAG = Articles + Embedding + Pinecone + OpenAI

参考资料

相关推荐
视觉语言导航6 分钟前
中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
人工智能·深度学习·无人机·具身智能
机器之心16 分钟前
「Next-Token」范式改变!刚刚,强化学习预训练来了
人工智能
(・Д・)ノ30 分钟前
python打卡day47
人工智能·深度学习
lgbisha37 分钟前
华为云Flexus+DeepSeek征文|体验华为云ModelArts快速搭建Dify-LLM应用开发平台并创建联网大模型
人工智能·ai·华为云
智驱力人工智能1 小时前
雨季智慧交通:从车辆盲区到客流统计的算法全覆盖
人工智能·科技·算法·安全·智慧城市·智慧交通·渣土车识别
深兰科技1 小时前
南昌市新建区委书记陈奕蒙会见深兰科技集团董事长陈海波一行
大数据·人工智能·ai应用·深兰科技·陈奕蒙
Xyz_Overlord1 小时前
深度学习——简介
人工智能·深度学习·机器学习
TYUT ljk1 小时前
Editing Language Model-based Knowledge Graph Embeddings
人工智能·知识图谱
智驱力人工智能1 小时前
大型活动交通拥堵治理的视觉算法应用
人工智能·算法·智慧城市·边缘计算·智慧交通·车牌识别算法·堵车识别算法
HyperAI超神经2 小时前
8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
人工智能·深度学习·机器学习·语言模型·自然语言处理·ai for science·蛋白质结构