Radek (Sixi)

sixi-asi 0.9: 45 tok/s from a 27B hybrid model on Jetson Thor, and the kernel switch point that was hiding it

Radek (Sixi) · 10 November 2026 · source, patches, benchmark scripts and raw results

Two days ago sixi-asi 0.8 decoded Qwen3.8-27B at 23.2 tokens per second on an NVIDIA Jetson AGX Thor. Version 0.9 does 45.3 on the same weights, 3.8 times plain autoregressive decoding, and answers a follow-up question about a 63,000-token document in one second instead of three and a half minutes. Most of the gain came from finding out that an explanation I published in the 0.8 write-up was wrong.

0.80.9
Decode, mean of 5 tasks23.2 tok/s45.3 tok/s
Reasoning workload (GSM8K + HumanEval, thinking on)-65.7 tok/s, 28/30 and 19/20
Next question about a 63k-token document209 s1.0 s to first token
Verify pass of 8 rows163 ms88 ms

What I got wrong in 0.8

Speculative decoding drafts k tokens and verifies them in one batched pass of the target model. In 0.8 I measured that every extra row in that pass cost about 17 ms on Thor, attributed it to the 48 Gated DeltaNet layers scanning the batch sequentially, and tuned the server to short drafts (k = 3).

A profile of one forward pass says otherwise. Quantized matrix products are 83 to 92% of GPU time. The recurrence is about 3 ms. The per-row cost came from llama.cpp's kernel selection: up to 8 rows it uses a matrix-vector kernel that decodes the 4-bit weights again for every row, and only from 9 rows on does it switch to a matrix-matrix kernel. Upstream keeps a tuned switch point for the RTX 4090, RTX 5090, DGX Spark and Jetson Orin. Thor (compute capability 11.0) had none and inherited the default.

Milliseconds per forward pass versus rows in the batch. Upstream llama.cpp climbs from 85 ms at 1 row to 163 ms at 8 rows, then 113 to 116 ms from 9 to 16 rows. With the patch it stays between 84 and 94 ms from 1 to 16 rows. The weight-read floor is about 58 ms.

The patch: 106 lines, two launch-shape changes

Neither change touches the weights or the arithmetic; test-backend-ops passes every MUL_MAT and MUL_MAT_ID case. One candidate from the sweep was faster than physics allows: 57 ms, below the roughly 58 ms it takes just to read 15.8 GB of weights at 273 GB/s. It failed 69 correctness cases and was dropped. A benchmark that beats the roofline is a bug report.

Drafters

With verification nearly flat from 4 to 16 rows, long drafts are free, so block drafters win. 0.9 drives three of them behind one interface: DSpine (16-token block), DSpark (Markov and confidence heads) and DFlash2. Two orchestration bugs were worth more than any tuning:

Numbers

NVIDIA Jetson AGX Thor developer kit (122.9 GiB unified LPDDR5X, about 273 GB/s, CUDA 13.2, MAXN). Qwen3.8-27B, greedy, batch 1, identical prompts for every engine, 256 generated tokens, thinking on, median of 3 runs per task. Every sixi-asi number was re-measured on the published build.

Decode tokens per second: TensorRT Edge-LLM DFlash2 on NVFP4 45.4, sixi-asi 0.9 DSpine on Q4_K_M 45.3, llama-server DSpine 43.7, sixi-asi DFlash2 41.4, sixi-asi DSpark 37.2, Edge-LLM DSpark 36.1, sixi-asi 0.8 23.2, llama-server autoregressive 11.9.

NVIDIA's TensorRT Edge-LLM is the reference to beat on this box: a TensorRT engine with native NVFP4 weights on the Blackwell tensor cores. sixi-asi matches it on plain Q4_K_M GGUF weights, with no 15-minute engine build per configuration, and passes it on the workload that looks like real use:

EngineGSM8KHumanEvalTool callstok/s
sixi-asi, DSpine, Q4_K_M28/3019/20pass65.7
TensorRT Edge-LLM, DFlash2, NVFP428/3019/20pass61.5
sixi-asi, DSpine, UD-Q4_K_XL28/3019/20pass54.5

All three miss the same three problems. I first ran this gate with a 1024-token cap and briefly believed NVFP4 was worse at code (15/20 against 18/20). It was not: the cap was cutting the model off mid-reasoning on three tasks, differently per run. With an 8192-token budget the scores are identical. Edge-LLM's server also defaults to thinking off, which makes it look 20% faster until both engines are asked to do the same work.

Long documents

A hybrid model's recurrent state cannot be rolled back further than its snapshot ring, and sixi-asi took its only snapshot at the end of the prompt, after the question. So a second question about the same document paid the whole prefill again. 0.9 leaves two device-side checkpoints near the end of every long prefill, 512 and 64 tokens before the end, each about a millisecond to take.

Time to first token for the next question about the same document. Full re-prefill: 11 s at 4k tokens, 50 s at 17k, 110 s at 36k, 209 s at 63k. With tail checkpoints: 0.7, 0.8, 0.9 and 1.0 seconds.

Decode holds 19 to 29 tok/s with 63k tokens in context and 30 to 48 tok/s at 4k. The KV cache costs about 70 KB per token because only 17 layers are attention layers, so on a 122 GiB machine context length is a time budget, not a memory budget.

What the numbers do not say

Every claim ships with its script (scripts/ab_bench.py, scripts/intel_eval.py, scripts/longctx_bench.py), the kernel patch (patches/llama.cpp/0003) and the raw JSON under configs/benchmarks/2026-11-10/. If you can refute a number on your own Thor, please open an issue.


Source, Apache-2.0: github.com/radeksixi/sixi-asi. Previous write-up: sixi-asi 0.8.