Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
60 changes: 60 additions & 0 deletions packages/sie_server/models/xiaomi-research__Xiaomi-OCR-0.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
sie_id: xiaomi-research/Xiaomi-OCR-0
hf_id: xiaomi-research/Xiaomi-OCR-0
hf_revision: bbd8cf8d21f256b3644b44cb860f3a7cecb93c30
inputs:
text: false
image: true
audio: false
video: false
tasks:
encode: null
score: null
extract: {}
# A page at the processor's own pixel limit is 16384 visual tokens; the
# window adds the card's 4096 new tokens and the prompt on top.
max_sequence_length: 24576
profiles:
# Plain Hugging Face reference path (Qwen3_5ForConditionalGeneration, native
# in transformers 5; no remote code). The card decodes greedily with 4096 new
# tokens; the checkpoint's own dtype is bfloat16.
transformers:
max_batch_tokens: 16384
compute_precision: bfloat16
adapter_path: sie_server.adapters.glm_ocr:GlmOcrAdapter
adapter_options:
loadtime:
# The model card's document-parsing prompt.
user_text: "Extract all information from the main body of the document image and represent it in markdown format, ignoring headers and footers. Tables should be expressed in OTSL format, formulas in the document should be represented using LATEX format, and the parsing should be organized according to the reading order."
runtime:
max_new_tokens: 4096
num_beams: 1
default:
max_batch_tokens: 16384
compute_precision: bfloat16
adapter_path: sie_server.adapters.sglang_vision_extract.adapter:SGLangVisionExtractAdapter
adapter_options:
loadtime:
# Native SGLang architecture (Qwen3_5ForConditionalGeneration); never
# execute repository code.
trust_remote_code: false
# Pages in flight, each up to 24576 tokens of page image and output,
# need far more KV than the automatic one-sequence pool of 24576.
# SGLang keeps (1 - fraction) of the memory free at launch as runtime
# headroom. One 16 MP page peaks about 3.5 GiB above the memory in use
# after load; on an L4, 0.85 leaves too little and the engine OOMs.
mem_fraction_static: 0.70
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
served_model_name: xiaomi-research/Xiaomi-OCR-0
# 64 full-size uploads at once outrun the adapter's /generate write
# timeout on an L4 worker; 32 was measured clean.
max_concurrent_requests: 32
# Model card prompts. The default is document parsing; callers pick
# another region type with the runtime ``task`` option.
default_task: document
task_prompts:
document: "Extract all information from the main body of the document image and represent it in markdown format, ignoring headers and footers. Tables should be expressed in OTSL format, formulas in the document should be represented using LATEX format, and the parsing should be organized according to the reading order."
text: "Extract the text in the image."
table: "Parse the table in the image into OTSL."
formula: "Identify the formula in the image and represent it using LATEX format."
runtime:
max_new_tokens: 4096
num_beams: 1
1 change: 1 addition & 0 deletions packages/sie_server/tests/config/test_bundle_coverage.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ def test_candle_bundle_only_exposes_profile_variants() -> None:
("lightonai/LightOnOCR-2-1B", "transformers5.yaml"),
("PaddlePaddle/PaddleOCR-VL-1.5", "default.yaml"),
("zai-org/GLM-OCR", "transformers5.yaml"),
("xiaomi-research/Xiaomi-OCR-0", "transformers5.yaml"),
],
)
def test_generative_ocr_defaults_to_isolated_sglang_extract_and_keeps_transformers_fallback(
Expand Down
43 changes: 43 additions & 0 deletions packages/sie_server/tests/config/test_xiaomi_ocr_profiles.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
"""Xiaomi-OCR-0 serves native weights with the model card's prompts."""

from pathlib import Path

import yaml

_CONFIG = Path(__file__).resolve().parents[2] / "models" / "xiaomi-research__Xiaomi-OCR-0.yaml"
_PROCESSOR_MAX_PAGE_TOKENS = 16_777_216 // (32 * 32)
_PROMPT_TOKENS = 256


def _profiles() -> dict:
return yaml.safe_load(_CONFIG.read_text())["profiles"]


def test_sglang_profile_never_trusts_repository_code() -> None:
default = _profiles()["default"]
assert default["adapter_path"].endswith(":SGLangVisionExtractAdapter")
assert default["adapter_options"]["loadtime"]["trust_remote_code"] is False


def test_both_profiles_default_to_the_same_card_prompt_and_decoding() -> None:
profiles = _profiles()
reference = profiles["transformers"]["adapter_options"]
sglang = profiles["default"]["adapter_options"]
task = sglang["loadtime"]["default_task"]
assert sglang["loadtime"]["task_prompts"][task] == reference["loadtime"]["user_text"]
assert sglang["runtime"] == reference["runtime"] == {"max_new_tokens": 4096, "num_beams": 1}


def test_a_full_resolution_page_and_its_output_fit_the_sequence_window() -> None:
config = yaml.safe_load(_CONFIG.read_text())
for profile in config["profiles"].values():
loadtime = profile["adapter_options"]["loadtime"]
assert "--mm-process-config" not in loadtime.get("extra_launch_args", [])
budget = _PROCESSOR_MAX_PAGE_TOKENS + profile["adapter_options"]["runtime"]["max_new_tokens"] + _PROMPT_TOKENS
assert budget <= config["max_sequence_length"]


def test_sglang_profile_keeps_its_l4_calibrated_reservation() -> None:
loadtime = _profiles()["default"]["adapter_options"]["loadtime"]
assert loadtime["mem_fraction_static"] == 0.70
assert loadtime["max_concurrent_requests"] == 32
Loading