Skip to content

hexagon: pack Q8_0 files for the NPU and measure them on the IQ-10 - #83

Open
thanhdq1o2 wants to merge 2 commits into
VinRobotics:mainfrom
thanhdq1o2:hexagon-quant
Open

thanhdq1o2 wants to merge 2 commits into
VinRobotics:mainfrom
thanhdq1o2:hexagon-quant

Conversation

@thanhdq1o2

@thanhdq1o2 thanhdq1o2 commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

What

  • scripts/quantize_gguf.py:
    • --pad-m32 zero-pads FFN widths that are not a multiple of 32 in the file (fc1 rows and bias, fc2 columns). The HMX takes no other width for a packed weight, and the loader pads an FFN at load only when its weights are float.
    • --dit also packs the DiT's weight matrices, except adaLN and the time embedding.
    • --keep-float REGEX leaves the matching weights at their source precision.
  • tests/py/test_converters.py: covers the three flags.
  • docs/benchmark/qualcomm-iq10.md: a "Q8_0 weights" section.
  • docs/backend/hexagon.md: the flags. CHANGELOG.md.

Why

A packed weight runs on the HMX only at widths that are multiples of 32, and the DiT and single weights had no switch.

Results on the IQ-10 at 71cdb09, per model:

  • mean ms: vla-bench latency of one predict() under the TEMPLATE protocol (3 warmups, 20 reps, 3 processes).
  • System RAM: the largest drop in the board's MemAvailable while the process ran, the weights mapped for the NPU included.
  • fixed / served max|Δ|: largest difference in the action chunk against the CPU-only build at F32, on fixed synthetic inputs (vla_predict_check) and on one LIBERO observation through vla-server.

Configurations, quantize_gguf.py --type Q8_0 plus:

  • default: no flag
  • vision, unpadded: --vision
  • vision: --vision --pad-m32
  • vision + DiT: --vision --pad-m32 --dit
  • keep-float (fixed / served / union, n): --keep-float with n weights left float, from a greedy search on the fixed-input deviation, the served one, or both

Octo-Small

Config mean ms vs F16 System RAM MiB vs F16 fixed max|Δ| served max|Δ|
F16 84.1 - 725 - 5.0e-4 1.4e-4
default 81.6 -3.0% 405 -44.1% 2.5e-3 2.0e-3
vision 83.5 -0.7% 402 -44.6% 1.9e-3 1.9e-3

ACT

Config mean ms vs F16 System RAM MiB vs F16 fixed max|Δ| served max|Δ|
F16 152.5 - 469 - 6.1e-4 1.0e-3
default 150.9 -1.0% 405 -13.6% 2.1e-3 2.4e-3

TurboVLA

Config mean ms vs F16 System RAM MiB vs F16 fixed max|Δ| served max|Δ|
F16 190.2 - 1079 - 3.7e-4 8.5e-4
default 186.5 -1.9% 814 -24.6% 1.3e-2 4.2e-3
vision 185.7 -2.4% 485 -55.1% 1.4e-2 8.3e-3
vision, keep-float (fixed, 32) 185.8 -2.3% 611 -43.4% 2.6e-3 6.9e-3

VLA-JEPA

Config mean ms vs F16 System RAM MiB vs F16 fixed max|Δ| served max|Δ|
F16 496.8 - 4018 - 2.1e-3 2.2e-3
default 432.1 -13.0% 2718 -32.4% 1.4e-2 1.0e-1
vision 411.6 -17.1% 2350 -41.5% 1.5e-2 1.6e-1
vision + DiT 393.5 -20.8% 2288 -43.1% 1.3e-2 1.3e-1
vision + DiT, keep-float (fixed, 233) 461.4 -7.1% 3614 -10.1% 2.9e-3 8.3e-3
vision + DiT, keep-float (served, 143) 436.6 -12.1% 3117 -22.4% 8.4e-3 2.1e-3
vision + DiT, keep-float (union, 244) 461.6 -7.1% 3679 -8.4% 3.7e-3 5.1e-3

GR00T N1.5

Config mean ms vs F16 System RAM MiB vs F16 fixed max|Δ| served max|Δ|
F16 529.3 - 3659 - 1.9e-3 1.2e-2
default 500.2 -5.5% 3148 -14.0% 5.1e-3 8.0e-2
vision 481.1 -9.1% 2754 -24.7% 7.2e-3 4.6e-2
vision + DiT 399.2 -24.6% 2339 -36.1% 8.4e-3 3.6e-2
vision + DiT, keep-float (fixed, 191) 449.0 -15.2% 3061 -16.3% 2.7e-3 2.8e-2
vision + DiT, keep-float (served, 223) 472.9 -10.7% 3172 -13.3% 6.8e-3 9.1e-3
vision + DiT, keep-float (union, 272) 491.2 -7.2% 3413 -6.7% 3.3e-3 1.1e-2

SmolVLA

Config mean ms vs F16 System RAM MiB vs F16 fixed max|Δ| served max|Δ|
F16 584.0 - 1226 - 7.4e-4 1.9e-3
default 569.0 -2.6% 919 -25.0% 1.2e-2 1.3e-2
vision 561.0 -3.9% 848 -30.8% 3.4e-2 1.6e-2
vision, keep-float (fixed, 58) 564.2 -3.4% 896 -26.9% 2.0e-3 1.6e-2

VLA-Adapter

