65.9K
CodeProject 正在变化。 阅读更多。
Home

构建和分发优雅 RAG 流水线的循序渐进指南

starIconstarIconstarIconstarIconstarIcon

5.00/5 (6投票s)

2024年7月9日

CPOL

6分钟阅读

viewsIcon

20852

在本文中,我们将使用 KitOps 构建一个检索增强生成 (RAG) 管道,集成 ChromaDB 用于嵌入,Llama 3 用于语言模型,以及 SentenceTransformer 用于嵌入模型。

引言

本教程将指导您完成使用KitOps创建时尚的检索增强生成(RAG)管道的过程。KitOps是一个开源MLOps工具,用于将RAG应用程序打包为ModelKit,以简化评估、测试和运营的协作。

除了KitOps,我们还将使用Chroma DB作为嵌入数据库,Llama 3作为大型语言模型(LLM),SentenceTransformer作为嵌入模型,以及LangChain进行分块。

背景

自然语言处理(NLP)最近已成为一个热门话题。寻找增强信息检索和生成上下文相关响应的方法,如今已成为企业组织的首要任务。

一种方法是检索增强生成,简称RAG管道。RAG结合了基于检索的系统和生成模型的优点,使开发人员能够构建智能、可扩展且高度可定制的应用程序。

从聊天机器人和虚拟助手到复杂的文本提取系统,学习创建RAG管道已成为一项有价值的技能。我们编写本教程是为了提供一个简单的入门方法。

1. 先决条件

在开始之前,请确保您拥有以下条件:

  • Python 3.9+:您可以在官方Python网站上找到并安装最新版本。
  • KitOps CLI:您可以在GitHub上找到最新版本的KitOps CLI,并遵循KitOps CLI安装指南
  • Python基础知识:本教程将使用一些Python代码,因此了解Python的基础知识是必需的。

2. 安装工具

我们的第一步是准备好所有工具,为此我们将执行以下操作:

  1. 安装ChromaDB:ChromaDB是我们的嵌入数据库。
pip install chromadb
  1. 安装LangChain:LangChain有助于对文本数据进行分块。
pip install langchain
  1. 安装Llama.cpp:这将允许我们与Llama模型进行交互。
pip install llama-cpp-python
  1. 安装SentenceTransformers:这是我们的嵌入模型框架。
pip install sentence_transformers

3. 加载Llama模型

接下来,我们需要准备好Llama模型,为此我们可以使用KitOps来加速过程,

  1. 拉取Llama 7B模型:使用KitOps下载Llama模型。
kit unpack ghcr.io/jozu-ai/llama3:8B-instruct-q4_0 -d ./llama3
  1. 加载模型:完成后,我们将在Python中加载模型。
 	from llama_cpp import Llama

llm = Llama(
    model_path="./llama3/llama3-8b-instruct-q4_0.gguf", 
    seed=1337 # set a specific seed
    # n_gpu_layers=-1, # Uncomment to use GPU acceleration
    # n_ctx=2048, # Uncomment to increase the context window
)

在此,我们初始化Llama模型,可以选择启用GPU加速并调整上下文窗口以处理更大的输入。

4. 分块

下一步是使用LangChain将数据分解成更易于管理的块。

分块是将大文本分割成更小的、更易于管理的“块”的过程。这一点很重要,因为它允许模型更有效地处理文本。使用更小的块,我们可以处理更大的数据集而不使模型过载。它还有助于保持上下文并确保文本的每个部分在处理过程中都能得到关注。分块使管理内存使用和处理时间更容易。

  1. 读取数据集:
 	from langchain.text_splitter import CharacterTextSplitter

try:
    with open("./dataset.txt", 'r') as file:
        content = file.read()
except FileNotFoundError:
    print("File not found.")
  1. 分割文本:
 	text_splitter = CharacterTextSplitter(
    chunk_size=1000,
    chunk_overlap=0,
    length_function=len,
)

split_texts = text_splitter.split_text(content)

此代码读取dataset.txt文件的内容,并将其分割成1000个字符大小的可管理块。

5. 创建和存储嵌入

我们现在将使用Chroma DB作为Vector DB来保存我们的嵌入。

嵌入是将文本数据转换为模型可以处理的数值向量的一种方式。这些向量捕获文本的语义含义,使模型能够更有效地理解和处理数据。通过创建和存储嵌入,我们确保文本数据是以模型可以轻松检索和比较的格式。像ChromaDB这样的Vector DB有助于存储嵌入,从而更容易进行搜索。

  1. 使用KitOps从ModelKit注册表中拉取SentenceTransformer嵌入模型
kit unpack ghcr.io/jozu-ai/all-minilm-l6-v2:safetensor -d minilm
  1. 初始化嵌入模型:
from sentence_transformers import SentenceTransformer
import chromadb

embedding_model = SentenceTransformer("./minilm")
  1. 编码文本块:
embeddings = embedding_model.encode(split_texts)
  1. 在ChromaDB中存储嵌入:
 	chroma_client = chromadb.Client()
collection = chroma_client.create_collection(name="dataset-collection")
collection.add(
    documents=split_texts,
    embeddings=embeddings,
    ids=[f"id{sno}" for sno in range(1, len(split_texts) + 1)]
)

此过程将把文本块编码为嵌入,并将它们存储在ChromaDB中。

6. 语义搜索

我们现在可以使用ChromaDB进行语义搜索

  1. 查询嵌入:
query = "workflow engines"
query_embedding = embedding_model.encode([query])
  1. 检索结果:
 	results = collection.query(
    query_embeddings=query_embedding,
    n_results=3,
)

print(results)

在这里,我们编码了搜索查询,并使用ChromaDB查找最相关的文本块。

7. 使用LLM生成响应

在运行RAG管道之前,最后一步是将搜索结果与用户查询一起传递给Llama模型,并提示从给定上下文中生成答案。这演示了模型如何综合检索到的上下文(语义搜索结果)中的信息并产生相关的答案。

  1. 准备提示:
contexts = results["documents"][0]
query = "Give me 3 open source workflow engines"
user_prompt = '''You are given a Query and a context, your task is to analyze the context and answer the given Query based on the context.
                        'Statement': {}
                        'Context': {}'''.format(query, contexts)
  1. 生成响应:
def generate_response(user_prompt):

    output = llm.create_chat_completion(
        messages=[{
            "role": "user",
            "content": user_prompt
        }],
    max_tokens=200
    )

    return output['choices'][0]['message']['content']

output = generate_response(user_prompt)
print(output)

8. 运行RAG管道

现在,我们可以将所有内容整合在一起并运行我们的RAG管道了,

  1. 定义RAG函数:
 	def rag(query):
    query_embedding = embedding_model.encode([query])

    results = collection.query(
        query_embeddings=query_embedding,
        n_results=3,
    )

    contexts = results["documents"][0]
    user_prompt = '''You are given a Query and a context, your task is to analyze the context and answer the given Query based on the context.
                            'Statement': {query}
                            'Context': {contexts}'''.format(query, contexts)
    output = generate_response(user_prompt)

    return output['choices'][0]['message']['content']
  1. 运行管道:
print(rag("Your Query here"))

此函数将所有内容联系起来,使您能够输入查询并获得上下文相关的响应。

如果您已经完成了这一步,恭喜您!您现在拥有一个功能齐全的RAG管道。该管道使您能够执行复杂的语义搜索并使用强大的语言模型生成响应。但是,我们还没有完成。现在我们的管道正在运行,我们希望将其打包以供分发。

为此,我们将使用ModelKits,它将有助于简化评估、测试和运营的协作。

ModelKits是一种符合OCI标准的打包格式,可实现AI/ML模型生命周期中所有必需工件的无缝共享。这包括数据集、代码、配置以及模型本身。通过标准化这些组件的打包方式,ModelKit促进了更精简的协作开发流程,该流程与几乎任何工具都兼容。您可以在此处了解有关ModelKits的更多信息。

1. 将Notebook转换为Python脚本

在开始之前,我们需要添加一个requirements.txt文件来列出管道所需的所有依赖项。为了简洁起见,我没有在此提供代码,但不用担心,您可以通过发出以下命令从我们现有的ModelKit中检索它,

kit unpack ghcr.io/jozu-ai/modelkit-examples/rag_pipeline:latest --code -d ./myrag

2. 组织您的工件,使其如下所示

接下来,我们需要正确组织我们的RAG工件。您的应该反映以下内容:

 Root-
   | - rag_pipeline #Includes the python, configuration and requirements.txt files.
   | - dataset.txt
   | - KitFile

3. 创建一个引用您的工件和基础模型的Kitfile

组织好后,我们需要创建一个Kitfile,其中列出了我们项目的所有工件。Kitfile是一种基于YAML的清单,旨在简化项目工件的封装和共享。从代码和数据集到模型及其元数据,Kitfile充当您项目的综合蓝图,确保每个组件都经过精心组织且易于访问。有关更多信息,请参阅Kitfile参考

您的Kitfile应如下所示:

manifestVersion: "1.0"
package:
  name: RAG with LLMA3
  version: 1.0.0
  authors: ["Jozu AI"]
model:
  name: llama3-8B-instruct-q4_0
  path: ghcr.io/jozu-ai/llama3:8B-instruct-q4_0 
  description: Llama 3 8B instruct model
  license: Apache 2.0
datasets:
  - path: ./dataset.txt
code: 
  - path: ./rag_pipeline
  - path: tutorial.py

4. 使用Kit将RAG管道打包并推送到您的注册表

接下来,我们需要将RAG管道打包并推送到我们选择的注册表,我们将从创建Kitfile的文件夹的根目录执行此操作。我们建议使用Docker Hub或Artifactory。

  1. 打包管道
kit pack . -t my-oci-registry/my-rag-repo/rag-tutorial:latest
  1. 推送到注册表以共享
kit push my-oci-registry/my-rag-repo/rag-tutorial:latest

5. 检索管道并获利

一旦我们推送了RAG管道,我们就可以检索并解压ModelKit,

kit unpack  ghcr.io/jozu-ai/modelkit-examples/rag_pipeline_bot:latest -d /path/to/unpacked

6. 快速尝试RAG教程

  1. 解压rag管道和基础LLM
kit unpack ghcr.io/jozu-ai/modelkit-examples/rag_pipeline:latest -d ./myrag
  1. 解压嵌入模型
kit unpack ghcr.io/jozu-ai/all-minilm-l6-v2:safetensor -d minilm
  1. 运行管道
python ./rag_pipeline/rag_user.py ./dataset.txt ./minilm llama3-8B-instruct-q4_0.gguf

恭喜!您已成功创建了一个功能齐全的RAG管道,并已将其打包以供分发。如果您觉得本教程有帮助,并希望了解有关KitOps的更多信息或为我们的项目做出贡献,请访问KitOps.ML或加入我们的Discord群组

© . All rights reserved.