exploring-edge-perf
  1. Theoretical LLM TPS on IQ-9075, Jetson, and NVIDIA GPUs
  • Research notebooks
  • Theoretical LLM TPS on IQ-9075, Jetson, and NVIDIA GPUs
  • 3D photo reconstruction / indoor navigation research notes
  • Autonomous indoor drone navigation / capture research notes
  • 04_ref_matrials.html
  • NVIDIA Isaac ecosystem research notes
  • ModalAI VOXL 2 Mini research notes
  • Flight compute and competing ecosystems
  • ModalAI module reference
  • The Pixhawk ecosystem
  • ROS, from zero
  • VIO and SLAM
  • Navigation and exploration
  • Drone platforms

On this page

  • Summary
  • Memory bandwidth calculation
  • Published LLM results found
  • Local GPU llama.cpp GGUF benchmark

Theoretical LLM TPS on IQ-9075, Jetson, and NVIDIA GPUs

Memory-bandwidth-bound estimate for autoregressive decode throughput.

Summary

Goal: first-pass, memory-bandwidth-bound estimate for autoregressive decode throughput.

Assumptions:

  • Batch = 1 decode/generation phase. Prefill ignored.
  • Each generated token streams model weights once.
  • Ideal theoretical TPS = peak_memory_bandwidth / weight_bytes_per_token.
  • Dtype determines bytes per parameter: INT4 = 0.5 bytes/parameter, INT8 = 1 byte/parameter, FP16 = 2 bytes/parameter.
  • Default edge deployment = INT4 weights. FP16 shown as unquantized comparison.
  • KV cache, activation traffic, dequant overhead, scheduler overhead, tokenizer, kernel efficiency ignored. Real numbers lower unless kernels/cache reuse help.
  • Jetson reference platform = Jetson AGX Orin 64GB / Developer Kit. Orin NX/Nano bandwidth noted separately.
  • NVIDIA GeForce RTX 3080 Laptop GPU = local detected GPU, 16GB VRAM (nvidia-smi).
  • NVIDIA GeForce RTX 5060 = cheap consumer desktop GPU reference; prices are point-in-time USD snapshots.

Memory bandwidth calculation

Formula:

\[ \mathrm{BW}_{GB/s} = \frac{W_{bits}}{8} \cdot \frac{R_{MT/s}}{1000} \]

where \(W_{bits}\) is memory bus width and \(R_{MT/s}\) is effective transfer rate.

LPDDR5 specs often publish 3200 MHz; for these platforms this corresponds to 6400 MT/s effective DDR data rate. NVIDIA’s own 128-bit @ 3200 MHz -> 102.4 GB/s confirms this convention [1]. For NVIDIA GeForce RTX 3080 Laptop GPU, use GDDR6 14 Gbps effective = 14000 MT/s; local nvidia-smi detects 16384 MiB VRAM. For NVIDIA GeForce RTX 5060, use GDDR7 28 Gbps effective = 28000 MT/s.

Platform Price basis Approx. USD price Memory config Bus Data rate Peak BW Status
Qualcomm Dragonwing IQ-9075 Lantronix Open-Q 9075IQ SOM [7] $886.09 3×12GB LPDDR5 ECC @ 3200MHz [2] 96-bit from 6×16-bit SA8775P-family platform [3] 6400 MT/s 76.8 GB/s Derived; public IQ brief does not publish BW
NVIDIA Jetson AGX Orin 64GB NVIDIA Jetson AGX Orin Developer Kit [8] $1,999 64GB LPDDR5 [1] 256-bit [1] 6400 MT/s 204.8 GB/s Official NVIDIA BW spec [1]
NVIDIA GeForce RTX 3080 Laptop GPU Laptop-only local GPU n/a standalone 16GB GDDR6 detected; 8/16GB GDDR6 public config [5] 256-bit [5] 14000 MT/s [6] 448.0 GB/s Published by TechPowerUp [6]
NVIDIA GeForce RTX 5060 NVIDIA MSRP [12]; Newegg listing [13] $299 MSRP; $349.99 listing 8GB GDDR7 [13] 128-bit [13] 28000 MT/s [13] 448.0 GB/s Cheap consumer desktop GPU

