~/satyajit

ZDTaichu5.0-9B: the release contradicts itself on its own best benchmark

mdjsonmcp

2026-09-18 · 18 min · multimodal · vision-language-models · benchmarks · quantization · inference-optimization · explainer

On 15 September 2026 the Taichu lab (紫东太初) open-sourced ZDTaichu5.0-9B: a Qwen3.5-9B decoder with an NVIDIA C-RADIOv4-H vision tower bolted on, pitched at spatial reasoning and embodied AI. There is no arXiv preprint and no tech report — the entire technical record is a model card, a GitHub README, and one subdirectory called recurrent_reasoning/. I read all of it, in both languages, and pulled every safetensors header over HTTP range requests without downloading a single weight.

The artifact is in good shape. The bytes reconcile exactly, the config matches the tensor shapes, and the vision tower is really there. The documentation is where this release falls over — and it falls over hardest on exactly the benchmarks where it beats a frontier closed model.

TaichuAI/ZDTaichu5.0-9B@a22afd1 · snapshot 2026-09-18
announced
9B, Qwen3.5-9B + C-RADIOv4-H, 128K context
measured
9,794,197,512
parameters
9.79B
repo size
19.61 GB
architecture
ZDTaichu5_0_ForConditionalGeneration
task
image-text-to-text
safetensors
5 shards
largest file
4.27 GB
files
39
downloads
1.8K
likes
178
languages
en, zh
parameters by dtype
BF169.79BI642
multimodalvision-language-modelspatial-reasoningagentvideo-understanding

Measured from the safetensors headers: 9,794,197,512 parameters in 820 tensors — 8.95B language model, 651.6M vision tower, 188.7M projector. config.json sets max_position_embeddings to 262,144 and the README's own recommended vLLM command asks for --max-model-len 220000, neither of which is 128K.

repo last modified 2026-09-15

The two READMEs

The model card has one table for spatial and embodied reasoning. recurrent_reasoning/README.md in the GitHub repo has another, for the same model on four of the same benchmarks. They do not agree, and nothing in either document reconciles them:

BenchmarkModel cardrecurrent_reasoning/README.mdDifference
ViewSpatial62.5054.10+8.40
MMSI-Bench47.2036.80+10.40
MindCube-tiny78.2774.04+4.23
RoboSpatial56.0068.00−12.00

The first three have an explanation, buried in a <sub> footnote under the model card's tables. For ViewSpatial, MMSI-Bench, MindCube-tiny and VSI-Bench, an output-format instruction was appended to the evaluation prompt:

You FIRST think about the reasoning process as an internal monologue and then provide the final answer. The reasoning process MUST BE enclosed within <think> </think> tags. The final answer MUST BE put in \boxed{}.

The EARR README's footnote says its numbers were taken without that instruction, through plain Transformers at batch_size=1. So the delta between the two tables is the price of that one paragraph of prompt. On MMSI-Bench it is worth 10.4 points.

MMSI-Bench is a fixed set of 1,000 multiple-choice questions (arXiv:2505.23764), which makes the denominator easy: 47.20 is 472 questions, 36.80 is 368. The <think>/\boxed{} wrapper is worth 104 questions out of 1,000.

RoboSpatial is worse, because it has no explanation at all. It is not in the list of benchmarks that received the format instruction, yet the same model is reported at 56.00 in one file and 68.00 in the other. One of those two numbers came from a different harness, a different split, or a different checkpoint, and the release does not say which. The Highlights section leads with "Scores of 48 on ERQA and 56 on RoboSpatial" — the lower of the two, which is at least not the flattering direction.

I checked the Chinese README_zh.md files on the assumption that the more candid document might be the untranslated one. It is not: both EARR READMEs are faithful translations of each other, same numbers, same footnote, and — a small tell about how carefully this was proofread — the same broken install line in both.

What the release figure shows, and what its own tables print

The headline figure is twelve bar-chart panels. The tables above it have twenty-seven rows.

A twelve-panel bar chart titled 'ZDTaichu5.0-9B: Comparison with Open Models', grouped into General Visual Understanding, Spatial and Embodied Capabilities, and Text and Agent Capabilities, comparing ZDTaichu5.0-9B against Qwen3.5-9B, STEP3-VL-10B and gemma4-8B-E4B.
The release's open-model comparison. Twelve of the twenty-seven benchmark rows in the tables directly above it made the cut (ZDTaichu5.0-9B release, docs/assets/, file taichu-release-benchmark-comparison.svg).

