前端也可以这样零基础入门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

参考资料

相关推荐
说私域28 分钟前
私域电商逆袭密码:AI 智能名片小程序与商城系统如何梦幻联动
人工智能·小程序
请站在我身后40 分钟前
复现Qwen-Audio 千问
人工智能·深度学习·语言模型·语音识别
love you joyfully1 小时前
目标检测与R-CNN——paddle部分
人工智能·目标检测·cnn·paddle
AI视觉网奇1 小时前
Detected at node ‘truediv‘ defined at (most recent call last): Node: ‘truediv‘
人工智能·python·tensorflow
西西弗Sisyphus1 小时前
开放世界目标检测 Grounding DINO
人工智能·目标检测·计算机视觉·大模型
芝麻粒儿2 小时前
Android修行手册 - 移动端几种常用动画方案对比
aigc·动画·lottie
抓哇能手2 小时前
数据库系统概论
数据库·人工智能·sql·mysql·计算机
canonical_entropy2 小时前
DeepSeek AI的技术理解力超越普通程序员--以Delta定制概念的理解为例
低代码·aigc·openai
火云洞红孩儿2 小时前
基于AI IDE 打造快速化的游戏LUA脚本的生成系统
c++·人工智能·inscode·游戏引擎·lua·游戏开发·脚本系统
风清扬雨2 小时前
【计算机视觉】超简单!傅里叶变换的经典案例
人工智能·计算机视觉