Price caveats: IQ-9075 price uses an available Lantronix SOM, not a Qualcomm direct MSRP. Jetson AGX price is a developer kit price. RTX 3080 Laptop GPU has no standalone card price. RTX 5060 street price is volatile; table keeps both NVIDIA MSRP and one retailer listing.

Calculations:

Platform Formula Peak BW
Qualcomm Dragonwing IQ-9075 \(\frac{96}{8}\cdot\frac{6400}{1000}\) 76.8 GB/s
NVIDIA Jetson AGX Orin 64GB \(\frac{256}{8}\cdot\frac{6400}{1000}\) 204.8 GB/s
NVIDIA GeForce RTX 3080 Laptop GPU \(\frac{256}{8}\cdot\frac{14000}{1000}\) 448.0 GB/s
NVIDIA GeForce RTX 5060 \(\frac{128}{8}\cdot\frac{28000}{1000}\) 448.0 GB/s

Caveat: Qualcomm’s public IQ-9075 brief gives memory capacity and clock, but not bus width or bandwidth. Public Linux notes describe QCS9075 as an IoT variant of SA8775P [4], so the 96-bit bus comes from public SA8775P-family platform docs [3].

Jetson family notes from NVIDIA official table [1]:

Jetson platform Memory Published BW Approx. USD price
AGX Orin 64GB / 32GB 256-bit LPDDR5 204.8 GB/s $1,999 AGX dev kit [8]
Orin NX 16GB / 8GB 128-bit LPDDR5 102.4 GB/s Varies by module/distributor
Orin Nano Super / Nano 8GB 128-bit LPDDR5 ~102 GB/s $249 dev kit [9]; $249 8GB SOM [10]
Orin Nano 4GB 64-bit LPDDR5 ~51 GB/s $259 Arrow module, no stock [11]

References:

  1. NVIDIA Jetson Orin official specs — https://www.nvidia.com/en-us/autonomous-machines/embedded-systems/jetson-orin/#:~:text=64GB%20256-bit%20LPDDR5%20204.8GB%2Fs
  2. Qualcomm Dragonwing IQ-9075 Module product brief — https://docs.qualcomm.com/doc/87-97354-1/87-97354-1_REV_B_Qualcomm_Dragonwing_IQ-9075_IQ-9100_Module_Product_Brief.pdf#page=1
  3. Thundercomm SA8255P/SA8775P platform specs — https://www.thundercomm.com/product/sa8255p-sa8775p-automotive-development-platform/#:~:text=Six-channel%20high-speed%20memory%20-3200%20MHz%20LPDDR5%20SDRAM%20%286%20x%2016-bit%29
  4. Linux kernel patch notes describing QCS9075 as SA8775P IoT variant — https://lkml.iu.edu/2506.1/07887.html#:~:text=QCS9075%20is%20an%20IoT%20variant%20of%20SA8775P%20SOC
  5. NVIDIA GeForce RTX 30-series Laptop GPU official compare specs — https://www.nvidia.com/en-eu/geforce/laptops/compare/30-series/
  6. TechPowerUp GeForce RTX 3080 Mobile specs — https://www.techpowerup.com/gpu-specs/geforce-rtx-3080-mobile.c3684
  7. Lantronix Open-Q 9075IQ SOM store listing — https://estore.lantronix.com/products/open-q-9075iq-som-system-on-module
  8. NVIDIA Jetson AGX Orin Developer Kit marketplace — https://marketplace.nvidia.com/en-us/enterprise/robotics-edge/jetson-agx-orin-developer-kit/
  9. NVIDIA Jetson Orin Nano Super Developer Kit — https://www.nvidia.com/en-us/autonomous-machines/embedded-systems/jetson-orin/nano-super-developer-kit/
  10. Arrow Jetson Orin Nano 8GB SOM listing — https://www.arrow.com/en/products/900-13767-0030-000/nvidia
  11. Arrow Jetson Orin Nano 4GB SOM listing — https://www.arrow.com/en/products/900-13767-0040-000/nvidia
  12. NVIDIA GeForce RTX 5060 launch/MSRP — https://www.nvidia.com/en-us/geforce/news/rtx-5060-out-now/
  13. Newegg GIGABYTE RTX 5060 listing — https://www.newegg.com/gigabyte-windforce-gv-n5060wf2oc-8gd-geforce-rtx-5060-8gb-graphics-card-double-fans/p/N82E16814932804

