Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Nemoretriever-parse (aka Eclair) NIM #230

Open
wants to merge 73 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
3fbcf68
Add doughnut http endpoint
edknv Nov 14, 2024
e5a281d
fix table and chart extraction
edknv Nov 14, 2024
d933a33
handle 202 reponses by repolling status
edknv Nov 18, 2024
af9ca0e
add table format in unit tests
edknv Nov 18, 2024
b5c992d
Merge branch 'main' into feat/doughnut-http-endpoint-1
edknv Nov 18, 2024
6ad99c0
fix table and image max dimensions
edknv Nov 19, 2024
e511dbf
Merge branch 'feat/doughnut-http-endpoint-1' of github.com:edknv/nv-i…
edknv Nov 19, 2024
b3c632b
add unit tests for the helper
edknv Nov 19, 2024
0deb5c9
add placeholder for url in docker compose
edknv Nov 19, 2024
2e7db6d
add check for empty dataframe in table/chart extraction
edknv Nov 19, 2024
c5b5d3e
clean up doughnut specific confiditions in inference func
edknv Nov 20, 2024
bcb0037
clean up doughnut specific confiditions in inference func
edknv Nov 20, 2024
187d13d
fix unit tests
edknv Nov 20, 2024
51b5bca
Merge branch 'main' into feat/doughnut-http-endpoint-1
edknv Nov 22, 2024
321052f
Add support for text bounding boxes
edknv Nov 22, 2024
a9a74b7
also add table and image bounding boxes to metadata
edknv Nov 23, 2024
1d532a4
Use seprate environment variable for private endpoint
edknv Dec 2, 2024
e141cad
Merge branch 'main' into feat/doughnut-http-endpoint-1
edknv Dec 3, 2024
ea057e6
Use seprate environment variable for private endpoint
edknv Dec 4, 2024
be8cc68
Merge branch 'feat/doughnut-http-endpoint-1' of github.com:edknv/nv-i…
edknv Dec 4, 2024
67ff768
Merge branch 'main' into feat/doughnut-http-endpoint-1
edknv Dec 4, 2024
001a3b5
Merge branch 'main' into feat/doughnut-http-endpoint-1
edknv Dec 6, 2024
ccb9f8f
Merge branch 'main' into feat/doughnut-http-endpoint-1
edknv Dec 9, 2024
8088eed
migrate to using NimClient and ModelInterface
edknv Dec 9, 2024
0163880
Merge branch 'feat/doughnut-http-endpoint-1' of github.com:edknv/nv-i…
edknv Dec 9, 2024
792b724
update unit tests
edknv Dec 9, 2024
8f77199
Merge branch 'main' into feat/doughnut-http-endpoint-1
edknv Dec 9, 2024
f96d406
Merge branch 'main' into feat/doughnut-http-endpoint-1
jdye64 Dec 10, 2024
9a17068
Merge branch 'main' into feat/doughnut-http-endpoint-1
edknv Dec 10, 2024
71d7212
lint
edknv Dec 10, 2024
e9f021f
fix unit test
edknv Dec 10, 2024
e456d9e
Merge branch 'main' into feat/doughnut-http-endpoint-1
edknv Dec 10, 2024
a7e0f36
Merge branch 'main' into feat/doughnut-http-endpoint-1
edknv Dec 11, 2024
7e2e518
Merge branch 'main' into feat/doughnut-http-endpoint-1
edknv Dec 13, 2024
b833850
Merge branch 'main' into feat/doughnut-http-endpoint-1
edknv Dec 13, 2024
247c431
Merge branch 'feat/doughnut-http-endpoint-1' of github.com:edknv/nv-i…
edknv Dec 13, 2024
1fc1b67
Merge branch 'main' into feat/doughnut-http-endpoint-1
edknv Dec 13, 2024
a705846
Merge branch 'main' into feat/doughnut-http-endpoint-1
edknv Dec 16, 2024
e4e3406
Merge branch 'main' into feat/doughnut-http-endpoint-1
edknv Dec 17, 2024
0ef5b86
Merge branch 'main' into feat/doughnut-http-endpoint-1
edknv Dec 20, 2024
a0c584c
Merge branch 'main' into feat/doughnut-http-endpoint-1
edknv Jan 6, 2025
a0befbf
Merge branch 'main' into feat/doughnut-http-endpoint-1
edknv Jan 13, 2025
c6b0a35
migrate doughnut config to pydantic 2
edknv Jan 13, 2025
410610e
Merge branch 'feat/doughnut-http-endpoint-1' of github.com:edknv/nv-i…
edknv Jan 13, 2025
23eae8f
Merge branch 'main' into feat/doughnut-http-endpoint-1
edknv Jan 13, 2025
26b5e50
Merge branch 'main' into feat/doughnut-http-endpoint-1
edknv Jan 14, 2025
e340c34
Merge branch 'main' into feat/doughnut-http-endpoint-1
edknv Jan 15, 2025
4f7bfeb
Merge branch 'main' into feat/doughnut-http-endpoint-1
edknv Jan 22, 2025
1c119ff
Replace nvcf with NIM
edknv Jan 24, 2025
6b7a29e
remove postprocessing
edknv Jan 24, 2025
237dfa4
drop codename
edknv Jan 24, 2025
71d81d2
update tests
edknv Jan 24, 2025
c92ae91
lint
edknv Jan 24, 2025
848d18d
refactor fot batch size 1
edknv Jan 26, 2025
6a962fb
Merge branch 'main' into feat/doughnut-http-endpoint-1
edknv Feb 6, 2025
db68afb
update model name and batch input
edknv Feb 6, 2025
e9fa05e
Merge branch 'main' into feat/doughnut-http-endpoint-1
edknv Feb 7, 2025
e97867b
Merge branch 'main' into feat/doughnut-http-endpoint-1
edknv Feb 10, 2025
4dc708f
Merge branch 'feat/doughnut-http-endpoint-1' of github.com:edknv/nv-i…
edknv Feb 10, 2025
23e901c
Merge branch 'main' into feat/doughnut-http-endpoint-1
edknv Feb 10, 2025
e99d775
rc5 uses the regular ngc key
edknv Feb 11, 2025
5dea3b7
find and replace all eclair -> nemoretriever_parse
edknv Feb 11, 2025
1c8f4fd
clean up
edknv Feb 11, 2025
1aa002c
more clean up
edknv Feb 11, 2025
d92da02
enable table/chart extraction with yolox
edknv Feb 12, 2025
398b179
Merge branch 'main' into feat/doughnut-http-endpoint-1
edknv Feb 12, 2025
ee32864
fix cached and paddle batching error
edknv Feb 12, 2025
6511ca6
update batching in nimclient
edknv Feb 12, 2025
41296ed
add option to select table extraction mode
edknv Feb 12, 2025
dfc9fd7
update image tag
edknv Feb 12, 2025
755ceea
fix page arrangement
edknv Feb 12, 2025
1de974d
Merge branch 'main' into feat/doughnut-http-endpoint-1
edknv Feb 12, 2025
632880f
Merge branch 'main' into feat/doughnut-http-endpoint-1
edknv Feb 13, 2025
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: 1 addition & 1 deletion client/src/nv_ingest_client/nv_ingest_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@
Example:
--task 'split:{"split_by":"page", "split_length":10}'
--task 'extract:{"document_type":"pdf", "extract_text":true}'
--task 'extract:{"document_type":"pdf", "extract_method":"doughnut"}'
--task 'extract:{"document_type":"pdf", "extract_method":"nemoretriever_parse"}'
--task 'extract:{"document_type":"pdf", "extract_method":"unstructured_io"}'
--task 'extract:{"document_type":"docx", "extract_text":true, "extract_images":true}'
--task 'store:{"content_type":"image", "store_method":"minio", "endpoint":"minio:9000"}'
Expand Down
15 changes: 2 additions & 13 deletions client/src/nv_ingest_client/primitives/tasks/extract.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,6 @@

