Instructions to use Qwen/Qwen3.8-27B with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use Qwen/Qwen3.8-27B with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("image-text-to-text", model="Qwen/Qwen3.8-27B") messages = [ { "role": "user", "content": [ {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"}, {"type": "text", "text": "What animal is on the candy?"} ] }, ] pipe(text=messages)# Load model directly from transformers import AutoProcessor, AutoModelForMultimodalLM processor = AutoProcessor.from_pretrained("Qwen/Qwen3.8-27B") model = AutoModelForMultimodalLM.from_pretrained("Qwen/Qwen3.8-27B", device_map="auto") messages = [ { "role": "user", "content": [ {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"}, {"type": "text", "text": "What animal is on the candy?"} ] }, ] inputs = processor.apply_chat_template( messages, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt", ).to(model.device) outputs = model.generate(**inputs, max_new_tokens=40) print(processor.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Inference
- HuggingChat
- Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use Qwen/Qwen3.8-27B with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "Qwen/Qwen3.8-27B" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Qwen/Qwen3.8-27B", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }'Use Docker
docker model run hf.co/Qwen/Qwen3.8-27B
- SGLang
How to use Qwen/Qwen3.8-27B with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "Qwen/Qwen3.8-27B" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Qwen/Qwen3.8-27B", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "Qwen/Qwen3.8-27B" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Qwen/Qwen3.8-27B", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }' - Docker Model Runner
How to use Qwen/Qwen3.8-27B with Docker Model Runner:
docker model run hf.co/Qwen/Qwen3.8-27B
Follow-up: I benchmarked 45 llama.cpp settings on Qwen3.8-27B. The MTP draft head is worth 1.81x, free (RTX 5090, Q4_K_M)
A while back I posted a comparison of Qwen3.8-27B against Nemotron 3.5 Lightning and Muse Glimmer on 16 hard problems. Several people asked what settings I was running, and it turned out I did not have a good answer. So I went back and benchmarked the settings themselves: 45 configurations of this model alone.
Sharing the findings here because a few of them changed how I run it, and one of them affects that earlier post.
Setup
- One RTX 5090, 32GB
- llama.cpp build b10448, CUDA, and Ollama 0.32.13 for the runtime comparison
- Q4_K_M GGUF (the Ollama blob, 27.3B), 32K context unless stated
- Median of 3 repeats, warmup discarded
- Server killed and GPU memory polled back to idle between every configuration, with the idle VRAM baseline re-measured each time
As before, this is about the 4-bit GGUF build, not the safetensors on this page.
1. The MTP draft head is real and it is free
Qwen3.8 ships a multi-token-prediction head inside the GGUF, an actual extra layer at index 64, present in a standard Q4_K_M download:
qwen35.nextn_predict_layers = 1
blk.64.nextn.eh_proj.weight [10240, 5120] Q4_K
One flag activates it. Draft depth is the only decision:
| setting | decode tok/s | vs off | accept rate | tokens/step | quality |
|---|---|---|---|---|---|
| off | 73.6 | - | - | - | 100% |
n=1 |
104.8 | 1.42x | 0.860 | 1.88 | 100% |
n=2 |
125.5 | 1.70x | 0.766 | 2.56 | 100% |
n=3 |
133.6 | 1.81x | 0.674 | 3.11 | 100% |
n=4 |
119.5 | 1.62x | 0.592 | 3.56 | 100% |
n=5 |
108.8 | 1.48x | 0.520 | 3.90 | 100% |
There is a peak because two curves fight: acceptance falls with depth (0.86 โ 0.52) while tokens harvested per step rises (1.88 โ 3.90). Product peaks at n=3.
Speculative decoding is lossless by construction, since a drafted token is kept only if the full model would have produced it, so nothing degrades at any depth. n=4 and n=5 are slower, not worse. Costs ~680MB at n=1, ~150MB per level after.
I re-ran the whole ladder in reverse order as a control, because this card is power-capped (599W of 600W, clocks dropping 3090 โ 2700MHz) and a sweep run n=1 first would show a peak near the front regardless. n=3 still won. Acceptance rates came back identical to four decimals in both directions, which is the tell that the measurement is sound.
2. Quantizing the KV cache makes it faster, not slower
| KV type | spec | decode tok/s | VRAM MiB | quality | needle recall |
|---|---|---|---|---|---|
| f16 | n=2 | 125.5 | 18798 | 100% | all depths pass |
| q8_0 | n=2 | 128.3 | 17924 | 100% | all depths pass |
| q4_0 | n=2 | 136.7 | 17412 | 100% | all depths pass |
Decoding is memory-bandwidth bound, so a smaller cache means less data read per token. q4_0 is 1.4GB lighter and faster.
Worth noting: q4_0 at n=2 (136.7) beats f16 at n=3 (133.6), the best result from the entire draft-depth sweep. The cache type matters more than the draft depth. Also, the best depth changes with the cache. With q4_0, n=2 and n=3 tie, so n=3 just costs you memory.
q8_0 is about 63% of f16 in size, not 50%.
3. Reasoning is a bigger lever than any server flag
| mode | spec | think tokens | time to answer | decode tok/s | accept |
|---|---|---|---|---|---|
| thinking on | none | 106 | 2.18 s | 73.6 | - |
| thinking on | n=3 | 106 | 1.30 s | 133.6 | 0.674 |
| thinking off | n=2 | 0 | 0.21 s | 151.2 | 0.863 |
Time to the first word of actual answer improves ~10x. Turning reasoning off also improves draft acceptance (0.766 โ 0.863), because reasoning prose is less predictable than a direct answer, so the effects multiply to 2.06x.
The chat template defines exactly three effort levels: low, medium, xhigh (default). medium cuts the wait by about a third for no measurable quality cost. llama.cpp's --reasoning-effort will also accept minimal, high and max; this model's template raises on them, so the server starts fine and then errors on every request.
4. Context: raising it is cheap, filling it is not
| ctx | VRAM | decode (short prompt) | TTFT (full window) |
|---|---|---|---|
| 32K | 18.4 GB | 126.5 | 11 s |
| 64K | 20.5 | 126.4 | 27 s |
| 128K | 21.6 | 120.6 | 78 s |
| 256K | 27.1 | 115.1 | 757 s |
Decode holds around 126 tok/s from 4K to 64K, so a bigger window costs VRAM, not throughput. But filling it is superlinear: 128K โ 256K multiplied time-to-first-token by 9.7x. 256K works on a 32GB card with perfect needle recall, but 12.5 minutes to first token makes it a batch setting. Interactive ceiling is 64K to 128K.
5. The one that affects my earlier post
Ollama measured ~2x a stock llama-server on the identical GGUF. That is not a runtime difference. Ollama runs llama-server as a child process. Reading the command line it passes:
--spec-type draft-mtp --spec-draft-n-max 4 --spec-draft-backend-sampling
-b 1024 -ub 1024 --no-jinja --chat-template chatml
Ollama enables the MTP draft head by default, at n=4. Adding its flags to stock llama.cpp one group at a time:
| config | tok/s | vs stock |
|---|---|---|
| llama.cpp, stock | 70.7 | 1.00x |
| + Ollama's MTP flags | 115.5 | 1.63x |
| + Ollama's chatml template | 147.8 | 2.09x |
| Ollama, default | 133.5 | 1.89x |
Matched on flags and template, llama.cpp is ~11% faster. There is no engine gap.
Why this matters for anyone benchmarking models on Ollama: it picks draft settings per model, silently. Checking the three models from my earlier post:
| model | draft_num_predict |
|---|---|
| qwen3.8 | 4 |
| nemotron-3.5-lightning | 2 |
| muse-glimmer | none |
So that comparison had one model drafting 4 tokens, one drafting 2, and one with speculative decoding off entirely. The accuracy results there are unaffected, because speculation is lossless, but the speed and latency numbers were partly measuring Ollama's per-model defaults rather than the models. Worth checking ollama show --parameters <model> before trusting any cross-model throughput comparison.
One more Ollama note: because it discards the model's Jinja template in favour of chatml, reasoning_effort cannot be set through it at all.
What I run now
llama-server -m Qwen3.8-27B-Q4_K_M.gguf \
-ngl 999 -fa on --jinja -np 1 \
-c 32768 \
--cache-type-k q4_0 --cache-type-v q4_0 \
--spec-type draft-mtp --spec-draft-n-max 2
136.7 tok/s, 17.0GB, 100% quality, measured exactly as written. Add --reasoning-effort medium if you want answers sooner.
Not worth enabling: ngram-mod (0.97x on novel prompts, since its apparent gain is cache replay from repeated benchmark prompts), -fa off (costs 2.3GB and 20% of prefill), f16 KV cache (slower and larger than q4_0).
Caveats
One card, one Q4_K_M build, 3 repeats per config. Every quality task scored 100% including thinking-off and q4_0, which shows these settings do not break basic competence. It does not show reasoning is unnecessary, as the suite is not hard enough to test that.
Happy to share the harness or run specific configurations if anyone wants a case tested on this build.
Full write-up with all 12 charts, the method, and the four measurement traps that produced wrong numbers before I caught them:
https://kgptalkie.com/tutorials/generative-ai/qwen-3-8-27b-settings-that-matter
Earlier post in this thread (the 3-model comparison):
https://kgptalkie.com/tutorials/generative-ai/qwen-3-8-27b-vs-nemotron-3-5-vs-muse-glimmer
MTP 3 is for sure the sweet spot. Got me from 50 to 70 tok/s
Hello, so thanks for this detailed share on MTP! Though, I got little confusing about the statics:
Here when n=1, statics show that accept rate is 0.860 and tokens/step is 1.88. But I think tokens/step should be (1 + accept rate) for n=1? So maybe tokens/step should be 1.86 for accept rate = 0.860? Is there any statistical error when infering? Or some missalign on 'accept rate' or 'tokens/step'?