Calculated tables

Platform Approx. price Bus Data rate Peak BW
IQ-9075 $886.09 SOM 96-bit 6,400 MT/s 76.8 GB/s
Jetson AGX Orin $1,999 dev kit 256-bit 6,400 MT/s 204.8 GB/s
Jetson Orin NX/Nano 8GB Nano Super/8GB SOM: $249 128-bit 6,400 MT/s 102.4 GB/s
Jetson Orin Nano 4GB $259 SOM 64-bit 6,400 MT/s 51.2 GB/s
NVIDIA GeForce RTX 3080 Laptop GPU n/a standalone 256-bit 14,000 MT/s 448.0 GB/s
NVIDIA GeForce RTX 5060 $299 MSRP; $349.99 listing 128-bit 28,000 MT/s 448.0 GB/s
NVIDIA GeForce RTX 4090 $1,599 MSRP 384-bit 21,000 MT/s 1008.0 GB/s
NVIDIA A100 80GB PCIe n/a 5120-bit 3,200 MT/s 2048.0 GB/s

Theoretical TPS: decode, memory-bound

For decode with batch = 1 and no KV/activation overhead:

\[ \mathrm{TPS} = \frac{\mathrm{BW}_{GB/s}}{P_B \cdot B_{param}} \]

where \(P_B\) is model parameters in billions and \(B_{param}\) is bytes per parameter implied by dtype.

INT4 weights (\(B_{param}=0.5\) bytes/parameter)

Platform 2B INT4 4B INT4 8B INT4
IQ-9075 76.8 tok/s 38.4 tok/s 19.2 tok/s
Jetson AGX Orin 204.8 tok/s 102.4 tok/s 51.2 tok/s
Jetson Orin NX/Nano 8GB 102.4 tok/s 51.2 tok/s 25.6 tok/s
Jetson Orin Nano 4GB 51.2 tok/s 25.6 tok/s 12.8 tok/s
NVIDIA GeForce RTX 3080 Laptop GPU 448.0 tok/s 224.0 tok/s 112.0 tok/s
NVIDIA GeForce RTX 5060 448.0 tok/s 224.0 tok/s 112.0 tok/s
NVIDIA GeForce RTX 4090 1008.0 tok/s 504.0 tok/s 252.0 tok/s
NVIDIA A100 80GB PCIe 2048.0 tok/s 1024.0 tok/s 512.0 tok/s

INT8 weights (\(B_{param}=1\) bytes/parameter)

Platform 2B INT8 4B INT8 8B INT8
IQ-9075 38.4 tok/s 19.2 tok/s 9.6 tok/s
Jetson AGX Orin 102.4 tok/s 51.2 tok/s 25.6 tok/s
Jetson Orin NX/Nano 8GB 51.2 tok/s 25.6 tok/s 12.8 tok/s
Jetson Orin Nano 4GB 25.6 tok/s 12.8 tok/s 6.4 tok/s
NVIDIA GeForce RTX 3080 Laptop GPU 224.0 tok/s 112.0 tok/s 56.0 tok/s
NVIDIA GeForce RTX 5060 224.0 tok/s 112.0 tok/s 56.0 tok/s
NVIDIA GeForce RTX 4090 504.0 tok/s 252.0 tok/s 126.0 tok/s
NVIDIA A100 80GB PCIe 1024.0 tok/s 512.0 tok/s 256.0 tok/s

FP16 weights (\(B_{param}=2\) bytes/parameter)