I parsed all three HTML tables out of the model card and scored every row against the best of the three open baselines the release itself chose. Toggle between the figure's twelve panels and the full twenty-seven:

10/1283.3% — rows where ZDTaichu5.0-9B is at least the best of Qwen3.5-9B, STEP3-VL-10B and gemma4-8B-E4B

what the release figure draws

benchmarkZDTaichubest openwhichΔin figure
ViewSpatialComplex spatial reasoning62.5048.20Qwen3.5-9B+14.30yes
MMSI-BenchComplex spatial reasoning47.2038.70Qwen3.5-9B+8.50yes
MindCube-tinyComplex spatial reasoning78.2762.81STEP3-VL-10B+15.46yes
VSI-BenchEmbodied interaction59.6955.68Qwen3.5-9B+4.01yes
WeMathMultimodal reasoning75.9075.20Qwen3.5-9B+0.70yes
MMStarGeneral VQA76.8079.70Qwen3.5-9B-2.90yes
AI2DGeneral VQA91.4890.20Qwen3.5-9B+1.28yes
RealWorldQAGeneral VQA76.9980.30Qwen3.5-9B-3.31yes
IFEvalInstruction following93.7088.72Qwen3.5-9B+4.98yes
LiveCodeBench v6Reasoning and coding73.4065.60Qwen3.5-9B+7.80yes
TAU2-BenchGeneral agent87.7081.70STEP3-VL-10B+6.00yes
Claw-Eval (general)General agent71.4066.60STEP3-VL-10B+4.80yes
Scores parsed from the three tables in the ZDTaichu5.0-9B model card; “in figure” read off the release SVG. Eight of the ten losses are to Qwen3.5-9B — the model’s own language backbone.

Across the full tables ZDTaichu5.0-9B leads the open field on 17 of 27 rows — 63.0%. Across the twelve panels promoted into the figure, 10 of 12 — 83.3%. Choosing a subset for a release graphic is normal, and every one of these losses is printed in the tables the figure sits under. The number worth carrying away is the one the graphic cannot show you: eight of the ten losses are to Qwen3.5-9B, the model's own language backbone. Both MMLU rows, OCRBench, MMStar, RealWorldQA, MathVista and MathVerse all go backwards relative to the text model this was built from. That is the visual-instruction-tuning tax, it is substantial (MathVerse Mini drops 7.74 points), and it is the honest cost of the spatial gains.

One more thing about the figure: in it, ZDTaichu's value label is bold in all twelve panels, including MMStar and RealWorldQA where it loses. In the tables, bold means best score among open models. Two conventions, one document.

Measuring the artifact

None of the above touches the weights, so I measured those separately. A safetensors file opens with an 8-byte little-endian header length followed by a JSON header listing every tensor's name, dtype and byte offsets — two range requests per file recover the complete tensor manifest for free.

# first 8 bytes -> header length n
curl -sSL -H 'Range: bytes=0-7' \
  https://huggingface.co/TaichuAI/ZDTaichu5.0-9B/resolve/main/model-1-of-5.safetensors \
  | xxd -e -g8
# then bytes 8..8+n-1 -> the JSON header
receiptscaptured 2026-09-18

ZDTaichu5.0-9B ships 9,794,197,512 parameters in 19,588,395,036 tensor bytes across five safetensors shards. Every shard's real size, tensor list and parameter count was recovered by HTTP range read without downloading any weights, and the three totals reconcile exactly: 8 length bytes per file, plus 106,344 bytes of JSON headers, plus tensor bytes, equals the sum of the CDN's Content-Length values to the byte.

fileCDN Content-Length (B)git-lfs pointer size (B)safetensors header (B)tensorsparameters
model-1-of-5.safetensors4,268,658,8724,268,658,8729,776752,134,324,544
model-2-of-5.safetensors4,265,727,1284,265,727,12816,6561282,132,855,232
model-3-of-5.safetensors4,215,379,9684,215,379,96816,7601282,107,681,600
model-4-of-5.safetensors3,123,658,7523,123,658,75212,408951,561,823,168
model-5-of-5.safetensors3,715,076,7003,715,076,70050,7443941,857,512,968
— total —19,588,501,42019,588,501,420106,3448209,794,197,512

The index file's declared metadata.total_size is 19,588,395,036, which is tensor bytes only and excludes headers — it matches the summed data_offsets exactly, so nothing is missing or double-counted. The parameter total splits into 8,953,803,264 in the language model, 651,645,448 in the C-RADIOv4-H vision tower (390 tensors, one of them an int64 index buffer) and 188,748,800 in the mlp1 projector. config.json labels the release "9B" via _model_size_label; the shipped artifact is 9.79B, of which 2,034,237,440 (20.8%) is the untied input embedding plus LM head over a 248,320-token vocabulary.

method For each shard: curl -sSL -I <resolve URL> to follow the xet CDN redirect and read Content-Length; then Range: bytes=0-7 for the little-endian u64 header length, then Range: bytes=8-(8+n-1) for the JSON header. Parameter counts are the product of each tensor's shape; byte counts are data_offsets[1]-data_offsets[0].
data /articles/zdtaichu-5-9b/data/checkpoint-ledger.json (6 rows, 3.2 KB)

Everything closes. 40 bytes of length prefixes plus 106,344 bytes of headers plus 19,588,395,036 tensor bytes equals 19,588,501,420, which is the sum of the five CDN Content-Length values to the byte. The model.safetensors.index.json declares total_size: 19588395036 — tensor bytes only, which is correct and not a discrepancy. The git-lfs pointer sizes match the post-redirect Content-Length exactly. No missing gigabytes.

The config matches too, including the two places where it looks like it shouldn't. q_proj ships as [8192, 4096] while num_attention_heads is 16 and head_dim is 256, which multiplies out to 4096 — but configuration.py's own header comment gives the reason: "Attention output gating (sigmoid gate on q_proj)", so the projection is 16 × 256 × 2. The DSpark draft model confirms it from the other side: its config is plain qwen3 with the same 16 heads and 256 head_dim, and its q_proj really is [4096, 4096]. The Gated DeltaNet layers line up the same way: in_proj_qkv is [8192, 4096] = 16×128 keys + 16×128 queries + 32×128 values, and in_proj_z is the 32×128 gate. The projector is exactly what mlp1 claims: [5120] RMSNorm → [20480, 5120][4096, 20480], where 5120 is the 1280-wide ViT output after a 0.5 pixel-shuffle. The vision tower is real — 390 tensors, 32 ViT-H/16 blocks, 651,645,448 parameters — not a config entry pointing at nothing.

Two things the config advertises that the checkpoint does not carry:

What "9B" is made of

Of the 9,794,197,512 parameters, 2,034,237,440 — 20.8% — is the untied input embedding plus LM head over a 248,320-token vocabulary. The non-embedding model is 7.76B. That framing matters as soon as you look at the quantized builds, because nobody quantized those two matrices.

ZDTaichu5.0-9B19.59 GB · 16.00 bits/weight · 100.0% still BF16
ZDTaichu5.0-9B-FP812.67 GB · 10.35 bits/weight · 45.4% still BF16
ZDTaichu5.0-9B-NVFP49.81 GB · 8.01 bits/weight · 38.0% still BF16
BF16F8_E4M3NVFP4scales / index buffers

C-RADIOv4-H tower32-block ViT-H/16, 651.6M params

ZDTaichu5.0-9B1,303,290,908 BBF16 1.30 GB · other 16 B
ZDTaichu5.0-9B-FP81,303,290,896 BBF16 1.30 GB · other 16 B
ZDTaichu5.0-9B-NVFP41,303,290,896 BBF16 1.30 GB · other 16 B
Bars are to scale against the BF16 checkpoint. Byte counts read from the safetensors JSON headers by HTTP range request; each total matches the file’s Content-Length minus its header.

Read the bits/weight figure. The FP8 build lands at 10.35 bits/weight, not 8, because 45.4% of it is still BF16: the embedding, the LM head, the entire C-RADIOv4-H tower and the projector. The NVFP4 build lands at 8.01 bits/weight, not 4, because only the MLP projections in layers 0 through 27 are actually 4-bit — 2.11 GB of U8-packed weights with E4M3 block scales at block size 16. Layers 28–31 keep FP8 MLPs, every attention and linear-attention projection stays FP8, the LM head is FP8, and embed_tokens is still BF16. Measured in parameters, 43.2% of the model is 4-bit in the "NVFP4" checkpoint.

The 1.68 GB vision tower and projector are byte-for-byte identical across all three checkpoints. For a model whose pitch is embodied and spatial deployment, the visual encoder is the one component that never gets quantized.

The fourth entry in that download table is ZDTaichu5.0-9B-DSpark, which is not a quantization at all and is never mentioned again anywhere in the README. Its header says 3,210,004,992 parameters in 62 tensors: embed_tokens, five Qwen3 decoder layers, an fc of [4096, 20480] that fuses five auxiliary hidden states, a markov_head of 2 × [248320, 256], and lm_head. It is an EAGLE-3-style speculative-decoding draft model, and its own card reports 2.46×–3.17× speedups on a single H800 at concurrency 1 with num_speculative_tokens: 7 — best-case conditions for speculative decoding, and a number that will not survive real batching. Two-thirds of its 6.42 GB (63.4%) is the two vocabulary matrices. It is tagged pipeline_tag: image-text-to-text on Hugging Face and contains no vision tensors, which is correct by design for a draft model and wrong as metadata.

The headline feature ships in neither place you would look for it

The fourth bullet in Highlights is Entropy-Gated Adaptive Recurrent Reasoning: "dynamically allocates additional recurrent refinement steps in latent space to more challenging tokens." It is the only architectural novelty claimed over stock Qwen3.5 + RADIO.

A flow diagram: Standard Forward produces logits and hidden states, feeding Entropy Gating which tests the entropy of the logits against a threshold; high entropy loops into Latent-Space Recurrent refinement, low entropy goes straight to Trajectory Readout. Below, five labelled boxes read Trigger — normalized entropy / margin, Termination — KL + hidden residual, Stability — damping + anchor, Deployment — KV-cache policy, Safety — best-state rollback.
The mechanism as the release draws it, including the five 'Key Design Points' along the bottom (ZDTaichu5.0-9B repo, recurrent_reasoning/, file EARR.png).

It is not in the Hugging Face repo. modeling.py there has no entropy gate at all. To get EARR you clone GitHub and copy two files over the downloaded checkpoint:

# recurrent_reasoning/README.md, verbatim
cp ./modeling.py /path/to/ZDTaichu5.0-9B/
cp ./recurrent_reasoning.py /path/to/ZDTaichu5.0-9B/

Diffing the two modeling.py files shows how thin the seam is — 22 changed lines, all of them plumbing, and the one that matters is the class declaration:

-class ZDTaichu5_0_ForConditionalGeneration(PreTrainedModel, GenerationMixin):
+class ZDTaichu5_0_ForConditionalGeneration(RecurrentReasoningMixin, PreTrainedModel, GenerationMixin):

It is also absent from the deployment path the README actually recommends. The Online Serving section serves the model with a forked vLLM, and vLLM does not run the repo's modeling.py. So the headline mechanism is available only through AutoModel, only at batch_size=1 (the code says so: "Batch size is always 1, so entropy is handled as one scalar"), and only if you configure it through process-level environment variables — recurrent_reasoning.py reads them with os.getenv at import time, and the README is explicit that they "are not passed as arguments to model.generate(...) and are not read from config.json."

What the mechanism actually does

Strip the prose and the loop is short. One ordinary forward pass produces logits; the entropy of the last position's distribution is compared against a threshold; if it is exceeded, the block of layers named by RECURRENT_REASONING_LAYER_INDICES (default "12,13,14,15") is re-run on a damped blend of its own input and output, and the new logits are kept only if entropy went down.

H > 1.0 → gate fires on this token

N=1the ordinary forward pass — always runs
N=2re-runs layers 12-15 on the damped blend; kept only if entropy drops
damping weight w = 1/(MAX_ITERS+1)
0.5000
extra decoder-layer applications
4
as a share of the 32-layer stack
12.5%
h' = 0.5000 * h_in(layer 12) + 0.5000 * h_out(layer 15)
Constants read from recurrent_reasoning.py in the GitHub repo. The gate reads raw entropy in nats at one position, batch size 1, and the block is the four layers named by RECURRENT_REASONING_LAYER_INDICES.

Two things fall out of that. The "damped update" is not a tuned constant — it is 1.0 / (RECURRENT_REASONING_MAX_ITERS + 1), so at the shipped default of MAX_ITERS=1 it is a flat 50/50 average, and the re-blend line inside the loop (guarded by if reasoning_iter < RECURRENT_REASONING_MAX_ITERS) never executes at all. And the "greater computational depth" the Highlights promise is, at default settings, one extra pass over four of thirty-two layers, on gated tokens only: 12.5% more decoder depth, once.

Raising MAX_ITERS does not simply buy more depth, either, because it shrinks the step: at MAX_ITERS=3 the damping weight drops to 0.25, so each of the three iterations moves the hidden state a quarter of the way instead of half.

