Running a local LLM with llama.cpp: build, download, serve, benchmark

A minimal llama.cpp workflow for running GGUF models on your own machine — from the cmake build to an OpenAI-compatible server and llama-bench.

Here is the minimal workflow I use to run GGUF models on my own hardware without a cloud API. The order is build → download the model → serve → benchmark.

Build

The basic build is two cmake lines.

# build whole
cmake -B build
cmake --build build --config Release

To pull models straight from Hugging Face you need curl enabled. Before passing -DLLAMA_CURL=ON, make sure curl and its development headers are installed on the system.

# for hugging-face, add curl option
# make sure to install curl
sudo apt install curl libcurl4-openssl-dev
cmake -B build -DLLAMA_CURL=ON

If you only need the server binary rather than the whole tree, name the target.

# build subset
cmake -B build build --config Release -t llama-server

Downloading models

GGUF files usually run to several gigabytes, so there are two ways to fetch them.

When cloning the whole repository with git, you need git-lfs for the large files to come along properly.

# for large file download from git
sudo apt install git-lfs
git clone {hf repository}

If you want to pick specific files or directories, huggingface-cli is more convenient.

# or, you can use huggingface-cli
pip install -U "huggingface_hub[cli]"
huggingface-cli download {hf repository name} --local-dir .

Watch memory and core usage during download and loading with htop.

Starting the server

The Python binding llama-cpp-python ships an OpenAI-compatible server directly.

# llama-cpp-python
pip install llama-cpp-python[server]
python3 -m llama_cpp.server --model {model_gguf_path} --host 0.0.0.0

Because the server follows the OpenAI spec, the client can just use the openai SDK. Point base_url at the local server, and put anything in api_key since it is never checked. (Match the port in base_url to whatever port the server actually came up on.)

from openai import OpenAI

client = OpenAI(
    base_url="http://localhost:8080",
    api_key="none",
)

stream = client.chat.completions.create(
    model="random",
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "What is your name?"},
    ],
    stream=True,
    temperature=0.9,
    max_tokens=1000,
)

for chunk in stream:
    if chunk.choices[0].delta.content is not None:
        print(chunk.choices[0].delta.content, end="")

The C++ llama-server built above exposes the same OpenAI-compatible endpoints. Use that one if you would rather run without the Python dependency.

Benchmarking

To measure a model’s throughput (tokens/s and friends), use llama-bench.

build/bin/llama-bench -m {gguf_path}

The built binaries land under build/bin/, so you can point at that path directly.