Downloads · 30 days
337
10% of all-time downloads
stockmark/Stockmark-Nemotron-3-Nano-Omni-JapanDocReader
Stockmark-Nemotron-3-Nano-Omni-JapanDocReader is a image-text-to-text model from stockmark. Use it for the image-text-to-text task on the model card, and read the license before you ship it in a product. It is set up for transformers. The card lists the license as other.
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 ca…
Downloads · 30 days
337
10% of all-time downloads
All-time downloads
3.4K
Public
Parameters
33B
66 GB on disk
Likes
8
Public
Click a slice to open those files.
.safetensors66 GB · 100%
How the weights are stored.
BF1633B · 100%
From the Hugging Face model README
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:
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.
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.
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
| 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.
⚠️ 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))
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
Released under the NVIDIA Open Model License, inherited from the base model. Please also review the base model's terms.
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.
@misc{stockmark_japandocreader_2026,
title={Stockmark-Nemotron-3-Nano-Omni-JapanDocReader: Structured Document Parsing via Capability Injection and Forgetting Control},
author={Stockmark Inc.},
year={2026},
eprint={2608.06758},
archivePrefix={arXiv},
primaryClass={cs.CL},
url={https://arxiv.org/abs/2608.06758},
}