Platform 2B FP16 4B FP16 8B FP16
IQ-9075 19.2 tok/s 9.6 tok/s 4.8 tok/s
Jetson AGX Orin 51.2 tok/s 25.6 tok/s 12.8 tok/s
Jetson Orin NX/Nano 8GB 25.6 tok/s 12.8 tok/s 6.4 tok/s
Jetson Orin Nano 4GB 12.8 tok/s 6.4 tok/s 3.2 tok/s
NVIDIA GeForce RTX 3080 Laptop GPU 112.0 tok/s 56.0 tok/s 28.0 tok/s
NVIDIA GeForce RTX 5060 112.0 tok/s 56.0 tok/s 28.0 tok/s
NVIDIA GeForce RTX 4090 252.0 tok/s 126.0 tok/s 63.0 tok/s
NVIDIA A100 80GB PCIe 512.0 tok/s 256.0 tok/s 128.0 tok/s

Example for 8B INT4 on IQ-9075:

\[ \mathrm{TPS} = \frac{76.8}{8 \cdot 0.5} = 19.2\ \mathrm{tok/s} \]

Published LLM results found

  • IQ-9075
    • Llama 2 13B (dtype not published): 12 tok/s [1]. Qualcomm IQ-9075 Module product brief says on-device AI runs Llama 2 13B at 12 tok/s.
    • Llama 2 7B (dtype not published): 22 tok/s [2]. Peridio hardware notes.
    • Llama 3.2 3B (W4A16): ~18.7 tok/s [3]. Hugging Face model card for QCS9075 HTP / Genie / QNN backend. Lower than pure BW limit for 3B INT4 (\(\frac{76.8}{3\cdot0.5}\approx51\) tok/s), showing runtime/NPU/dequant/KV overhead.
  • Jetson AGX Orin
    • Falcon-H1 3B (FP16): 29 tok/s; Qwen3.5 4B (dtype not published): 21 tok/s [4]. Cordatus OpenClaw benchmark, Ollama backend.
  • Jetson Orin Nano original / Super
    • MLC INT4 benchmarks: Llama 3.1 8B (INT4): 14 / 19.14 tok/s; Llama 3.2 3B (INT4): 27.7 / 43.07 tok/s; Gemma 2 2B (INT4): 21.5 / 34.97 tok/s [5]. Nano has ~102 GB/s BW [6], so 8B INT4 theoretical is \(\frac{102.4}{8\cdot0.5}=25.6\) tok/s; published 19.14 tok/s is plausible after overhead.
  • Jetson AI Lab HF example
    • Llama-2-7B (FP16): 6.2 tok/s; Llama-2-7B GPTQ (dtype not published in source): 10.3 tok/s; Llama-2-7B AWQ (dtype not published in source): 11.2 tok/s [7]. Transformers stack example; much slower than optimized MLC/TensorRT-style paths.

References:

  1. Qualcomm Dragonwing IQ-9075 Module product brief — https://docs.qualcomm.com/doc/87-97354-1/87-97354-1_REV_B_Qualcomm_Dragonwing_IQ-9075_IQ-9100_Module_Product_Brief.pdf#page=1
  2. Peridio IQ-9075 hardware notes — https://docs.peridio.com/hardware/under-evaluation/iq-9075#:~:text=Llama%202%207B%20%40%2022%20tokens%2Fsec
  3. Hugging Face QCS9075 HTP model card — https://huggingface.co/zededa/Llama-3.2-3B-Instruct-QCS9075-HTP#::text=18.7%20TPS%20on%20QCS9075
  4. Cordatus OpenClaw Jetson benchmark — https://blog.cordatus.ai/large-language-models/running-llms-on-jetson-openclaw-benchmark/#:~:text=Ollama%20%7C%20AGX%20Orin
  5. NVIDIA Jetson AI Lab benchmark archive — https://www.jetson-ai-lab.com/archive/benchmarks.html#:~:text=Llama%203.1%208B
  6. NVIDIA Jetson Orin official specs — https://www.nvidia.com/en-us/autonomous-machines/embedded-systems/jetson-orin/#:~:text=8GB%20128-bit%20LPDDR5%20102%20GB%2Fs
  7. NVIDIA Jetson AI Lab API examples — https://www.jetson-ai-lab.com/archive/tutorial_api-examples.html#:~:text=6.2%20tokens%2Fsec

