Exp 2026 10 09 fp16 K Slice Is Inert On The Inference Path - oRKLLM/ork-driver GitHub Wiki

Exp-2026-10-09 โ€” the fp16 K-slice fix is a tie end-to-end, because ggml-ork never calls fp16

Board: RK3588 10.3.0.236, kernel 6.1.115-vendor-rk35xx-fence, governors verified (DDR 2112 MHz / A76 2400 MHz, both performance), NPU guard held, 0 faults. Stack: llama.cpp-rockchip diverged-history @ e32561c79, built fresh in a separate clone (~/benchf16) with -DGGML_ORK=ON -DGGML_OPENMP=ON -DGGML_NATIVE=ON. Model: qwen3-1.7b-f16.gguf, ork_bench โ€ฆ 128 32 128, 3 reps per arm, warm.

Result โ€” a tie

arm prefill tok/s decode tok/s
ork-driver 1.0.165 (new, ran first) 193.58 / 192.80 / 192.56 โ†’ 192.98 6.18 / 6.20 / 6.19 โ†’ 6.19
ork-driver 1.0.160 (old) 192.71 / 192.07 / 191.91 โ†’ 192.23 6.20 / 6.22 / 6.19 โ†’ 6.20

+0.4% prefill, โˆ’0.2% decode. Both are far inside this project's ~2% screen resolution, and well below the arm-position bias band (up to 1.126ร— on this board). The new arm deliberately ran from the disadvantaged first position and its nominal 0.4% edge is too small to mean anything either way. Call it a tie.

Why โ€” the fp16 datapath is not on this route at all

The fix in question (Exp-2026-10-09-fp16-K-Slice-and-the-Training-Step) is real and large where it applies: orki_f16_sched's window is [128,2048) while the SoC's fp16 K-slice was 2048, so every full fp16 K-slice landed on sched=0 with its 8-row M-cap, and a submit re-streams its whole weight slice regardless of row count. Probed alone that is 2.3โ€“2.5ร— at ordinary K and 5.01ร— on a 248k-wide contraction.

It changes nothing here because ggml-ork routes even an f16 GGUF through the int8 datapath. ORK_PROFILE=1 on this exact run reports:

[ork PROFILE] run_i8: 501 calls, 1081.0 ms total, 2158 us/call

and nothing else โ€” ork_f16_mm_* is never reached, so a change to fp16 K-slicing cannot show up.

Caveat on that evidence: ork-driver has run_i8 and run_i4 profile counters and no fp16 counter, so "zero fp16 calls" is an inference from the absence of a line, not a measurement. That is why the timing A/B was run anyway rather than resting on the profile. If fp16 routing is ever pursued in ggml-ork, add the counter first.

What this is good for

  • The submodule bump is safe. 1.0.160 โ†’ 1.0.165 is neutral on the inference path; nothing regressed.
  • Don't re-derive this. A future reader seeing a 5ร— fp16 matmul win should not expect it in ork_bench numbers. The win lives in the training path, in ork_bmm_fp16/ORK_ATTN work, and in any future fp16 routing โ€” not in Q8_0/f16 GGUF inference as currently dispatched.
  • Predict the dispatch before booking board time. The mechanism (int8-only routing) was visible in a single ORK_PROFILE line and would have predicted the tie before six benchmark runs.

Method notes worth keeping

  • sudo -E resets HOME to root's. A bench script using $HOME/model.gguf under sudo -E sh script silently resolved to /root/..., the binary never ran, and the harness printed three blank result lines rather than failing. Use absolute paths in anything run under sudo. This is a second face of the sudo env trap already recorded in AGENTS.md ยง3.
  • The benchmark ran in a separate clone, because .236's ~/llama.cpp had ~3000 lines of uncommitted ggml-ork work in it. That is snapshotted on branch wip/board-236-ggml-ork-20261009 rather than discarded.