LangChain 剧本#
重排序对于在检索管道中实现高精度和高效率至关重要。它起着至关重要的作用,尤其是在管道包含来自不同数据存储的引文时,因为每个数据存储可能采用其自己独特的相似性评分算法。重排序有两个主要目的
- 提高每个数据存储中单个引文的准确性。
- 整合来自多个数据存储的结果,以提供一组连贯且相关的引文。
本剧本介绍了如何将 NeMo 检索器文本重排序 NIM(文本重排序 NIM)与 LangChain 结合使用,通过 NVIDIARerank
类进行文档压缩和检索。
Notebook 要求#
访问受支持的 GPU
Docker 版本 26.1.4 或更高版本
适用于 LLM 的 NVIDIA NIM 或 NVIDIA API 目录
Python 版本 3.10.12 或更高版本
Jupyter Notebook(可选)
设置#
使用以下 bash
脚本安装本剧本所需的软件包和依赖项。
cat > requirements.txt << "EOF"
faiss_cpu==1.8.0
fastapi==0.115.6
langchain==0.3.13
langchain-community==0.3.12
langchain-core==0.3.27
langchain-nvidia-ai-endpoints==0.3.7
numpy==1.26.4
sentence-transformers==3.3.1
unstructured==0.16.11
EOF
pip install -r requirements.txt
使用 NVIDIA API 目录或适用于 LLM 的 NVIDIA NIM#
使用以下示例之一来初始化本剧本的 LLM。第一个示例使用 NVIDIA API 目录;第二个示例使用适用于 LLM 的 NVIDIA NIM。您可以使用 langchain-nvidia-ai-endpoints
包中的 ChatNVIDIA
类访问任一示例的聊天模型,该包包含 LangChain 集成,用于构建使用 NVIDIA NIM for LLMs 上的模型的应用程序。有关更多信息,请参阅 ChatNVIDIA 文档。
选项 1:NVIDIA API 目录#
要使用 NVIDIA API 目录,您需要将 NVIDIA_API_KEY
设置为环境变量。有关生成和使用 API 密钥的信息,请参阅 NGC 身份验证。
import os
from langchain_nvidia_ai_endpoints import ChatNVIDIA
os.environ["NVIDIA_API_KEY"] = "nvapi-***"
llm = ChatNVIDIA(model="meta/llama-3.1-8b-instruct")
选项 2:适用于 LLM 的 NVIDIA NIM#
要使用适用于 LLM 的 NVIDIA NIM,请按照快速入门中的说明进行操作。在您的基础设施上部署 NIM 后,使用 Python ChatNVIDIA
类访问 NIM,如下例所示。
from langchain_nvidia_ai_endpoints import ChatNVIDIA
# connect to a LLM NIM running at localhost:8000, specifying a specific model
llm = ChatNVIDIA(base_url="http://127.0.0.1:8000/v1", model="meta/llama-3.1-8b-instruct")
LLM 准备就绪后,使用 LangChain 的 ChatPromptTemplate
类来构建多轮对话并格式化语言模型的输入,如下例所示。
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
prompt = ChatPromptTemplate.from_messages([
("system", (
"You are a helpful and friendly AI!"
"Your responses should be concise and no longer than two sentences."
"Say you don't know if you don't have this information."
)),
("user", "{question}")
])
chain = prompt | llm | StrOutputParser()
要在 LangChain 表达式语言 (LCEL) 链中与 LLM 交互,请使用 invoke
方法,如下例所示。
print(chain.invoke({"question": "What's the difference between a GPU and a CPU?"}))
此查询应产生类似于以下的输出
GPU,即图形处理器,是一种专门类型的处理器,旨在快速渲染和处理图形和图像。CPU,即中央处理器,是计算机的主要处理组件,负责执行计算机内部的大部分处理工作。虽然 CPU 对于通用处理任务仍然很重要,但 GPU 更适合并行处理,并且通常用于涉及图形、游戏和机器学习的任务。
接下来询问有关 NVIDIA H200 GPU 的以下问题。由于许多 LLM 的知识截止日期是 2022 年末或 2023 年初,因此该模型可能无法访问该时间范围之后的信息。
print(chain.invoke({"question": "What is the H in the NVIDIA H200?"}))
很抱歉,目前我没有关于 NVIDIA H200 中的“H”代表什么的信息。这可能是一个特定于型号的标识符或代码。您可能需要查看 NVIDIA 的官方文档或直接联系他们以获得澄清。
使用文本重排序 NIM 进行重排序#
为了回答之前的问题,构建一个简单的检索和重排序管道,以找到与查询最相关的信息片段。
加载 NVIDIA H200 数据手册,以在检索管道中使用。LangChain 提供了各种文档加载器,用于处理各种类型的文档,例如来自私有 S3 存储桶和公共网站等来源和位置的 HTML、PDF 和代码。以下示例使用 LangChain PyPDFLoader
加载有关 NVIDIA H200 Tensor Core GPU 的数据手册。
from langchain_community.document_loaders import PyPDFLoader
loader = PyPDFLoader("https://nvdam.widen.net/content/udc6mzrk7a/original/hpc-datasheet-sc23-h200-datasheet-3002446.pdf")
document = loader.load()
document[0]
加载文档后,通常会对它们进行转换。一种转换方法称为分块,它将大段文本(例如长文档)分解为较小的片段。这项技术很有价值,因为它有助于优化从向量数据库返回的内容的相关性。
LangChain 提供了各种文档转换器,例如文本分割器。以下示例使用 RecursiveCharacterTextSplitter
。RecursiveCharacterTextSplitter
根据指定的块大小将大段文本分割成较小的块。它采用递归作为其分割文本的核心机制,利用预定义的一组字符(例如“\n\n”、“\n”、“ ”和“”)来确定应在何处进行分割。该过程首先尝试使用集合中的第一个字符来分割文本。如果生成的块仍然大于所需的块大小,它将继续使用集合中的下一个字符并尝试再次分割。此过程一直持续到所有块都符合指定的最大块大小。
文本分割存在一些细微的复杂性,因为从理论上讲,语义相关的文本应该放在一起。
from langchain.text_splitter import RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=100,
separators=["\n\n", "\n", ".", ";", ",", " ", ""],
)
document_chunks = text_splitter.split_documents(document)
print("Number of chunks from the document:", len(document_chunks))
以下示例使用 LangChain 通过使用与上一个示例相同的 langchain-nvidia-ai-endpoints
包中的 NVIDIAReranking
类与文本重排序 NIM 进行交互。在使用此示例之前,请验证 NeMo 检索器文本重排序 NIM 是否正在运行。此示例使用 nvidia/llama-3.2-nv-embedqa-1b-v2
。如果您使用不同的文本重排序 NIM,请更新 model
。
from langchain_nvidia_ai_endpoints import NVIDIARerank
query = "What is the H in the NVIDIA H200?"
# Initialize and connect to a NeMo Retriever Text Reranking NIM (nvidia/llama-3.2-nv-rerankqa-1b-v2) running at localhost:8002
reranker = NVIDIARerank(model="nvidia/llama-3.2-nv-rerankqa-1b-v2",
base_url="http://127.0.0.1:8002/v1")
reranked_chunks = reranker.compress_documents(query=query,
documents=document_chunks)
下一节显示了使用文本重排序 NIM 根据查询到文档的相关性评分对文档块进行重排序的结果。
for chunks in reranked_chunks:
# Access the metadata of the document
metadata = chunks.metadata
# Get the page content
page_content = chunks.page_content
# Print the relevance score if it exists in the metadata, followed by page content
if 'relevance_score' in metadata:
print(f"Relevance Score: {metadata['relevance_score']}, Page Content: {page_content}...")
print(f"{'-' * 100}")
此命令应产生类似于以下的输出
相关性评分:11.390625,页面内容:NVIDIA H200 Tensor Core GPU | 数据手册 | 1
NVIDIA H200 Tensor Core GPU 为 AI 和 HPC 工作负载提供强大动力。更高性能和更大更快的内存 NVIDIA H200 Tensor Core GPU 通过改变游戏规则的性能和内存功能,为生成式 AI 和高性能计算 (HPC) 工作负载提供强大动力。NVIDIA H200 基于 NVIDIA Hopper™ 架构,是首款提供 141 GB HBM3e 内存(速度为 4.8 TB/秒)的 GPU,容量几乎是 NVIDIA H100 Tensor Core GPU 的两倍,内存带宽增加了 1.4 倍。H200 更大更快的内存加速了生成式 AI 和大型语言模型,同时通过更高的能源效率和更低的总拥有成本,推进了 HPC 工作负载的科学计算。通过高性能 LLM 推理解锁洞察力 在不断发展的 AI 领域,企业依靠大型语言模型来…
相关性评分:10.25,页面内容:NVIDIA H200 Tensor Core GPU | 数据手册 | 3
适用于主流企业服务器的 AI 加速,配备
H200 NVL NVIDIA H200 NVL 非常适合需要灵活配置的低功耗、风冷企业机架设计,为各种规模的 AI 和 HPC 工作负载提供加速。通过 NVIDIA NVLink™ 连接的多达四个 GPU 和 1.5 倍的内存增加,大型语言模型 (LLM) 推理可以加速高达 1.7 倍,HPC 应用程序的性能比 H100 NVL 提高高达 1.3 倍。企业级:AI 软件简化开发和部署 NVIDIA H200 NVL 附带五年 NVIDIA AI Enterprise 订阅,并简化了构建企业级 AI 就绪平台的方式。H200 加速了生产就绪型生成式 AI 解决方案的 AI 开发和部署,包括计算机视觉、语音 AI、检索增强生成 (RAG) 等。NVIDIA AI Enterprise 包括 NVIDIA NIM™,这是一组易于使用的…
相关性评分:9.109375,页面内容:NVIDIA H200 Tensor Core GPU | 数据手册 | 2
为高性能计算提供强大动力 内存带宽对于 HPC 应用程序至关重要,因为它能够实现更快的数据传输并减少复杂的处理瓶颈。对于内存密集型 HPC 应用程序(如模拟、科学研究和人工智能),H200 的更高内存带宽确保可以高效地访问和操作数据,从而使结果的实现时间加快 110 倍。初步规格。可能会有所更改。HPC MILC 数据集 NERSC Apex Medium | HGX H200 4-GPU | 双 Sapphire Rapids 8480 HPC 应用 - CP2K:数据集 H2O-32-RI-dRPA-96points | GROMACS:数据集 STMV | ICON:数据集 r2b5 | MILC:数据集 NERSC Apex Medium | Chroma:数据集 HMC Medium | Quantum Espresso:数据集 AUSURF112 | 1 个 H100 SXM | 1 个 H200 SXM。降低能耗和 TCO 随着 H200 的推出,能效和 TCO 达到了新水平。这…
相关性评分:9.109375,页面内容:NVIDIA MGX™ H200 NVL 合作伙伴和 NVIDIA 认证系统,最多 8 个 GPU
包含 NVIDIA AI Enterprise 附加组件 1. 初步规格。可能会有所更改。2. 具有稀疏性。准备好开始了吗?要了解有关 NVIDIA H200 Tensor Core GPU 的更多信息,请访问 nvidia.com/h200 © 2024 NVIDIA Corporation 及关联公司。保留所有权利。NVIDIA、NVIDIA 徽标、HGX、Hopper、MGX、NIM、NVIDIA 认证系统和 NVLink 是 NVIDIA Corporation 及其在美国和其他国家/地区的关联公司的商标和/或注册商标。其他公司和产品名称可能是与其关联的各自所有者的商标。3512650. NOV24…
相关性评分:5.125,页面内容:随着 H200 的推出,能效和 TCO 达到了新水平。
这项尖端技术提供了无与伦比的性能,所有这些都在与 H100 Tensor Core GPU 相同的功耗范围内实现。不仅更快而且更环保的 AI 工厂和超级计算系统提供了经济优势,从而推动了 AI 和科学界向前发展。初步规格。可能会有所更改。Llama2 70B:ISL 2K,OSL 128 | 吞吐量 | H100 SXM 1x GPU BS 8 | H200 SXM 1x GPU BS 32…
将文本重排序 NIM 与 LCEL 结合使用#
检索的一个挑战是,通常您不知道将数据摄取到系统时,文档存储系统将面临哪些特定查询。这意味着与查询最相关的信息可能埋藏在包含大量不相关文本的文档中。通过您的应用程序传递完整的文档可能会导致更昂贵的 LLM 调用和较差的响应。
上下文压缩是一种通过以下方式改进检索系统的技术
- 解决在摄取数据时处理未知未来查询的挑战。
- 减少检索文档中不相关的文本,以提高 LLM 响应质量和效率。
- 压缩单个文档并根据查询上下文过滤掉不相关的文档。
上下文压缩检索器需要
基本检索器
文档压缩器
它的工作原理是
- 将查询传递给基本检索器
- 通过文档压缩器发送检索到的文档
- 通过减少内容或完全删除不相关的文档来缩短文档列表
以下示例演示了如何将文本重排序 NIM 用作 LangChain 的文档压缩器。
首先初始化一个嵌入模型,以嵌入查询和文档块。这里有两个示例。一个使用 NVIDIA API 目录,另一个使用文本嵌入 NIM。
选项 1:NVIDIA API 目录#
要使用 NVIDIA API 目录,如果您在剧本的第一部分初始化 LLM 时尚未设置 NVIDIA_API_KEY
作为环境变量,请设置它。有关如何生成 API 密钥的信息,请参阅 NGC 身份验证。
import os
from langchain_nvidia_ai_endpoints import NVIDIAEmbeddings
# Set the NVIDIA_API_KEY environment variable if it hasn't been set already
# os.environ["NVIDIA_API_KEY"] = "nvapi-***"
embedding_model = NVIDIAEmbeddings(model="nvidia/llama-3.2-nv-embedqa-1b-v2")
选项 2:文本嵌入 NIM#
要使用文本嵌入 NIM,请按照(快速入门)中的说明进行操作。在您的基础设施上部署 NIM 后,您可以使用 NVIDIAEmbeddings
类访问它,如下例所示。
from langchain_nvidia_ai_endpoints import NVIDIAEmbeddings
# Initialize and connect to a NeMo Retriever Text Embedding NIM running at localhost:8001
embedding_model = NVIDIAEmbeddings(model="nvidia/llama-3.2-nv-embedqa-1b-v2",
base_url="http://127.0.0.1:8001/v1")
接下来,我们将初始化一个简单的向量存储检索器,并存储 NVIDIA H200 数据手册
的文档块。LangChain 为大量向量存储提供支持,在此示例中我们将使用 FAISS。
from langchain_community.vectorstores import FAISS
retriever = FAISS.from_documents(document_chunks, embedding=embedding_model).as_retriever(search_kwargs={"k": 10})
通过运行以下代码,使用 NVRerank
作为文档压缩器,将基本检索器与 ContextualCompressionRetriever
类包装起来。此示例使用 llama-3.2-nv-embedqa-1b-v2
。如果您使用不同的文本重排序 NIM,请更新 model
。
from langchain.retrievers import ContextualCompressionRetriever
from langchain_nvidia_ai_endpoints import NVIDIARerank
# Re-initialize and connect to a NeMo Retriever Text Reranking NIM running at localhost:8002
compressor = NVIDIARerank(model="nvidia/llama-3.2-nv-rerankqa-1b-v2",
base_url="http://127.0.0.1:8002/v1")
compression_retriever = ContextualCompressionRetriever(
base_compressor=compressor,
base_retriever=retriever
)
接下来,再次向 LLM 询问有关 NVIDIA H200 中“H”的相同问题,但这次使用检索和重排序管道。
from langchain.chains import RetrievalQA
query = "What is the H in the NVIDIA H200?"
chain = RetrievalQA.from_chain_type(llm=llm, retriever=compression_retriever)
chain.invoke(query)
此命令应产生类似于以下的输出
{‘query’: ‘NVIDIA H200 中的 H 是什么?’,
‘result’: ‘根据提供的上下文,NVIDIA H200 中的“H”指的是 NVIDIA Hopper 架构。文本指出:“NVIDIA H200 基于 NVIDIA Hopper 架构,是首款提供 141 GB HBM3e 内存的 GPU”。’}