LLaMA.cpp container quick start
Download models, benchmark them and run llama.cpp, all from the official container
Published on updated on
There is a Quick Start on llama.cpp’s GitHub page but this page is focused on using containers.
The models are big so I prefer to download them once, not on every container run.
Download models
#!/bin/bash
declare -a HF_MODELS=(
'google/gemma-4-12B-it-qat-q4_0-gguf'
'google/gemma-4-E4B-it-qat-q4_0-gguf'
'google/gemma-4-E2B-it-qat-q4_0-gguf'
'unsloth/gemma-4-12B-it-qat-GGUF:UD-Q4_K_XL'
'unsloth/gemma-4-26B-A4B-it-qat-GGUF:UD-Q4_K_XL'
'unsloth/Qwen3-Coder-30B-A3B-Instruct-GGUF:Q4_K_XL'
)
mkdir -p "$HOME"/llama/models
for model_name in "${HF_MODELS[@]}"; do
podman run -it --rm \
--volume $HOME/llama/models:/models \
--env LLAMA_CACHE=/models \
ghcr.io/ggml-org/llama.cpp:light -hf "${model_name}"
done
Benchmark
cd "$HOME/llama/models"
podman run -it --rm \
--volume $HOME/llama/models:/models \
--env LLAMA_CACHE=/models \
ghcr.io/ggml-org/llama.cpp:full --bench \
$(find . -name '*.gguf' -not -name '*mmproj*' -exec printf -- '-m /models/%s ' {} +) \
-t 12 --progress
load_backend: loaded CPU backend from /app/libggml-cpu-alderlake.so
| model | size | params | backend | threads | test | t/s |
|---|---|---|---|---|---|---|
| gemma4 E2B Q4_0 | 3.10 GiB | 4.63 B | CPU | 12 | pp512 | 145.36 ± 2.03 |
| gemma4 E2B Q4_0 | 3.10 GiB | 4.63 B | CPU | 12 | tg128 | 20.32 ± 0.13 |
| gemma4 E4B Q4_0 | 4.79 GiB | 7.46 B | CPU | 12 | pp512 | 87.48 ± 3.85 |
| gemma4 E4B Q4_0 | 4.79 GiB | 7.46 B | CPU | 12 | tg128 | 11.20 ± 0.03 |
| gemma4 ?B Q4_0 | 6.24 GiB | 11.91 B | CPU | 12 | pp512 | 28.17 ± 0.22 |
| gemma4 ?B Q4_0 | 6.24 GiB | 11.91 B | CPU | 12 | tg128 | 5.19 ± 0.00 |
| gemma4 ?B Q4_0 | 6.48 GiB | 11.91 B | CPU | 12 | pp512 | 28.97 ± 0.40 |
| gemma4 ?B Q4_0 | 6.48 GiB | 11.91 B | CPU | 12 | tg128 | 5.06 ± 0.01 |
| gemma4 26B.A4B Q4_0 | 13.26 GiB | 25.23 B | CPU | 12 | pp512 | 65.15 ± 1.29 |
| gemma4 26B.A4B Q4_0 | 13.26 GiB | 25.23 B | CPU | 12 | tg128 | 13.05 ± 0.06 |
| qwen3moe 30B.A3B Q4_K - Medium | 16.45 GiB | 30.53 B | CPU | 12 | pp512 | 59.02 ± 0.50 |
| qwen3moe 30B.A3B Q4_K - Medium | 16.45 GiB | 30.53 B | CPU | 12 | tg128 | 14.25 ± 0.05 |
CPU vs GPU
podman run -it --rm \
--volume $HOME/llama/models:/models --env LLAMA_CACHE=/models \
ghcr.io/ggml-org/llama.cpp:full --bench \
-m /models/models--google--gemma-4-E2B-it-qat-q4_0-gguf/snapshots/1894d1fc0a19d86697abd40483f5983c867df03f/gemma-4-E2B_q4_0-it.gguf \
-t 12 --progress
load_backend: loaded CPU backend from /app/libggml-cpu-alderlake.so
| model | size | params | backend | threads | test | t/s |
|---|---|---|---|---|---|---|
| gemma4 E2B Q4_0 | 3.10 GiB | 4.63 B | CPU | 12 | pp512 | 175.99 ± 4.21 |
| gemma4 E2B Q4_0 | 3.10 GiB | 4.63 B | CPU | 12 | tg128 | 20.68 ± 0.11 |
I only have integrated GPU, nothing really interesting.
Use ls -l /dev/dri to find the graphic cards. For intel:
podman run -it --rm \
--device /dev/dri/renderD128:/dev/dri/renderD128 \
--device /dev/dri/card1:/dev/dri/card1 \
--volume $HOME/llama/models:/models --env LLAMA_CACHE=/models \
ghcr.io/ggml-org/llama.cpp:full-intel --bench \
-m /models/models--google--gemma-4-E2B-it-qat-q4_0-gguf/snapshots/1894d1fc0a19d86697abd40483f5983c867df03f/gemma-4-E2B_q4_0-it.gguf \
-ngl -1 --progress
load_backend: loaded SYCL backend from /app/libggml-sycl.so
load_backend: loaded CPU backend from /app/libggml-cpu-alderlake.so
| model | size | params | backend | ngl | test | t/s |
|---|---|---|---|---|---|---|
| gemma4 E2B Q4_0 | 3.10 GiB | 4.63 B | SYCL | -1 | pp512 | 316.79 ± 0.86 |
| gemma4 E2B Q4_0 | 3.10 GiB | 4.63 B | SYCL | -1 | tg128 | 13.98 ± 0.04 |
Run
For tests
Run unsloth/gemma-4-26B-A4B-it-qat-GGUF with Unsloth’s recommended settings:
model='/models/models--unsloth--gemma-4-26B-A4B-it-qat-GGUF/snapshots/02749a7b272109255a4c559a80894d3d9777574c/gemma-4-26B-A4B-it-qat-UD-Q4_K_XL.gguf'
podman run --rm -d --name llama-test \
--volume "$HOME/llama/models":/models:ro --env LLAMA_CACHE=/models \
-p 127.0.0.1:8080:8080 \
ghcr.io/ggml-org/llama.cpp:server -m "$model" \
--temp 1.0 --top-p 0.95 --top-k 64 \
--host 0.0.0.0 --port 8080
then point your browser to http://127.0.0.1:8080
Production environment
For production, the container should be restricted. Example:
model='/models/models--unsloth--gemma-4-26B-A4B-it-qat-GGUF/snapshots/02749a7b272109255a4c559a80894d3d9777574c/gemma-4-26B-A4B-it-qat-UD-Q4_K_XL.gguf'
podman run -d --name llama-production \
--read-only --tmpfs /tmp \
--security-opt no-new-privileges \
--cap-drop=ALL \
--volume "$HOME/llama/models":/models:ro --env LLAMA_CACHE=/models \
-p 127.0.0.1:8080:8080 \
ghcr.io/ggml-org/llama.cpp:server -m "$model" \
--temp 1.0 --top-p 0.95 --top-k 64 \
--host 0.0.0.0 --port 8080
then point your browser to http://127.0.0.1:8080
Also, -c and -n can be used to explicitly restrict de input context size and the maximum predicted tokens. Example: -c 4096 -n 512
Cleanup with:
podman stop llama-production
podman rm llama-production
Images cleanup
# display the images for current user
podman images
# remove **all** unused images for current user
podman image prune -a