Instructions to use sionic-ai/Wasabi-30B with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use sionic-ai/Wasabi-30B with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("image-text-to-text", model="sionic-ai/Wasabi-30B") 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)# pip install -U transformers accelerate # Load model directly from transformers import AutoProcessor, AutoModelForMultimodalLM processor = AutoProcessor.from_pretrained("sionic-ai/Wasabi-30B") model = AutoModelForMultimodalLM.from_pretrained("sionic-ai/Wasabi-30B", device_map="auto") 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?"} ] }, ] inputs = processor.apply_chat_template( messages, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt", ).to(model.device) outputs = model.generate(**inputs, max_new_tokens=256) print(processor.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use sionic-ai/Wasabi-30B with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "sionic-ai/Wasabi-30B" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "sionic-ai/Wasabi-30B", "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/sionic-ai/Wasabi-30B
- SGLang
How to use sionic-ai/Wasabi-30B 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 "sionic-ai/Wasabi-30B" \ --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": "sionic-ai/Wasabi-30B", "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 "sionic-ai/Wasabi-30B" \ --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": "sionic-ai/Wasabi-30B", "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 sionic-ai/Wasabi-30B with Docker Model Runner:
docker model run hf.co/sionic-ai/Wasabi-30B
Wasabi-30B
Wasabi-30B reads a Japanese document page image and writes the page as Markdown:
- full text in reading order;
- tables as HTML
<table>; - math as LaTeX,
$...$inline and$$...$$for display; - ruby (furigana) kept inline as
<ruby>base<rt>reading</rt></ruby>.
Model details
- Fine-tune of Muse-Glimmer-30B (https://huggingface.co/meta-models/Muse-Glimmer-30B, revision
97c77dff50b2797bcc558fa2d909761dbc575c59). - A LoRA adapter trained for Japanese page transcription, merged into BF16 weights.
- Two safetensors shards.
Files in this repository
| path | what it is |
|---|---|
model-00001-of-00002.safetensors, model-00002-of-00002.safetensors, model.safetensors.index.json |
merged BF16 weights |
config.json, generation_config.json, processor_config.json |
model and processor configuration |
tokenizer.json, tokenizer_config.json, chat_template.jinja |
tokenizer and chat template |
inference/ |
the page reader package (wasabi_read, AGPL-3.0) and its two prompts |
LICENSE, NOTICE, notices/ |
licence texts: this model (AGPL-3.0), the base model (Apache-2.0) and its usage policy |
SHA256SUMS |
checksums of every file |
Inference
The package reads a folder of page images (.jpg, .jpeg, .png) and writes one .md file per page.
pip install -e "./inference[dewarp]"
Python 3.10+. The reader flattens every page locally with UVDoc on CPU, so torch and OpenCV are required in every mode, including endpoint mode.
Local serving needs vLLM with muse_glimmer support, built from commit 6adad08767583f52eb4d2122111af0bf638ed5e6
(version 0.26.1rc1.dev769). Released vLLM 0.26.0 has no muse_glimmer model, so it cannot serve this model. A
source build needs a CUDA toolchain:
pip install "vllm @ git+https://github.com/vllm-project/vllm.git@6adad08767583f52eb4d2122111af0bf638ed5e6" "transformers==5.15.0"
Then, with the Python of that vLLM environment, apply the one-file processor fix. Without it, the muse_glimmer
processor of this vLLM commit rejects the max_image_tokens setting that every server below is started with, and the
server does not start. The script edits one file, checks its sha256 before and after, and can undo the edit
(--check, --revert). A server you start yourself (endpoint mode, direct model use) needs it too.
python inference/patch_vllm_max_image_tokens.py --apply
An endpoint run needs no local vLLM.
Tested with Python 3.12, vLLM 0.26.1rc1.dev769 (commit 6adad087), transformers 5.15.0, torch 2.13.0,
opencv-python-headless 5.0.0.93, numpy 2.3.5 and Pillow 13.0.0.
Wasabi-30B is the only checkpoint the reader needs: it checks the page orientation and reads the page.
Local vLLM (the package starts and stops the servers itself: first the orientation check, then the reader, both from the same weights):
python inference/wasabi_read.py pages/ out/ --engine vllm --model-dir /models/Wasabi-30B --tensor-parallel-size 1 --whole-upscale-tokens 8192
Against OpenAI-compatible servers you already run, both serving Wasabi-30B: the reader started with
--mm-processor-kwargs '{"max_image_tokens": 8192}', the orientation check with
--mm-processor-kwargs '{"max_image_tokens": 4096}', and both with --reasoning-parser muse_glimmer. Name what each
server serves with --endpoint-revision and --orient-endpoint-revision; the addresses and revisions are part of the
output identity, so a rerun against another server is refused instead of mixed into the same output directory.
python inference/wasabi_read.py pages/ out/ --engine endpoint --endpoint-url http://gpu-host:8000 --endpoint-revision wasabi-30b-v1.0 --orient-endpoint-url http://gpu-host:8001 --orient-endpoint-revision wasabi-30b-v1.0
--plan prints the stages and exits without loading a model.
The API key, the UVDoc cache location and offline UVDoc use are described under Configuration.
Direct model use
This sends the page image as it is: no orientation check, no flattening, no enlargement and no retries. It is a basic transcription path, separate from the reader above. It uses the vLLM build and the processor fix from the Inference section.
pip install openai
vllm serve /models/Wasabi-30B --served-model-name wasabi --max-model-len 36864 \
--mm-processor-kwargs '{"max_image_tokens": 8192}' --reasoning-parser muse_glimmer
Then send one page with the OpenAI-compatible API, using the recommended decoding (greedy, repetition penalty 1.10, seed 42, up to 24,576 new tokens, low reasoning strength):
import base64
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="none")
png = base64.b64encode(open("page.png", "rb").read()).decode()
prompt = open("inference/wasabi_read/prompts/draft.txt", encoding="utf-8").read()
r = client.chat.completions.create(
model="wasabi",
messages=[{"role": "user", "content": [
{"type": "image_url", "image_url": {"url": "data:image/png;base64," + png}},
{"type": "text", "text": prompt}]}],
temperature=0.0,
seed=42,
max_tokens=24576,
extra_body={"repetition_penalty": 1.10,
"repetition_detection": {"max_pattern_size": 512, "min_pattern_size": 4, "min_count": 16},
"chat_template_kwargs": {"reasoning_strength": "low", "current_date": "2026-10-16"}},
)
print(r.choices[0].message.content)
The transcription prompt is the file inference/wasabi_read/prompts/draft.txt. The reader pins current_date so that the output does
not depend on the day you run it, and repetition_detection stops a looping answer early.
generation_config.json keeps the base model's sampling defaults; pass temperature=0 (as above) for the
recommended greedy transcription.
What the reader does
Per page:
- Orientation check: Wasabi-30B answers a four-way upright probe at 4,096 image tokens; a turn is applied only when the margin is at least 5.0.
- Flattening with UVDoc on CPU. The UVDoc code and weights are fetched at first use from a pinned commit and checked by sha256 before loading.
- A whole-page read at 8,192 image tokens, greedy.
- If the answer is degenerate, a retry ladder at temperatures 0.1, 0.3, 0.5 and 0.8.
- Output is written per page as
<stem>.md, atomically. Rerunning the same command resumes: finished pages are skipped. Pages with no usable answer are listed inout/.wasabi-read/run-report.json.
Benchmark submission
The MDPBench submission includes additional inference components provided to the organizers. The complete inference code is maintained in a private repository. The code included here runs independently of that repository.
Limitations
- Japanese-focused. Other languages are not a target.
- The
transformersengine has not been measured and is not guaranteed to follow the vLLM path's image size and decoding; use the vLLM or endpoint engine for the behaviour documented here. - Each orientation decision comes from one greedy probe per rotation, so a different serving stack (attention backend, CUDA build, batching) can change the turn on a few pages.
- Ruby appears only as the model writes it inline; there is no separate ruby pass.
- Photographed pages and very small print can be misread.
- The reader package runs on Linux and macOS only (it uses POSIX file locks). Its local vLLM engine starts the servers with the FlashInfer vision-encoder attention backend; to use another backend, serve the model yourself and use endpoint mode.
License
- This model and the reader package: GNU Affero General Public License v3.0 (
LICENSE). - Base model Muse-Glimmer-30B: Apache License 2.0 (
notices/Muse-Glimmer-30B-LICENSE.txt), together with its publisher's usage policy (notices/Muse-Glimmer-30B-USAGE_POLICY.md). - UVDoc code (commit 4c9b82b5): MIT License, Copyright (c) 2023 Tanguy MAGNE. The reader downloads the UVDoc code and its pretrained weights at first use and does not redistribute them. The weights carry no separate licence statement and remain under their upstream terms.
Copyright 2026 Sionic AI Inc.
- Downloads last month
- 48