Quickstart
Goal: first successful chat completion in under five minutes, against the flagship Qwen3.5-35B-A3B model running at 131 tok/s on a single GB10.
1. Start the server
sudo docker run -d \
--name atlas-35b \
--network host --gpus all --ipc=host \
-v ~/.cache/huggingface:/root/.cache/huggingface \
avarok/atlas-gb10:latest \
serve Sehyo/Qwen3.5-35B-A3B-NVFP4 \
--port 8888 \
--max-seq-len 8192 \
--kv-cache-dtype nvfp4 \
--gpu-memory-utilization 0.88 \
--scheduling-policy slai \
--speculative \
--mtp-quantization nvfp4
What's happening:
- The container binds the host's network (
--network host) so port8888is reachable on the host directly.--gpus allgrants the GB10,--ipc=hostenables shared memory for larger KV buffers. serve <model-id>selects the model; the binary auto-detectsmodel_typefromconfig.jsonand picks the matching kernel target.--kv-cache-dtype nvfp4keeps the KV cache in 4-bit E2M1 — halves memory vs FP8, with no measurable coherence loss for Qwen3.5.--speculative --mtp-quantization nvfp4turns on Multi-Token Prediction speculative decoding with the NVFP4 MTP head that ships in the checkpoint. This is the change that takes throughput from ~70 tok/s to ~131 tok/s.--scheduling-policy slaienables SLO-aware scheduling — prioritises decode steps approaching their TBT deadline.
First start-up takes 2–5 minutes: the loader reads 15–40 GB of safetensors through the O_DIRECT fast path, CUDA graphs are captured for every batch size, and the HTTP server binds. Watch the log:
sudo docker logs -f atlas-35b
You'll see loaded 125000 tensors in 34s, then captured graph for batch=1, then finally Listening on 127.0.0.1:8888. The server does not accept requests before that last line appears.
The address in that line is whatever --bind resolved to, and --bind defaults
to 127.0.0.1 — so the default run is loopback-only and logs a second line
saying so. You get Listening on 0.0.0.0:8888 only if you pass --bind 0.0.0.0,
which also emits a LAN-exposure warning. Note the capital L: grepping for
listening on 0.0.0.0 matches nothing.
2. Send a request
Once the server logs listening, a standard OpenAI request works:
curl -s http://localhost:8888/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "atlas",
"messages": [{"role": "user", "content": "Explain the key idea behind speculative decoding in one paragraph."}],
"max_tokens": 256
}'
Atlas accepts any model string — it serves exactly one model per container, so the field is ignored. Use the real HF id if you want round-tripping through OpenAI clients to feel natural.
3. Stream tokens
curl -sN http://localhost:8888/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "atlas",
"messages": [{"role": "user", "content": "Write a short poem about kernels."}],
"max_tokens": 200,
"stream": true
}'
Each chunk is a standard data: {...} SSE frame with choices[0].delta.content. Tool calls stream as choices[0].delta.tool_calls chunks in the same format OpenAI emits.
4. From Python (OpenAI SDK)
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8888/v1", api_key="unused")
stream = client.chat.completions.create(
model="atlas",
messages=[{"role": "user", "content": "Hello!"}],
max_tokens=200,
stream=True,
)
for chunk in stream:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)
The same client works with Open WebUI — set Base URL: http://<host>:8888/v1, API key sk-dummy.
5. Stop
sudo docker stop atlas-35b && sudo docker rm atlas-35b
Troubleshooting
error: out of memoryduring start-up — drop--gpu-memory-utilizationto0.85, or--max-seq-lento4096. 35B has the headroom; it's usually leaked GPU state from a previous container.nvidia-smishould show ~0 MB used before starting.- Server logs
loaded 0 tensors— your HF cache is empty or the path is wrong. Verify withls ~/.cache/huggingface/hub/models--Sehyo--Qwen3.5-35B-A3B-NVFP4. - Connection refused on port 8888 — the server hasn't finished initialising. Watch the log;
Listening on <bind>:<port>is the readiness marker. If it has printed and you're still refused from another machine, that's the--bind 127.0.0.1default, not a start-up problem — see Quickstart §Network exposure. - Tokens are gibberish — almost always a model/loader mismatch. Check that the HF model id in the command line matches the cached directory. If the kernel target the binary picked is wrong (unlikely — Atlas logs it on startup), open an issue; Atlas's house rule is never blame the model, always find the Atlas bug.
Next: pick a different model from Supported Models, or dive into the Architecture.