Local GPU llama.cpp GGUF benchmark

I ran a local benchmark on my laptop; results roughly track the theoretical max TPS at BF16, but dip down below 50% of theoretical max at lower quant levels.

llama.cpp provides direct GGUF dtype/quant sweeps. Local build: llama.cpp commit d749821, CUDA backend, llama-bench, GPU NVIDIA GeForce RTX 3080 Laptop GPU 16GB. Build used repo-local .deps/llama.cpp plus CUDA compiler/libs from .venv (nvidia/cu13); build/runtime env is in bench_env.sh and build_llama_cpp.sh.

Models are unsloth/Qwen3.5-{2B,4B,9B}-GGUF. Run config: prompt processing = 512 tokens, generation eval = 256 tokens, repetitions = 3, batch/ubatch defaults (2048/512), all layers GPU (-ngl -1), KV cache f16, flash-attn auto. llama.cpp reports prompt processing tok/s (n_prompt=512) separately from decode tok/s (n_gen=256). GPU memory is sampled with nvidia-smi; delta subtracts desktop baseline. 9B BF16 skipped: GGUF is 17.92 GB before KV/overhead, over local 16GB VRAM.

Run the next hidden cell from this notebook to replace llama_cpp_tps_results.jsonl next to index.ipynb, then render the table. The script deletes that result file before writing fresh rows.

Prompt processing is prompt-ingest throughput, not generation throughput; compare decode to decode.

