Skip to content

Fix hosted Nemotron Parse contract - #2398

Merged
charlesbluca merged 3 commits into
NVIDIA:mainfrom
charlesbluca:nvbug-6492557
Jul 27, 2026
Merged

Fix hosted Nemotron Parse contract#2398
charlesbluca merged 3 commits into
NVIDIA:mainfrom
charlesbluca:nvbug-6492557

Conversation

@charlesbluca

Copy link
Copy Markdown
Collaborator

Description

Fix the public SDK integration with the hosted NVIDIA Build Nemotron Parse model at https://integrate.api.nvidia.com/v1/chat/completions using model ID nvidia/nemotron-parse.

The SDK previously sent the self-hosted v1.2 control-token text prompt before the page image. The hosted model is image-only and rejected that request with HTTP 400: The model does not support text input. This change resolves an internal request/response contract from the endpoint and model:

  • Hosted nvidia/nemotron-parse sends image-only content, omits tools and repetition penalty, and routes returned tool-call JSON.
  • Legacy v1.0/v1.1 models preserve their markdown_bbox tool declaration and tool-call routing.
  • Versioned v1.2 and later models preserve control-token input and tagged-text routing.
  • Omitted models resolve to the hosted model on NVIDIA Build and retain the v1.2 default elsewhere; mixed hosted/self-hosted endpoint lists require an explicit model.
  • Parse-specific endpoint/model configuration now requires method="nemotron_parse" so silently ignored configuration fails early.

This restores hosted advanced PDF parsing in both inprocess and batch SDK modes while preserving existing self-hosted and local v1.2 behavior. SDK examples and the support matrix now document the distinct hosted and self-hosted model contracts.

Validation:

  • 263 passed across Nemotron Parse actor, graph, parameter, chat-client, CPU-actor, ingest-plan, and local v1.2 suites.
  • Ruff and git diff --check passed.
  • Live NVIDIA Build smoke test: image-only control returned HTTP 200 with structured markdown_bbox output; inprocess and batch each returned three pages without Parse errors and equivalent text, two tables, and two infographic-routed pictures. The old text-plus-image request retained the expected HTTP 400 as a negative control.

Checklist

  • I am familiar with the Contributing Guidelines.
  • New or existing tests cover these changes.
  • The documentation is up to date with these changes.

Signed-off-by: Charles Blackmon-Luca <20627856+charlesbluca@users.noreply.github.com>
Signed-off-by: Charles Blackmon-Luca <20627856+charlesbluca@users.noreply.github.com>
@charlesbluca
charlesbluca marked this pull request as ready for review July 23, 2026 17:30
@charlesbluca
charlesbluca requested review from a team as code owners July 23, 2026 17:30
@charlesbluca
charlesbluca requested a review from jdye64 July 23, 2026 17:30
@greptile-apps

greptile-apps Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes the public SDK integration with the hosted NVIDIA Build Nemotron Parse model by introducing a contract-resolution layer that distinguishes three profiles (hosted tool-call, legacy v1.0/v1.1 tool-call, and v1.2 tagged-text) and routes requests and responses accordingly. The core problem — the hosted model rejecting the text control-token prepended to the image — is cleanly addressed by omitting task_prompt and repetition_penalty for the hosted profile.

  • _resolve_nemotron_parse_contract detects NVIDIA Build vs. self-hosted endpoints by parsing the hostname, selects the appropriate model default, and assigns a contract profile; comma-separated load-balanced URLs are handled correctly by mirroring the existing _parse_invoke_urls logic already present in NIMClient.
  • repetition_penalty is made Optional[float] in both NIMClient and the free-function wrapper; when None, the key is omitted from the request body so the hosted endpoint is not sent an unsupported parameter.
  • A new ExtractParams validator rejects nemotron_parse_invoke_url/nemotron_parse_model when method != \"nemotron_parse\", turning previously silent misconfigurations into immediate errors.

Confidence Score: 5/5

Safe to merge. The contract resolution logic is well-tested with parametrized cases covering all three profiles, mixed-endpoint rejection, and the new hosted end-to-end path. The repetition_penalty opt-out change is narrow and backward-compatible.

All changes are clearly scoped to the Nemotron Parse inference path. The comma-separated URL handling in the new contract resolver correctly mirrors the existing NIMClient round-robin logic. The traceback chain is preserved through cause and verified by the test suite. The only notable fragility is the substring-match used to activate the user-facing hint, which is non-blocking.

