Hardware
- CPU: Ryzen 9 5950X
- RAM: 1x32GB 2400MHz DDR4 Corsair Vengeance
- CUDA0: RTX 3080 10GB
- CUDA1: RTX A2000 6GB
- PSU: MSI Mag A850GL (850W, 80 Plus Gold)
- Motherboard: MSI Mag B550 Tomahawk WiFi Max
- Machine name: Basilisk
Methodology
- Downloaded model weights to laptop, then transferred to Basilisk via sftp. See setup and initial tests here, or .
- Installed Nvidia drivers and llama.cpp.
-
Ran each model through
llama benchwith various parameters using bash-fu with jsonl outputs. See full benchmark scripts below. - Failed runs due to OoM are being logged.
- Will process jsonl files into one json file for this page.
#!/bin/bash
modeldir1=/mnt/sda1/weights/dense
modeldir2=/mnt/sda1/weights/MoE
modeldir3=~/Downloads/models/weights/dense
modeldir4=~/Downloads/models/weights/MoE
resultsdir=~/Downloads/models/stats
logfile=~/Downloads/models/cpu-bench.log
errorlogfile=~/Downloads/models/cpu-bench.error.log
opts="-t 32 -o jsonl --device none -ngl 0"
depths="0 32768 65536 131072"
kvquants="q8_0 q4_0"
source ~/Dowloads/models/bench-time.sh
startts=`timestamp`
set -o pipefail
benchit() {
model=$1
modeldir=$2
for d in $depths; do
for kv in $kvquants; do
perm="-m $modeldir/$model $opts -d $d -ctk $kv -ctv $kv"
if grep -Fqx -- "complete: $perm" $logfile; then
echo "Skipping $perm"
else
echo "llama bench $perm"
llama bench $perm | tee -a $resultsdir/$model.jsonl
if [ $? -ne 0 ]; then
echo Error: $perm | tee -a $errorlogfile
fi
echo "complete: $perm" >> $logfile
echo Running for $(formattime $(( `timestamp` - $startts )))
fi
done
done
}
touch $logfile
for modeldir in $modeldir1 $modeldir2 $modeldir3 $modeldir4; do
for model in $(ls $modeldir | grep .gguf | grep -v mmproj | grep -vi mtp); do
benchit $model $modeldir
done
done
#!/bin/bash
modeldir1=/mnt/sda1/weights/dense
modeldir2=~/Downloads/models/weights/dense
resultsdir=~/Downloads/models/stats
logfile=~/Downloads/models/gpu-bench.log
errorlogfile=~/Downloads/models/gpu-bench.error.log
opts="-t 32 -o jsonl"
devices="CUDA0 CUDA1"
depths="0 32768 65536 131072"
kvquants="q8_0 q4_0"
nkvos="0 1"
source ~/Dowloads/models/bench-time.sh
startts=`timestamp`
set -o pipefail
benchit() {
model=$1
modeldir=$2
for dev in $devices; do
for d in $depths; do
for kv in $kvquants; do
for nkvo in $nkvos; do
perm="-m $modeldir/$model $opts --device $dev"
perm="$perm -d $d -ctk $kv -ctv $kv -nkvo $nkvo"
if grep -Fqx -- "complete: $perm" $logfile; then
echo "Skipping $perm"
else
echo "llama bench $perm"
llama bench $perm | tee -a $resultsdir/$model.jsonl
if [ $? -ne 0 ]; then
echo Error: $perm | tee -a $errorlogfile
fi
echo "complete: $perm" >> $logfile
echo Running for $(formattime $(( `timestamp` - $startts )))
fi
done
done
done
done
}
touch $logfile
for modeldir in $modeldir1 $modeldir2; do
for model in $(ls $modeldir | grep .gguf | grep -v mmproj | grep -vi mtp); do
benchit $model $modeldir
done
done
#!/bin/bash
modeldir1=/mnt/sda1/weights/MoE
modeldir2=~/Downloads/models/weights/MoE
resultsdir=~/Downloads/models/stats
logfile=~/Downloads/models/gpu-bench.log
errorlogfile=~/Downloads/models/gpu-bench.error.log
opts="-t 32 -o jsonl"
devices="CUDA0 CUDA1 CUDA0/CUDA1"
ncmoes="0 100 200"
depths="0 32768 65536 131072"
kvquants="q8_0 q4_0"
nkvos="0 1"
source ~/Dowloads/models/bench-time.sh
startts=`timestamp`
set -o pipefail
benchit() {
model=$1
modeldir=$2
for dev in $devices; do
for ncmoe in $ncmoes; do
for d in $depths; do
for kv in $kvquants; do
for nkvo in $nkvos; do
perm="-m $modeldir/$model $opts --device $dev"
perm="$perm -ncmoe $ncmoe -d $d -ctk $kv -ctv $kv -nkvo $nkvo"
if grep -Fqx -- "complete: $perm" $logfile; then
echo "Skipping $perm"
else
echo "llama bench $perm"
llama bench $perm | tee -a $resultsdir/$model.jsonl
if [ $? -ne 0 ]; then
echo Error: $perm | tee -a $errorlogfile
fi
echo "complete: $perm" >> $logfile
echo Running for $(formattime $(( `timestamp` - $startts )))
fi
done
done
done
done
done
}
touch $logfile
for modeldir in $modeldir1 $modeldir2; do
for model in $(ls $modeldir | grep .gguf | grep -v mmproj | grep -vi mtp); do
benchit $model $modeldir
done
done
#!/bin/bash
timestamp() {
date +%s
}
formattime() {
seconds=$1
minutes=$(( seconds / 60 ))
seconds=$(( seconds - minutes * 60 ))
hours=$(( minutes / 60 ))
minutes=$(( minutes - hours * 60 ))
echo "$hours:$minutes:$seconds"
}
Notes
- The inclusion of a model in these benchmarks does not constitute an endorsement of that model for any purpose. Some of these are good, and some of them are really dumb.
-
I originally intended to benchmark more models and more
parameter permutations, but it would take ~16 months to
complete, so I drastically reduced the scope and optimized the
scripts.
-
Replaced CSV parameters with nested bash
forloops. -
Split GPU testing into dedicated dense and MoE scripts to
remove irrelevant
--device CUDA0/CUDA1and-ncmoe Xparams from dense. - Added logging of permutations and the ability to skip previously run permutations upon restart.
-
Removed the
-r 30param that would repeat each benchmark 30 times. - Replaced independently varying K and V cache types with linked KV cache types.
-
Removed
f16andiq4_nlfrom tested KV quants. -
Removed
5120and10240from tested context depths.
-
Replaced CSV parameters with nested bash
-
This benchmark system uses random tokens; MoE models often have
better performance in practice due to token correlations,
causing relevant experts to remain on the GPU when running
llama serve --moe-cache-mib N -
CPU-only was achieved via
n_gpu_layers=0(-ngl 0on CLI), whereas it was left at the default=-1for GPU -
CPU-only was achieved via
device=none, whereas it was set to another value for GPU(s) -
Both
ngl=0anddevice=nonewere required for CPU-only execution -
-dsets the context depth at which the test begins -
-ncmoeconfigures CPU offloading for MoE and was excluded for CPU tests -
-nkvo 1disables KV cache offloading to CPU/RAM during GPU tests -
-ctkand-ctvset the types for KV cache keys and values, respectively - I will endeavor to expand benchmark coverage once the first batch of results are processed, whenever the right combo of convenience, ability, and motivation strikes.
Agentic Tests
The dense academic data that will fill up the table and contribute to useful graphs will take a while to generate and collate. In the meantime, I am doing some read-only agentic tasks in real harnesses and comparing inference engines, parameters, etc. (A side quest into pragmatism.)
One such agentic task benchmark compared llama.cpp with ik_llama on Flint 40B-A2.5B IQ3_XXS. Those results can be viewed here . Or view it in a modal .
Filtering
You can filter the benchmark rows by any column. Pick a field from the dropdown and a value from the suggestions, then click Add Filter to create a removable tag. Within a single field, multiple values use OR logic (a row matches if it matches any of them); across different fields, filters use AND logic (a row must match all fields). The model field uses case-insensitive substring matching, while all other fields use case-insensitive exact matching. Clear everything with Reset Filters.
| Model | Device | GPU Layers | CPU MoE | Split Mode | Threads | K Quant | V Quant | NKVO | Depth | PP t/s | TG t/s | PP t/s σ | TG t/s σ |
|---|
Charts
Failed Runs
| Model | Device | GPU Layers | CPU MoE | Split Mode | Threads | K Quant | V Quant | NKVO | Depth |
|---|