!python bench_llama_cpp.py --profile matrix --prompt-tokens 512 --gen-tokens 256 --repetitions 3
Warning: You are sending unauthenticated requests to the HF Hub. Please set a HF_TOKEN to enable higher rate limits and faster downloads.
model 2B BF16: /home/xl0/work/work/tm/research/.hf/hub/models--unsloth--Qwen3.5-2B-GGUF/snapshots/f6d5376be1edb4d416d56da11e5397a961aca8ae/Qwen3.5-2B-BF16.gguf
Running: '/home/xl0/work/work/tm/research/.deps/llama.cpp/build/bin/llama-bench -m /home/xl0/work/work/tm/research/.hf/hub/models--unsloth--Qwen3.5-2B-GGUF/snapshots/f6d5376be1edb4d416d56da11e5397a961aca8ae/Qwen3.5-2B-BF16.gguf -p 512 -n 256 -r 3 -t 8 -ngl -1 -fa auto -o jsonl'
2B   BF16 prefill  5569.11 tok/s   0.180 ms/tok, peak 4788 MiB
2B   BF16 decode     89.97 tok/s  11.115 ms/tok, peak 4788 MiB
model 2B Q8_0: /home/xl0/work/work/tm/research/.hf/hub/models--unsloth--Qwen3.5-2B-GGUF/snapshots/f6d5376be1edb4d416d56da11e5397a961aca8ae/Qwen3.5-2B-Q8_0.gguf
Running: '/home/xl0/work/work/tm/research/.deps/llama.cpp/build/bin/llama-bench -m /home/xl0/work/work/tm/research/.hf/hub/models--unsloth--Qwen3.5-2B-GGUF/snapshots/f6d5376be1edb4d416d56da11e5397a961aca8ae/Qwen3.5-2B-Q8_0.gguf -p 512 -n 256 -r 3 -t 8 -ngl -1 -fa auto -o jsonl'
2B   Q8_0 prefill  6987.02 tok/s   0.143 ms/tok, peak 3058 MiB
2B   Q8_0 decode    142.75 tok/s   7.005 ms/tok, peak 3058 MiB
model 2B Q4_K_M: /home/xl0/work/work/tm/research/.hf/hub/models--unsloth--Qwen3.5-2B-GGUF/snapshots/f6d5376be1edb4d416d56da11e5397a961aca8ae/Qwen3.5-2B-Q4_K_M.gguf
Running: '/home/xl0/work/work/tm/research/.deps/llama.cpp/build/bin/llama-bench -m /home/xl0/work/work/tm/research/.hf/hub/models--unsloth--Qwen3.5-2B-GGUF/snapshots/f6d5376be1edb4d416d56da11e5397a961aca8ae/Qwen3.5-2B-Q4_K_M.gguf -p 512 -n 256 -r 3 -t 8 -ngl -1 -fa auto -o jsonl'
2B Q4_K_M prefill  6829.30 tok/s   0.146 ms/tok, peak 2360 MiB
2B Q4_K_M decode    178.20 tok/s   5.612 ms/tok, peak 2360 MiB
model 4B BF16: /home/xl0/work/work/tm/research/.hf/hub/models--unsloth--Qwen3.5-4B-GGUF/snapshots/e87f176479d0855a907a41277aca2f8ee7a09523/Qwen3.5-4B-BF16.gguf
Running: '/home/xl0/work/work/tm/research/.deps/llama.cpp/build/bin/llama-bench -m /home/xl0/work/work/tm/research/.hf/hub/models--unsloth--Qwen3.5-4B-GGUF/snapshots/e87f176479d0855a907a41277aca2f8ee7a09523/Qwen3.5-4B-BF16.gguf -p 512 -n 256 -r 3 -t 8 -ngl -1 -fa auto -o jsonl'
4B   BF16 prefill  2426.62 tok/s   0.412 ms/tok, peak 9270 MiB
4B   BF16 decode     42.67 tok/s  23.438 ms/tok, peak 9270 MiB
model 4B Q8_0: /home/xl0/work/work/tm/research/.hf/hub/models--unsloth--Qwen3.5-4B-GGUF/snapshots/e87f176479d0855a907a41277aca2f8ee7a09523/Qwen3.5-4B-Q8_0.gguf
Running: '/home/xl0/work/work/tm/research/.deps/llama.cpp/build/bin/llama-bench -m /home/xl0/work/work/tm/research/.hf/hub/models--unsloth--Qwen3.5-4B-GGUF/snapshots/e87f176479d0855a907a41277aca2f8ee7a09523/Qwen3.5-4B-Q8_0.gguf -p 512 -n 256 -r 3 -t 8 -ngl -1 -fa auto -o jsonl'
4B   Q8_0 prefill  2955.97 tok/s   0.338 ms/tok, peak 5462 MiB
4B   Q8_0 decode     69.34 tok/s  14.422 ms/tok, peak 5462 MiB
model 4B Q4_K_M: /home/xl0/work/work/tm/research/.hf/hub/models--unsloth--Qwen3.5-4B-GGUF/snapshots/e87f176479d0855a907a41277aca2f8ee7a09523/Qwen3.5-4B-Q4_K_M.gguf
Running: '/home/xl0/work/work/tm/research/.deps/llama.cpp/build/bin/llama-bench -m /home/xl0/work/work/tm/research/.hf/hub/models--unsloth--Qwen3.5-4B-GGUF/snapshots/e87f176479d0855a907a41277aca2f8ee7a09523/Qwen3.5-4B-Q4_K_M.gguf -p 512 -n 256 -r 3 -t 8 -ngl -1 -fa auto -o jsonl'
4B Q4_K_M prefill  2843.13 tok/s   0.352 ms/tok, peak 3800 MiB
4B Q4_K_M decode     85.12 tok/s  11.749 ms/tok, peak 3800 MiB
model 9B Q8_0: /home/xl0/work/work/tm/research/.hf/hub/models--unsloth--Qwen3.5-9B-GGUF/snapshots/3885219b6810b007914f3a7950a8d1b469d598a5/Qwen3.5-9B-Q8_0.gguf
Running: '/home/xl0/work/work/tm/research/.deps/llama.cpp/build/bin/llama-bench -m /home/xl0/work/work/tm/research/.hf/hub/models--unsloth--Qwen3.5-9B-GGUF/snapshots/3885219b6810b007914f3a7950a8d1b469d598a5/Qwen3.5-9B-Q8_0.gguf -p 512 -n 256 -r 3 -t 8 -ngl -1 -fa auto -o jsonl'
9B   Q8_0 prefill  1838.12 tok/s   0.544 ms/tok, peak 9248 MiB
9B   Q8_0 decode     40.83 tok/s  24.495 ms/tok, peak 9248 MiB
model 9B Q4_K_M: /home/xl0/work/work/tm/research/.hf/hub/models--unsloth--Qwen3.5-9B-GGUF/snapshots/3885219b6810b007914f3a7950a8d1b469d598a5/Qwen3.5-9B-Q4_K_M.gguf
Running: '/home/xl0/work/work/tm/research/.deps/llama.cpp/build/bin/llama-bench -m /home/xl0/work/work/tm/research/.hf/hub/models--unsloth--Qwen3.5-9B-GGUF/snapshots/3885219b6810b007914f3a7950a8d1b469d598a5/Qwen3.5-9B-Q4_K_M.gguf -p 512 -n 256 -r 3 -t 8 -ngl -1 -fa auto -o jsonl'
9B Q4_K_M prefill  1698.81 tok/s   0.589 ms/tok, peak 6064 MiB
9B Q4_K_M decode     40.67 tok/s  24.587 ms/tok, peak 6064 MiB
import json
from pathlib import Path
import pandas as pd
from IPython.display import Markdown, display