No files require special attention. The nemotron_parse.py hint-activation condition is worth a follow-up to anchor it on structured error data, but it does not affect correctness of the happy path.

Important Files Changed

Filename Overview
nemo_retriever/src/nemo_retriever/operators/extract/parse/nemotron_parse.py Core change: adds contract resolution enum/dataclass, replaces the v1-only routing function with a recursive _collect heuristic used for both hosted and legacy profiles, and adds an error-hint block in the except handler. The brittle 'text input' string-match for hint activation is the only notable concern.
nemo_retriever/src/nemo_retriever/models/nim/nim.py Makes repetition_penalty optional (defaults to 1.1) and omits the key from the merged payload when None; clean and correct change that lets the hosted model skip the unsupported parameter.
nemo_retriever/src/nemo_retriever/models/nim/chat_completions.py Mirrors the repetition_penalty: Optional[float] signature change from nim.py; straightforward and consistent.
nemo_retriever/src/nemo_retriever/common/params/models.py Adds a Pydantic model_validator guard that rejects nemotron_parse_invoke_url/nemotron_parse_model when method is not nemotron_parse; intentionally makes previously-silently-ignored configuration fail early.
nemo_retriever/tests/test_actor_operators.py Well-structured new tests covering hosted contract (image-only, no repetition_penalty), contract resolution parametrize, mixed-endpoint rejection, and the mismatch hint in the error payload; test for traceback chain correctly asserts on both cause and hint.
nemo_retriever/tests/test_params_models.py Adds two tests for the new ExtractParams validation: one verifying that parse-specific fields without the parse method raise ValidationError, one verifying valid configurations pass.
nemo_retriever/tests/test_pipeline_graph.py New graph-level test confirms the hosted Build contract resolves correctly end-to-end; updated inprocess CPU actor test passes operator kwargs through and validates contract resolution.
nemo_retriever/README.md Updates the nemotron_parse example to show the explicit hosted endpoint and model ID, matching the new required parameters for the Build path.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[nemotron_parse_pages called] --> B{invoke_url set?}
    B -- No --> C[Local vLLM model path]
    B -- Yes --> D{URL contains /v1/chat/completions?}
    D -- No --> E[Image inference batch path]
    D -- Yes --> F[_resolve_nemotron_parse_contract]

    F --> G{Endpoint type detection}
    G --> H{all NVIDIA Build?}
    H -- Yes, no explicit model --> I[HOSTED_TOOL_CALL profile
model=nvidia/nemotron-parse]
    H -- No, no explicit model --> J{Any Build mixed with self-hosted?}
    J -- Yes --> K[Raise: must set explicit model]
    J -- No --> L[V1_2_TAGGED profile
model=nvidia/nemotron-parse-v1.2]
    H -- explicit model set --> M{Explicit model matches
nvidia/nemotron-parse?}
    M -- Yes --> I
    M -- Is legacy v1.0/v1.1? --> N[LEGACY_TOOL_CALL profile]
    M -- Otherwise --> L

    I --> O[Image-only content
No task_prompt
No repetition_penalty
No tools]
    N --> P[Tool-call content
tools=markdown_bbox
repetition_penalty=1.1]
    L --> Q[Text+image content
task_prompt set
repetition_penalty=1.1]

    O --> R[_route_tool_call_elements]
    N --> R
    P --> R
    Q --> S[_route_parsed_elements]

    R --> T[Output: table/chart/infographic/text]
    S --> T
Loading

Reviews (2): Last reviewed commit: "Preserve Nemotron Parse error traceback" | Re-trigger Greptile

Signed-off-by: Charles Blackmon-Luca <20627856+charlesbluca@users.noreply.github.com>
@charlesbluca
charlesbluca merged commit 3fe3b5b into NVIDIA:main Jul 27, 2026
10 checks passed
kheiss-uwzoo added a commit to kheiss-uwzoo/nv-ingest that referenced this pull request Jul 27, 2026
kheiss-uwzoo added a commit to kheiss-uwzoo/nv-ingest that referenced this pull request Jul 27, 2026
…ontract selection

After NVIDIA#2398, the library supports both NVIDIA Build and self-hosted
nemotron-parse contracts. Refresh the support-matrix note and
troubleshooting entry to describe automatic contract selection and
model/endpoint mismatch guidance instead of the pre-NVIDIA#2398 failure mode.
Use method="nemotron_parse" for the public ExtractParams parameter.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants