Views
No views yet
<class_Chart> class token, and updated training coverage for chart/table-heavy documents. NVIDIA Nemotron Parse 2.0 is intended for document understanding, information retrieval, data extraction, and multimodal data-curation workflows.auxiliary_prediction_heads.safetensors.extra for future multi-token prediction research. Standard generation uses the tied decoder input/output embeddings; the default model.safetensors, Transformers examples, and vLLM examples do not load this auxiliary head.<predict_bbox>, <predict_classes>, <predict_text_in_pic>, and <predict_no_text_in_pic>, plus the chart class token <class_Chart>. Use of the tokenizer included in this model is governed by the CC-BY-4.0 license.</s><s><predict_bbox><predict_classes><output_markdown><predict_no_text_in_pic>. The model can emit chart regions using <class_Chart> when chart content is detected.nvcr.io/nvidia/pytorch:25.03-py3 with the following library versions installed on top:1pip install accelerate==1.12.0
2pip install transformers==5.6.1
3pip install timm==1.0.22
4pip install open_clip_torch==3.2.0
5pip install einops==0.8.1
6pip install beautifulsoup4open_clip_torch is currently needed only by the direct Transformers path because C-RADIO's remote-code validation inspects an optional OpenCLIP adaptor. Nemotron Parse does not configure or execute that adaptor. Albumentations is not used by the Nemotron Parse 2.0 processor.1import torch
2from PIL import Image, ImageDraw
3from transformers import AutoModel, AutoProcessor, AutoTokenizer, GenerationConfig
4from postprocessing import extract_classes_bboxes, transform_bbox_to_original, postprocess_text
5
6# Load model and processor
7model_path = "nvidia/NVIDIA-Nemotron-Parse-2.0" # Or use a local path
8device = "cuda:0"
9
10model = AutoModel.from_pretrained(
11 model_path,
12 trust_remote_code=True,
13 torch_dtype=torch.bfloat16
14).to(device).eval()
15tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)
16processor = AutoProcessor.from_pretrained(model_path, trust_remote_code=True)
17
18# Load image
19image = Image.open("document.png")
20task_prompt = "</s><s><predict_bbox><predict_classes><output_markdown><predict_no_text_in_pic>"
21# task_prompt = "</s><s><predict_bbox><predict_classes><output_markdown><predict_text_in_pic>"
22
23# Process image
24inputs = processor(images=[image], text=task_prompt, return_tensors="pt", add_special_tokens=False).to(device)
25
26generation_config = GenerationConfig.from_pretrained(model_path, trust_remote_code=True)
27
28# Generate text
29outputs = model.generate(**inputs, generation_config=generation_config)
30
31# Decode the generated text
32generated_text = processor.batch_decode(outputs, skip_special_tokens=True)[0]1from PIL import ImageDraw
2from postprocessing import extract_classes_bboxes, transform_bbox_to_original, postprocess_text
3
4classes, bboxes, texts = extract_classes_bboxes(generated_text)
5bboxes = [transform_bbox_to_original(bbox, image.width, image.height) for bbox in bboxes]
6
7# Specify output formats for postprocessing
8table_format = "latex" # latex | HTML | markdown | json | json_hierarchical | csv
9text_format = "markdown" # markdown | plain
10blank_text_in_figures = False # set True to remove text inside 'Picture' class
11texts = [
12 postprocess_text(
13 text,
14 cls=cls,
15 table_format=table_format,
16 text_format=text_format,
17 blank_text_in_figures=blank_text_in_figures,
18 )
19 for text, cls in zip(texts, classes)
20]
21
22for cl, bb, txt in zip(classes, bboxes, texts):
23 print(cl, ": ", txt)
24
25draw = ImageDraw.Draw(image)
26for bbox in bboxes:
27 draw.rectangle((bbox[0], bbox[1], bbox[2], bbox[3]), outline="red")table_format: latex | HTML | markdown | json | json_hierarchical | csvalbumentations or open_clip_torch installation is required for this vLLM path. The model's lightweight encoder configuration prevents vLLM startup from recursively importing C-RADIO's unused OpenCLIP adaptor. This container-only dependency path was validated with vLLM v0.20. On A100 and A10 systems, we recommend running vllm serve with --attention-backend=TRITON_ATTN.lm_head.weight tied to decoder.embed_tokens.weight and does not materialize a duplicate output-head tensor. Current vLLM 0.20 Nemotron Parse builds create a separate output head unless patched. If your vLLM build does not already support tied Nemotron Parse output embeddings, fetch the included runtime patch and add it to PYTHONPATH before starting vLLM:1PATCH_ROOT=$(python - <<'PY'
2from huggingface_hub import snapshot_download
3print(snapshot_download(
4 "nvidia/NVIDIA-Nemotron-Parse-2.0",
5 allow_patterns="vllm_tied_patch/sitecustomize.py",
6))
7PY
8)
9export PYTHONPATH="${PATCH_ROOT}/vllm_tied_patch:${PYTHONPATH}"1from vllm import LLM, SamplingParams
2from PIL import Image
3
4
5def main():
6 sampling_params = SamplingParams(
7 temperature=0,
8 top_k=1,
9 repetition_penalty=1.1,
10 max_tokens=9000,
11 skip_special_tokens=False,
12 )
13
14 llm = LLM(
15 model="nvidia/NVIDIA-Nemotron-Parse-2.0",
16 max_num_seqs=64,
17 limit_mm_per_prompt={"image": 1},
18 dtype="bfloat16",
19 trust_remote_code=True,
20 )
21
22 image = Image.open("document.png")
23
24 prompts = [
25 {
26 "prompt": "</s><s><predict_bbox><predict_classes><output_markdown><predict_no_text_in_pic>",
27 "multi_modal_data": {
28 "image": image,
29 },
30 },
31 {
32 "encoder_prompt": {
33 "prompt": "",
34 "multi_modal_data": {
35 "image": image,
36 },
37 },
38 "decoder_prompt": "</s><s><predict_bbox><predict_classes><output_markdown><predict_no_text_in_pic>",
39 },
40 ]
41
42 outputs = llm.generate(prompts, sampling_params)
43
44 for output in outputs:
45 prompt = output.prompt
46 generated_text = output.outputs[0].text
47 print(f"Decoder prompt: {prompt!r}, Generated text: {generated_text!r}")
48
49
50if __name__ == "__main__":
51 main()1vllm serve nvidia/NVIDIA-Nemotron-Parse-2.0 \
2 --dtype bfloat16 \
3 --max-num-seqs 8 \
4 --limit-mm-per-prompt '{"image": 1}' \
5 --trust-remote-code \
6 --port 80001import base64
2from openai import OpenAI
3
4client = OpenAI(
5 base_url="http://localhost:8000/v1",
6 api_key="EMPTY",
7)
8
9with open("document.png", "rb") as f:
10 img_b64 = base64.b64encode(f.read()).decode("utf-8")
11
12prompt_text = "</s><s><predict_bbox><predict_classes><output_markdown><predict_no_text_in_pic>"
13
14resp = client.chat.completions.create(
15 model="nvidia/NVIDIA-Nemotron-Parse-2.0",
16 messages=[
17 {
18 "role": "user",
19 "content": [
20 {
21 "type": "text",
22 "text": prompt_text,
23 },
24 {
25 "type": "image_url",
26 "image_url": {
27 "url": f"data:image/png;base64,{img_b64}",
28 },
29 },
30 ],
31 }
32 ],
33 max_tokens=8192,
34 temperature=0.0,
35 extra_body={
36 "repetition_penalty": 1.1,
37 "top_k": 1,
38 "skip_special_tokens": False,
39 },
40)
41print(resp.choices[0].message.content)</s><s><predict_bbox><predict_classes><output_markdown><predict_no_text_in_pic></s><s><predict_bbox><predict_classes><output_markdown><predict_text_in_pic></s><s><predict_bbox><predict_classes><output_no_text><predict_no_text_in_pic>NemotronParseRepetitionStopProcessor: detects repeating n-grams during generation and forces the model to close the coordinate block when repeated structured output suggests a potential hallucination.NemotronParseTableInsertionLogitsProcessor: forces every block to follow a table structure, which can be useful when running the model on table image crops.example_with_processor.py for Python-model usage. With vLLM, add the model repository's logitsprocs/ directory to PYTHONPATH and pass the desired processor to vllm serve:1PROCESSOR_ROOT=$(python - <<'PY'
2from huggingface_hub import snapshot_download
3print(snapshot_download(
4 "nvidia/NVIDIA-Nemotron-Parse-2.0",
5 allow_patterns="logitsprocs/nemotron_parse_vllm_logitprocs.py",
6))
7PY
8)
9export PYTHONPATH="${PROCESSOR_ROOT}/logitsprocs:${PYTHONPATH}"
10
11vllm serve nvidia/NVIDIA-Nemotron-Parse-2.0 \
12 --dtype bfloat16 \
13 --max-num-seqs 4 \
14 --limit-mm-per-prompt '{"image": 1}' \
15 --attention-backend=TRITON_ATTN \
16 --trust-remote-code \
17 --logits-processors nemotron_parse_vllm_logitprocs:NemotronParseTableInsertionLogitsProcessor \
18 --port 8000vllm_example.py.data_source: note slice. | Benchmark | Metric | NVIDIA Nemotron Parse v1.2 | NVIDIA Nemotron Parse 2.0 | Change |
|---|---|---|---|---|
| ParseBench | Overall score | 0.5782 | 0.6391 | ↑ +0.0609 |
| OmniDocBench Notes (Handwriting) | Text edit distance (lower is better) | 0.9739 | 0.3395 | ↓ -0.6343 |
| IndicVisionBench | Overall ANLS character | 0.0612 | 0.7203 | ↑ +0.6592 |
| MOSCAR (Multilingual) | Overall BoC F1 | 0.4410 | 0.9102 | ↑ +0.4692 |