logger = logging.getLogger(__name__)

DOUGHNUT_TRITON_HOST = os.environ.get("DOUGHNUT_TRITON_HOST", "localhost")
DOUGHNUT_TRITON_PORT = os.environ.get("DOUGHNUT_TRITON_PORT", "8001")
DOUGHNUT_BATCH_SIZE = os.environ.get("DOUGHNUT_TRITON_PORT", "16")

UNSTRUCTURED_API_KEY = os.environ.get("UNSTRUCTURED_API_KEY", None)
UNSTRUCTURED_URL = os.environ.get("UNSTRUCTURED_URL", "https://api.unstructured.io/general/v0/general")
UNSTRUCTURED_STRATEGY = os.environ.get("UNSTRUCTURED_STRATEGY", "auto")
Expand All @@ -49,7 +45,7 @@

_Type_Extract_Method_PDF = Literal[
"adobe",
"doughnut",
"nemoretriever_parse",
"haystack",
"llama_parse",
"pdfium",
Expand All @@ -74,7 +70,7 @@
"tiff": get_args(_Type_Extract_Method_Image),
}

_Type_Extract_Tables_Method_PDF = Literal["yolox", "pdfium"]
_Type_Extract_Tables_Method_PDF = Literal["yolox", "pdfium", "nemoretriever_parse"]

_Type_Extract_Tables_Method_DOCX = Literal["python_docx",]

Expand Down Expand Up @@ -238,13 +234,6 @@ def to_dict(self) -> Dict:
"unstructured_url": "", # TODO(Devin): Should be an environment variable
}
task_properties["params"].update(unstructured_properties)
elif self._extract_method == "doughnut":
doughnut_properties = {
"doughnut_triton_host": os.environ.get("DOUGHNUT_TRITON_HOST", DOUGHNUT_TRITON_HOST),
"doughnut_triton_port": os.environ.get("DOUGHNUT_TRITON_PORT", DOUGHNUT_TRITON_PORT),
"doughnut_batch_size": os.environ.get("DOUGHNUT_BATCH_SIZE", DOUGHNUT_BATCH_SIZE),
}
task_properties["params"].update(doughnut_properties)
elif self._extract_method == "unstructured_io":
unstructured_properties = {
"unstructured_api_key": os.environ.get("UNSTRUCTURED_API_KEY", UNSTRUCTURED_API_KEY),
Expand Down
26 changes: 25 additions & 1 deletion docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,27 @@ services:
capabilities: [gpu]
runtime: nvidia

nemoretriever-parse:
image: ${NEMORETRIEVER_PARSE_IMAGE:-nvcr.io/nvidia/nemo-microservices/nemoretriever-parse}:${NEMORETRIEVER_PARSE_TAG:-1.2.0ea}
ports:
- "8015:8000"
- "8016:8001"
- "8017:8002"
user: root
environment:
- NIM_HTTP_API_PORT=8000
- NIM_TRITON_LOG_VERBOSE=1
- NGC_API_KEY=${NIM_NGC_API_KEY:-${NGC_API_KEY:-ngcapikey}}
- CUDA_VISIBLE_DEVICES=0
deploy:
resources:
reservations:
devices:
- driver: nvidia
device_ids: ["0"]
capabilities: [gpu]
runtime: nvidia

nv-ingest-ms-runtime:
image: nvcr.io/nvidia/nemo-microservices/nv-ingest:24.12
build:
Expand Down Expand Up @@ -155,7 +176,6 @@ services:
# build.nvidia.com hosted deplot
#- DEPLOT_HTTP_ENDPOINT=https://ai.api.nvidia.com/v1/vlm/google/deplot
- DEPLOT_INFER_PROTOCOL=http
- DOUGHNUT_GRPC_TRITON=triton-doughnut:8001
- EMBEDDING_NIM_MODEL_NAME=${EMBEDDING_NIM_MODEL_NAME:-nvidia/nv-embedqa-e5-v5}
- INGEST_LOG_LEVEL=DEFAULT
# Message client for development
Expand All @@ -168,6 +188,10 @@ services:
- MESSAGE_CLIENT_TYPE=redis
- MINIO_BUCKET=${MINIO_BUCKET:-nv-ingest}
- MRC_IGNORE_NUMA_CHECK=1
# build.nvidia.com hosted nemoretriever-parse
#- NEMORETRIEVER_PARSE_HTTP_ENDPOINT=https://ai.api.nvidia.com/v1/vlm/nvidia/nemoretriever-parse
- NEMORETRIEVER_PARSE_HTTP_ENDPOINT=http://nemoretriever-parse:8000/v1/chat/completions
- NEMORETRIEVER_PARSE_INFER_PROTOCOL=http
- NGC_API_KEY=${NGC_API_KEY:-ngcapikey}
- NVIDIA_BUILD_API_KEY=${NVIDIA_BUILD_API_KEY:-${NGC_API_KEY:-ngcapikey}}
- OTEL_EXPORTER_OTLP_ENDPOINT=otel-collector:4317
Expand Down
Binary file removed docs/docs/assets/images/doughnut_batch_dize.png
Binary file not shown.
4 changes: 0 additions & 4 deletions docs/docs/user-guide/developer-guide/deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,6 @@ docker compose up -d otel-collector prometheus grafana zipkin
# The `embed` task will not be functional without this service.
docker compose up -d embedding

# Optional (Triton) See below for Triton setup we need Triton for any model inference
# This is only needed for captioning or DOUGHNUT based extraction.
docker compose up -d triton

# Ingest service
docker compose up -d nv-ingest-ms-runtime
```
Expand Down
2 changes: 0 additions & 2 deletions docs/docs/user-guide/developer-guide/environment-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ The following are the environment configuration variables that you can specify i
|----------------------------------|--------------------------------|-----------------------------------------------------------------------|
| `CAPTION_CLASSIFIER_GRPC_TRITON` | - `triton:8001` <br/> | The endpoint where the caption classifier model is hosted using gRPC for communication. This is used to send requests for caption classification. You must specify only ONE of an http or gRPC endpoint. If both are specified gRPC will take precedence. |
| `CAPTION_CLASSIFIER_MODEL_NAME` | - `deberta_large` <br/> | The name of the caption classifier model. |
| `DOUGHNUT_TRITON_HOST` | - `triton-doughnut` <br/> | The hostname or IP address of the DOUGHNUT model service. |
| `DOUGHNUT_TRITON_PORT` | - `8001` <br/> | The port number on which the DOUGHNUT model service is listening. |
| `INGEST_LOG_LEVEL` | - `DEBUG` <br/> - `INFO` <br/> - `WARNING` <br/> - `ERROR` <br/> - `CRITICAL` <br/> | The log level for the ingest service, which controls the verbosity of the logging output. |
| `MESSAGE_CLIENT_HOST` | - `redis` <br/> - `localhost` <br/> - `192.168.1.10` <br/> | Specifies the hostname or IP address of the message broker used for communication between services. |
| `MESSAGE_CLIENT_PORT` | - `7670` <br/> - `6379` <br/> | Specifies the port number on which the message broker is listening. |
Expand Down
4 changes: 2 additions & 2 deletions docs/docs/user-guide/developer-guide/nv-ingest_cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Options:
Example:
--task 'split:{"split_by":"page", "split_length":10}'
--task 'extract:{"document_type":"pdf", "extract_text":true}'
--task 'extract:{"document_type":"pdf", "extract_method":"doughnut"}'
--task 'extract:{"document_type":"pdf", "extract_method":"nemoretriever_parse"}'
--task 'extract:{"document_type":"pdf", "extract_method":"unstructured_io"}'
--task 'extract:{"document_type":"docx", "extract_text":true, "extract_images":true}'
--task 'store:{"content_type":"image", "store_method":"minio", "endpoint":"minio:9000"}'
Expand Down Expand Up @@ -120,7 +120,7 @@ nv-ingest-cli \

Submit a PDF file with splitting and extraction tasks.

**Note: (TODO)** This currently only works for pdfium, doughnut, and Unstructured.io; haystack, Adobe, and LlamaParse
**Note: (TODO)** This currently only works for pdfium, nemoretriever_parse, and Unstructured.io; haystack, Adobe, and LlamaParse
have existing workflows but have not been fully converted to use our unified metadata schema.

```bash
Expand Down
5 changes: 3 additions & 2 deletions src/nv_ingest/extraction_workflows/image/image_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@
from wand.image import Image as WandImage

import nv_ingest.util.nim.yolox as yolox_utils
from nv_ingest.extraction_workflows.pdf.doughnut_utils import crop_image
from nv_ingest.schemas.image_extractor_schema import ImageConfigSchema
from nv_ingest.schemas.metadata_schema import AccessLevelEnum
from nv_ingest.util.image_processing.transforms import crop_image
from nv_ingest.util.image_processing.transforms import numpy_to_base64
from nv_ingest.util.nim.helpers import create_inference_client
from nv_ingest.util.pdf.metadata_aggregators import CroppedImageWithContent
Expand Down Expand Up @@ -160,7 +160,8 @@ def extract_table_and_chart_images(
*bbox, _ = bboxes
h1, w1, h2, w2 = np.array(bbox) * np.array([height, width, height, width])

base64_img = crop_image(original_image, (int(h1), int(w1), int(h2), int(w2)))
cropped_img = crop_image(original_image, (int(h1), int(w1), int(h2), int(w2)))
base64_img = numpy_to_base64(cropped_img) if cropped_img is not None else None

table_data = CroppedImageWithContent(
content="",
Expand Down
4 changes: 2 additions & 2 deletions src/nv_ingest/extraction_workflows/pdf/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@


from nv_ingest.extraction_workflows.pdf.adobe_helper import adobe
from nv_ingest.extraction_workflows.pdf.doughnut_helper import doughnut
from nv_ingest.extraction_workflows.pdf.nemoretriever_parse_helper import nemoretriever_parse
from nv_ingest.extraction_workflows.pdf.llama_parse_helper import llama_parse
from nv_ingest.extraction_workflows.pdf.pdfium_helper import pdfium_extractor as pdfium
from nv_ingest.extraction_workflows.pdf.tika_helper import tika
Expand All @@ -15,6 +15,6 @@
"pdfium",
"tika",
"unstructured_io",
"doughnut",
"nemoretriever_parse",
"adobe",
]
Loading
Loading