在本文我们将使用Weaviate来支持我们的RAG应用程序。此外,我们还将使用本地LLM和嵌入模型,使处理私人和机密信息时更加安全和方便,这些信息不能离开你的设施。
在本文中,我们将使用LangChain从YouTube中获取播客的字幕,将其嵌入并存储在Weaviate中,然后使用本地LLM构建一个RAG应用程序。
Weaviate云服务
要按照本文中的示例进行操作,你首先需要在WCS上注册。注册后,你可以通过点击“创建集群”按钮来创建一个新的Weaviate集群。在本教程中,我们将使用免费试用计划,该计划将为你提供一个为期14天的沙盒。
在下一步中,你将需要以下两个信息来访问你的集群:
集群URL
Weaviate API密钥(在“启用-身份验证”下)
import weaviate
WEAVIATE_URL = "WEAVIATE_CLUSTER_URL"
WEAVIATE_API_KEY = "WEAVIATE_API_KEY"
client = weaviate.Client(
url=WEAVIATE_URL, auth_client_secret=weaviate.AuthApiKey(WEAVIATE_API_KEY)
)
本地嵌入和LLM模型
我对LangChain LLM框架最为熟悉,所以我们将使用这个框架来处理文档的数据输入和检索。我们将使用sentence_transformers/all-mpnet-base-v2嵌入模型和zephyr-7b-alpha llm模型。这两个模型都是开源的,并且在HuggingFace上可用。
我们将从定义嵌入模型开始,可以使用以下代码轻松从HuggingFace中检索:
# specify embedding model (using huggingface sentence transformer)
embedding_model_name = "sentence-transformers/all-mpnet-base-v2"
model_kwargs = {"device": "cuda"}
embeddings = HuggingFaceEmbeddings(
model_name=embedding_model_name,
model_kwargs=model_kwargs
)
将HubermanLabs的播客导入Weaviate
我了解到YouTube上的每个频道都有一个RSS源,可以用来获取最新10个视频的链接。由于RSS源返回的是XML,我们需要使用一个简单的Python脚本来提取链接。
import requests
import xml.etree.ElementTree as ET
URL = "https://www.youtube.com/feeds/videos.xml?channel_id=UC2D2CMWXMOVWx7giW1n3LIg"
response = requests.get(URL)
xml_data = response.content
# Parse the XML data
root = ET.fromstring(xml_data)
# Define the namespace
namespaces = {
"atom": "http://www.w3.org/2005/Atom",
"media": "http://search.yahoo.com/mrss/",
}
# Extract YouTube links
youtube_links = [
link.get("href")
for link in root.findall(".//atom:link[@rel='alternate']", namespaces)
][1:]
现在我们已经有了视频链接,可以使用LangChain的YoutubeLoader来获取字幕。接下来,和大多数RAG摄入流水线一样,在摄入之前,我们需要将文本切分成较小的部分。我们可以利用LangChain内置的文本切分功能来实现。
from langchain.document_loaders import YoutubeLoader
all_docs = []
for link in youtube_links:
# Retrieve captions
loader = YoutubeLoader.from_youtube_url(link)
docs = loader.load()
all_docs.extend(docs)
# Split documents
text_splitter = TokenTextSplitter(chunk_size=128, chunk_overlap=0)
split_docs = text_splitter.split_documents(all_docs)
# Ingest the documents into Weaviate
vector_db = Weaviate.from_documents(
split_docs, embeddings, client=client, by_text=False
)
你可以使用以下代码对向量检索器进行测试。
print(
vector_db.similarity_search(
"Which are tools to bolster your mental health?", k=3)
)
设置本地LLM
这部分代码完全从AI Geek提供的示例中复制而来。它加载了来自HuggingFace的zephyr-7b-alpha-sharded模型和它的分词器,并将其作为LangChain LLM模块加载。
# specify model huggingface mode name
model_name = "anakin87/zephyr-7b-alpha-sharded"
# function for loading 4-bit quantized model
def load_quantized_model(model_name: str):
"""
:param model_name: Name or path of the model to be loaded.
:return: Loaded quantized model.
"""
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_use_double_quant=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.bfloat16,
)
model = AutoModelForCausalLM.from_pretrained(
model_name,
load_in_4bit=True,
torch_dtype=torch.bfloat16,
quantization_config=bnb_config,
)
return model
# function for initializing tokenizer
def initialize_tokenizer(model_name: str):
"""
Initialize the tokenizer with the specified model_name.
:param model_name: Name or path of the model for tokenizer initialization.
:return: Initialized tokenizer.
"""
tokenizer = AutoTokenizer.from_pretrained(model_name, return_token_type_ids=False)
tokenizer.bos_token_id = 1 # Set beginning of sentence token id
return tokenizer
# initialize tokenizer
tokenizer = initialize_tokenizer(model_name)
# load model
model = load_quantized_model(model_name)
# specify stop token ids
stop_token_ids = [0]
# build huggingface pipeline for using zephyr-7b-alpha
pipeline = pipeline(
"text-generation",
model=model,
tokenizer=tokenizer,
use_cache=True,
device_map="auto",
max_length=2048,
do_sample=True,
top_k=5,
num_return_sequences=1,
eos_token_id=tokenizer.eos_token_id,
pad_token_id=tokenizer.eos_token_id,
)
# specify the llm
llm = HuggingFacePipeline(pipeline=pipeline)
我还没有尝试过,但是你可能可以重用这段代码来加载来自HuggingFace的其他LLMs。
构建对话链
现在我们有了向量检索和LLM,我们只需要几行代码就可以实现一个带有检索增强功能的聊天机器人。
qa_chain = RetrievalQA.from_chain_type(
llm=llm, chain_type="stuff", retriever=vector_db.as_retriever()
)
让我们现在测试一下它的表现如何:
response = qa_chain.run(
"How does one increase their mental health?")
print(response)
让我们尝试另一个:
response = qa_chain.run("How to increase your willpower?")
print(response)
总结
就在几个月前,我们大多数人都没有意识到我们能够很快在笔记本电脑或免费的Google Collab上运行LLMs。许多RAG应用程序涉及私密和机密数据,这些数据不能与第三方LLM提供商共享。在这些情况下,使用本地嵌入和LLM模型,如本文章所述,是理想的解决方案。