LangChain Integrates NVIDIA NIM for GPU-optimized LLM Inference in RAG

LangChain 集成 NVIDIA NIM,在 RAG 中实现 GPU 优化的 LLM 推理

阅读需时 4 分钟

大约一年半前,OpenAI 发布了 ChatGPT,真正开启了生成式 AI 时代。从那时起,我们看到了各个行业和各种企业的快速增长和广泛采用。随着企业将注意力从 LLM 应用程序的原型设计转向生产化,他们通常希望从第三方模型服务转向自托管解决方案。我们看到很多人为此苦苦挣扎,这就是 LangChain 如此兴奋地集成新的 NVIDIA NIM 推理微服务的原因。

什么是 NVIDIA NIM?

NVIDIA NIM 是一组易于使用的微服务,旨在加速生成式 AI 在企业中的部署。这种通用的运行时支持广泛的 AI 模型,从开源社区模型到 NVIDIA AI 基础模型,以及自定义 AI 模型。借助行业标准 API,开发人员只需几行代码即可快速构建企业级 AI 应用程序。NIM 构建于强大的基础上,包括推理引擎,如 NVIDIA Triton 推理服务器、NVIDIA TensorRT、NVIDIA TensorRT-LLM 和 PyTorch,旨在促进大规模无缝 AI 推理,确保您可以在任何地方自信地部署 AI 应用程序。无论是在本地还是在云端工作,NIM 都是实现大规模加速生成式 AI 推理的最快方式。

我们为什么对 NVIDIA NIM 感到兴奋?

我们对 NIM 感到兴奋有几个原因。

首先,最重要的一点:它是完全自托管的。这意味着您发送到基于 NVIDIA 模型的任何数据都不会离开您的场所。这对于基于 RAG 的应用程序尤其令人兴奋,因为在这些应用程序中,您通常会传入敏感数据。

其次:它配备了几个开箱即用的预构建容器。这使得您可以从最新的生成式 AI 模型中进行选择,而无需做太多工作。

第三:它是可扩展的。在您的笔记本电脑上本地运行模型是一回事。将其作为服务托管,并具有与托管服务提供商相同的可靠性和正常运行时间又是另一回事。幸运的是,NIM 正在为您应对这一挑战。

如何访问 NVIDIA NIM?

NIM 的入门非常简单。在 NVIDIA API 目录中,开发人员可以访问各种 AI 模型,以构建和部署生成式 AI 应用程序。NIM 作为 NVIDIA AI Enterprise 的一部分提供,NVIDIA AI Enterprise 是一个端到端的云原生软件平台,可简化生产级 AI 应用程序的开发和部署。查看 这篇博客,获取有关如何入门的分步指南。

如何在 LangChain 中使用 NVIDIA NIM?

最后,来说说有趣的部分。我们添加了一个新的集成包,支持 NIM。要开始集成,您需要安装我们专用的集成包

pip install langchain_nvidia_ai_endpoints

之后,您可以导入模型,例如

from langchain_nvidia_ai_endpoints import NVIDIAEmbeddings, ChatNVIDIA

集成示例

本文档的其余部分将重点介绍构建示例应用程序。如果您更喜欢可视化学习,可以在 此处找到视频演练。

我们将基于 LangSmith 文档的一部分构建一个 RAG 应用程序。为了使其更有趣,我们将使用一种高级检索方法:假设文档嵌入 (HyDE)。HyDE 的动机是,搜索查询可能与我们检索的文档不在相似的嵌入空间中。为了解决这个问题,我们可以使用 LLM 生成一个假设文档,然后检索与该假设文档相似的文档。

首先,我们需要安装其他一些软件包。

pip install langchain-community langchain-text-splitters faiss-cpu

然后,我们将加载一些我们想要进行 RAG 的数据 - LangSmith 文档!

from langchain_community.document_loaders import WebBaseLoader
loader = WebBaseLoader("https://langsmith.langchain.ac.cn/user_guide")

docs = loader.load()

在索引文档之前,我们可以初始化我们的嵌入模型。

from langchain_nvidia_ai_endpoints import NVIDIAEmbeddings
embeddings = NVIDIAEmbeddings()

我们现在可以执行索引步骤,使用 FAISS 向量存储。

from langchain_community.vectorstores import FAISS
from langchain_text_splitters import RecursiveCharacterTextSplitter

text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
documents = text_splitter.split_documents(docs)
vector = FAISS.from_documents(documents, embeddings)
retriever = vector.as_retriever()

然后我们可以初始化我们的 LLM

from langchain_core.prompts import ChatPromptTemplate
from langchain_nvidia_ai_endpoints import ChatNVIDIA
from langchain_core.output_parsers import StrOutputParser


model = ChatNVIDIA(model="mistral_7b")

现在,我们将创建我们的假设文档生成器。这个链包括一个提示、LLM 和一个简单的输出解析器。

hyde_template = """Even if you do not know the full answer, generate a one-paragraph hypothetical answer to the below question:

{question}"""
hyde_prompt = ChatPromptTemplate.from_template(hyde_template)
hyde_query_transformer = hyde_prompt | model | StrOutputParser()

然后我们可以将此链和原始检索器包装到一个新链中

from langchain_core.runnables import chain

@chain
def hyde_retriever(question):
    hypothetical_document = hyde_query_transformer.invoke({"question": question})
    return retriever.invoke(hypothetical_document)

然后我们可以创建链,该链将获取检索到的文档和问题,以生成最终答案

template = """Answer the question based only on the following context:
{context}

Question: {question}
"""
prompt = ChatPromptTemplate.from_template(template)
answer_chain = prompt | model | StrOutputParser()

最后,我们可以将此链与假设文档检索器结合起来,创建一个最终链

@chain
def final_chain(question):
    documents = hyde_retriever.invoke(question)
    for s in answer_chain.stream({"question": question, "context": documents}):
        yield s

请注意,我们返回令牌,以便我们可以流式传输此最终链!让我们试一试

for s in final_chain.stream("how can langsmith help with testing"):
    print(s, end="")