result_path = Path('llama_cpp_tps_results.jsonl')
if not result_path.exists(): raise FileNotFoundError(f'missing {result_path}; run the benchmark cell above')

rows = [json.loads(l) for l in result_path.read_text().splitlines() if l.strip()]
df = pd.DataFrame(rows)
size_order, quant_order = ['2B', '4B', '9B'], ['BF16', 'Q8_0', 'Q4_K_M']
perf = df.groupby(['size', 'quant', 'phase'], as_index=False).agg(tok_s=('avg_ts', 'mean'))
mem = df.groupby(['size', 'quant'], as_index=False).agg(gpu_mem_delta_gib=('delta_peak_vram_mib', lambda s: s.dropna().mean()/1024))
out = perf.pivot(index=['size', 'quant'], columns='phase', values='tok_s').reset_index().merge(mem, on=['size', 'quant'])
out['size'] = pd.Categorical(out['size'], size_order, ordered=True)
out['quant'] = pd.Categorical(out['quant'], quant_order, ordered=True)
out = out.sort_values(['size', 'quant'])

lines = ['| Size | GGUF quant | Prompt processing | Decode | GPU mem delta |', '|---:|---:|---:|---:|---:|']
first = True
for size in size_order:
    part = out[out['size'].astype(str).eq(size)]
    if part.empty: continue
    if not first: lines.append('|  |  |  |  |  |')
    first = False
    for _, r in part.iterrows():
        lines.append(f"| {r['size']} | {r['quant']} | {r['prefill']:,.2f} tok/s | {r['decode']:,.2f} tok/s | {r['gpu_mem_delta_gib']:.2f} GiB |")
display(Markdown('\n'.join(lines)))
Size GGUF quant Prompt processing Decode GPU mem delta
2B BF16 5,569.11 tok/s 89.97 tok/s 4.26 GiB
2B Q8_0 6,987.02 tok/s 142.75 tok/s 2.57 GiB
2B Q4_K_M 6,829.30 tok/s 178.20 tok/s 1.89 GiB
4B BF16 2,426.62 tok/s 42.67 tok/s 8.63 GiB
4B Q8_0 2,955.97 tok/s 69.34 tok/s 4.92 GiB
4B Q4_K_M 2,843.13 tok/s 85.12 tok/s 3.29 GiB
9B Q8_0 1,838.12 tok/s 40.83 tok/s 8.61 GiB
9B Q4_K_M 1,698.81 tok/s 40.67 tok/s 5.50 GiB