Instructions to use stockmark/Stockmark-Nemotron-3-Nano-Omni-JapanDocReader with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use stockmark/Stockmark-Nemotron-3-Nano-Omni-JapanDocReader with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("image-text-to-text", model="stockmark/Stockmark-Nemotron-3-Nano-Omni-JapanDocReader", trust_remote_code=True) messages = [ { "role": "user", "content": [ {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"}, {"type": "text", "text": "What animal is on the candy?"} ] }, ] pipe(text=messages)# Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("stockmark/Stockmark-Nemotron-3-Nano-Omni-JapanDocReader", trust_remote_code=True, device_map="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use stockmark/Stockmark-Nemotron-3-Nano-Omni-JapanDocReader with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "stockmark/Stockmark-Nemotron-3-Nano-Omni-JapanDocReader" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "stockmark/Stockmark-Nemotron-3-Nano-Omni-JapanDocReader", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }'Use Docker
docker model run hf.co/stockmark/Stockmark-Nemotron-3-Nano-Omni-JapanDocReader
- SGLang
How to use stockmark/Stockmark-Nemotron-3-Nano-Omni-JapanDocReader with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "stockmark/Stockmark-Nemotron-3-Nano-Omni-JapanDocReader" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "stockmark/Stockmark-Nemotron-3-Nano-Omni-JapanDocReader", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "stockmark/Stockmark-Nemotron-3-Nano-Omni-JapanDocReader" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "stockmark/Stockmark-Nemotron-3-Nano-Omni-JapanDocReader", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }' - Docker Model Runner
How to use stockmark/Stockmark-Nemotron-3-Nano-Omni-JapanDocReader with Docker Model Runner:
docker model run hf.co/stockmark/Stockmark-Nemotron-3-Nano-Omni-JapanDocReader
Stockmark-Nemotron-3-Nano-Omni-JapanDocReader
Introduction
Stockmark-Nemotron-3-Nano-Omni-JapanDocReader is a Japanese document-reading multimodal model built on top of NVIDIA's Nemotron-3-Nano-Omni-30B-A3B-Reasoning. This model injects Japanese structured document parsing capability while preserving as much of the original VQA ability as possible.
It is trained with a two-stage recipe:
- Mixed SFT — supervised fine-tuning on a mixture of structured parsing data and VQA data. Mixing VQA into the SFT set mitigates catastrophic forgetting of the base model's reasoning/VQA ability that pure structured-parsing-only SFT would cause. SFT was performed with NeMo Megatron-Bridge.
- DAPO — reinforcement learning applied to the structured document parsing capability on top of the mixed-SFT base. This pushes structured document parsing quality above the SFT base while keeping the VQA regression small. DAPO was performed with NeMo-RL.
All training keeps thinking mode on and uses English reasoning traces, which is central to preserving multi-step-reasoning VQA performance (switching to no-think or changing the reasoning language degrades the base model's reasoning distribution).
Training data was synthesized with Stockmark's Japanese document synthesis pipeline using Nemotron-Personas-Japan and Qwen3.6-27B as the generator.
For a detailed write-up (in Japanese), see our our blog.
Quickstart
The model serves as a standard OpenAI-compatible endpoint via vLLM (≥ 0.20). It is a reasoning model — keep thinking mode on and inject a reasoning budget so it closes </think> and answers.
1. Launch the server
vllm serve stockmark/Stockmark-Nemotron-3-Nano-Omni-JapanDocReader \
--served-model-name japandocreader \
--host 0.0.0.0 --port 8000 \
--dtype bfloat16 \
--max-model-len 210000 \
--tensor-parallel-size 1 \
--trust-remote-code \
--reasoning-parser nemotron_v3 \
--allowed-local-media-path / \
--media-io-kwargs '{"video": {"fps": 2, "num_frames": 256}}' \
--video-pruning-rate 0.5
2. Recommended inference parameters
| Parameter | Value | Note |
|---|---|---|
| temperature | 0.6 | official thinking-mode setting |
| top_p | 0.95 | official thinking-mode setting |
| repetition_penalty | 1.0 | recommended default (no penalty); keeps picture descriptions intact |
| reasoning_budget | 16384 | thinking token budget |
| max_tokens | 20480 | must be > reasoning_budget (leaves room for the answer) |
| max_model_len | 210000 | server-side |
max_tokens > reasoning_budgetis required: the budget caps the think block, and the remainingmax_tokens − reasoning_budgettokens hold the answer. Setting them equal starves the answer.
3. Structured document parsing
⚠️ Use this exact prompt. The model was trained with the fixed Japanese structured document parsing prompt below. The prompt defines the task, the JSON schema, the allowed
classvalues, and the coordinate convention — the model's output format is conditioned on it. Do not paraphrase, translate, or reorder it; changing the prompt degrades layout accuracy and JSON validity. Keep it verbatim, including the trailingReturn ONLY the JSON objectinstruction.
import base64, json, re, urllib.request
PROMPT = """画像に含まれるドキュメントの構造をJSON形式で抽出してください。
出力フォーマット:
{
"document_structure": [
{
"class": "title" | "heading" | "text" | "table" | "list" | "picture" | "formula",
"bbox": [x1, y1, x2, y2],
"contents": "内容(pictureの場合は画像内容の説明、formulaの場合は数式のlatex表記)",
"caption": "pictureのキャプション文字(オプション)"
}
]
}
classの種類: title(タイトル)、heading(見出し)、text(本文)、table(表)、list(リスト)、picture(画像)、formula(数式)
bboxは左上(x1,y1)と右下(x2,y2)の座標です。bboxの座標系は0-1000の相対座標です。
Return ONLY the JSON object. No markdown, no extra commentary."""
def parse_document(image_path, base_url="http://127.0.0.1:8000"):
with open(image_path, "rb") as f:
b64 = base64.b64encode(f.read()).decode()
payload = {
"model": "japandocreader",
"messages": [{"role": "user", "content": [
{"type": "image_url", "image_url": {"url": f"data:image/png;base64,{b64}"}},
{"type": "text", "text": PROMPT},
]}],
"temperature": 0.6, "top_p": 0.95,
"repetition_penalty": 1.0,
"max_tokens": 20480,
"chat_template_kwargs": {"enable_thinking": True, "reasoning_budget": 16384},
"thinking_token_budget": 17408, # reasoning_budget + grace
}
req = urllib.request.Request(
base_url.rstrip("/") + "/v1/chat/completions",
data=json.dumps(payload).encode(),
headers={"Content-Type": "application/json", "Authorization": "Bearer EMPTY"},
method="POST")
with urllib.request.urlopen(req, timeout=1800) as r:
msg = r.read(); msg = json.loads(msg)["choices"][0]["message"]
# thinking is split into reasoning_content; the answer is the JSON in `content`
answer = msg.get("content") or ""
m = re.search(r"\{.*\}", answer, re.DOTALL)
return json.loads(m.group(0) if m else answer) # -> {"document_structure": [...]}
result = parse_document("document.png")
print(json.dumps(result, ensure_ascii=False, indent=2))
4. Document VQA
For VQA, send the image plus the question (no docparse prompt); the model reasons in <think> and
answers in natural language:
payload["messages"] = [{"role": "user", "content": [
{"type": "image_url", "image_url": {"url": f"data:image/png;base64,{b64}"}},
{"type": "text", "text": "この文書について: <your question in Japanese>"},
]}]
# same sampling params as above; the answer is in message.content, the reasoning in reasoning_content
License
Released under the NVIDIA Open Model License, inherited from the base model. Please also review the base model's terms.
Acknowledgements
In this experiment, we used 8×B300 Blackwell Ultra compute resources provided by NVIDIA, and conducted training on NVIDIA Brev using NVIDIA NeMo. We sincerely thank everyone at NVIDIA for supporting the large-scale SFT and RL experiments.
Developed by
Citation
@misc{stockmark_japandocreader_2026,
title={Stockmark-Nemotron-3-Nano-Omni-JapanDocReader},
author={Stockmark Inc.},
year={2026}
}
- Downloads last month
- 129