Nemotron 3.5 Super VL
A step-by-step guide for fine-tuning Nemotron 3.5 Super VL (121B hybrid Mamba and Attention Mixture-of-Experts (MoE) VLM) to extract structured receipt data from scanned images using NeMo AutoModel. Full SFT on 4 nodes or LoRA on a single node, then inference and evaluation on the CORD-v2 validation split.
What is Nemotron 3.5 Super VL?
Nemotron 3.5 Super VL (nvidia/NVIDIA-Nemotron-3.5-Super-midtrain-67B-vision-pretrained,
architecture NemotronH_Omni_Reasoning_V3) is the 121B member of the Nemotron 3.5 family.
Key architectural details:
- LLM backbone: NemotronV3 hybrid, 88 layers (40 Mamba2, 8 attention, 40 MoE), hidden dim 4096
- MoE: 512 routed experts per MoE layer, top-22 routing plus 1 shared expert
- Vision encoder: RADIO v2.5-H (ViT-Huge), 512x512 tiles, 256 vision tokens per tile
- Audio: This vision-pretrained checkpoint ships no
sound_config, so no audio tower is built - MTP: The checkpoint ships one multi-token-prediction head; the recipe below keeps it off (
num_nextn_predict_layers: 0) - Parameters: 120.7B trainable with the vision tower frozen (99.31% of the model); ~227 GB in bf16
Fine-Tune for Receipt Field Extraction
This guide fine-tunes the model on CORD-v2 (Consolidated Receipt Dataset) to extract structured fields from scanned receipts:
The base model produces free-form descriptions. After fine-tuning, it outputs structured XML-like token sequences matching the receipt fields.
Guide Overview
Hardware Requirements
- 4 nodes x 8 H100 80 GB (512 experts sharded with
ep_size=32;cp_size=4so the 8-sample global batch is one sample per data-parallel rank) - SFT memory: ~65 GiB per GPU (fp32 master weights, bf16 Adam moments, activation checkpointing)
- Training time: ~21 min on 4x8 H100 for 400 steps (4 epochs of the 800 training samples), including four validation passes with checkpoint saves; about 26 min wall clock with model loading and the final consolidated export
- LoRA PEFT: one node x 8 H100 (
cp_size 1/ep_size 8, ~39 GiB per GPU). The frozen base needs no fp32 master copy or optimizer state.
Step 0 — Set Up the Environment
Nemotron 3.5 Super VL requires mamba_ssm and causal_conv1d (the cuda extra, pre-built in the
NeMo AutoModel container), Transformer Engine (attn: te, linear: te), and DeepEP for
expert dispatch. The checkpoint is ~227 GB in bf16 (63 safetensors shards); download it into
$HF_HOME before launching so that all 32 ranks read from the shared cache.
Step 1 — Explore the CORD-v2 Dataset
CORD-v2 contains scanned receipts with structured ground-truth JSON labels.
Expected output:
Target Format for JSON-to-Token Conversion
NeMo AutoModel converts structured JSON into an XML-like token sequence using
the json2token() function. This is the format the model is trained to produce:
Step 2 — Training Configuration
Config file: examples/vlm_finetune/nemotron_3_5_super_vl/nemotron_3_5_super_vl_cord_v2.yaml
LoRA PEFT Config
Config file: examples/vlm_finetune/nemotron_3_5_super_vl/nemotron_3_5_super_vl_cord_v2_peft.yaml
Same data pipeline and schedule; the base model stays frozen and rank-64 LoRA adapters are trained on
the LLM’s linear projections (Mamba in_proj/out_proj, attention q/k/v/o_proj, MoE latent
projections and shared-expert MLPs). The vision tower, projector and lm_head are excluded:
Without fp32 master weights and optimizer state for the frozen 121B parameters, LoRA fits on a single node of 8 H100 (~39 GiB per GPU). 177M trainable parameters (0.15%).
Collate Function
Nemotron 3.5 Super VL uses InternVL-style image handling: each
<image> token is expanded to 256 vision embeddings per tile during the forward pass.
The collate function extracts the images from the conversation, applies the chat template
(which adds the <think></think> prefix for the assistant turn), runs the processor, and
builds the training labels.
Step 3 — Launch Fine-Tuning
On a Slurm cluster (one task per GPU, 4 nodes):
You can also launch the same recipe with the automodel launcher: automodel examples/vlm_finetune/nemotron_3_5_super_vl/nemotron_3_5_super_vl_cord_v2.yaml --nproc-per-node 8 --nnodes 4.
W&B logging is opt-in: add --wandb.enable=true --wandb.entity=<entity> --wandb.project=<project> to either command.
LoRA PEFT
You can also launch it on any 8-GPU machine with the automodel launcher: automodel examples/vlm_finetune/nemotron_3_5_super_vl/nemotron_3_5_super_vl_cord_v2_peft.yaml --nproc-per-node 8.
Training Log for LoRA PEFT
400 steps take ~13 min on 8 H100 (including the four validation passes). Each checkpoint holds the adapter only (~355 MB), so
vlm_checkpoints/nemotron_3_5_super_vl_cord_v2_peft/ stays small even with a checkpoint per validation step.
Training Log for Full SFT
Training loss keeps falling through epoch 4 while validation loss bottoms out at epoch 3 and rises in the last epoch — the 800-receipt training set is small enough for a 121B model to start memorizing it.
Checkpoints Saved
A checkpoint is written at the end of every epoch (every 100 steps for the 800-receipt training set) and at the
final step, so LOWEST_VAL can point at any of them; with fp32 master weights and Adam moments each sharded
checkpoint of this model is ~1.4 TB, so budget ~6 TB for the run. Intermediate checkpoints stay sharded; run their
model/consolidate.sh to get an HF export of LOWEST_VAL.
Step 4 — Run Inference and Evaluation
Full SFT Inference
Load the consolidated HF export across all visible GPUs (device_map="auto"; the bf16 weights need
~227 GB, so use one node with 8x H100), greedy-decode CORD-v2 validation receipts with the training
prompt (<image>\nDescribe this image., enable_thinking=False) and score each prediction against
json2token(gt_parse, sort_json_key=True):
- exact match — prediction identical to the ground-truth token sequence
- similarity — normalized sequence similarity (difflib ratio; 1.0 = identical)
Pointing CKPT at the base checkpoint id (nvidia/NVIDIA-Nemotron-3.5-Super-midtrain-67B-vision-pretrained)
scores the un-tuned model the same way.
LoRA PEFT Inference
LoRA checkpoints contain only adapter_model.safetensors + adapter_config.json, saved under the
training wrapper’s module names (language_model.model.layers.N.mixer.in_proj, …), which match the
HF module tree. Load the base checkpoint as above, fold the adapters into the base weights
(W += (B @ A) * alpha / r), then run the same predict loop:
Resources: One node with 8x H100 (bf16 weights spread over the GPUs). Runtime: About 2–4 min to load the 227 GB export, then about 26 s per receipt (greedy, up to 1024 new tokens); 20 samples take about 13 min. The un-tuned base model is slower (~55 s per sample) because its free-form descriptions run to the token limit.
Step 5 — Results
Evaluation on the First 20 CORD-v2 Validation Samples
The checkpoint with the lowest validation loss also decodes best, so evaluate LOWEST_VAL (run its
model/consolidate.sh first; the final step is the only one exported inline).
The base model answers Describe this image. with prose (“This is a photograph of a receipt from a
restaurant, likely a pizzeria …”). After fine-tuning every prediction is a well-formed
<s_total>...</s_total><s_menu>...</s_menu> sequence; the remaining errors are field-level (a
dropped <s_cnt> or <s_vatyn>, a <s_sub> block where the label has none) or OCR digits.