Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions nemo_retriever/helm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,8 @@ The retriever service picks up the in-cluster ASR endpoint when `nimOperator.aud
| `serviceConfig.pipeline.batchWorkers` | `48` | Per-pod batch worker count. Refer to [Timeouts and alleviating ingest failures](#timeouts-and-alleviating-ingest-failures) if embed or pool errors appear under load. |
| `serviceConfig.resources.maxUploadBytes` | `500000000` | Maximum upload file size in bytes; requests exceeding the limit are rejected before buffering. |
| `serviceConfig.nimEndpoints.*InvokeUrl` | `""` | Override the auto-resolved NIM Operator URL. Available knobs: `pageElementsInvokeUrl`, `tableStructureInvokeUrl`, `ocrInvokeUrl`, `embedInvokeUrl`, and `captionInvokeUrl` (refer to [Image captioning (Omni 30B)](#image-captioning-omni-30b)). |
| `serviceConfig.nimEndpoints.rerankInvokeUrl` | `""` | `/v1/ranking` endpoint used by `POST /v1/query` when `rerank=true`. This value is not auto-resolved from `nimOperator.rerankqa`. |
| `serviceConfig.nimEndpoints.rerankModelName` | `""` | Model id sent to `rerankInvokeUrl`; setting a model requires a non-empty reranker URL. |
| `serviceConfig.nimEndpoints.captionModelName` | `""` | Model id sent to the remote VLM. Auto-set to `nvidia/nemotron-3-nano-omni-30b-a3b-reasoning` whenever a caption URL is resolved. |
| `serviceConfig.llm.enabled` | `false` | Enables `POST /v1/answer`. Auto-flips to true when `nimOperator.answer_llm` is enabled and the operator URL resolves. |
| `serviceConfig.llm.apiBase` | `""` | OpenAI-compatible LLM base URL. Explicit value wins; otherwise `answer_llm` opt-in resolves to `http://answer-llm:8000/v1` by default. |
Expand Down
7 changes: 7 additions & 0 deletions nemo_retriever/helm/templates/configmap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ inherits the NIMService resource name, so the mapping is fixed:
{{- $auth := $ctx.Values.serviceConfig.auth -}}
{{- $scopeTokenSecret := $auth.scopeTokenSecret -}}
{{- $internalAuth := $ctx.Values.serviceConfig.vectordb.internalAuth -}}
{{- $rerankInvokeURL := $ctx.Values.serviceConfig.nimEndpoints.rerankInvokeUrl | default "" | trim -}}
{{- $rerankModelName := $ctx.Values.serviceConfig.nimEndpoints.rerankModelName | default "" | trim -}}
{{- if and $rerankModelName (not $rerankInvokeURL) -}}
{{- fail "serviceConfig.nimEndpoints.rerankModelName requires serviceConfig.nimEndpoints.rerankInvokeUrl." -}}
{{- end -}}
{{- if and $auth.enabled (not $auth.apiToken) (not $scopeTokenSecret.name) -}}
{{- fail "serviceConfig.auth.enabled=true requires serviceConfig.auth.scopeTokenSecret.name or serviceConfig.auth.apiToken." -}}
{{- end -}}
Expand Down Expand Up @@ -109,6 +114,8 @@ nim_endpoints:
{{- else }}
embed_model_provider_prefix: null
{{- end }}
rerank_invoke_url: {{ if .Values.serviceConfig.nimEndpoints.rerankInvokeUrl }}{{ .Values.serviceConfig.nimEndpoints.rerankInvokeUrl | quote }}{{ else }}null{{ end }}
rerank_model_name: {{ if .Values.serviceConfig.nimEndpoints.rerankModelName }}{{ .Values.serviceConfig.nimEndpoints.rerankModelName | quote }}{{ else }}null{{ end }}
Comment thread
greptile-apps[bot] marked this conversation as resolved.
caption_invoke_url: {{ if .captionURL }}{{ .captionURL | quote }}{{ else }}null{{ end }}
caption_model_name: {{ if .captionModelName }}{{ .captionModelName | quote }}{{ else }}null{{ end }}
audio_grpc_endpoint: {{ if .audioGrpcEndpoint }}{{ .audioGrpcEndpoint | quote }}{{ else }}null{{ end }}
Expand Down
2 changes: 2 additions & 0 deletions nemo_retriever/helm/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,8 @@ serviceConfig:
# nvidia/nemotron-parse or self-hosted v1.2 contract from the URL.
nemotronParseModel: ""
embedInvokeUrl: ""
rerankInvokeUrl: ""
rerankModelName: ""
# Optional remote VLM endpoint for image captioning (Nemotron 3 Nano
# Omni). Auto-wired from the in-cluster Service when
# `nimOperator.nemotron_3_nano_omni_30b_a3b_reasoning.enabled=true`
Expand Down
72 changes: 72 additions & 0 deletions nemo_retriever/tests/test_helm_rerank_endpoint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES.
# All rights reserved.
# SPDX-License-Identifier: Apache-2.0

"""Helm wiring for remote reranker configuration."""

import subprocess

import pytest
import yaml

from tests.test_helm_shared_results import _render


@pytest.mark.parametrize(
("topology_args", "expected_modes"),
(((), {"standalone"}), (("--set", "topology.mode=split"), {"gateway", "realtime", "batch"})),
)
def test_rerank_endpoint_is_rendered_in_each_service_config(topology_args, expected_modes) -> None:
url = "http://reranker.example:8000/v1/ranking"
model = "nvidia/llama-nemotron-rerank-vl-1b-v2"
documents = _render(
*topology_args,
"--set-string",
f"serviceConfig.nimEndpoints.rerankInvokeUrl={url}",
"--set-string",
f"serviceConfig.nimEndpoints.rerankModelName={model}",
)

configs = [
yaml.safe_load(document["data"]["retriever-service.yaml"])
for document in documents
if document.get("kind") == "ConfigMap" and "retriever-service.yaml" in document.get("data", {})
]

assert {config["mode"] for config in configs} == expected_modes
for config in configs:
assert config["nim_endpoints"]["rerank_invoke_url"] == url
assert config["nim_endpoints"]["rerank_model_name"] == model


def test_rerank_endpoint_allows_url_without_model() -> None:
url = "http://reranker.example:8000/v1/ranking"
documents = _render(
"--set-string",
f"serviceConfig.nimEndpoints.rerankInvokeUrl={url}",
)

config = next(
yaml.safe_load(document["data"]["retriever-service.yaml"])
for document in documents
if document.get("kind") == "ConfigMap" and "retriever-service.yaml" in document.get("data", {})
)

assert config["nim_endpoints"]["rerank_invoke_url"] == url
assert config["nim_endpoints"]["rerank_model_name"] is None


@pytest.mark.parametrize("endpoint", (None, " "))
def test_rerank_model_without_endpoint_fails_rendering(endpoint: str | None) -> None:
args = [] if endpoint is None else ["--set-string", f"serviceConfig.nimEndpoints.rerankInvokeUrl={endpoint}"]
with pytest.raises(subprocess.CalledProcessError) as error:
_render(
*args,
"--set-string",
"serviceConfig.nimEndpoints.rerankModelName=nvidia/llama-nemotron-rerank-vl-1b-v2",
)

assert (
"serviceConfig.nimEndpoints.rerankModelName requires serviceConfig.nimEndpoints.rerankInvokeUrl"
in error.value.stderr
)
Loading