Five of the diagram's terms return zero grep hits

The figure's bottom row lists five mechanisms. I grepped the released recurrent_reasoning.py — all 45 KB of it — for the term behind each. Five of those terms (margin, normaliz, residual, anchor, rollback) return zero hits, case-insensitive; one design point survives intact, and it is the one with the least marketing attached:

Claim in the figure / READMEIn recurrent_reasoning.py
Trigger: "normalized entropy / margin"Raw entropy in nats against a constant. margin and normaliz appear 0 times.
Termination: "KL + hidden residual"KL early-stop is there. residual appears 0 times; the second stop rule is "entropy went up".
Stability: "damping + anchor"Damping is there. anchor appears 0 times — the blend at iteration k is against iteration k's own input, not the initial representation.
Safety: "best-state rollback"rollback appears 0 times. The loop keeps the last accepted candidate and breaks on the first entropy rise — greedy, not best-of-trajectory.
Deployment: "KV-cache policy"Genuinely implemented, and the most substantial part of the file: cache forking, frozen history rebuild, DeltaNet recurrent-state snapshots.

The one the README under-sells is the one that is real. Re-running four layers over cached decode state without corrupting a hybrid KV/DeltaNet cache is fiddly, and _build_recurrent_reasoning_history_cache, _fork_recurrent_reasoning_cache and _snapshot_recurrent_reasoning_linear_states are where the engineering went. During prefill there is no such luck — the comment in the code is blunt: "Prefill reasoning recomputes the current input tokens without a KV/recurrent cache", which for a long multi-image prompt means those four layers get re-run over the entire sequence.

And the gains it buys

Benchmarkungatedwith EARRΔ
ViewSpatial54.1054.27+0.17
MMSI-Bench36.8037.40+0.60
MindCube-tiny74.0475.00+0.96
RoboSpatial68.0070.00+2.00

Four benchmarks, one run each, no seeds, no item counts, no error bars. On MMSI-Bench's 1,000 questions, +0.60 is 6 questions. The release bolds all four as wins. To its credit, the README states the limitation itself, and states it well:

Output entropy reflects the model's own uncertainty and does not establish whether an answer is correct.

That is exactly right, and it is the reason a gate that accepts whichever candidate has lower entropy is selecting for confidence, not accuracy. A more confident wrong answer passes this filter.

The install line does not work

Three files — the Hugging Face model card, recurrent_reasoning/README.md, and recurrent_reasoning/README_zh.md — give the same installation command:

pip install tranformer==5.3.0 torch==2.10.0 torchvision==0.25.0 accelerate timm

tranformer is a typo for transformers, and there is no PyPI project by that name: https://pypi.org/pypi/tranformer/json returns 404, as does transformer without the trailing s. Nobody who copy-pasted the quickstart got past line one. (No typosquat exists on either name today, which is luck rather than design.) Everything else in the quickstart checks out — processor.from_messages(...) really is defined, at processing.py:424.

The context length is muddled the same way. The model card's spec table and prose both say 128K. config.json sets max_position_embeddings: 262144. The vLLM command the README tells you to run asks for --max-model-len 220000. Three numbers, no reconciliation — and unusually, the marketing figure is the smallest of the three.

The demo

The GitHub repo ships agent demo recordings. This is the one for a damped-harmonic-oscillator task — solve it analytically with Wolfram, then numerically in Python, then compare the phase portraits — driven through an agent harness called ScienceClaw, which is presumably the source of the release's Claw-Eval numbers.

Official demo, uncropped and untrimmed; downscaled to 1,280px and stripped of audio, nothing else. The vendor's replay toolbar is visible top right: playback speed is set to 2x, 49% through a session the header timestamps at 34 minutes (ZDTaichu5.0-9B repo, docs/assets/agents/, file zdtaichu5_agent_damped_oscillator.mp4).

Worth noting what the toolbar tells you that the README doesn't: this is a session replay, not real time, and its own speed selector is set to 2x. The 16-second clip is a sped-up excerpt of a session the header labels 34 minutes old. That is a normal thing for a product viewer to do and an easy thing to forget when you are watching an agent look fast.

What I would actually do with this

Set the documentation aside and there is a real model here. But which model depends on a number the release does not publish.

