diff --git a/.github/workflows/integration-test-library-mode.yml b/.github/workflows/integration-test-library-mode.yml index cff105566..6f58e46a5 100644 --- a/.github/workflows/integration-test-library-mode.yml +++ b/.github/workflows/integration-test-library-mode.yml @@ -37,7 +37,7 @@ jobs: # Hosted NIM / integrate.api auth (ExtractParams / EmbedParams read NVIDIA_API_KEY / NGC_API_KEY). NVIDIA_API_KEY: ${{ secrets.NVIDIA_BUILD_API_KEY }} PAGE_ELEMENTS_INVOKE_URL: "https://ai.api.nvidia.com/v1/cv/nvidia/nemotron-page-elements-v3" - OCR_INVOKE_URL: "https://ai.api.nvidia.com/v1/cv/nvidia/nemoretriever-ocr-v1" + OCR_INVOKE_URL: "https://ai.api.nvidia.com/v1/cv/nvidia/nemotron-ocr-v2" GRAPHIC_ELEMENTS_INVOKE_URL: "https://ai.api.nvidia.com/v1/cv/nvidia/nemotron-graphic-elements-v1" TABLE_STRUCTURE_INVOKE_URL: "https://ai.api.nvidia.com/v1/cv/nvidia/nemotron-table-structure-v1" EMBED_INVOKE_URL: "https://integrate.api.nvidia.com/v1" diff --git a/nemo_retriever/README.md b/nemo_retriever/README.md index 24c24bd94..064cbb3fd 100644 --- a/nemo_retriever/README.md +++ b/nemo_retriever/README.md @@ -178,7 +178,7 @@ python -m nemo_retriever.examples.graph_pipeline \ /your-example-dir \ --vdb-kwargs-json '{"uri":"lancedb","table_name":"nemo-retriever"}' \ --page-elements-invoke-url https://ai.api.nvidia.com/v1/cv/nvidia/nemotron-page-elements-v3 \ - --ocr-invoke-url https://ai.api.nvidia.com/v1/cv/nvidia/nemotron-ocr-v1 \ + --ocr-invoke-url https://ai.api.nvidia.com/v1/cv/nvidia/nemotron-ocr-v2 \ --table-structure-invoke-url https://ai.api.nvidia.com/v1/cv/nvidia/nemotron-table-structure-v1 \ --embed-invoke-url https://integrate.api.nvidia.com/v1/embeddings \ --embed-model-name nvidia/llama-nemotron-embed-1b-v2 @@ -537,7 +537,7 @@ ingestor = ( .extract( # for self hosted NIMs, your URLs will depend on your NIM container DNS settings page_elements_invoke_url="https://ai.api.nvidia.com/v1/cv/nvidia/nemotron-page-elements-v3", - ocr_invoke_url="https://ai.api.nvidia.com/v1/cv/nvidia/nemotron-ocr-v1", + ocr_invoke_url="https://ai.api.nvidia.com/v1/cv/nvidia/nemotron-ocr-v2", table_structure_invoke_url="https://ai.api.nvidia.com/v1/cv/nvidia/nemotron-table-structure-v1", ) .embed( diff --git a/nemo_retriever/docs/cli/README.md b/nemo_retriever/docs/cli/README.md index a84c4cf9b..2463cb527 100644 --- a/nemo_retriever/docs/cli/README.md +++ b/nemo_retriever/docs/cli/README.md @@ -109,7 +109,7 @@ export NVIDIA_API_KEY=nvapi-... retriever ingest ./data/multimodal_test.pdf \ --page-elements-invoke-url https://ai.api.nvidia.com/v1/cv/nvidia/nemotron-page-elements-v3 \ - --ocr-invoke-url https://ai.api.nvidia.com/v1/cv/nvidia/nemotron-ocr-v1 \ + --ocr-invoke-url https://ai.api.nvidia.com/v1/cv/nvidia/nemotron-ocr-v2 \ --table-structure-invoke-url https://ai.api.nvidia.com/v1/cv/nvidia/nemotron-table-structure-v1 \ --embed-invoke-url https://integrate.api.nvidia.com/v1/embeddings \ --embed-model-name nvidia/llama-nemotron-embed-1b-v2 diff --git a/nemo_retriever/src/nemo_retriever/operators/extract/chart/cpu_actor.py b/nemo_retriever/src/nemo_retriever/operators/extract/chart/cpu_actor.py index e96263af5..83be09320 100644 --- a/nemo_retriever/src/nemo_retriever/operators/extract/chart/cpu_actor.py +++ b/nemo_retriever/src/nemo_retriever/operators/extract/chart/cpu_actor.py @@ -23,13 +23,12 @@ class GraphicElementsCPUActor(AbstractOperator, CPUOperator): """CPU-only variant of :class:`GraphicElementsActor`. - Defaults to build.nvidia.com endpoints for ``nemotron-graphic-elements-v1`` - and hosted ``nemotron-ocr-v1``. Remote OCR remains URL-driven until OCR v2 - NIM is released. + Defaults to the build.nvidia.com endpoint for + ``nemotron-graphic-elements-v1`` and hosted ``nemotron-ocr-v2``. """ DEFAULT_GRAPHIC_ELEMENTS_INVOKE_URL = "https://ai.api.nvidia.com/v1/cv/nvidia/nemotron-graphic-elements-v1" - DEFAULT_OCR_INVOKE_URL = "https://ai.api.nvidia.com/v1/cv/nvidia/nemotron-ocr-v1" + DEFAULT_OCR_INVOKE_URL = "https://ai.api.nvidia.com/v1/cv/nvidia/nemotron-ocr-v2" def __init__( self, diff --git a/nemo_retriever/src/nemo_retriever/operators/extract/ocr/cpu_ocr.py b/nemo_retriever/src/nemo_retriever/operators/extract/ocr/cpu_ocr.py index e40de327e..e302acb75 100644 --- a/nemo_retriever/src/nemo_retriever/operators/extract/ocr/cpu_ocr.py +++ b/nemo_retriever/src/nemo_retriever/operators/extract/ocr/cpu_ocr.py @@ -19,11 +19,10 @@ class OCRCPUActor(AbstractOperator, CPUOperator): """Remote OCR variant of :class:`OCRActor`. - The hosted NIM endpoint is still v1-only until OCR v2 is released remotely. + Defaults to the hosted Nemotron OCR v2 NIM endpoint. """ - # Keep the remote default on v1 until a hosted OCR v2 NIM is available. - DEFAULT_INVOKE_URL = "https://ai.api.nvidia.com/v1/cv/nvidia/nemotron-ocr-v1" + DEFAULT_INVOKE_URL = "https://ai.api.nvidia.com/v1/cv/nvidia/nemotron-ocr-v2" def __init__(self, **ocr_kwargs: Any) -> None: super().__init__(**ocr_kwargs) diff --git a/nemo_retriever/src/nemo_retriever/operators/extract/table/cpu_actor.py b/nemo_retriever/src/nemo_retriever/operators/extract/table/cpu_actor.py index ad68b0c99..29fa7ddde 100644 --- a/nemo_retriever/src/nemo_retriever/operators/extract/table/cpu_actor.py +++ b/nemo_retriever/src/nemo_retriever/operators/extract/table/cpu_actor.py @@ -23,9 +23,8 @@ class TableStructureCPUActor(AbstractOperator, CPUOperator): """CPU-only variant of :class:`TableStructureActor`. - Defaults to the build.nvidia.com endpoint for - ``nemotron-table-structure-v1`` and hosted ``nemotron-ocr-v1``. Remote OCR - remains URL-driven until OCR v2 NIM is released. + Uses NVIDIA's hosted table-structure service by default. OCR is not turned on + unless you provide an ``ocr_invoke_url``. """ DEFAULT_TABLE_STRUCTURE_INVOKE_URL = "https://ai.api.nvidia.com/v1/cv/nvidia/nemotron-table-structure-v1" diff --git a/nemo_retriever/src/nemo_retriever/operators/extract/video/ocr_actor.py b/nemo_retriever/src/nemo_retriever/operators/extract/video/ocr_actor.py index 811376a88..a643b3d37 100644 --- a/nemo_retriever/src/nemo_retriever/operators/extract/video/ocr_actor.py +++ b/nemo_retriever/src/nemo_retriever/operators/extract/video/ocr_actor.py @@ -87,11 +87,11 @@ def postprocess(self, data: Any, **kwargs: Any) -> Any: class VideoFrameOCRCPUActor(AbstractOperator, CPUOperator): """Remote Nemotron OCR on full video frames, batched per call. - Hosted OCR NIM is currently v1-only; the local GPU variant uses + Hosted OCR NIM defaults to Nemotron OCR v2; the local GPU variant uses ``NemotronOCRV2`` with the selected OCR mode. """ - DEFAULT_INVOKE_URL = "https://ai.api.nvidia.com/v1/cv/nvidia/nemotron-ocr-v1" + DEFAULT_INVOKE_URL = "https://ai.api.nvidia.com/v1/cv/nvidia/nemotron-ocr-v2" def __init__(self, **ocr_kwargs: Any) -> None: super().__init__(**ocr_kwargs) diff --git a/nemo_retriever/tests/test_actor_operators.py b/nemo_retriever/tests/test_actor_operators.py index ef0615e2d..1bcf1e6c5 100644 --- a/nemo_retriever/tests/test_actor_operators.py +++ b/nemo_retriever/tests/test_actor_operators.py @@ -391,9 +391,9 @@ def test_init_with_ocr_invoke_url_skips_local_ocr(self, monkeypatch): monkeypatch.setitem(local_models.__dict__, "NemotronTableStructureV1", mock_ts) monkeypatch.setitem(local_models.__dict__, "NemotronOCRV2", mock_ocr) - actor = GPUActor(ocr_invoke_url="http://ocr.example/v1/cv/nvidia/nemotron-ocr-v1") + actor = GPUActor(ocr_invoke_url="http://ocr.example/v1/cv/nvidia/nemotron-ocr-v2") - assert actor._ocr_invoke_url == "http://ocr.example/v1/cv/nvidia/nemotron-ocr-v1" + assert actor._ocr_invoke_url == "http://ocr.example/v1/cv/nvidia/nemotron-ocr-v2" assert actor._ocr_model is None mock_ocr.assert_not_called() mock_ts.assert_called_once_with() diff --git a/nemo_retriever/tests/test_operator_flags_and_cpu_actors.py b/nemo_retriever/tests/test_operator_flags_and_cpu_actors.py index 4aead6dd9..05d21537c 100644 --- a/nemo_retriever/tests/test_operator_flags_and_cpu_actors.py +++ b/nemo_retriever/tests/test_operator_flags_and_cpu_actors.py @@ -182,7 +182,7 @@ def test_uses_default_urls(self): assert actor._graphic_elements_model is None assert actor._ocr_model is None assert "nemotron-graphic-elements-v1" in actor._graphic_elements_invoke_url - assert "nemotron-ocr-v1" in actor._ocr_invoke_url + assert "nemotron-ocr-v2" in actor._ocr_invoke_url def test_creates_with_custom_urls(self): from nemo_retriever.operators.extract.chart.cpu_actor import GraphicElementsCPUActor @@ -317,7 +317,7 @@ def test_uses_default_invoke_url(self): actor = OCRCPUActor() assert actor._model is None - assert "nemotron-ocr-v1" in actor.ocr_kwargs["invoke_url"] + assert "nemotron-ocr-v2" in actor.ocr_kwargs["invoke_url"] def test_creates_with_custom_invoke_url(self): from nemo_retriever.operators.extract.ocr.cpu_ocr import OCRCPUActor diff --git a/nemo_retriever/tests/test_readme_video_pipeline_example.py b/nemo_retriever/tests/test_readme_video_pipeline_example.py index 6e7ae099a..9eafb5427 100644 --- a/nemo_retriever/tests/test_readme_video_pipeline_example.py +++ b/nemo_retriever/tests/test_readme_video_pipeline_example.py @@ -94,7 +94,7 @@ def test_readme_video_pipeline_build_graph_chain() -> None: graph = build_graph( extraction_mode="auto", extract_params=ExtractParams( - ocr_invoke_url="https://ai.api.nvidia.com/v1/cv/nvidia/nemoretriever-ocr-v1", + ocr_invoke_url="https://ai.api.nvidia.com/v1/cv/nvidia/nemotron-ocr-v2", ), audio_chunk_params=AudioChunkParams( enabled=True, @@ -134,7 +134,7 @@ def test_audio_only_excludes_visual_branch_from_graph() -> None: graph = build_graph( extraction_mode="auto", extract_params=ExtractParams( - ocr_invoke_url="https://ai.api.nvidia.com/v1/cv/nvidia/nemoretriever-ocr-v1", + ocr_invoke_url="https://ai.api.nvidia.com/v1/cv/nvidia/nemotron-ocr-v2", ), audio_chunk_params=AudioChunkParams( enabled=True, diff --git a/nemo_retriever/tests/test_table_structure_nim_empty_bbox.py b/nemo_retriever/tests/test_table_structure_nim_empty_bbox.py index 080e579a3..c2e3929c4 100644 --- a/nemo_retriever/tests/test_table_structure_nim_empty_bbox.py +++ b/nemo_retriever/tests/test_table_structure_nim_empty_bbox.py @@ -300,7 +300,7 @@ def test_empty_nim_response_does_not_raise_in_torchless_image(self) -> None: df, table_structure_invoke_url="http://nemotron-table-structure-v1:8000/v1/infer", page_elements_invoke_url="http://nemotron-page-elements-v3:8000/v1/infer", - ocr_invoke_url="http://nemotron-ocr-v1:8000/v1/infer", + ocr_invoke_url="http://nemotron-ocr-v2:8000/v1/infer", ) # Stage finished successfully, no row-level error recorded. @@ -336,7 +336,7 @@ def test_empty_nim_response_does_not_call_prediction_to_detections(self) -> None df, table_structure_invoke_url="http://nemotron-table-structure-v1:8000/v1/infer", page_elements_invoke_url="http://nemotron-page-elements-v3:8000/v1/infer", - ocr_invoke_url="http://nemotron-ocr-v1:8000/v1/infer", + ocr_invoke_url="http://nemotron-ocr-v2:8000/v1/infer", ) def test_non_bbox_response_still_falls_through_to_legacy_parser(self) -> None: @@ -364,7 +364,7 @@ def test_non_bbox_response_still_falls_through_to_legacy_parser(self) -> None: df, table_structure_invoke_url="http://nemotron-table-structure-v1:8000/v1/infer", page_elements_invoke_url="http://nemotron-page-elements-v3:8000/v1/infer", - ocr_invoke_url="http://nemotron-ocr-v1:8000/v1/infer", + ocr_invoke_url="http://nemotron-ocr-v2:8000/v1/infer", ) # The non-bbox legacy response triggers the fallback exactly once. diff --git a/nemo_retriever/tests/test_video_frame_ocr_actor.py b/nemo_retriever/tests/test_video_frame_ocr_actor.py index 50227679a..0a594ac73 100644 --- a/nemo_retriever/tests/test_video_frame_ocr_actor.py +++ b/nemo_retriever/tests/test_video_frame_ocr_actor.py @@ -72,10 +72,10 @@ def test_cpu_actor_calls_remote_batched_with_b64_list() -> None: assert call_kwargs["invoke_url"] == "https://example/ocr" -def test_cpu_actor_defaults_to_hosted_ocr_v1() -> None: +def test_cpu_actor_defaults_to_hosted_ocr_v2() -> None: actor = VideoFrameOCRCPUActor() - assert "nemotron-ocr-v1" in actor._invoke_url + assert "nemotron-ocr-v2" in actor._invoke_url def test_gpu_actor_invokes_local_model_per_frame() -> None: