Serving Llama 3.3 70B on one node.
From a machine delivered five minutes ago to an OpenAI-compatible endpoint answering requests — with the two flags that quietly halve your throughput and the one that gets you compromised.
The short answer
- Memory needed
- 43 GB at 4-bit, 82 GB at FP8, 164 GB at BF16 — all at 8k context
- Simplest machine
- One 80 GB card. No sharding, no interconnect, no synchronisation
- Time to first token
- Under fifteen minutes from delivery, most of it downloading weights
- The one mistake
- Publishing port 8000 on a public address. It has no authentication
What you need
70 billion parameters. At 4-bit that is 35 GB of weights; the KV cache adds 2.5 GB at 8k context for a single request, and the runtime overhead about 15%. Everything else follows from those three numbers — the sizing guide shows where they come from.
| Precision | Weights | Total at 8k | Total at 32k | Total at 128k |
|---|---|---|---|---|
| BF16 / FP16 | 140 GB | 164 GB | 173 GB | 207 GB |
| FP8 | 70 GB | 82 GB | 86 GB | 103 GB |
| 4-bit (AWQ, GPTQ) | 35 GB | 43 GB | 52 GB | 86 GB |
Note the 4-bit row at 128k: the weights shrink to 35 GB but the cache does not shrink at all, because AWQ and GPTQ quantise weights only. That single fact decides most of the machine choice below.
Choosing the node
The cheapest machines in our catalogue that hold this model on a single card, which is the configuration you want if you can have it — no sharding means no synchronisation and one less thing to debug.
| Node | Precision that fits | Card memory | Estimated tok/s | Per month |
|---|---|---|---|---|
| NVIDIA RTX A6000 | 4-bit (AWQ, GPTQ) | 48 GB | ~10 | $286/mo |
| 2 × NVIDIA RTX A6000 | 4-bit (AWQ, GPTQ) | 48 GB | ~10 | $597/mo |
| NVIDIA L40S | 4-bit (AWQ, GPTQ) | 48 GB | ~11 | $714/mo |
| NVIDIA A100 PCIe | 4-bit (AWQ, GPTQ) | 80 GB | ~25 | $1,091/mo |
Throughput is single-stream generation, bounded by memory bandwidth, and deliberately conservative. With continuous batching the aggregate across concurrent requests is several times higher — that is the whole point of vLLM.
Ten minutes of setup
Nothing here is specific to us except the address. Docker, the NVIDIA container toolkit and a working driver stack are already on the machine.
$ ssh root@203.0.113.42
$ nvidia-smi --query-gpu=name,memory.total --format=csv
# Weights on the fast local NVMe, not the system volume.
$ mkdir -p /scratch/models
$ df -h /scratch
# A gated model needs a token. Skip if yours is open.
$ export HF_TOKEN=hf_xxxxxxxxxxxxxxxxxxxx
Starting the server
One container. The first run downloads roughly 40 GB of quantised weights, which on a 1 Gbit/s port takes a few minutes; every restart afterwards is seconds.
$ docker run -d --name vllm --restart unless-stopped \
--gpus all --ipc=host \
-v /scratch/models:/root/.cache/huggingface \
-e HF_TOKEN="$HF_TOKEN" \
-p 127.0.0.1:8000:8000 \
vllm/vllm-openai:latest \
--model casperhansen/llama-3.3-70b-instruct-awq \
--quantization awq_marlin \
--max-model-len 8192 \
--gpu-memory-utilization 0.92
# Watch it load. "Application startup complete" is the signal.
$ docker logs -f vllm
$ curl -s http://127.0.0.1:8000/v1/models | head
$ curl -s http://127.0.0.1:8000/v1/chat/completions \
-H 'Content-Type: application/json' \
-d '{"model":"casperhansen/llama-3.3-70b-instruct-awq",
"messages":[{"role":"user","content":"In one sentence: what is a KV cache?"}],
"max_tokens":80}'
The flags that matter
Not publishing it to the world
0.0.0.0 on a public address it is an open inference server, and scanners find those in hours. Note the -p 127.0.0.1:8000:8000 in the command above — that leading address is what keeps it off the internet, and it is the single character most often dropped when copying a command from elsewhere.
Reach it from your own machine over an SSH tunnel — no port opened, no certificate to manage, nothing to misconfigure:
$ ssh -N -L 8000:127.0.0.1:8000 root@203.0.113.42
# Now http://127.0.0.1:8000 on your laptop is the server.
If it genuinely must be public, put a reverse proxy in front with TLS and an API key, and restrict the source addresses in the firewall as well. The documentation has a minimal ruleset. Belt and braces is the correct posture for an endpoint that will answer anyone who asks.
Getting the throughput up
In the order worth trying. The first two are free and usually give the largest gains.
- Lower
--max-model-lento your real context. Almost always the biggest single win, and it costs nothing you were using. - Raise
--gpu-memory-utilizationto 0.95. This is a dedicated machine; there is nothing else on the card to leave room for. - Turn on FP8 KV cache if the card supports it. Doubles what you can hold.
- Batch on the client side. Continuous batching only helps if requests arrive concurrently. One-at-a-time requests leave most of the card idle whatever you configure.
- Then, and only then, consider a faster card. Generation is bounded by memory bandwidth, so an H200 at 4,800 GB/s is roughly 2.4× an H100 PCIe at 2,000 for the same model — a real gain, and the most expensive one on this list.
$ docker exec vllm python -m vllm.entrypoints.openai.api_server --help | head -1
$ docker exec vllm vllm bench serve \
--model casperhansen/llama-3.3-70b-instruct-awq \
--num-prompts 200 --request-rate 8
# And watch the card while it runs: if utilisation sits below 90%,
# the bottleneck is your client, not the GPU.
$ nvidia-smi dmon -s um
Keeping it running
Three things worth doing on the first day, because all three are annoying to discover on the fourteenth.
Restart policy
--restart unless-stopped is in the command above. After a reboot the container comes back and the weights are already on /scratch, so it is up in under a minute.
Watch the card, not the process
A GPU that has fallen off the bus keeps a healthy-looking container. nvidia-smi -q -d PERFORMANCE in a health check catches it; a port check does not.
Weights are not backed up
They are on your local NVMe and nowhere else. That is fine — they are re-downloadable. Your fine-tuned adapters are not, so put those somewhere off the machine.
And when the term ends, the disks are erased within the hour with no grace period. Everything on /scratch goes with it. That is deliberate — it is the same promise that guarantees the machine you were given had nobody else's data on it — but it means the last day of a term is not the day to start copying things off.
Check this model against every node we rent.
The configurator reports which configurations hold it on a single card, which have to split it, and what each costs.
Other guides
- Practice · 10 min
Fine-tuning a 70B model on one card
QLoRA on a single 48 GB GPU: what fits, what it costs for a month, and why full fine-tuning is a different order of machine.
Read the guide - Payment · 8 min
Paying for a server in crypto
What actually happens between clicking pay and getting root, which coin to choose, and the four mistakes that lose money on a first payment.
Read the guide - Sizing · 9 min
How much VRAM a model actually needs
The arithmetic behind “will it fit”: weights, KV cache, and the two places a rule of thumb goes wrong by a factor of three.
Read the guide