https://www.youtube.com/watch?v=L9QZ97y9Exg
This repo provides a dialog-based launcher to run llama.cpp throughput tests and sweeps.
- Create and activate a virtual environment (optional):
python3 -m venv .venv
source .venv/bin/activate- Install
dialog:
- macOS:
brew install dialog - Debian/Ubuntu:
sudo apt-get install dialog - Fedora:
sudo dnf install dialog - Arch:
sudo pacman -S dialog
- Run the launcher:
./run_llama_tests.pyThe launcher lets you pick a test/sweep, select a GGUF model file, and enter env overrides.
Use the interactive menu to pick tests or sweeps and supply optional env overrides.
The launcher will try to auto-detect a .gguf in common locations unless you
pick one or set LLAMA_MODEL_PATH.
It also auto-detects llama-server from LLAMA_CPP_DIR, walking up parent
directories to find llama.cpp, or PATH unless you set it in the menu.
Model auto-detection searches common locations including ./models, ./llama.cpp/models,
/models, ~/models, ~/Models, ~/Downloads, and ~/.cache/lm-studio/models.
If you need to access the server from another machine, set LLAMA_SERVER_HOST=0.0.0.0
so nginx and llama-server bind to all interfaces (default is 127.0.0.1).
./run_llama_tests.pyRun any test or sweep directly with Python and environment variables.
.venv/bin/python -m unittest tests/test_llama_server_single.py
.venv/bin/python -m unittest tests/test_llama_server_concurrent.py
.venv/bin/python -m unittest tests/test_llama_server_round_robin.py
.venv/bin/python tests/test_llama_server_threads_sweep.py
.venv/bin/python scripts/round_robin_sweep.py
.venv/bin/python scripts/full_sweep.pyTests are quick, pass/fail checks you can run like normal unit tests. Sweeps are longer benchmark runs that explore parameter ranges and report the best throughput.
Tests:
- Single request
- Concurrent requests
- Round-robin (nginx + multiple servers, requires
nginx)
Sweeps:
- Threads (--threads/--threads-http)
- Round-robin (max_tokens x concurrency, requires
nginx) - Full (instances x parallel x concurrency, requires
nginx)
Utilities:
- Configure and run round robin (submenu to set instances/ports/parallel, then start/stop)
These use the same env overrides (e.g., LLAMA_SERVER_INSTANCES, LLAMA_PARALLEL,
LLAMA_SERVER_BASE_PORT, LLAMA_NGINX_PORT, LLAMA_SERVER_HOST, LLAMA_MODEL_PATH,
LLAMA_SERVER_BIN).
- llama.cpp built with
llama-serveravailable. nginxinstalled for round-robin tests/sweeps (brew install nginxon macOS).- Model in GGUF format.
You must provide a GGUF model path via the launcher or LLAMA_MODEL_PATH.
You need a local build of llama.cpp with the llama-server binary available.
git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp
cmake -B build
cmake --build build --config Release -jBy default this repo will look for llama-server in ./llama.cpp (a sibling of this
repo). If your llama.cpp lives elsewhere, set one of:
LLAMA_CPP_DIR=/path/to/llama.cpp
LLAMA_SERVER_BIN=/path/to/llama-server
You can supply overrides in the launcher (space-separated KEY=VALUE pairs), or set them in your shell.
LLAMA_MODEL_PATH: GGUF model path.LLAMA_MODEL_DIRS: colon- or comma-separated directories to auto-detect a.gguf(launcher only).LLAMA_MODEL_SEARCH_DEPTH: max directory depth to scan when auto-detecting (default4).LLAMA_CPP_DIR: llama.cpp repo path.LLAMA_SERVER_BIN: path tollama-serverbinary.
LLAMA_SERVER_ARGS: extra args passed tollama-serverusing comma-separated format with=for values (e.g.--ctx-size=4096,-fa=1,--mmproj=/path/to/model.bin). Space-separated args are still accepted for backward compatibility but won't handle paths with spaces. Can be set via the Advanced Args menu in the launcher or via Env Overrides. If--ctx-sizeor--parallelappear in these args, the corresponding computed value is skipped entirely (not duplicated). See Advanced Server Arguments for details.LLAMA_CTXSIZE_PER_SESSION: context size per session (tokens). If set (e.g. via env overrides), the server is started with--ctx-size (ctxsizePerSession * parallel). If not set, context is derived fromLLAMA_N_PREDICT. Formula:ctx_size = (LLAMA_CTXSIZE_PER_SESSION or LLAMA_N_PREDICT) * LLAMA_PARALLEL. The dialog UI does not expose this; it always uses the single-test token value for context.LLAMA_SERVER_HOST: host for llama-server (default127.0.0.1).LLAMA_SERVER_PORT: fixed port for single-server tests (optional).LLAMA_SERVER_INSTANCES: number of servers for round-robin tests/sweeps.LLAMA_SERVER_BASE_PORT: base port for multi-server runs (default9000).LLAMA_NGINX_PORT: nginx listen port (default8088).LLAMA_READY_TIMEOUT: seconds to wait for model readiness.LLAMA_SERVER_BIND_TIMEOUT: seconds to wait for server to bind (default 180; increase if model load is slow).LLAMA_STARTUP_DELAY_S: delay between starting servers (stagger startup).
LLAMA_PROMPT: prompt text.LLAMA_N_PREDICT: tokens to generate per request.LLAMA_TEMPERATURE: sampling temperature.LLAMA_CONCURRENCY: concurrent requests (tests).LLAMA_NUM_REQUESTS: total requests per run (tests/sweeps).
LLAMA_THREADS_LIST: comma/space list for--threads.LLAMA_THREADS_HTTP_LIST: list for--threads-http(usedefaultfor unset).LLAMA_THREADS_HTTP: single value override for--threads-http(legacy).
LLAMA_MAX_TOKENS_LIST: list of max tokens (round-robin sweep). Values ≤2048 use one server run (ctx=2048×parallel); values >2048 restart the server per value (ctx=n_predict×parallel).LLAMA_CONCURRENCY_LIST: list of concurrencies (sweeps).LLAMA_INSTANCES_LIST: list of instance counts (full sweep).LLAMA_PARALLEL_LIST: list of--parallelvalues (full sweep).LLAMA_BATCH_LIST: list for--batch-size(round-robin/full sweep, usedefaultto skip).LLAMA_UBATCH_LIST: list for--ubatch(round-robin/full sweep, usedefaultto skip).LLAMA_REQUESTS_MULTIPLIER: ifLLAMA_NUM_REQUESTSis unset, total requests = concurrency * multiplier.LLAMA_CONTINUE_ON_ERROR: set to0to stop on the first failing config (default continues).LLAMA_REQUEST_TIMEOUT: per-request timeout (seconds).LLAMA_RETRY_ATTEMPTS: retries for transient HTTP errors.LLAMA_RETRY_SLEEP_S: base retry backoff (seconds).LLAMA_CELL_PAUSE_S: pause between sweep cells (seconds).LLAMA_WARMUP_REQUESTS: warmup requests before a sweep run.LLAMA_RESULTS_DIR: base directory for sweep output files (defaultresults).
The launcher exposes an Advanced Args field (main menu option 6, and in the
round-robin submenu) that lets you pass arbitrary flags directly to llama-server
via the LLAMA_SERVER_ARGS environment variable.
Use comma-separated tokens (recommended). Join flags and values with =:
--ctx-size=4096,-fa=1,--mmproj=/path with spaces/file.bin
Each comma-delimited token becomes one argument. Paths with spaces are fully supported because commas (not spaces) delimit arguments.
If you omit commas, the legacy space-separated format is still accepted, but paths with spaces will break.
If --ctx-size or --parallel are present in LLAMA_SERVER_ARGS, the launcher
skips injecting the corresponding computed value entirely — it does not pass
the flag twice and rely on last-value-wins. This matters because llama-server
divides the total --ctx-size budget among --parallel slots. If you set
--ctx-size=262144,--parallel=16, each slot gets 16 384 tokens of context.
For example, if you enter --ctx-size=262144 in Advanced Args, the launcher will
not inject its own computed --ctx-size at all, so the value you set is the one
the server sees.
If you set LLAMA_SERVER_ARGS in the Env Overrides field (e.g.
LLAMA_SERVER_ARGS="--ctx-size=8192"), it takes priority over the Advanced Args
field. The Advanced Args value is only used when LLAMA_SERVER_ARGS is not
already present in Env Overrides.
The full sweep (scripts/full_sweep.py) filters --parallel, --batch-size,
and --ubatch from LLAMA_SERVER_ARGS and replaces them with sweep-specific
values. Other arguments (e.g. -fa 1, --mmproj) are preserved.
- Reserved flags in sweeps:
--parallel,--batch-size, and--ubatchare auto-managed by sweep scripts and will be stripped/replaced. Do not rely on setting these through Advanced Args when running sweeps.
Run the launcher and pass overrides in the dialog:
LLAMA_CONCURRENCY=64 LLAMA_NUM_REQUESTS=64 LLAMA_SERVER_ARGS="--parallel=64"
Note: LLAMA_SERVER_ARGS is for fixed runs. For the full sweep, use
LLAMA_PARALLEL_LIST (it already sweeps --parallel), so you can omit
LLAMA_SERVER_ARGS.
Run a concurrent test with custom concurrency and requests:
LLAMA_CONCURRENCY=64 LLAMA_NUM_REQUESTS=64 \
.venv/bin/python -m unittest tests/test_llama_server_concurrent.pyRun full sweep with custom ranges:
LLAMA_INSTANCES_LIST="2,4,8,16" \
LLAMA_PARALLEL_LIST="16,32,64" \
LLAMA_CONCURRENCY_LIST="32,64,128" \
.venv/bin/python scripts/full_sweep.pySweep results are written incrementally to:
results/full_sweep/full_sweep_<timestamp>.csv
results/round_robin_sweep/round_robin_sweep_<timestamp>.csv
Progress updates are printed to stderr during sweeps (completed/total and elapsed time).
python analyze-data.py --file results/full_sweep/full_sweep_20260131_150913.csv --field errors --order desc --count 10Parameters:
--file ... which file you want to process (required)
--field ... which field do you want to sort by (throughput_tps is the default if none is given)
--order ... 'asc' or 'desc' for ascending or descending (descending is the default if not given)
--count ... how many records to show (5 is the default)
Output will look something like this:
$ python analyze-data.py --file results/full_sweep/full_sweep_20260131_150913.csv
instances | parallel | batch | ubatch | concurrency | throughput_tps | total_tokens | elapsed_s | errors
-----------------------------------------------------------------------------------------------------------
2.0 | 64.0 | default | default | 128.0 | 359.4 | 16384.0 | 45.59 | 0.0
2.0 | 32.0 | default | default | 64.0 | 217.6 | 8192.0 | 37.64 | 0.0
2.0 | 64.0 | default | default | 64.0 | 217.5 | 8192.0 | 37.67 | 0.0
2.0 | 32.0 | default | default | 128.0 | 91.0 | 8448.0 | 92.82 | 62.0
2.0 | 64.0 | default | default | 32.0 | 75.0 | 4096.0 | 54.59 | 0.0
$ python analyze-data.py --file results/full_sweep/full_sweep_20260131_150913.csv --field errors --order desc --count 10
instances | parallel | batch | ubatch | concurrency | throughput_tps | total_tokens | elapsed_s | errors
-----------------------------------------------------------------------------------------------------------
4.0 | 32.0 | default | default | 128.0 | 0.0 | 0.0 | 14.07 | 128.0
4.0 | 16.0 | default | default | 128.0 | 19.1 | 2560.0 | 134.05 | 108.0
2.0 | 16.0 | default | default | 128.0 | 46.7 | 4352.0 | 93.12 | 94.0
4.0 | 32.0 | default | default | 64.0 | 0.0 | 0.0 | 14.05 | 64.0
2.0 | 32.0 | default | default | 128.0 | 91.0 | 8448.0 | 92.82 | 62.0
4.0 | 16.0 | default | default | 64.0 | 16.2 | 2176.0 | 134.08 | 47.0
4.0 | 32.0 | default | default | 32.0 | 0.0 | 0.0 | 28.94 | 32.0
2.0 | 16.0 | default | default | 64.0 | 48.6 | 4352.0 | 89.6 | 30.0
2.0 | 16.0 | default | default | 32.0 | 73.9 | 4096.0 | 55.46 | 0.0
2.0 | 32.0 | default | default | 32.0 | 73.6 | 4096.0 | 55.64 | 0.0