Config mean ms vs F16 System RAM MiB vs F16 fixed max|Δ| served max|Δ|
F16 669.2 - 3569 - 3.9e-4 3.9e-4
default 653.5 -2.3% 3200 -10.3% 4.3e-3 6.3e-3
vision 623.4 -6.8% 2555 -28.4% 3.1e-3 6.0e-3
vision, keep-float (fixed, 8) 622.7 -6.9% 2516 -29.5% 2.8e-3 6.3e-3
vision, keep-float (served, 40) 627.7 -6.2% 2494 -30.1% 2.9e-3 2.9e-3

GR00T N1.6

Config mean ms vs F16 System RAM MiB vs F16 fixed max|Δ| served max|Δ|
F16 682.6 - 4929 - 1.3e-3 1.0e-2
default 644.5 -5.6% 3959 -19.7% 7.2e-3 3.4e-2
vision, unpadded 817.3 +19.7% 3738 -24.2% 7.1e-3 2.5e-2
vision 622.5 -8.8% 3588 -27.2% 8.0e-3 2.9e-2
vision + DiT 462.2 -32.3% 2777 -43.7% 8.1e-3 2.9e-2
vision + DiT, keep-float (fixed, 57) 482.3 -29.3% 3076 -37.6% 2.8e-3 3.6e-2
vision + DiT, keep-float (served, 3) 464.0 -32.0% 2800 -43.2% 7.6e-3 9.2e-3
vision + DiT, keep-float (union, 60) 480.7 -29.6% 3114 -36.8% 3.0e-3 8.6e-3

GR00T N1.7

Config mean ms vs F16 System RAM MiB vs F16 fixed max|Δ| served max|Δ|
F16 744.9 - 5108 - 2.0e-3 2.0e-3
default 703.5 -5.6% 4356 -14.7% 1.1e-2 2.0e-2
vision 688.4 -7.6% 3996 -21.8% 2.0e-2 2.2e-2
vision + DiT 536.1 -28.0% 3151 -38.3% 2.8e-2 2.1e-2
vision + DiT, keep-float (fixed, 185) 606.0 -18.6% 4051 -20.7% 2.6e-3 5.3e-3
vision + DiT, keep-float (served, 157) 579.8 -22.2% 3870 -24.2% 4.2e-2 2.8e-3
vision + DiT, keep-float (union, 233) 614.4 -17.5% 4249 -16.8% 3.9e-3 6.5e-3

π0.5

Config mean ms vs F16 System RAM MiB vs F16 fixed max|Δ| served max|Δ|
F16 1107.8 - 5980 - 4.8e-4 3.7e-4
default 971.0 -12.3% 3997 -33.2% 4.9e-4 1.9e-3
vision, unpadded 1320.2 +19.2% 3760 -37.1% 8.5e-4 2.7e-3
vision 941.3 -15.0% 3676 -38.5% 9.2e-4 2.8e-3

π0

Config mean ms vs F16 System RAM MiB vs F16 fixed max|Δ| served max|Δ|
F16 1123.3 - 5662 - 7.7e-4 5.8e-4
default 978.8 -12.9% 3723 -34.2% 1.8e-2 1.7e-3
vision 937.6 -16.5% 3337 -41.1% 1.6e-2 1.7e-3
default, keep-float (fixed, 8) 978.8 -12.9% 3711 -34.5% 1.4e-3 5.2e-4

OpenVLA-OFT

Config mean ms vs F16 System RAM MiB vs F16 fixed max|Δ| served max|Δ|
F16 1125.2 - 15266 - 3.1e-4 7.5e-4
default 845.7 -24.8% 9403 -38.4% 5.9e-4 3.5e-3
vision 812.5 -27.8% 8821 -42.2% 7.9e-4 3.2e-3
vision, keep-float (served, 12) 821.4 -27.0% 8959 -41.3% 7.9e-4 2.5e-3

Evo-1

Config mean ms vs F16 System RAM MiB vs F16 fixed max|Δ| served max|Δ|
F16 1659.0 - 1582 - 6.2e-4 1.1e-3
default 1655.4 -0.2% 1459 -7.8% 5.4e-3 1.2e-2
vision 1638.8 -1.2% 1121 -29.1% 6.3e-3 1.4e-2
vision, keep-float (fixed, 25) 1634.5 -1.5% 1171 -26.0% 2.4e-3 1.1e-2

Verified

  • Builds clean under -Wall -Wextra (first-party code): no C++ change
  • ctest passes: no C++ change
  • Numeric output unchanged: the runtime is untouched
  • python3 tests/py/test_converters.py passes

Archs and backends tested: SmolVLA, π0, π0.5, Evo-1, GR00T N1.5 / N1.6 / N1.7, VLA-JEPA, VLA-Adapter, OpenVLA-OFT, Octo-Small, TurboVLA and ACT on the IQ-10's Hexagon NPU, against the CPU-only build (-DGGML_HEXAGON=OFF, --weight-dtype f32 --flash-attn 0).

scripts/quantize_gguf.py gains three flags:

- --pad-m32 zero-pads FFN widths that are not a multiple of 32 in the
  file. The HMX takes no other width for a packed weight, and the
  loader pads an FFN at load only when its weights are float.
- --dit also packs the DiT's weight matrices, except adaLN and the time
  embedding.
- --keep-float REGEX leaves the matching weights at their source
  precision.

tests/py/test_converters.py covers them. docs/benchmark/qualcomm-iq10.md
reports latency, memory and fidelity of each Q8_0 configuration of the
13 models on the IQ-10's Hexagon NPU, against the CPU-only build at F32.
The runtime is unchanged.
Its F16 rows gave the size of the shipped file, which stores F32 or
BF16, so they did not compare with the Q8_0 rows; System RAM is the
memory measure. The tensor column now says what it counts.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant