Lakshya

LLM Systems Engineering · Chapter 10 of 20

Running an open-weight model yourself

Where to get one, what the files are, what hardware it needs, and the five genuinely different ways to change its behaviour.

10 min read1 diagramAll 20 chapters

The companion chapter covers what the categories mean and why anyone publishes a model for free. This one is practical: getting one, running it, and changing what it does.

First, a correction that saves confusion later

People say “modify the source” by analogy with software. There is no source to modify.

A model is a file of numbers. The code that runs it is a few hundred lines that are already open and rarely need touching. The behaviour you want to change lives in the numbers, and in what you put in front of them.

So ‘modifying a model’ means one of five quite different things, at five wildly different costs. The last section of this chapter is that ladder, and picking the right rung is most of the skill.

Where you get one

Hugging Face is where essentially all of this lives — a public repository of models, datasets and the libraries to use them. It is to models roughly what npm or PyPI is to packages: not the only place, but the one everything defaults to.

Each model has a model card, and reading it before downloading is the difference between a working afternoon and a wasted one. What to actually look at:

  • The licence, and whether it is the permissive kind. Some repositories require you to accept terms before the download unlocks.
  • Base or instruction-tuned. A base model only continues text; ask it a question and it may write more questions. An instruct or chat variant has been tuned to follow instructions. Almost always you want the instruct variant, and this is the single most common first-time mistake.
  • Context length — how much text it can consider at once.
  • The prompt template. Models are trained with specific markers around the system, user and assistant turns. Use the wrong template and quality drops sharply for no visible reason. Modern tooling usually applies it for you; when output is mysteriously poor, check this first.
  • Whether the numbers were reported by the publisher. They usually were.

What the files are

FormatWhat it isUse it when
safetensorsThe standard weight format. Replaced Python's pickle format, which could execute code on load — a genuine security fix, not a convenience one.Serving on GPUs, and anything you intend to fine-tune.
GGUFA single-file format built for running on ordinary hardware, including CPU only.Laptops, desktops, edge devices, anything without a datacentre GPU.

You will also see the weights split across numbered shards with an index file — that is just chunking for large downloads, and the tooling reassembles them.

Running it

Four tools cover almost every situation, and choosing wrongly is the usual cause of a frustrating start.

ToolWhat it is forHonest assessment
OllamaGetting something working in five minutes on your own machineStart here. One command pulls and runs a model, and it exposes an OpenAI-compatible endpoint so existing code often works unchanged.
LM StudioThe same, with a graphical interfaceGood if you would rather click than type. Same underlying engine.
llama.cppThe engine underneath both, in C++Reach for it directly when you need control over quantisation or are targeting unusual hardware.
vLLMProduction serving, many concurrent usersA different class of thing. Continuous batching and efficient memory handling give far higher throughput. Do not run Ollama as a production service.
shellthe fastest honest path from nothing to running
# --- five minutes to a working local model -----------------------
curl -fsSL https://ollama.com/install.sh | sh

ollama run qwen3:8b            # pulls ~5 GB, then you are talking to it

# it also serves an OpenAI-compatible endpoint on localhost:11434,
# so most existing client code works by changing two lines:

python3 - <<'PY'
from openai import OpenAI
client = OpenAI(base_url="http://localhost:11434/v1", api_key="unused")
r = client.chat.completions.create(
    model="qwen3:8b",
    messages=[{"role": "user", "content": "Summarise this in one line: ..."}],
)
print(r.choices[0].message.content)
PY
shellvLLM — when it stops being an experiment
# --- production serving, same weights, very different engine -----
pip install vllm

vllm serve Qwen/Qwen3-8B \
    --max-model-len 32768 \
    --gpu-memory-utilization 0.90 \
    --tensor-parallel-size 2          # split across 2 GPUs

# Also OpenAI-compatible. The difference from Ollama is not the API --
# it is continuous batching, which is what makes concurrent users viable.

Will it fit?

WILL IT FIT? — THE ONLY ARITHMETIC YOU NEED BEFORE DOWNLOADING MEMORY ≈ (PARAMETERS × BYTES PER PARAMETER) + about 20% for the rest The “rest” is the KV cache — the running notes the model keeps about the conversation so far. Longer chats need more of it. BYTES PER PARAMETER, BY PRECISION — this is what quantisation changes FP16 / BF162 bytesthe weights as trained — the reference quality8-bit1 bytehalf the memory; quality loss usually not noticeable4-bit0.5 bytesa quarter of the memory; measurable but often acceptable loss2-bit0.25 bytesruns, but the quality cost is real. Rarely the right answer. WORKED, FOR A 70-BILLION-PARAMETER MODEL FP16 — ~168 GB2+ datacentre GPUs8-bit — ~84 GB1 large datacentre GPU4-bit — ~42 GBone 48 GB card, tightA 7B at 4-bit — ~5 GBa laptop, comfortably So the real question is never “can I run an open model?” It is “how big a one, at what precision, on what I already have?” A 7–8B model at 4-bit runs on an ordinary laptop. That is enough for classification, extraction, routing and drafting — a very large shareof real work.
Do this arithmetic before you download 140 GB. It takes ten seconds and it is the thing people skip.

A note on where the memory actually goes. The weights are a fixed cost. The KV cache — the model's running notes on the conversation so far — grows with context length and with the number of simultaneous users, and on a busy server it can rival the weights. That is the number that surprises people in production, and it is covered properly in Inference economics.

Mixture-of-experts models break the arithmetic in a useful direction. A model described as having, say, 100 billion parameters may activate only a few billion per token — so it is fast like a small model while still needing memory like a large one. Read the model card for both numbers; the headline is usually the total.

The five ways to change what it does

This is the ladder. Work down it, and stop at the first rung that solves your problem — the costs rise by orders of magnitude and the top two rungs are almost never the right answer for a first attempt.

What you changeCostUse it for
1. PromptingThe instructions you send. Nothing about the model.Minutes. Free.Tone, format, refusals, scope. Solves more than people expect.
2. RetrievalWhat information you put in front of it.Days.Making it answer from your documents. This is the answer to ‘it does not know about our products’ — not fine-tuning.
3. QuantisationThe precision of the numbers. Behaviour is meant to be unchanged.Hours.Fitting it on the hardware you have, or serving it more cheaply.
4. LoRA fine-tuningA small set of added parameters, alongside frozen originals.Hours to days. One GPU is often enough.A consistent style, a domain vocabulary, a rigid output format. Adapters are a few megabytes and swappable at runtime.
5. Full fine-tuningEvery parameter.Expensive, and you can degrade the model.Rare. Usually a sign that rungs 1–4 were skipped rather than tried.

The single most common expensive mistake in this field: reaching for fine-tuning to teach a model facts.

Fine-tuning teaches behaviour and form. Retrieval supplies knowledge. If the complaint is “it does not know our policies”, the answer is rung 2. If the complaint is “it will not consistently return the JSON shape we need”, that is rung 4.

Getting this backwards costs weeks and a GPU bill, and then it still gets facts wrong — because you taught it a style, not a fact.

The mechanics of rungs 4 and 5 are in Fine-tuning, properly; rung 3 is in Quantisation; rung 2 is in Retrieval internals.

pythonPEFT — the standard library for adapter fine-tuning
# --- LoRA: what fine-tuning actually looks like now --------------
from peft import LoraConfig, get_peft_model

config = LoraConfig(
    r=16,                 # rank -- how much capacity the adapter has
    lora_alpha=32,
    target_modules=["q_proj", "v_proj"],   # which layers get an adapter
    lora_dropout=0.05,
    task_type="CAUSAL_LM",
)
model = get_peft_model(base_model, config)
model.print_trainable_parameters()
# trainable params: 4,194,304 || all params: 8,034,000,000 || trainable%: 0.05

# 0.05% of the parameters. That is why this fits on one GPU, why the
# result is a few megabytes, and why you can keep several adapters
# for different tasks and swap them at serving time.

What you take on by self-hosting

Stated plainly, because the decision is usually made on price and the price is not the whole cost.

  • The safety layer is now yours. A provider's endpoint sits behind filtering, abuse detection and a policy team. A downloaded model has whatever refusal behaviour its training left it with, and that can be removed by anyone with modest resources. If your application is user-facing, you are building the guardrails.
  • Upgrades stop being free. A better model appearing means an evaluation, a migration and a redeployment — not a changed string in a config file.
  • You need evaluations more, not less. With a hosted model you can at least assume the vendor tested it. Here, the only evidence that your quantised, adapted model still works is evidence you generated. See Evaluation.
  • The economics have a crossover point, and it is a real one. Self-hosting is fixed cost against an API's variable cost, so it wins at sustained high volume and loses badly at low or spiky volume — an idle GPU bills exactly the same as a busy one. Inference economics has the arithmetic.

And the reasons that have nothing to do with cost, which are frequently the real ones: data that legally cannot leave a network; a model you need to still exist and behave identically in five years; latency that a round trip cannot meet; or a language or domain no commercial provider will prioritise. Any one of those justifies the work on its own, and none of them shows up in a price comparison.

Check yourself

Is there source code to modify?Not in the software sense. A model is a file of numbers; the code that runs it is small and already open. Behaviour changes come from the numbers or from what you put in front of them.
What is the most common first-time mistake?Downloading the base model instead of the instruct or chat variant. A base model only continues text — it will not follow instructions.
safetensors or GGUF?safetensors for GPU serving and anything you will fine-tune; GGUF for laptops, CPUs and edge devices. safetensors also replaced a format that could execute code on load.
Which tool should you start with?Ollama — one command, and an OpenAI-compatible endpoint so existing code often works unchanged. Move to vLLM for production, where continuous batching makes concurrent users viable.
How do you know if a model will fit?Parameters times bytes per parameter, plus about 20%. A 70B model needs ~168 GB at FP16, ~42 GB at 4-bit; a 7B at 4-bit needs about 5 GB and runs on a laptop.
What is the fine-tuning versus retrieval rule?Fine-tuning teaches behaviour and form. Retrieval supplies knowledge. 'It doesn't know our policies' is a retrieval problem, not a fine-tuning one.
Why does LoRA fit on one GPU?It trains roughly 0.05% of the parameters as a small added adapter while the originals stay frozen. The result is a few megabytes and swappable at serving time.
What do you take on when you self-host?The safety layer, the upgrade path, and the evaluation burden — plus fixed cost that wins at sustained volume and loses badly at spiky volume.
← AgentCore in practice — the contract, the code, the limitsA fine-tune, start to finish →