Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion docs/benchmark/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ Per-device latency and memory for every architecture, measured with `vla-bench`
synthetic inputs at `c93ca0a` (PR #32), llama.cpp `b11223`. The Core Ultra X7
358H ran at `450992c`, which differs from `c93ca0a` only by an OpenVINO fix
(`3ff447c`) and docs. The Jetson Orin NX ran at `f7e0f7f`, which differs from
`c93ca0a` only by docs, release tooling and OpenVINO-only scripts. Each report
`c93ca0a` only by docs, release tooling and OpenVINO-only scripts. The Arc B390
SYCL row ran later, at `1adf078` (after PR #33, same llama.cpp pin). Each report
lists the device, the build, each model's configuration, latency and peak memory
at the defaults, and the fastest runtime flags for that device.

The table below gives the minimum latency in ms at the defaults, the one number
every report has. `N/A` means the arch does not run on that backend, and `-`
means the model does not fit or fails there; each report says which and why.
`n/r` means not run.

| Device | Octo-Small | TurboVLA | VLA-JEPA | VLA-Adapter | GR00T N1.5 | GR00T N1.6 | GR00T N1.7 | BitVLA | SmolVLA | π0 | π0.5 | OpenVLA-OFT | Evo-1 |
|---|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|
Expand All @@ -22,6 +24,7 @@ means the model does not fit or fails there; each report says which and why.
| [Jetson Orin NX 16 GB (CUDA)](jetson-orin-nx.md) | 27.4 | 79.7 | 176.7 | 270.7 | 260.8 | 252.1 | 251.4 | 269.1 | 411.2 | 739.6 | 742.9 | - | 893.2 |
| [Jetson Orin Nano Super (CUDA)](jetson-orin-nano.md) | 31.9 | 89.3 | 193.9 | 297.5 | 293.4 | 272.3 | 271.7 | 335.0 | 462.8 | 845.2 | 849.7 | - | 1011.5 |
| [Apple M4 (Metal)](apple-m4.md) | 22.6 | 65.2 | 248.7 | 315.7 | 401.5 | 358.9 | 350.8 | N/A | 357.6 | 1141.1 | 1153.8 | 1650.7 | 829.3 |
| [Intel Arc B390 iGPU (SYCL)](core-ultra-x7-358h.md) | 17.0 | 45.0 | 103.5 | 144.9 | 156.7 | 183.1 | 181.2 | N/A | 228.0 | 366.7 | 369.1 | n/r | 535.8 |
| [Intel Arc B390 iGPU (OpenVINO)](core-ultra-x7-358h.md) | N/A | 35.6 | 152.4 | 232.6 | 145.5 | 225.1 | 230.8 | N/A | 499.8 | 795.8 | 581.5 | 1494.4 | 841.5 |
| [Intel Arc A380 (SYCL)](arc-a380.md) | 60.5 | 103.5 | 355.9 | 408.9 | 472.0 | 646.0 | 615.3 | N/A | 734.5 | 921.9 | 945.6 | - | 1047.3 |
| [Snapdragon X Hexagon NPU](snapdragon-x-hexagon.md) | 239.7 | 2280.8 | 821.0 | 4072.1 | 2755.7 | 2940.0 | 1400.2 | N/A | 1239.3 | 5730.0 | 9321.7 | - | 7208.6 |
Expand All @@ -46,6 +49,9 @@ Notes on the table:
CPU row shows the same effect: `min` sits 42% below `p50` for Octo-Small and
about 18% below for VLA-JEPA and GR00T N1.7. On its AI Boost NPU, VLA-Adapter's
`min` is 27% below `p50`.
- On the Arc B390 SYCL row, OpenVLA-OFT was not run: its 15 GB GGUF was not
downloaded for that round. SYCL there goes through the OpenCL adapter, because
the Level Zero adapter segfaults with that machine's loader (1.16.1).
- The OpenVINO rows have no Octo-Small, because OpenVINO cannot translate one of
its ops yet. The NPU compiler rejects the graphs of six archs; the report
quotes each error.
Expand Down
93 changes: 91 additions & 2 deletions docs/benchmark/core-ultra-x7-358h.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
`vla-bench` times `predict()` in-process on synthetic inputs. It measures the
engine only: no transport, no simulator, and no claim about task success.

Four ways to run on this chip, from two builds. The OpenVINO build selects its device with
Five ways to run on this chip, from three builds. The OpenVINO build selects its device with
`GGML_OPENVINO_DEVICE`: `GPU` for the Arc B390 iGPU, `NPU` for the AI Boost NPU and `CPU` for
OpenVINO's CPU plugin. Every OpenVINO run was checked against ggml's `OpenVINO: using device` line,
so a silent fallback to another device would have been counted as a failure. A build without
OpenVINO gives ggml's own CPU backend.
OpenVINO gives ggml's own CPU backend. A SYCL build runs ggml's SYCL backend on the Arc B390; it
was measured later, at a newer commit, and its section has its own setup table.

## Test setup

Expand Down Expand Up @@ -128,6 +129,76 @@ vision stage separately.

</details>

## Latency and memory: Arc B390 iGPU (SYCL)

A third build: ggml's SYCL backend, compiled with oneAPI. It ran later than the
other sections, on a newer commit and driver, so it has its own setup table.

| | |
|---|---|
| Commit | `1adf078` (main, after PR #33) |
| llama.cpp | `b11223` |
| OS | Ubuntu 24.04.5 LTS, kernel 7.0 |
| Toolkit | oneAPI 2026.1 (icx/icpx), GPU compute runtime 26.35.39758.10, Level Zero loader 1.16.1 |
| SYCL adapter | OpenCL (`UR_ADAPTERS_FORCE_LOAD=.../libur_adapter_opencl.so.0`). The Level Zero adapter segfaults with loader 1.16.1, so every run went through OpenCL. The A380 report ran on Level Zero. |
| Power | platform profile `balanced`; PL1 25 W, PL2 65 W; `intel_pstate` `powersave` governor |
| Date | 2026-10-09 12:17 to 20:25 and 2026-10-12 13:53 to 13:57 (π0.5) (UTC+07) |
| Build | `-DGGML_SYCL=ON -DCMAKE_C_COMPILER=icx -DCMAKE_CXX_COMPILER=icpx -DCMAKE_BUILD_TYPE=Release -G Ninja` (`GGML_NATIVE=ON`), after `source /opt/intel/oneapi/setvars.sh` |
| Method | as above: 3 warmups + 20 timed reps per process, 3 processes, best mean; the same flag screen |

Peak device buffers are the xe `fdinfo` counters, as for the OpenVINO GPU plugin.

Rows are sorted by latency. `vision ms` is `-` for archs that do not time their
vision stage separately.

| Model | Views | Input | min ms | mean ms | p50 ms | p90 ms | vision ms | Peak device buffers MiB | Peak RSS MiB |
|---|--:|--:|--:|--:|--:|--:|--:|--:|--:|
| Octo-Small | 2 | 256 + 128 | 17.0 | 17.2 | 17.1 | 17.4 | 2.0 | 605 | 417 |
| TurboVLA | 2 | 256 | 45.0 | 46.0 | 45.7 | 47.2 | - | 901 | 423 |
| VLA-JEPA | 1 | 256 | 103.5 | 104.7 | 104.8 | 105.5 | 40.0 | 3866 | 394 |
| VLA-Adapter | 1 | 224 | 144.9 | 145.1 | 145.0 | 145.4 | 77.9 | 2760 | 1039 |
| GR00T N1.5 | 1 | 224 | 156.7 | 156.9 | 156.8 | 157.1 | 39.2 | 3548 | 386 |
| GR00T N1.7 | 1 | 256 | 181.2 | 184.6 | 184.9 | 187.5 | 40.6 | 4933 | 382 |
| GR00T N1.6 | 1 | 224 | 183.1 | 183.8 | 183.7 | 184.4 | 39.8 | 4581 | 383 |
| SmolVLA | 2 | 512 | 228.0 | 228.3 | 228.2 | 228.6 | 155.2 | 1129 | 396 |
| π0 | 2 | 224 | 366.7 | 367.6 | 367.5 | 368.5 | 79.1 | 5380 | 451 |
| π0.5 | 2 | 224 | 369.1 | 370.0 | 369.9 | 370.5 | 78.6 | 5706 | 449 |
| Evo-1 | 1 | 448 | 535.8 | 536.9 | 536.5 | 538.4 | 261.7 | 1474 | 485 |

### Fastest configuration: Arc B390 iGPU (SYCL)

| Model | Fastest flags | min ms | mean ms | p50 ms | p90 ms | vision ms | Peak device buffers MiB | Peak RSS MiB | vs defaults |
|---|---|--:|--:|--:|--:|--:|--:|--:|--:|
| Octo-Small | *(defaults)* | 17.0 | 17.2 | 17.1 | 17.4 | 2.0 | 605 | 417 | - |
| TurboVLA | `--weight-dtype f16 --flash-attn` | 23.7 | 23.9 | 23.8 | 24.0 | - | 550 | 419 | -48% |
| VLA-JEPA | *(defaults)* | 103.5 | 104.7 | 104.8 | 105.5 | 40.0 | 3866 | 394 | - |
| GR00T N1.5 | `--weight-dtype bf16 --flash-attn` | 144.5 | 144.9 | 144.8 | 145.4 | 36.9 | 3557 | 399 | -8% |
| VLA-Adapter | *(defaults)* | 144.9 | 145.1 | 145.0 | 145.4 | 77.9 | 2760 | 1039 | - |
| GR00T N1.6 | `--weight-dtype bf16 --flash-attn` | 174.8 | 175.1 | 175.1 | 175.6 | 37.5 | 4578 | 386 | -5% |
| SmolVLA | `--flash-attn --mm-prec default` | 177.0 | 177.3 | 177.2 | 177.6 | 104.1 | 1108 | 396 | -22% |
| GR00T N1.7 | *(defaults)* | 181.2 | 184.6 | 184.9 | 187.5 | 40.6 | 4933 | 382 | - |
| π0 | *(defaults)* | 366.7 | 367.6 | 367.5 | 368.5 | 79.1 | 5380 | 451 | - |
| π0.5 | *(defaults)* | 369.1 | 370.0 | 369.9 | 370.5 | 78.6 | 5706 | 449 | - |
| Evo-1 | `--weight-dtype bf16 --flash-attn` | 437.7 | 438.4 | 438.4 | 438.8 | 163.2 | 1435 | 481 | -18% |

<details><summary>Screen means (ms) per flag set</summary>

| Model | defaults | `--flash-attn` | `--mm-prec default` | `--flash-attn --mm-prec default` | `--weight-dtype bf16` | `--weight-dtype bf16 --flash-attn` | `--weight-dtype f16` | `--weight-dtype f16 --flash-attn` |
|---|--:|--:|--:|--:|--:|--:|--:|--:|
| Octo-Small | 17.2 | 17.6 | 17.4 | 17.6 | 17.2 | 17.6 | 17.3 | 17.4 |
| TurboVLA | 45.6 | 36.3 | 45.8 | 36.3 | 36.7 | 25.5 | 35.3 | 23.9 |
| VLA-JEPA | 113.0 | 98.9 | 112.5 | 108.2 | 112.1 | 99.7 | 269.3 | 284.0 |
| VLA-Adapter | 145.2 | 145.1 | 145.1 | 145.2 | 145.5 | 145.2 | 270.3 | 269.4 |
| GR00T N1.5 | 157.1 | 145.4 | 157.2 | 145.2 | 157.3 | 145.1 | 421.9 | 409.7 |
| GR00T N1.7 | 198.8 | 195.2 | 198.9 | 195.9 | 186.3 | 195.2 | 606.7 | 604.1 |
| GR00T N1.6 | 199.4 | 178.8 | 180.4 | 177.1 | 179.2 | 175.7 | 688.7 | 488.0 |
| SmolVLA | 229.4 | 177.3 | 229.7 | 177.1 | 229.2 | 177.7 | 330.1 | 278.8 |
| π0 | 367.7 | 367.8 | 367.7 | 367.2 | 367.1 | 367.8 | 907.5 | 923.4 |
| π0.5 | 370.3 | 373.6 | 370.3 | 372.6 | 369.4 | 370.5 | 907.4 | 907.0 |
| Evo-1 | 537.9 | 438.2 | 537.2 | 438.2 | 536.6 | 437.7 | 782.3 | 682.6 |

</details>

## Latency and memory: AI Boost NPU (OpenVINO NPU plugin)

Rows are sorted by latency. `vision ms` is `-` for archs that do not time their
Expand Down Expand Up @@ -287,6 +358,11 @@ vision stage separately.
GGML OpenVINO backend ov::Exception: Check 'it != m_translator_map.end()' failed at openvino/translate_session.cpp:304
```

### Arc B390 iGPU (SYCL)

- **BitVLA**: N/A off CUDA. The only published GGUF is int2-packed, and only CUDA builds load it.
- **OpenVLA-OFT**: not attempted. Its 15 GB GGUF was not downloaded for this round, so whether it fits is unknown.

### AI Boost NPU (OpenVINO NPU plugin)

- **π0.5**: the NPU compiler rejects the graph's dynamic shape:
Expand Down Expand Up @@ -371,6 +447,10 @@ A latency is not a correctness check. `docs/backend/ov.md` lists π0 as wrong on

The chip runs under a 25 W long-term power limit. The first timed calls of a process can run at boost power, so on the CPU sections read `mean` or `p50` for sustained latency.

On SYCL, a few models settle at one of two speeds per process. The three process means were 199.9, 184.6 and 199.0 ms for GR00T N1.7, 184.6, 183.8 and 201.0 ms for GR00T N1.6, and 104.7, 112.7 and 113.2 ms for VLA-JEPA; the reported row is the fast process. The one-process screen often landed on the slow speed, so for these three models the gap between the defaults and a flag set in the screen is within this noise.

The SYCL build at `1adf078` is not the same binary as an SYCL build at `c93ca0a`. PR #33 links `vla_core` with `-fsycl-device-code-split=per_kernel` and the JIT option `-cl-fp32-correctly-rounded-divide-sqrt`. Both are link options, so they also apply to ggml-sycl's kernels in the same binary.

## Reproducing

```bash
Expand All @@ -385,6 +465,15 @@ ZE_ENABLE_ALT_DRIVERS=/lib/x86_64-linux-gnu/libze_intel_npu.so.1 GGML_OPENVINO_D
./build-ov/vla-bench --ckpt smolvla-libero.gguf --images 2 --size 512 --warmup 3 --reps 20
GGML_OPENVINO_DEVICE=CPU ./build-ov/vla-bench --ckpt smolvla-libero.gguf --images 2 --size 512 --warmup 3 --reps 20

# SYCL build: Arc B390 iGPU
source /opt/intel/oneapi/setvars.sh
cmake -S . -B build-sycl -G Ninja -DGGML_SYCL=ON -DCMAKE_C_COMPILER=icx -DCMAKE_CXX_COMPILER=icpx -DCMAKE_BUILD_TYPE=Release
cmake --build build-sycl -j
export UR_ADAPTERS_FORCE_LOAD=/opt/intel/oneapi/compiler/2026.1/lib/libur_adapter_opencl.so.0 # Level Zero 1.16.1 segfaults
./build-sycl/vla-bench --ckpt smolvla-libero.gguf --images 2 --size 512 --warmup 3 --reps 20
# GR00T and Octo also need their env (see Model configuration), for example:
VLA_GR00T_EMBODIMENT=libero_sim ./build-sycl/vla-bench --ckpt gr00tn1d7-libero-object.gguf --images 1 --size 256 --warmup 3 --reps 20

# ggml CPU backend
cmake -S . -B build-cpu -DCMAKE_BUILD_TYPE=Release && cmake --build build-cpu -j
./build-cpu/vla-bench --ckpt smolvla-libero.gguf --images 2 --size 512 --warmup 3 --reps 20
Expand Down
Loading