LeetLLM
My PlanLearnGlossaryTracksPracticeBlog
LeetLLM

Your go-to resource for mastering AI & LLM systems.

Product

  • Learn
  • Glossary
  • Tracks
  • Practice
  • Blog
  • RSS

Legal

  • Terms of Service
  • Privacy Policy

© 2026 LeetLLM. All rights reserved.

Blog
Local LLMQwen3.6UnslothGGUF+2

Run Qwen3.6 Locally with Unsloth GGUF

Run Qwen3.6 locally with llama.cpp and Unsloth GGUF. Pin 27B or 35B-A3B, budget total memory from Unsloth's ladder, expose a local endpoint, then test MTP only after the plain run works.

May 13, 2026Updated August 13, 202621 min read

A local Qwen3.6 box should read a repo, explain a failing test, and suggest a patch without sending source to a hosted model. The first attempt often fails before it answers anything: the file fills the GPU, a projector is downloaded by surprise, or the context setting reserves more memory than expected.

That failure is useful if we make it legible. Use llama.cpp as the runtime and Unsloth GGUF as the model source. You'll download a prebuilt GGUF, not install the Unsloth Python package or export weights yourself. Pick one artifact, make one short text request, and keep that run as the control while you change one variable at a time.

Qwen positions Qwen3.6 around stability, agentic coding, repository-level reasoning, and thinking preservation.[1]Reference 1Qwen3.6https://github.com/QwenLM/Qwen3.6 Ollama exposes convenient tags, while the Unsloth GGUF path keeps the exact file, quant, llama.cpp flags, and multi-token prediction (MTP) variant visible.[2]Reference 2qwen3.6https://ollama.com/library/qwen3.6[3]Reference 3Qwen3.6-35B-A3B-GGUFhttps://huggingface.co/unsloth/Qwen3.6-35B-A3B-GGUF[4]Reference 4Qwen3.6-27B-GGUFhttps://huggingface.co/unsloth/Qwen3.6-27B-GGUF That extra visibility matters when a run fails: we can identify which bytes and which runtime produced the result.

Pick the right first model

Two open-weight Qwen3.6 models make useful starting points. Qwen3.6-27B is dense, so every parameter path runs for every token. Qwen3.6-35B-A3B is a Mixture-of-Experts (MoE) model, so a router activates only part of its expert capacity for each token. Qwen released 35B-A3B on April 16, 2026 and 27B on April 22, 2026. Both official model repositories use Apache 2.0.[1]Reference 1Qwen3.6https://github.com/QwenLM/Qwen3.6[5]Reference 5Qwen3.6-35B-A3Bhttps://huggingface.co/Qwen/Qwen3.6-35B-A3B[6]Reference 6Qwen3.6-27Bhttps://huggingface.co/Qwen/Qwen3.6-27B

Before choosing, ask which experiment you want. A dense 27B run gives us a simpler first debug loop. The 35B-A3B run tests sparse routing and agentic coding, but its 35B total parameters still occupy memory even though only 3B are active per token. The model card lists 256 experts, with 8 routed experts and 1 shared expert active during inference.[5]Reference 5Qwen3.6-35B-A3Bhttps://huggingface.co/Qwen/Qwen3.6-35B-A3B Mixture of Experts Architecture explains that active compute and weight residency are different budgets.

Both choices also need memory for weights, KV cache, runtime buffers, and any vision projector file. Inference: TTFT, TPS & KV Cache goes deeper on cache sizing, but we can make the first decision with Unsloth's planning ladder below.

Starting laneChoose it forKeep fixed during first test
27B dense Q3Lowest-memory dense control; Unsloth plans 15 GB total memoryExact GGUF pin, 8K context, one request
27B dense Q4Dense quality comparison; Unsloth plans 18 GB total memorySame prompt pack and server build
35B-A3B MoE Q4Deliberate sparse-model test; Unsloth plans 23 GB total memorySame context, sampling, and acceptance tests
Ollama Qwen3.6 tagThe shortest setup rather than exact artifact controlExplicit tag and observed context allocation

First-run rule: Change one variable at a time. Prove the plain text endpoint before adding longer context, MTP, vision, or parallel slots.

Unsloth defines those estimates as total available memory across RAM and VRAM, or unified memory. They aren't guaranteed GPU-fit numbers.[7]Reference 7Qwen3.6 - How to Run Locallyhttps://unsloth.ai/docs/models/qwen3.6 MTP uses a separate ladder: 27B needs about 16 GB at 3-bit and 19 GB at 4-bit; 35B-A3B needs about 18 GB at 3-bit and 24 GB at 4-bit. Those rounded plans include neither a promise that one GPU holds the whole file nor a fixed context budget. KV cache and runtime buffers still sit on top.