At the model card's gated scores, ZDTaichu5.0-9B is 8.5 to 15.5 points clear of the best open baseline on the three complex-spatial rows. At the lab's own ungated scores it is 36.80 on MMSI-Bench, and the model card's number for its own backbone, Qwen3.5-9B, is 38.70. Those two are not directly comparable — the card never says whether Qwen was given the format instruction — and that is precisely the problem. Depending on the answer, ZDTaichu5.0-9B is either 8.5 points ahead of Qwen3.5-9B on MMSI-Bench or 1.9 points behind it.

That is one missing sentence away from resolved: were the baselines in the spatial table evaluated with the same <think>/\boxed{} addendum? If they were, the lead is real and recurrent_reasoning/README.md is just an ablation at different settings. If they were not, the four marquee spatial results compare a prompted model against unprompted baselines. Until that is stated, the defensible claim is narrower than the one on the front page: ZDTaichu5.0-9B is a 9.79B multimodal model that responds unusually well to an explicit reasoning-format instruction on multi-image spatial tasks — worth 10.4 points on MMSI-Bench alone. That is a useful thing to know, and you can get it from the release's own two tables — just not from either one alone.

What would change my mind

5 claims above, and what would falsify each

  1. The model card's spatial scores and recurrent_reasoning/README.md's scores were produced under different prompts, and the gap is the prompt.

    The model card's own footnote says the format instruction was added for ViewSpatial, MMSI-Bench, MindCube-tiny and VSI-Bench; the EARR footnote says it was not used. If the lab publishes an eval log showing the two tables differ for some other reason — a checkpoint revision, a different harness — the attribution is wrong, though the 10.4-point contradiction on MMSI-Bench stands either way. RoboSpatial's 12-point gap has no such explanation at all.

  2. ZDTaichu5.0-9B's MMSI-Bench lead over Gemini 3 Pro depends on the prompt addendum.

    Run MMSI-Bench's 1,000 questions against Gemini 3 Pro with the identical <think>/\boxed{} instruction. If Gemini stays at 45.20 with the addendum, the 2.0-point lead is real and this reservation is unfounded.

  3. Most of the 'Key Design Points' in EARR.png have no implementation in the released code.

    A grep of recurrent_reasoning.py (github.com/Taichu-AI/ZDTaichu5.0-9B, read 2026-09-18) returns zero hits for margin, normaliz, residual, anchor and rollback. If a later commit adds them, or if they live in unreleased training code and the diagram describes the trained model rather than the shipped inference path, this reads as a labelling problem rather than a missing feature.

  4. The NVFP4 checkpoint is 8.01 bits/weight, not 4.

    Read the header: 2,113,929,216 bytes of U8 packed weights against a 9,811,117,776-byte total and 9,794,197,512 parameters. If TaichuAI reuploads with the embedding, the vision tower and layers 28–31 quantized, the number moves. As shipped on 2026-09-18, it does not.

  5. The parameter count, shard sizes and config all agree with the artifact.

    Every shard's post-redirect Content-Length equals its git-lfs pointer size, and 8×5 + 106,344 + 19,588,395,036 = 19,588,501,420 = their sum. A mismatch on any shard, or a tensor shape contradicting config.json beyond the documented q_proj output gate, would break this.

A twelve-panel bar chart titled 'ZDTaichu5.0-9B: Comparison with Closed Models', comparing ZDTaichu5.0-9B against Gemini 3 Pro, Grok 4 and GPT-5.2 across general visual understanding, spatial and embodied capabilities, and text and agent capabilities.
The closed-model comparison. The four spatial panels — MindCube-tiny, ViewSpatial, MMSI-Bench, VSI-Bench — are exactly the benchmarks whose ZDTaichu scores were measured with the added output-format instruction (ZDTaichu5.0-9B release, docs/assets/, file taichu-vs-closed-models.svg).

Sources. TaichuAI/ZDTaichu5.0-9B · Taichu-AI/ZDTaichu5.0-9B · FP8 · NVFP4 · DSpark · MMSI-Bench. All headers read 2026-09-18; weights under the NVIDIA Open Model License, upstream Qwen3.5 under Apache-2.0.

Cite this article

For attribution, please use the following reference or BibTeX:

Satyajit Ghana, "ZDTaichu5.0-9B: the release contradicts itself on its own best benchmark", ai.thesatyajit.com, September 2026.

bibtex
@misc{ghana2026zdtaichu59b,
  author = {Satyajit Ghana},
  title  = {ZDTaichu5.0-9B: the release contradicts itself on its own best benchmark},
  url    = {https://ai.thesatyajit.com/articles/zdtaichu-5-9b},
  year   = {2026}
}
share