Haystack 与 NVIDIA NIM 集成指南:Embedder、ChatGenerator 与 Ranker 组件实战解析
【免费下载链接】haystackOpen-source AI orchestration framework for building context-engineered, production-ready LLM applications. Design modular pipelines and agent workflows with explicit control over retrieval, routing, memory, and generation. Built for scalable agents, RAG, multimodal applications, semantic search, and conversational systems.项目地址: https://gitcode.com/GitHub_Trending/ha/haystack
本文围绕 Haystack 官方文档(版本 2.18 参考文档 docs-website/reference_versioned_docs/version-2.18/integrations-api/nvidia.md)中定义的 NVIDIA 集成 API,系统讲解nvidia-haystack集成包中的四大组件:文档/文本向量化(NvidiaDocumentEmbedder、NvidiaTextEmbedder)、对话生成(NvidiaChatGenerator)与重排序(NvidiaRanker)。你将掌握这些组件的全部初始化参数、运行契约、截断模式、串行化机制,以及如何将它们接入索引管道和 RAG 查询管道,构建基于 NVIDIA API Catalog 或自托管 NIM 的生产级 LLM 应用。
集成概览:一个包覆盖 Embedding / Generation / Reranking
NVIDIA 集成是 Haystack 生态中把 NVIDIA 的推理能力接入管道(Pipeline)的标准方式。它通过nvidia-haystack包提供,覆盖 LLM 应用中三个核心环节:
| 组件 | 模块路径 | 职责 | 管道中的典型位置 |
|---|---|---|---|
NvidiaDocumentEmbedder | haystack_integrations.components.embedders.nvidia | 为一组 Document 计算向量并写回每个文档的embedding字段 | 索引管道中DocumentWriter之前 |
NvidiaTextEmbedder | haystack_integrations.components.embedders.nvidia | 将单个字符串(如查询)编码为向量 | 查询/RAG 管道中向量检索器之前 |
NvidiaChatGenerator | haystack_integrations.components.generators.nvidia | 基于 NVIDIA 生成式模型完成对话补全 | ChatPromptBuilder之后 |
NvidiaRanker | haystack_integrations.components.rankers.nvidia | 依据查询对文档做语义相关性排序 | 查询管道中检索器之后 |
这些组件既支持 NVIDIA 托管的API Catalog(默认接入https://integrate.api.nvidia.com/v1),也支持自托管 NVIDIA NIM(api_url指向本地地址即可)。官方使用指南(见 NvidiaDocumentEmbedder、NvidiaTextEmbedder、NvidiaChatGenerator、NvidiaRanker)与其一一对应,可配合参考文档交叉阅读。
环境准备与密钥配置
安装集成包:
pip install nvidia-haystack组件默认通过环境变量读取配置,支持的变量如下:
| 环境变量 | 作用 | 默认行为 |
|---|---|---|
NVIDIA_API_KEY | NVIDIA NIM / API Catalog 的 API 密钥 | 各组件默认以Secret.from_env_var("NVIDIA_API_KEY")读取 |
NVIDIA_API_URL | 自定义 API 地址 | 各组件默认取该变量值,未设置时使用内置的DEFAULT_API_URL(托管 API 为https://integrate.api.nvidia.com/v1) |
NVIDIA_TIMEOUT | 请求超时时间(秒) | 未设置时timeout参数默认为 60 |
NVIDIA_MAX_RETRIES | 内部错误后的最大重试次数(仅 Chat Generator) | 未设置时默认重试 5 次 |
密钥除了走环境变量,还可以通过 Haystack 的Secret机制显式传入。Secret的完整实现见 haystack/utils/auth.py,它支持从环境变量(Secret.from_env_var(...))或明文令牌(Secret.from_token(...))构造,且不会在序列化时泄露明文值。例如:
from haystack.utils import Secret api_key = Secret.from_env_var("NVIDIA_API_KEY") # 推荐:从环境变量读取 api_key = Secret.from_token("<your-api-key>") # 显式令牌NvidiaDocumentEmbedder:为文档批量生成向量
NvidiaDocumentEmbedder负责为一批Document计算语义向量,并把结果写入每个文档的embedding字段。它通常出现在索引管道中、位于DocumentWriter之前,保证入库的文档自带可检索向量。
初始化参数
__init__( model: str | None = None, api_key: Secret | None = Secret.from_env_var("NVIDIA_API_KEY"), api_url: str = os.getenv("NVIDIA_API_URL", DEFAULT_API_URL), prefix: str = "", suffix: str = "", batch_size: int = 32, progress_bar: bool = True, meta_fields_to_embed: list[str] | None = None, embedding_separator: str = "\n", truncate: EmbeddingTruncateMode | str | None = None, timeout: float | None = None, ) -> None| 参数 | 类型 | 说明 |
|---|---|---|
model | str \| None | 使用的嵌入模型。若同时未指定模型且api_url指向本地 NIM,组件会调用/modelsAPI 自动探测并选用可用模型 |
api_key | Secret \| None | NVIDIA NIM 的 API 密钥,默认从NVIDIA_API_KEY环境变量读取 |
api_url | str | 自定义 API 地址,格式为http://host:port;托管服务默认https://integrate.api.nvidia.com/v1 |
prefix | str | 拼接到每段文本开头的字符串 |
suffix | str | 拼接到每段文本末尾的字符串 |
batch_size | int | 一次编码的 Document 数量,默认 32,不能超过 50 |
progress_bar | bool | 是否显示进度条,默认True |
meta_fields_to_embed | list[str] \| None | 需要随正文一起参与向量化的元数据字段名列表 |
embedding_separator | str | 拼接元数据字段与正文时使用的分隔符,默认换行符"\n" |
truncate | EmbeddingTruncateMode \| str \| None | 超长输入的处理策略,None时行为由模型决定 |
timeout | float \| None | 请求超时;未设置时读取NVIDIA_TIMEOUT,再缺省为 60 秒 |
运行契约
run(documents: list[Document]) -> dict[str, list[Document] | dict[str, Any]]- 入参:
documents,必须是一个Document列表,否则抛出TypeError。 - 返回值:字典包含两个键——
documents:处理完成、已带embedding的文档列表(Document数据类定义见 haystack/dataclasses/document.py);meta:用量统计等元信息。
使用示例
方式一:使用 NVIDIA API Catalog(托管模型)
from haystack import Document from haystack.utils.auth import Secret from haystack_integrations.components.embedders.nvidia import NvidiaDocumentEmbedder documents = [ Document(content="A transformer is a deep learning architecture"), Document(content="Large language models use transformer architectures"), ] embedder = NvidiaDocumentEmbedder( model="nvidia/nv-embedqa-e5-v5", api_url="https://integrate.api.nvidia.com/v1", api_key=Secret.from_token("<your-api-key>"), ) result = embedder.run(documents=documents) print(result["documents"]) print(result["meta"])方式二:对接本地自托管 NIM
将api_url指向本地服务,并把api_key设为None:
from haystack import Document from haystack_integrations.components.embedders.nvidia import NvidiaDocumentEmbedder documents = [ Document(content="A transformer is a deep learning architecture"), Document(content="Large language models use transformer architectures"), ] embedder = NvidiaDocumentEmbedder( model="nvidia/nv-embedqa-e5-v5", api_url="http://localhost:9999/v1", api_key=None, # 本地 NIM 无需密钥 ) result = embedder.run(documents=documents) print(result["documents"]) print(result["meta"])方法与属性
class_name() -> str:返回序列化用的类名标识。default_model() -> None:在本地 NIM 模式下设置默认模型(借助/modelsAPI 探测可用模型)。available_models -> list[Model]:列出与NvidiaDocumentEmbedder兼容的可用模型。warm_up() -> None:初始化组件。与文档中示例注释一致,组件会在首次运行时自动 warm up,无需显式调用。close() -> None:关闭后端并释放资源。to_dict() -> dict[str, Any]/from_dict(data) -> NvidiaDocumentEmbedder:将组件序列化为字典、或从字典反序列化,用于管道持久化与 YAML/JSON 配置加载。
NvidiaTextEmbedder:为查询字符串生成向量
NvidiaTextEmbedder将单个字符串编码为向量,适用于查询侧(query embedding)。对于区分 query 与 document 输入的模型,本组件会按query语义编码输入。
初始化参数
__init__( model: str | None = None, api_key: Secret | None = Secret.from_env_var("NVIDIA_API_KEY"), api_url: str = os.getenv("NVIDIA_API_URL", DEFAULT_API_URL), prefix: str = "", suffix: str = "", truncate: EmbeddingTruncateMode | str | None = None, timeout: float | None = None, ) -> None参数含义与NvidiaDocumentEmbedder同名参数一致(model、api_key、api_url、prefix、suffix、truncate、timeout),区别在于它没有batch_size、progress_bar、meta_fields_to_embed、embedding_separator——因为它的输入就是单一字符串。
运行契约
run(text: str) -> dict[str, list[float] | dict[str, Any]]- 入参:
text,必须是字符串,否则抛出TypeError;空字符串抛出ValueError。 - 返回值:字典包含两个键——
embedding:文本对应的向量(list[float]);meta:用量统计等元信息。
使用示例
from haystack.utils.auth import Secret from haystack_integrations.components.embedders.nvidia import NvidiaTextEmbedder embedder = NvidiaTextEmbedder( model="nvidia/nv-embedqa-e5-v5", api_url="https://integrate.api.nvidia.com/v1", api_key=Secret.from_token("<your-api-key>"), ) result = embedder.run("A transformer is a deep learning architecture") print(result["embedding"]) print(result["meta"])本地 NIM 场景同样只需将api_url指向http://localhost:9999/v1并把api_key设为None。其生命周期方法(class_name、default_model、warm_up、close、to_dict、from_dict)与available_models属性与文档嵌入器保持一致。
截断模式:EmbeddingTruncateMode
EmbeddingTruncateMode是继承自Enum的枚举,用于指定输入超出模型最大 token 长度时的处理策略:
| 取值 | 行为 |
|---|---|
START | 从输入开头开始截断 |
END | 从输入末尾开始截断 |
NONE | 不截断;输入过长时直接返回错误 |
from haystack_integrations.components.embedders.nvidia.truncate import EmbeddingTruncateMode mode = EmbeddingTruncateMode.from_str("END") # 从字符串创建截断模式from_str(string: str) -> EmbeddingTruncateMode接受"START"、"END"、"NONE"等字符串并返回对应枚举。这就是NvidiaDocumentEmbedder与NvidiaTextEmbedder的truncate参数可直接传字符串的原因。
NvidiaChatGenerator:基于 NVIDIA 模型的对话生成
NvidiaChatGenerator基于OpenAIChatGenerator实现,用于调用 NVIDIA 生成式模型完成对话补全。它采用 Haystack 的ChatMessage格式组织输入输出(ChatMessage数据类实现见 haystack/dataclasses/chat_message.py),确保对话上下文连贯。任何 NVIDIA Chat Completion API 支持的生成参数,都可以通过__init__或run中的generation_kwargs直接透传。
初始化参数
__init__( *, api_key: Secret = Secret.from_env_var("NVIDIA_API_KEY"), model: str = "nvidia/nemotron-3.5-lightning-30b-a3b", streaming_callback: StreamingCallbackT | None = None, api_base_url: str | None = os.getenv("NVIDIA_API_URL", DEFAULT_API_URL), generation_kwargs: dict[str, Any] | None = None, tools: ToolsType | None = None, timeout: float | None = None, max_retries: int | None = None, http_client_kwargs: dict[str, Any] | None = None, ) -> None| 参数 | 类型 | 说明 |
|---|---|---|
api_key | Secret | NVIDIA API 密钥,默认读取NVIDIA_API_KEY |
model | str | 对话补全模型名。2.18 参考文档默认值为nvidia/nemotron-3.5-lightning-30b-a3b;新版用户指南(NvidiaChatGenerator)中的默认模型为meta/llama-3.1-8b-instruct,使用时请以对应版本的文档为准 |
streaming_callback | StreamingCallbackT \| None | 流式回调函数,每收到一个新 token(StreamingChunk)即被调用 |
api_base_url | str \| None | NVIDIA API 基础地址,默认取NVIDIA_API_URL,缺省为托管地址 |
generation_kwargs | dict \| None | 直接透传给 NVIDIA 端点的生成参数(详见下文) |
tools | ToolsType \| None | 供模型准备调用的工具,可传Tool列表或Toolset实例 |
timeout | float \| None | NVIDIA API 调用超时 |
max_retries | int \| None | 内部错误后的最大重试次数,默认读NVIDIA_MAX_RETRIES,缺省为 5 |
http_client_kwargs | dict \| None | 用于配置自定义httpx.Client/httpx.AsyncClient的关键字参数 |
generation_kwargs 深度解析
这些参数会原样发送到 NVIDIA API 端点,常用的包括:
max_tokens:输出文本的最大 token 数。temperature:采样温度。越高越有创造性;需要确定答案时设为0(argmax 采样),创意型应用可尝试0.9。top_p:核采样(nucleus sampling)概率阈值。例如0.1表示只考虑概率质量最高的前 10% 的 token。stream:是否流式返回部分进度;若开启,token 会以 server-sent events 形式陆续返回,并以data: [DONE]结束。response_format:NIM 服务器支持有限。基础 JSON 模式{"type": "json_object"}可用于兼容模型输出合法 JSON;需要结构化 JSON 输出时使用json_schema,例如:
generation_kwargs={ "response_format": { "type": "json_schema", "json_schema": { "name": "my_schema", "schema": json_schema, # 你的 JSON Schema 定义 }, } }工具调用(Function Calling)
tools参数支持三种灵活的组合方式(详见 NvidiaChatGenerator 用户指南):
- Tool 对象列表:逐个传入独立工具;
- 单个 Toolset:直接传入整个工具集;
- 混合组合:在同一个列表中混用多个 Toolset 与独立 Tool。
from haystack.tools import Tool, Toolset from haystack_integrations.components.generators.nvidia import NvidiaChatGenerator weather_tool = Tool( name="weather", description="Get weather info", parameters=..., function=... ) news_tool = Tool( name="news", description="Get latest news", parameters=..., function=... ) math_toolset = Toolset([add_tool, subtract_tool, multiply_tool]) generator = NvidiaChatGenerator( tools=[math_toolset, weather_tool, news_tool] # Toolset 与 Tool 混合 )使用示例
基础对话:
from haystack.dataclasses import ChatMessage from haystack.utils import Secret from haystack_integrations.components.generators.nvidia import NvidiaChatGenerator generator = NvidiaChatGenerator( model="meta/llama-3.1-8b-instruct", api_key=Secret.from_env_var("NVIDIA_API_KEY"), ) messages = [ChatMessage.from_user("What's Natural Language Processing? Be brief.")] result = generator.run(messages) print(result["replies"])多模态输入(视觉模型):
from haystack.dataclasses import ChatMessage, ImageContent from haystack.utils import Secret from haystack_integrations.components.generators.nvidia import NvidiaChatGenerator llm = NvidiaChatGenerator( model="meta/llama-3.2-11b-vision-instruct", api_key=Secret.from_env_var("NVIDIA_API_KEY"), ) image = ImageContent.from_file_path("apple.jpg") user_message = ChatMessage.from_user( content_parts=[ "What does the image show? Max 5 words.", image, ], ) response = llm.run([user_message])["replies"][0].text print(response) # Red apple on straw.接入管道(配合 ChatPromptBuilder):
from haystack import Pipeline from haystack.components.builders import ChatPromptBuilder from haystack.dataclasses import ChatMessage from haystack.utils import Secret from haystack_integrations.components.generators.nvidia import NvidiaChatGenerator pipe = Pipeline() pipe.add_component("prompt_builder", ChatPromptBuilder()) pipe.add_component( "llm", NvidiaChatGenerator( model="meta/llama-3.1-8b-instruct", api_key=Secret.from_env_var("NVIDIA_API_KEY"), ), ) pipe.connect("prompt_builder", "llm") country = "Germany" system_message = ChatMessage.from_system( "You are an assistant giving out valuable information to language learners.", ) messages = [ system_message, ChatMessage.from_user("What's the official language of {{ country }}?"), ] res = pipe.run( data={ "prompt_builder": { "template_variables": {"country": country}, "template": messages, }, }, ) print(res)序列化
to_dict() -> dict[str, Any]将组件序列化为字典(YAML/JSON 管道配置即依赖此能力),供管道持久化与再加载使用。
NvidiaRanker:语义重排序组件
NvidiaRanker基于查询对一组Document做语义相关性排序,通常位于查询管道中检索器之后(例如 BM25 粗排之后做精排)。文档示例中的模型为nvidia/llama-nemotron-rerank-vl-1b-v2;按用户指南(NvidiaRanker)说明,若未设置model参数,托管端默认使用nv-rerank-qa-mistral-4b:1。
初始化参数
__init__( model: str | None = None, truncate: RankerTruncateMode | str | None = None, api_url: str = os.getenv("NVIDIA_API_URL", DEFAULT_API_URL), api_key: Secret | None = Secret.from_env_var("NVIDIA_API_KEY"), top_k: int = 5, query_prefix: str = "", document_prefix: str = "", meta_fields_to_embed: list[str] | None = None, embedding_separator: str = "\n", timeout: float | None = None, ) -> None| 参数 | 类型 | 说明 |
|---|---|---|
model | str \| None | 排序模型;不设置时使用 NIM 默认模型 |
truncate | RankerTruncateMode \| str \| None | 截断策略,可为"NONE"、"END"或RankerTruncateMode,默认跟随 NIM 默认值 |
api_key | Secret \| None | NVIDIA NIM API 密钥 |
api_url | str | 自定义 API 地址,格式http://host:port |
top_k | int | 返回的文档数量,默认 5;初始化时若top_k <= 0抛出ValueError |
query_prefix | str | 排序前拼接到查询文本开头的字符串,可用于按bge等重排序模型的要求注入指令 |
document_prefix | str | 排序前拼接到每个文档开头的字符串,同样用于模型指令 |
meta_fields_to_embed | list[str] \| None | 参与排序的文档元数据字段列表 |
embedding_separator | str | 拼接元数据字段与文档内容的分隔符,默认"\n" |
timeout | float \| None | 请求超时;未设置时读取NVIDIA_TIMEOUT,缺省 60 秒 |
运行契约
run( query: str, documents: list[Document], top_k: int | None = None ) -> dict[str, list[Document]]- 入参:
query(查询字符串)、documents(待排序文档列表)、top_k(返回数量,可覆盖初始化值)。 - 返回值:字典中的
documents键对应按相关性降序排列的文档列表。 - 异常:参数类型错误抛出
TypeError;top_k <= 0抛出ValueError。
使用示例
单独使用:
from haystack_integrations.components.rankers.nvidia import NvidiaRanker from haystack import Document from haystack.utils import Secret ranker = NvidiaRanker( model="nvidia/llama-nemotron-rerank-vl-1b-v2", api_key=Secret.from_env_var("NVIDIA_API_KEY"), ) # 组件会在首次运行时自动 warm up query = "What is the capital of Germany?" documents = [ Document(content="Berlin is the capital of Germany."), Document(content="The capital of Germany is Berlin."), Document(content="Germany's capital is Berlin."), ] result = ranker.run(query, documents, top_k=2) print(result["documents"])管道中使用(BM25 召回 + NVIDIA 精排):
from haystack import Document, Pipeline from haystack.components.retrievers.in_memory import InMemoryBM25Retriever from haystack.document_stores.in_memory import InMemoryDocumentStore from haystack_integrations.components.rankers.nvidia import NvidiaRanker docs = [ Document(content="Paris is in France"), Document(content="Berlin is in Germany"), Document(content="Lyon is in France"), ] document_store = InMemoryDocumentStore() document_store.write_documents(docs) retriever = InMemoryBM25Retriever(document_store=document_store) ranker = NvidiaRanker() document_ranker_pipeline = Pipeline() document_ranker_pipeline.add_component(instance=retriever, name="retriever") document_ranker_pipeline.add_component(instance=ranker, name="ranker") document_ranker_pipeline.connect("retriever.documents", "ranker.documents") query = "Cities in France" res = document_ranker_pipeline.run( data={ "retriever": {"query": query, "top_k": 3}, "ranker": {"query": query, "top_k": 2}, }, )关于
top_k的实践提示:上述示例中 Retriever 与 Ranker 的top_k含义不同——Retriever 的top_k决定召回多少文档,Ranker 的top_k决定最终返回/向下游传递多少文档。当 Ranker 是管道末组件时,管道输出即 Rankertop_k数量的结果。合理调小 Retriever 的top_k可减少 Ranker 处理量、加快整体管道速度。
方法与生命周期
class_name() -> str:序列化类名标识。to_dict() -> dict[str, Any]/from_dict(data) -> NvidiaRanker:序列化与反序列化。warm_up() -> None:初始化排序器;若使用 NVIDIA 托管 NIM 而缺少 API 密钥,抛出ValueError。close() -> None:关闭后端并释放资源。
重排序截断模式:RankerTruncateMode
RankerTruncateMode继承自str和Enum,用于指定排序器输入超长时的处理策略:
| 取值 | 行为 |
|---|---|
NONE | 不截断,输入过长时直接返回错误 |
END | 从输入末尾开始截断 |
from haystack_integrations.components.rankers.nvidia.truncate import RankerTruncateMode mode = RankerTruncateMode.from_str("END") # 从字符串创建from_str(string: str) -> RankerTruncateMode将字符串转换为对应枚举,因此NvidiaRanker的truncate参数可以直接传"NONE"或"END"。
组件生命周期与序列化机制
四个 NVIDIA 组件遵循 Haystack 组件规范,具备一致的运行模型:
- 自动 warm up:组件在首次
run时自动初始化后端,无需手动预热;也可显式调用warm_up()。 - 资源释放:调用
close()关闭后端并释放连接等资源。 - 可序列化:
to_dict()将组件转换为纯字典(含class_name标识),from_dict()从字典还原组件。这意味着包含 NVIDIA 组件的管道可以完整导出为 YAML/JSON 并在其他环境中重建,实现配置化部署。
深入阅读
- 关联 API 参考(版本 2.18):docs-website/reference_versioned_docs/version-2.18/integrations-api/nvidia.md
- 用户指南:NvidiaDocumentEmbedder、NvidiaTextEmbedder、NvidiaChatGenerator、NvidiaRanker
- 相关数据类与基础设施:ChatMessage、Document、Secret
- 管道核心:haystack/core/pipeline
【免费下载链接】haystackOpen-source AI orchestration framework for building context-engineered, production-ready LLM applications. Design modular pipelines and agent workflows with explicit control over retrieval, routing, memory, and generation. Built for scalable agents, RAG, multimodal applications, semantic search, and conversational systems.项目地址: https://gitcode.com/GitHub_Trending/ha/haystack
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考