Grouped bar chart of Unsloth Qwen3.6 total-memory plans in GB: 27B needs 15 at 3-bit and 18 at 4-bit, rising to 16 and 19 with MTP; 35B-A3B needs 17 at 3-bit and 23 at 4-bit, rising to 18 and 24 with MTP.
Unsloth's Qwen3.6 ladder is total RAM plus VRAM, or unified memory. MTP adds about 1 GB on the same quant. A 16 GB card is still a squeeze for the 15 GB 27B Q3 plan once cache and buffers land.

A 14.47 GB Q3 file on a 16 GB card leaves little room for cache and buffers, so expect CPU offload or choose a smaller quant if the measured run doesn't fit. The same warning applies to a 23 GB Q4 plan on a 24 GB card. The file size is the first subtraction, not the final capacity test.

If you only want the shortest setup, Ollama lists qwen3.6, qwen3.6:27b, and qwen3.6:35b tags with 256K context and text plus image input. Its current library page shows qwen3.6:27b at 18 GB and qwen3.6:35b at 23 GB, so those tags aren't the Unsloth 15 GB Q3 pin.[2]Reference 2qwen3.6https://ollama.com/library/qwen3.6 Run ollama run qwen3.6:27b for that path. This tutorial continues with llama.cpp because a repository revision, filename, and checksum make the artifact easier to replay.

Read the quant name

GGUF is the model-file format used by llama.cpp and many local apps. These Unsloth repositories already contain exported and quantized files. You're selecting an artifact, not converting the original BF16 checkpoint during setup.

Suppose the file is Qwen3.6-35B-A3B-UD-Q4_K_M.gguf. Read it left to right: model family, parameter shape, Unsloth Dynamic label, rough bit width, llama.cpp quant tier, and file format. 35B-A3B tells you which weights you need. Q4 narrows the size and quality trade-off. The complete filename tells the downloader exactly which artifact to fetch.

Unsloth's Dynamic 2.0 docs explain that newer GGUFs use model-specific layer choices and calibration data instead of applying one uniform quantization recipe everywhere.[8]Reference 8Unsloth Dynamic 2.0 GGUFshttps://unsloth.ai/docs/basics/unsloth-dynamic-2.0-ggufs Model Quantization: GPTQ, AWQ & GGUF covers how GGUF differs from GPU-oriented GPTQ and AWQ workflows.

Quantization stores weights with fewer bits. Smaller quants need less memory, but task quality can change. Q4 is a quant family, not a promise that every weight uses exactly four bits or that every Q4 file has the same size. Compare exact filenames and byte sizes before downloading:

  • Q3: first 16 GB dense test
  • Q4: default useful local coding target
  • Q5 or Q6: try when you have headroom
  • Q8 or BF16 (bfloat16): quality comparison or server-class memory

Unsloth's Qwen3.6 guide gives this total-memory ladder:[7]Reference 7Qwen3.6 - How to Run Locallyhttps://unsloth.ai/docs/models/qwen3.6

Model3-bit4-bit
27B15 GB18 GB
27B MTP16 GB19 GB
35B-A3B17 GB23 GB
35B-A3B MTP18 GB24 GB

Those are planning numbers. Runtime allocations can still push a nominal fit over capacity.

Run one local endpoint

llama.cpp is the local inference engine behind many GGUF workflows. Qwen lists it as a supported path for Qwen3.6 text and vision models, and the Unsloth model cards show direct llama-server -hf ... commands.[1]Reference 1Qwen3.6https://github.com/QwenLM/Qwen3.6[3]Reference 3Qwen3.6-35B-A3B-GGUFhttps://huggingface.co/unsloth/Qwen3.6-35B-A3B-GGUF

There are two ways to get a model into the server. -hf resolves a repository and quant for you, which is convenient for a quick trial. It also follows the repository's current state and, on current llama.cpp builds, downloads an mmproj when one is available unless you pass --no-mmproj. The command below uses --model instead: the repository revision, filename, and SHA-256 are explicit, and the first run stays text-only.

The Linux/NVIDIA setup below pins a llama.cpp commit, an Unsloth repository revision, a GGUF filename, and a SHA-256 verified on August 25, 2026.[9]Reference 9llama.cpp: Inference of LLaMA model in pure C/C++https://github.com/ggml-org/llama.cpp[4]Reference 4Qwen3.6-27B-GGUFhttps://huggingface.co/unsloth/Qwen3.6-27B-GGUF The pin is intentional. Reproduce this control first, then try a newer llama.cpp commit as a separate variable if support or performance changes.

terminal
1git clone https://github.com/ggml-org/llama.cpp 2git -C llama.cpp checkout 8e7f22b67ef4667b4ddd50230771287f328cfb3f 3 4cmake -S llama.cpp -B llama.cpp/build \ 5 -DBUILD_SHARED_LIBS=OFF \ 6 -DGGML_CUDA=ON 7 8cmake --build llama.cpp/build \ 9 --config Release \ 10 -j \ 11 --target llama-server llama-cli 12 13./llama.cpp/build/bin/llama-server --version 14 15MODEL_REPO="unsloth/Qwen3.6-27B-GGUF" 16MODEL_REV="82d411acf4a06cfb8d9b073a5211bf410bfc29bf" 17MODEL_FILE="Qwen3.6-27B-UD-Q3_K_XL.gguf" 18MODEL_SHA256="cff4a2da6b5350a53f57dc6f798516e0195816f90c196c3f7bd3fd55556632dd" 19MODEL_DIR="models/qwen36-27b-q3" 20 21mkdir -p "$MODEL_DIR" 22curl -fL --retry 5 --retry-delay 2 -C - \ 23 -o "$MODEL_DIR/$MODEL_FILE" \ 24 "https://huggingface.co/$MODEL_REPO/resolve/$MODEL_REV/$MODEL_FILE?download=true" 25 26printf '%s %s\n' "$MODEL_SHA256" "$MODEL_DIR/$MODEL_FILE" \ 27 | sha256sum -c - 28 29./llama.cpp/build/bin/llama-server \ 30 --model "$MODEL_DIR/$MODEL_FILE" \ 31 --no-mmproj \ 32 --alias local-qwen36 \ 33 --ctx-size 8192 \ 34 --n-gpu-layers all \ 35 --host 127.0.0.1 \ 36 --port 8080

The download is about 14.47 decimal GB. curl -C - resumes a partial file, while sha256sum -c rejects a corrupt or different artifact. --no-mmproj keeps this control run text-only. The alias matches the smoke-test "model" field below.

On Apple Silicon, build the same pinned commit with -DGGML_CUDA=OFF; Metal is enabled by default. Use shasum -a 256 in place of sha256sum. For CPU-only inference, also set --n-gpu-layers 0. Qwen lists MLX as another supported Apple Silicon path, but switching runtimes creates a different benchmark.[1]Reference 1Qwen3.6https://github.com/QwenLM/Qwen3.6

The plain Q3 command gives us a baseline. If it loads and answers the smoke request, vary one server setting at a time:

  • Lowest-memory dense control: Qwen3.6-27B-UD-Q3_K_XL.gguf at 8192 context.
  • 27B quality test: unsloth/Qwen3.6-27B-GGUF:UD-Q4_K_XL at 8192 context. The matching Q4 file is about 17.61 decimal GB, so it doesn't fit a 16 GB card without offload.
  • 35B-A3B MoE test: unsloth/Qwen3.6-35B-A3B-GGUF:UD-Q4_K_M at 8192 first, then 32768.

If output is repeated symbols or broken formatting, check the selected file, checksum, and llama.cpp version before blaming the model. Qwen3.6 support has moved quickly, so an older binary is one possible variable, not a reason to change three settings at once.

Verify artifact and host state

The pinned workflow downloads before server startup, so model-transfer time can't be mistaken for load time. Preserve the startup log until it shows the selected file, embedded chat template, memory placement, context allocation, and listening address.

Run the server command a second time before measuring cold model load. Did it reuse the file? If another large transfer starts, inspect the repository selector, cache location, and partial download before changing the model. A repeatable load is part of the control, not a minor convenience.

For strict artifact control, resolve the repository revision and filename before the benchmark, then store both in the run receipt. A quant label describes a file family; the repository revision records which published state supplied it.

Keep separate disk and runtime checks:

inspect-qwen36-host.sh
1df -h . 2du -sh models/qwen36-27b-q3 3git -C llama.cpp rev-parse HEAD 4./llama.cpp/build/bin/llama-server --version 5sha256sum models/qwen36-27b-q3/Qwen3.6-27B-UD-Q3_K_XL.gguf

Free disk space answers whether the artifact can be stored. It doesn't answer whether weights, KV cache, and buffers fit during inference. Keep those questions separate when a download succeeds but the first request fails.

Three 16 GB GPU stacks for pinned 27B files: the 14.47 GB Q3 file leaves 1.53 GB, Q3 plus the 0.93 GB F16 projector leaves 0.60 GB, and the 17.61 GB Q4 file overruns the card by 1.61 GB.
Leftover is 16 GB minus the pinned file, not a measured KV-cache budget. Q3 text-only is the 16 GB attempt. Adding the F16 projector or switching to Q4 eats that remainder before the first long prompt.

Point tools at http://127.0.0.1:8080/v1 and test one completion from your normal SDK or client. OpenAI-compatible SDKs usually expect an API key even for local servers. Use a placeholder such as local, set the base URL to the local endpoint, and keep the first prompt short enough to separate runtime problems from task complexity.

Verify the endpoint contract

Start with a health request, then send one non-streaming chat completion:

verify-qwen36-endpoint.sh
1curl -fsS http://127.0.0.1:8080/health 2 3curl -fsS http://127.0.0.1:8080/v1/chat/completions \ 4 -H 'Content-Type: application/json' \ 5 -H 'Authorization: Bearer local' \ 6 -d '{ 7 "model": "local-qwen36", 8 "messages": [ 9 {"role": "user", "content": "Reply with exactly: endpoint-ready"} 10 ], 11 "temperature": 0, 12 "max_tokens": 16, 13 "stream": false 14 }' > qwen36-smoke.json

That smoke request answers one narrow question: "is the server up, and can it satisfy a tiny output contract?" Qwen3.6 generates thinking content by default and doesn't support the older /think or /nothink soft switch.[6]Reference 6Qwen3.6-27Bhttps://huggingface.co/Qwen/Qwen3.6-27B For a non-thinking client, restart the server with --chat-template-kwargs '{"enable_thinking":false}' and use the non-thinking sampling row below. To keep prior reasoning traces in later turns, Unsloth documents a separate preserve_thinking kwarg.[7]Reference 7Qwen3.6 - How to Run Locallyhttps://unsloth.ai/docs/models/qwen3.6

The smoke request keeps temperature at zero only to make a tiny endpoint assertion. It isn't the coding baseline. First prove transport and response shape; then choose a thinking mode and sampling policy for the task.

The exact response ID and usage counts vary. Validate stable structure and requested content:

check-qwen36-response.sh
1jq -e ' 2 (.choices | length) == 1 3 and .choices[0].message.role == "assistant" 4 and (.choices[0].message.content | contains("endpoint-ready")) 5' qwen36-smoke.json

If health passes but completion fails, read the server log before changing the model. If completion returns malformed content, repeat with the same prompt after confirming the llama.cpp build, selected GGUF, and chat template.

Add MTP after the plain run works

Multi-token prediction (MTP) lets a draft path propose more than one future token while the main model verifies them.[10]Reference 10Multi-Token Predictionhttps://unsloth.ai/docs/models/mtp Qwen trained MTP into Qwen3.6, and Unsloth publishes dedicated MTP GGUF repositories for both 27B and 35B-A3B.[5]Reference 5Qwen3.6-35B-A3Bhttps://huggingface.co/Qwen/Qwen3.6-35B-A3B[6]Reference 6Qwen3.6-27Bhttps://huggingface.co/Qwen/Qwen3.6-27B[11]Reference 11Qwen3.6-27B-MTP-GGUFhttps://huggingface.co/unsloth/Qwen3.6-27B-MTP-GGUF[12]Reference 12Qwen3.6-35B-A3B-MTP-GGUFhttps://huggingface.co/unsloth/Qwen3.6-35B-A3B-MTP-GGUF

The useful prediction is simple: if the draft tokens match what the main model would have produced, decode needs fewer full passes. Prompt ingestion, model weights, and context memory don't disappear. Unsloth reports roughly 1.4x to 2.2x faster generation without an accuracy change in its own benchmarks, while also warning that the best draft count depends on hardware.[7]Reference 7Qwen3.6 - How to Run Locallyhttps://unsloth.ai/docs/models/qwen3.6[10]Reference 10Multi-Token Predictionhttps://unsloth.ai/docs/models/mtp

Use --spec-draft-n-max 2 as a starting point, not a guarantee. Unsloth's current guide says to try values from 1 through 6, and the pinned llama.cpp build defaults this option to 3. A wider draft can use more memory or produce fewer accepted tokens, so the only useful speedup is the one that survives your output checks.

Stop the plain server, download the matching MTP artifact, verify it, then launch with the MTP flags:

run-qwen36-mtp.sh
1MTP_REPO="unsloth/Qwen3.6-27B-MTP-GGUF" 2MTP_REV="5cb35eb3dcbf52dbce5f87dbc64df6aaffadcace" 3MTP_FILE="Qwen3.6-27B-UD-Q3_K_XL.gguf" 4MTP_SHA256="661a031ced3e048eeb6d831f8dccaa2020dee480fdd15d9fc9f0fc588e0851f6" 5MTP_DIR="models/qwen36-27b-q3-mtp" 6 7mkdir -p "$MTP_DIR" 8curl -fL --retry 5 --retry-delay 2 -C - \ 9 -o "$MTP_DIR/$MTP_FILE" \ 10 "https://huggingface.co/$MTP_REPO/resolve/$MTP_REV/$MTP_FILE?download=true" 11 12printf '%s %s\n' "$MTP_SHA256" "$MTP_DIR/$MTP_FILE" \ 13 | sha256sum -c - 14 15./llama.cpp/build/bin/llama-server \ 16 --model "$MTP_DIR/$MTP_FILE" \ 17 --no-mmproj \ 18 --alias local-qwen36 \ 19 --ctx-size 8192 \ 20 --n-gpu-layers all \ 21 --flash-attn on \ 22 --parallel 1 \ 23 --spec-type draft-mtp \ 24 --spec-draft-n-max 2 \ 25 --host 127.0.0.1 \ 26 --port 8080

The MTP file is about 14.79 decimal GB, roughly 315 MB larger than the plain Q3 artifact. The current MTP cards say -np > 1 and --mmproj aren't supported with MTP.[11]Reference 11Qwen3.6-27B-MTP-GGUFhttps://huggingface.co/unsloth/Qwen3.6-27B-MTP-GGUF[12]Reference 12Qwen3.6-35B-A3B-MTP-GGUFhttps://huggingface.co/unsloth/Qwen3.6-35B-A3B-MTP-GGUF Keep --parallel 1 and --no-mmproj. Unsloth's general how-to-run examples include --mmproj, so follow the more specific MTP card for this combination and recheck it after the article's refresh date.

The same cards' -hf snippets can still auto-pull a projector. The pinned --model path plus --no-mmproj avoids that extra file.

Diagram showing Controlled comparison, Plain GGUF 8K · text · 1 slot, Record output contract and median decode speed, and Swap only to matching MTP repo + flags.
Controlled comparison, Plain GGUF 8K · text · 1 slot, Record output contract and median decode speed, and Swap only to matching MTP repo + flags.

Compare MTP against a control

Measure plain decoding first, then change only the model repository and MTP flags. Keep these fixed:

  • llama.cpp commit and build flags
  • base model and quant tier
  • prompt tokens and output cap
  • context length and parallel slots
  • sampling settings and warm-up policy
  • hardware, power mode, and background load

Run a prompt pack with short and sustained generations. Record time to first token separately from generated-token throughput because speculation can help decode without helping prompt ingestion. Also record accepted draft tokens when the runtime reports them. Low acceptance can erase the expected speedup, especially on the MoE path.

MTP passes only when output still clears the same task checks. Compare tests, JSON validity, and required facts before comparing speed. A faster run that breaks the answer contract is a regression.

Store medians from repeated warm runs, plus every failed run. Don't delete out-of-memory or malformed-output trials: they define the usable operating envelope.

Keep context small at first

What changes after the plain 8K run? The context setting changes allocation even when the first prompt is short. Qwen3.6 model cards list a native context length of 262,144 tokens and an extended path up to 1,010,000 tokens with RoPE scaling (YaRN).[5]Reference 5Qwen3.6-35B-A3Bhttps://huggingface.co/Qwen/Qwen3.6-35B-A3B[6]Reference 6Qwen3.6-27Bhttps://huggingface.co/Qwen/Qwen3.6-27B That's a model capability, not a laptop startup setting. The cards also warn that static YaRN can hurt shorter texts, so don't turn on the 1M path for an 8K coding loop.

Qwen3.6 uses a hybrid stack. The 27B card lists 16 Gated Attention layers and 48 Gated DeltaNet layers; the 35B-A3B card lists 10 Gated Attention layers and 30 Gated DeltaNet layers.[5]Reference 5Qwen3.6-35B-A3Bhttps://huggingface.co/Qwen/Qwen3.6-35B-A3B[6]Reference 6Qwen3.6-27Bhttps://huggingface.co/Qwen/Qwen3.6-27B For a first estimate, count conventional attention KV entries from those Gated Attention layers. The recurrent state, runtime buffers, and backend choices still make total memory machine-specific, so a simple full-attention formula can overstate or understate the running process.

A model can load weights successfully, then fail on the first long request because context allocation pushes it over the edge. Treat context as measured capacity, not a number you can infer from download size.

Context ladder

Start at 8K, then double to 16K and 32K while recording peak memory and the same prompt result. Move to 64K, 128K, or 262K only when a measured workload needs it and each earlier step fits. Task labels such as "agentic coding" don't determine a safe context allocation.

The Qwen model cards advise keeping at least 128K when possible to preserve thinking capabilities, but also recommend reducing context if you hit out-of-memory errors.[5]Reference 5Qwen3.6-35B-A3Bhttps://huggingface.co/Qwen/Qwen3.6-35B-A3B[6]Reference 6Qwen3.6-27Bhttps://huggingface.co/Qwen/Qwen3.6-27B For a beginner setup, read 128K as a target to grow toward, not a first command.

Add vision only after text works

The official Qwen3.6 model cards describe both 27B and 35B-A3B as causal language models with vision encoders.[5]Reference 5Qwen3.6-35B-A3Bhttps://huggingface.co/Qwen/Qwen3.6-35B-A3B[6]Reference 6Qwen3.6-27Bhttps://huggingface.co/Qwen/Qwen3.6-27B The Unsloth GGUF repositories include mmproj (multimodal projector) files that connect image features to the language model.[3]Reference 3Qwen3.6-35B-A3B-GGUFhttps://huggingface.co/unsloth/Qwen3.6-35B-A3B-GGUF[4]Reference 4Qwen3.6-27B-GGUFhttps://huggingface.co/unsloth/Qwen3.6-27B-GGUF Keep the first run text-only:

  1. Run text-only llama-server
  2. Test /v1/chat/completions
  3. Increase context or switch model pins only after it stays stable
  4. Download mmproj-F16.gguf from the same repository revision, verify its checksum, and pass its local path with --mmproj

Vision adds another file, more memory pressure, and more syntax variation across runtimes.

For the pinned 27B repository revision above, mmproj-F16.gguf is 927.61 MB and its SHA-256 is eacf610d1ee4bd5ed0197a0777dd8f4fceb8eefa27009067c7d496cb68fbde45. A projector from another model or repository revision isn't an interchangeable vision adapter.

Modality rule: Keep text-only as the control run. Add the matching vision projector only to the plain GGUF path after the same server build, GGUF pin, and context length are stable. Current Qwen3.6 MTP cards don't support combining MTP with --mmproj.

Measure memory on the running process

Planning numbers tell you which download to try. Measure the running process before increasing context or concurrency.

On NVIDIA, sample device memory while the server loads and while a request generates:

watch-qwen36-gpu.sh
1nvidia-smi \ 2 --query-compute-apps=pid,process_name,used_memory \ 3 --format=csv \ 4 --loop=1

In another terminal, send the fixed smoke request, then a longer benchmark request. Record idle loaded-model memory, peak prompt-processing memory, and peak generation memory. Use ps -o pid,rss,command -C llama-server to capture host resident memory when CPU offload or unified memory matters.

Repeat after each context increase. Change parallel slots only after the single-request curve is stable. This produces a machine-specific capacity table:

RunContextParallel slotsPeak device memoryPeak host memoryResult
Control8K1measuredmeasuredpass or fail
Context step32K1measuredmeasuredpass or fail
Plain concurrency step32K2measuredmeasuredpass or fail
MTP control8K1measuredmeasuredpass or fail

Don't copy memory values from another machine into this table. Backend, quant, offload, context, and runtime build all change the result.

Plan the memory footprint

Before launching the server, turn the published ladder into a rough budget. Unsloth's numbers are rounded total-memory plans, not loader guarantees.[7]Reference 7Qwen3.6 - How to Run Locallyhttps://unsloth.ai/docs/models/qwen3.6 Qwen3.6 is hybrid, so the cache estimate below counts only conventional FP16 attention K/V entries; recurrent state and backend buffers still need measurement. conservative_total_gb adds explicit cache and projector terms to the published plan as a guardrail, not as a promise that the process will use exactly that amount.

The projector entries use rounded current F16 file sizes from the Unsloth repositories: 0.93 GB for 27B and 0.90 GB for 35B-A3B.[4]Reference 4Qwen3.6-27B-GGUFhttps://huggingface.co/unsloth/Qwen3.6-27B-GGUF[3]Reference 3Qwen3.6-35B-A3B-GGUFhttps://huggingface.co/unsloth/Qwen3.6-35B-A3B-GGUF

qwen36_memory_budget.py
1def qwen36_memory_plan_gb( 2 model: str, 3 quant: str, 4 context_tokens: int = 8192, 5 slots: int = 1, 6 with_projector: bool = False, 7 with_mtp: bool = False, 8) -> dict[str, float | str | bool]: 9 published_plans = { 10 ("27B", "Q3", False): 15.0, 11 ("27B", "Q4", False): 18.0, 12 ("35B-A3B", "Q3", False): 17.0, 13 ("35B-A3B", "Q4", False): 23.0, 14 ("27B", "Q3", True): 16.0, 15 ("27B", "Q4", True): 19.0, 16 ("35B-A3B", "Q3", True): 18.0, 17 ("35B-A3B", "Q4", True): 24.0, 18 } 19 architecture = { 20 "27B": {"attention_layers": 16, "kv_heads": 4, "head_dim": 256}, 21 "35B-A3B": {"attention_layers": 10, "kv_heads": 2, "head_dim": 256}, 22 } 23 projector_gb = {"27B": 0.93, "35B-A3B": 0.90}[model] if with_projector else 0.0 24 published_total_gb = published_plans[(model, quant, with_mtp)] 25 26 # Conventional FP16 attention KV cache: K and V use 2 bytes each. 27 attention = architecture[model] 28 bytes_per_token = ( 29 attention["attention_layers"] 30 * attention["kv_heads"] 31 * attention["head_dim"] 32 * 4 33 ) 34 kv_cache_bytes = context_tokens * bytes_per_token * slots 35 kv_cache_gb = round(kv_cache_bytes / (1000**3), 2) 36 conservative_total_gb = round(published_total_gb + projector_gb + kv_cache_gb, 2) 37 38 return { 39 "config": f"Qwen3.6-{model}-{quant}{'+MTP' if with_mtp else ''}{'+Vision' if with_projector else ''}", 40 "published_total_gb": published_total_gb, 41 "projector_gb": projector_gb, 42 "attention_kv_cache_gb": kv_cache_gb, 43 "conservative_total_gb": conservative_total_gb, 44 "fits_16gb_gpu": conservative_total_gb <= 16.0, 45 "fits_24gb_gpu": conservative_total_gb <= 24.0, 46 } 47 48q3_control = qwen36_memory_plan_gb("27B", "Q3", context_tokens=8192) 49q3_vision = qwen36_memory_plan_gb("27B", "Q3", context_tokens=8192, with_projector=True) 50q4_dense = qwen36_memory_plan_gb("27B", "Q4", context_tokens=8192) 51moe_q4 = qwen36_memory_plan_gb("35B-A3B", "Q4", context_tokens=8192) 52 53for plan in [q3_control, q3_vision, q4_dense, moe_q4]: 54 print( 55 f"{plan['config']}: {plan['conservative_total_gb']} GB conservative " 56 f"(published plan: {plan['published_total_gb']} GB, " 57 f"projector: {plan['projector_gb']} GB, attention KV: {plan['attention_kv_cache_gb']} GB) | " 58 f"16 GB fit: {plan['fits_16gb_gpu']} | 24 GB fit: {plan['fits_24gb_gpu']}" 59 ) 60 61assert q3_control["published_total_gb"] == 15.0 62assert q3_vision["projector_gb"] == 0.93 63assert q3_control["attention_kv_cache_gb"] == 0.54 64assert q4_dense["fits_16gb_gpu"] is False 65assert moe_q4["fits_24gb_gpu"] is True
Output
1Qwen3.6-27B-Q3: 15.54 GB conservative (published plan: 15.0 GB, projector: 0.0 GB, attention KV: 0.54 GB) | 16 GB fit: True | 24 GB fit: True 2Qwen3.6-27B-Q3+Vision: 16.47 GB conservative (published plan: 15.0 GB, projector: 0.93 GB, attention KV: 0.54 GB) | 16 GB fit: False | 24 GB fit: True 3Qwen3.6-27B-Q4: 18.54 GB conservative (published plan: 18.0 GB, projector: 0.0 GB, attention KV: 0.54 GB) | 16 GB fit: False | 24 GB fit: True 4Qwen3.6-35B-A3B-Q4: 23.17 GB conservative (published plan: 23.0 GB, projector: 0.0 GB, attention KV: 0.17 GB) | 16 GB fit: False | 24 GB fit: True

Tune for coding

For coding, use narrow prompts with visible acceptance criteria. Name the function or file, list allowed inputs, state the output shape, and ask for code plus one short explanation. Then run tests.

Sampling baseline

Qwen and Unsloth publish separate sampling settings for thinking and non-thinking modes.[6]Reference 6Qwen3.6-27Bhttps://huggingface.co/Qwen/Qwen3.6-27B[5]Reference 5Qwen3.6-35B-A3Bhttps://huggingface.co/Qwen/Qwen3.6-35B-A3B[7]Reference 7Qwen3.6 - How to Run Locallyhttps://unsloth.ai/docs/models/qwen3.6

ModeTemperaturetop_ptop_kmin_pPresence penaltyRepeat penalty
Thinking, general1.00.95200.00.01.0 or disabled
Thinking, precise coding0.60.95200.00.01.0 or disabled
Non-thinking0.70.8200.01.51.0 or disabled

Set the output cap from the task rather than copying a large default. Keep one baseline prompt pack, raw responses, and task checks so quant, context, and MTP comparisons use the same work.

Local iteration is cheap, but code still needs a verifier: your test suite.

When things go wrong

SymptomInspect firstSafe next action
Out of memory during load or first promptDevice and host peaks, context, GPU placementReturn to 8K, one slot, and text-only; then choose a smaller quant or measured CPU offload
Slow generationCPU offload, device utilization, prompt versus decode timingKeep context fixed, reduce offload with a smaller artifact, and compare generated tokens per second
Broken or gibberish outputQuant family, CUDA toolkit, pinned llama.cpp commit, exact checksum, context, cache typesIf the file is IQ3_S, IQ3_XXS, or IQ2_M on CUDA 13.2, move to a supported toolkit; otherwise retest the verified file and build before changing context
MTP has no speedupSame base/quant, accepted draft tokens, one-slot controlReturn to plain GGUF when median decode doesn't improve; expect a smaller gain on 35B-A3B than on 27B
Image input failsPlain text control, projector repo and revisionRemove --mmproj, recover text, then re-add the matching projector on the non-MTP path
Almost-valid tool JSONEmbedded chat template, client schema, raw responseTest one tool call, validate externally, and don't treat parseable-looking text as a successful call

⚠️ CUDA 13.2: Unsloth's tracked issue names IQ3_S, IQ3_XXS, and IQ2_M quants as affected by gibberish on CUDA 13.2; the issue is now marked fixed. If one of those files fails, try CUDA 12.8 or 13.0, or a current build with the fix.[13]Reference 13Qwen3.6 GGUF CUDA 13.2 issuehttps://github.com/unslothai/unsloth/issues/4849 Unsloth's guide still advises avoiding 13.2, so verify current guidance for other quant families before changing toolkits.[7]Reference 7Qwen3.6 - How to Run Locallyhttps://unsloth.ai/docs/models/qwen3.6

Keep a reproducible receipt

Start with one known-good text run. Record the llama.cpp commit, build flags, model repository revision and filename, context, sampling, GPU placement, prompt-pack revision, raw response, and memory measurements. That receipt makes dense-versus-MoE, Q3-versus-Q4, and plain-versus-MTP comparisons reproducible.

Once the control run is stable, change one dimension at a time: MTP, context, vision, then concurrency. If a step fails, return to the control and compare logs before changing the model.

That discipline generalizes beyond this model. Local LLM Deployment connects fit, quantization, and serving placement; Speculative Decoding explains why an MTP draft path can help decode without making prefill or memory pressure disappear.

PreviousBest AI Coding Plans in 2026NextAI Engineer Portfolio Projects for Interviews
Share this article
XFacebookLinkedInBlueskyRedditHacker NewsEmail
References

Qwen3.6

Qwen Team · 2026

https://github.com/QwenLM/Qwen3.6

qwen3.6

Ollama · 2026

https://ollama.com/library/qwen3.6

Qwen3.6-35B-A3B-GGUF

Unsloth · 2026

https://huggingface.co/unsloth/Qwen3.6-35B-A3B-GGUF

Qwen3.6-27B-GGUF

Unsloth · 2026

https://huggingface.co/unsloth/Qwen3.6-27B-GGUF

Qwen3.6-35B-A3B

Qwen Team · 2026

https://huggingface.co/Qwen/Qwen3.6-35B-A3B

Qwen3.6-27B

Qwen Team · 2026

https://huggingface.co/Qwen/Qwen3.6-27B

Qwen3.6 - How to Run Locally

Unsloth · 2026

https://unsloth.ai/docs/models/qwen3.6

Unsloth Dynamic 2.0 GGUFs

Unsloth · 2026

https://unsloth.ai/docs/basics/unsloth-dynamic-2.0-ggufs

llama.cpp: Inference of LLaMA model in pure C/C++

Gerganov, G. · 2023

https://github.com/ggml-org/llama.cpp

Multi-Token Prediction

Unsloth · 2026

https://unsloth.ai/docs/models/mtp

Qwen3.6-27B-MTP-GGUF

Unsloth · 2026

https://huggingface.co/unsloth/Qwen3.6-27B-MTP-GGUF

Qwen3.6-35B-A3B-MTP-GGUF

Unsloth · 2026

https://huggingface.co/unsloth/Qwen3.6-35B-A3B-MTP-GGUF

Qwen3.6 GGUF CUDA 13.2 issue

Unsloth · 2026

https://github.com/unslothai/unsloth/issues/4849