📚 More on this topic: DFlash vs MTP on RTX 3090 · Qwen 3.6 27B with MTP: 60 tok/s · Qwen 3.6 Complete Guide · Best Qwen Models Ranked · The 35B MoE on a 3090

The Qwen3.8-27B weights went up on Hugging Face on August 5, the community GGUFs followed on the 13th and 14th, and by the time I finished downloading one, my feed was already full of people quoting the model card at each other. Apache 2.0, 262K context, 64 layers, trained with multi-token prediction. All true, all copied from the same page, none of it a measurement.

So I benched it. One RTX 3090, one headless session, Qwen 3.8-27B against Qwen 3.6-27B at the same quant from the same publisher, run A-B-B-A so that drift and thermal state show up as a difference between the two halves of each pair rather than hiding inside the comparison. I went looking for other 3090 numbers on the 27B before I started and came up empty on August 14, which is less a boast than a statement about how new the file is.

Here’s the deal: on generation speed, the new generation is a wash. The interesting result is 254 MiB wide and sits in the VRAM column, and it contradicts a figure this site has been carrying since May.

Updated August 16. This page originally stopped at speed and VRAM, and said as much, because throughput tells you nothing about whether a model is any good. That turned out to be the thing readers actually wanted, so I went back and measured it: HumanEval pass@1, same two files, same card. The capability half starts here.


The run

Everything in this section describes the throughput and VRAM run of August 14. The HumanEval run added on August 16 used the same box and the same two model files under different conditions, and those are stated in its own section.

Hardware. Miu, my workstation: single RTX 3090 24GB, Intel Core i7-8086K, 64GB DDR4-2667 across four Samsung dual-rank DIMMs in two channels, Xubuntu 24.04. Driver 580.159.03. Display manager stopped for the duration, so the card starts each slot with 9 MiB in use and nothing competing for it.

Build. llama.cpp b10088, commit 67b9b0e, CUDA.

Command. llama-bench with -ngl 99 -fa 1 -p 512 -n 128 -d 0,4096,8192 -r 5. Five repetitions per cell, three context depths, prompt processing and generation measured separately.

Models. Both Unsloth UD-Q4_K_XL, same publisher, same recipe name on the tin:

Qwen 3.8-27BQwen 3.6-27B
File on disk17,923,394,624 bytes (16.69 GiB)17,612,564,704 bytes (16.40 GiB)
sha256 vs upstreambee238bb… matchedff6941de… matched
general.architectureqwen35qwen35
block_count6564

Both checksums were verified against the upstream repos before either model was loaded, which is the step that turns “I downloaded a file called UD-Q4_K_XL” into “I ran the file Unsloth published.” Caches were dropped between models so neither one got to reuse the other’s page cache.

Order. A1 (3.8), B1 (3.6), B2 (3.6), A2 (3.8). GPU start temperature ranged 57 to 62C across the four slots, clocks sat at 1725 to 1740 MHz, and package power landed between 417.05 and 418.90 W. Nothing thermally interesting happened.


Repeatability first, because it licenses everything below

A two-model comparison is only worth reading if the harness can tell the two models apart from itself. So here is the same model against itself, first slot versus last slot, roughly six minutes apart:

Test3.8 A13.8 A23.6 B13.6 B2
tg12841.4941.4941.7841.76
tg128 @ d409641.0241.0041.2141.19
tg128 @ d819240.4940.4740.6840.67

Same-model repeats land 0.00 to 0.02 tok/s apart on every generation cell, against reported per-cell standard deviations of 0.02 to 0.05. Generation on this rig is a solid measurement.

Prompt processing is not, and I want that on the record before the table below rather than after it. Same-model repeats on pp512 differ by 0.50 t/s for 3.8 and 2.87 t/s for 3.6, but the within-run standard deviation on those cells runs ±14.85 to ±37.22. Any prompt-processing difference smaller than about 30 t/s on this setup is noise wearing a number’s clothing.


The numbers

Each figure is the mean of that model’s two slots.

TestQwen 3.8-27BQwen 3.6-27BDelta
pp5121440.31 t/s1432.12 t/snot resolvable
tg12841.49 tok/s41.77 tok/s−0.67%
pp512 @ d40961372.78 t/s1367.86 t/snot resolvable
tg128 @ d409641.01 tok/s41.20 tok/s−0.46%
pp512 @ d81921312.78 t/s1308.09 t/snot resolvable
tg128 @ d819240.48 tok/s40.67 tok/s−0.48%

Every pp512 gap in that table is smaller than the run-to-run spread of the runs that produced it, so there is no prefill delta to report in either direction. The generation rows are measurements.

Read the two halves differently, because they carry different weight.

The prompt-processing column is a wash and I can’t honestly call it anything else. The largest gap is 8.18 t/s at depth 0, which sits well inside the ±25 to ±37 spread of the runs that produced it. If 3.8 prefills faster on this card, this bench can’t see it.

The generation column is real. A 0.28 tok/s gap at depth 0 is more than ten times the same-model repeat spread and roughly six times the reported standard deviation, and the sign is consistent across all three depths and all four slots. Qwen 3.8-27B generates a bit under one percent slower than 3.6-27B here, every time, and the margin narrows slightly as context grows.

One percent is not a thing you will feel. At 41 tok/s you are looking at about a quarter of a second across a 1,000-token reply. What makes it worth measuring is the reason it is that small, which is the next section.

The “nothing changed for your rig” argument has been made twice on this site already, and I’m not going to make it a third time. Inkling 975B vs Your 3090 covers what a frontier release does and doesn’t do to hardware you own, and the DFlash bench across both Qwens found the same near-parity a generation earlier, 2.59x against 2.56x on speculative-decoding speedup. If you want the stay-versus-move framing for the Qwen family specifically, that decision lives here and this page is not going to fork it.


The 254 MiB

Peak VRAM, measured on the card during each slot:

Peak VRAMRepeats
Qwen 3.8-27B17,942 MiBA1 and A2 identical
Qwen 3.6-27B17,688 MiBB1 and B2 identical
Difference+254 MiB+1.44%

Four slots, two values, no variance at all. That is the cleanest number in the whole run.

Now the part that matters. Qwen 3.8’s Unsloth GGUF carries 65 blocks where 3.6’s carries 64, and the extra one is the multi-token-prediction head: nextn.eh_proj plus the enorm, hnorm, and shared_head_norm tensors that go with it. Both models were trained with MTP, and Qwen’s own 3.6 card says so too. The difference is that the stock Unsloth 3.8 quant ships the block inside the file, and the stock Unsloth 3.6 quant does not, which is exactly why the community had to bake separate MTP GGUFs for 3.6 back in May.

This site has been quoting a number for what that block costs, and quoting it from someone else. Our DFlash vs MTP head-to-head puts “~2.49 GiB MTP layer (per PR)” in its comparison table, sourced from the PR #22673 thread rather than from anything I measured. Our MTP throughput piece turns that into advice: “MTP costs roughly 2.5 GiB extra VRAM beyond the base model,” with a warning that a 16GB card might not have room for it.

Here is the honest reconciliation, because the two figures are not measuring the same thing and I’d rather say so than take a cheap win. The PR-derived 2.49 GiB is the layer plus its KV cache during an active speculative run. My 254 MiB is peak allocation with the block resident and speculation switched off, so no MTP KV cache is ever allocated. Those are different quantities and both can be true.

What does not survive is the weights half of the claim, the one our own page states as “2.5 GiB extra VRAM beyond the base model.” The entire generation-over-generation difference on this card, MTP block included, is 254 MiB. The block’s weights cannot be costing gigabytes, because the whole delta between the two models is a quarter of one. If you have been sizing a 16GB card around a 2.5 GiB penalty for having MTP in the file, that penalty is smaller than you were told. Both of those pages were corrected on August 14 and now separate the drafting cost from the resident cost.

Updated August 28: 254 MiB is a ceiling, not a price tag

A second pair went through the same card and the same protocol on August 28, and it puts a boundary around the number above that I did not have in August.

Ornith 1.5-35B-A3B against Qwen 3.6-35B-A3B: Ornith’s file carries 41 blocks and the last one is an MTP block, Qwen 3.6’s carries 40 and has none. Same structural difference as the pair on this page. The peak-VRAM delta came out at 14 MiB, with the MTP-carrying model on the lower side.

So the method that produced 254 MiB can also produce 14, or a negative number. It was never measuring the block. It was measuring the net difference between two whole files, one of which happens to have an extra block in it, and everything else those files disagree about is folded into the same figure. As a ceiling on what the block can cost, 254 MiB did its job and the correction it supported stands. As a number to carry to the next model, it does not exist.

I can now say why, because I went back and opened both files rather than reasoning from the deltas.

Qwen 3.8-27B (Unsloth UD-Q4_K_XL)Ornith 1.5-35B (bartowski Q4_K_M)
MTP block weight tensorsQ5_K, with nextn.eh_proj at Q6_KQ4_0, every one
Average over the block5.38 bits per weight4.52 bits per weight
Block on disk272.6 MiB454.9 MiB
A normal block in the same file238.1 MiB459.2 MiB

Two quantizers, opposite decisions about the same component. bartowski says so on the Ornith model card: “the MTP layers are stored at Q4_0 in the imatrix quants (except for the Q8_0 quant), since imatrix calibration does not exercise them.” A block the calibration never touches gets stored cheaply. Unsloth made the other call on 3.8 and kept it at the same elevated precision as the rest of the model.

The last row is the one that reframes this whole section. An MTP block is a full-size transformer block. The parts that make it an MTP block — nextn.eh_proj, enorm, hnorm, shared_head_norm — come to 41.1 MiB in the 3.8 file and 4.5 MiB in Ornith’s. Everything else in it is an ordinary block: attention, norms, and a feed-forward stack, which on Ornith’s MoE means a full set of 256 experts. That is why it lands within a few percent of a normal block in both files, and why “what does an MTP block cost” has no single answer. It costs roughly one more block, at whatever precision your quantizer chose to store it.

What to take away, in the order that matters:

  • A resident, unused MTP block is cheap enough that it will not change your card decision. That is the finding, and both pairs support it.
  • How cheap depends on the quantizer, not on MTP. A 0.86 bit-per-weight difference between two publishers is larger than anything MTP itself decides.
  • A net delta between two files is an upper bound on the block, never a measurement of it. If you want the block, open the file and add up the tensors.

A bigger file that costs nothing to generate from

3.8 is the larger model on every static measure. It carries 27.32B parameters against 26.90B, a 1.56% increase. Its file is 310,829,920 bytes bigger, which is 296.4 MiB. The tensors llama-bench loads come to 16.68 GiB against 16.39 GiB, the same 0.29 GiB gap from the other direction.

It generates 0.67% slower.

The intuition worth killing here is the one that reads a file-size number and expects generation speed to track it. Decode speed is set by the bytes the GPU reads on every single token, and with speculation off the MTP block sits outside that set. llama-bench does not run speculative decoding. The block gets loaded into VRAM, takes its share of those 254 MiB, and is then never touched by the decode loop. A model that is 296 MiB bigger on disk costs essentially nothing per token, because those particular bytes are not read per token.

That leaves a sub-one-percent residual on generation that this bench is not going to resolve into a cause. It’s consistent in sign and comfortably above the noise floor, so something is producing it, and 0.42B parameters of extra tensors sitting in the same memory space is a reasonable suspect. I’m not going to dress a suspect up as a finding.

There was a rough consistency check sitting in the arithmetic here, and as of August 28 it does not have to be rough. I opened the 3.8 file and added the extra block up tensor by tensor. It holds 424.7M parameters, which is the 0.42B the two parameter counts imply, stored at an average of 5.38 bits per weight, and it comes to 272.6 MiB.

That replaces an estimate this paragraph used to carry. It said “0.42B parameters at Q4-class bit rates comes to somewhere around 225 MiB,” and the estimate was low, because the assumption underneath it was wrong: Unsloth did not store that block at Q4-class rates. Most of it is Q5_K and nextn.eh_proj is Q6_K.

With the measured figure the accounting closes better than the guess did. The block is 272.6 MiB, the file delta is 296.4 MiB, and about 24 MiB is left over for everything else the two files disagree about.

It also corrects the direction of something the old paragraph implied. The block by itself is larger than the 254 MiB VRAM delta it was being treated as a component of. Peak VRAM is not a straight sum of tensor bytes, so the two are not obliged to line up, and I am not going to pretend the residual is fully explained. But it does rule out reading 254 MiB as the block plus a little: something in those files pulls the other way, the quant enums differ and 3.8’s is the smaller one, and that is the likeliest place for it to come from. The scope note above has the version of this that generalises.


What it scores, and what that is worth

Speed and memory were the easy half. The question everyone asked after this page first went up was whether the new weights are actually any good, so I ran the one capability benchmark I can execute end to end on my own hardware and check afterwards.

HumanEval, pass@1, all 164 problems, scored with OpenAI’s official harness rather than a reimplementation. Both models at the same Unsloth UD-Q4_K_XL quant, served through llama-server on the same 3090, greedy decode, every sampling parameter pinned and sent explicitly with each request so nothing drifts between the two arms.

One condition matters enough to name, because it is easy to miss and it bounds everything below. Both arms ran raw prompts through /v1/completions with --no-jinja, so neither model’s chat template was applied and the reasoning path never fired on either side. That is the standard way HumanEval is run and it is symmetric, which is what makes the comparison fair. It also means these numbers describe both models as plain code completers, not as reasoning models. What the same file does on the chat path, with the template on and thinking enabled, is a different measurement and it has its own page.

pass@1Solved
Qwen 3.6-27B UD-Q4_K_XL82.32%135 / 164
Qwen 3.8-27B UD-Q4_K_XL80.49%132 / 164

Three problems apart, and that gap is not a result. The paired breakdown is the part worth reading:

both pass    120        only 3.6 passes  15
both fail     17        only 3.8 passes  12
discordant pairs: 27 of 164
exact McNemar two-sided p = 0.7011
3.6 95% CI: 75.8 – 87.4      3.8 95% CI: 73.8 – 85.8

A p of 0.70 is about as close to “no evidence of a difference” as a paired test gets, and the two intervals overlap across nearly their whole range. The 27 discordant problems are the interesting artefact: these models disagree on one problem in six, in both directions, roughly evenly. They trade wins. That is the signature of two models with genuinely different failure surfaces landing on the same accuracy, not a regression from one generation to the next.

Conditions, which differ from the llama-bench run above. These arms ran through llama-server with a display attached, not headless, so nothing here is throughput-comparable to the tok/s figures earlier on this page. That costs roughly 8% on generation speed and nothing at all on pass@1, because greedy decode does not care how much VRAM headroom is left over.

Provenance, because this rig turned out to have a single-bit page-cache fault the day before. For 3.8: the file was evicted, re-read and checksummed against Unsloth’s published digest immediately before the server loaded it, checksummed again after the eval finished, and four independent runs produce byte-identical completions. The 3.6 arm got the same eviction and the same pre-load verification against its own upstream digest, and three of its runs are byte-identical, but it has no post-run checksum. That is less coverage than 3.8 got and I would rather say so than imply the two arms were treated identically.

One confound worth disclosing. Nvidia’s driver went from 580.159.03 to 580.178.04 on this box at 16:58 on August 15. Every arm of the head-to-head, all three 3.6 runs and the first three 3.8 runs, landed between 12:15 and 13:57 that afternoon, so the comparison itself sits entirely on the older driver and is internally matched. The bracketed 3.8 run reported above ran the next day on the newer one and reproduced the earlier 3.8 completions byte for byte. So the driver change is documented rather than hidden, and the evidence says it moved nothing: same weights, same sampling, same output, either side of the upgrade.

Worth knowing if you ever do this yourself: --no-mmap does not protect you here, because llama.cpp still reads the file through the page cache. It is the verification immediately before load that makes a run trustworthy, not the flag.

On what a HumanEval number is and isn’t worth in 2026, we’ve written the long version separately. Short version for this page: it measures isolated function synthesis, which is a narrow slice of coding, and it is one of very few capability benchmarks a person with one GPU can actually run and reproduce. Both of those are true at once, and the second one is why it’s here.


What Alibaba claims

Neither model card reports HumanEval, so there is no vendor figure to check mine against. What the Qwen3.8-27B card does report is a four-row agentic-coding comparison, and the gaps in it are not small:

Benchmark — all figures Alibaba’sQwen 3.6-27BQwen 3.8-27B
DeepSWE 1.1 (Datacurve’s benchmark)13.342.2
SWE-bench Pro53.561.7
QwenSWEBench49.379.0
LiveCodeBench v683.990.3

A tripling on Datacurve’s DeepSWE 1.1 is not a rounding error and I am not going to wave it away. If those numbers hold, 3.8 is a substantially better agent than 3.6, and nothing I measured contradicts that. HumanEval scores single-function synthesis; an agentic suite scores a model working a repository across many turns with tools. Those are different quantities, and a null on one says nothing about the other.

Four things to hold alongside the table.

These are agent-harness results, not model results. Every row is a score for a model inside a scaffold: tools, retries, a control loop. Change the scaffold and the number moves, which is why the same benchmark can produce several different “best” scores in the same month. A pass@1 is one model, one prompt, one completion, and it is a much smaller claim.

Half the 3.6 baselines rest on Alibaba grading its own predecessor. SWE-bench Pro’s 53.5 and LiveCodeBench v6’s 83.9 also appear on the 3.6 card, so those two are corroborated across two separate releases. DeepSWE 1.1’s 13.3 and QwenSWEBench’s 49.3 appear only on the 3.8 card — the 3.6 card carries neither benchmark. Note which two that is: the table’s two largest gaps are precisely the two whose baselines are single-sourced.

One of the three Opus comparisons is Alibaba’s own benchmark. DeepSWE 1.1 lists no Opus figure at all, so only three of the four rows compare against Opus4.6 Max. Of those three, SWE-bench Pro is Scale AI’s and LiveCodeBench is academic. QwenSWEBench, where the margin over Opus is widest, is Qwen’s own.

The two cards do not line up. The 3.6 card benchmarks against Claude 4.5 Opus; the 3.8 card against Opus4.6 Max. The 3.6 card reports SWE-bench Verified at 77.2 and the 3.8 card does not report that benchmark at all. Beyond the four shared rows above, there is no common ground to compare across the two cards.

One naming trap, because it is genuinely misleading. Two unrelated projects are called DeepSWE. The row on the card is Datacurve’s benchmark, 113 original long-horizon software-engineering tasks. Separately there is DeepSWE-Preview, an RL-trained coding agent from Agentica and Together AI built from Qwen3-32B. Search the bare name and you can easily land on the second and conclude Qwen is benchmarking against a Qwen derivative. It isn’t. Every DeepSWE figure on this page is Datacurve’s benchmark.


Nobody outside Alibaba has run these

This is the part I did not expect to find, and it matters more than the scores.

I went to run LiveCodeBench v6 myself, since it is the one row on that table with an independent academic harness behind it. I couldn’t, and neither can you, for four reasons that stack.

The runner cannot reach a local server. LiveCodeBench’s repository documents no base_url or API-base argument. There is no supported way to point it at an OpenAI-compatible endpoint, which is how every local inference server exposes itself.

Its local path will not load your model. For open models the runner drives vLLM in-process. vLLM does not load GGUF files, so the format every consumer setup actually runs is not a format this harness accepts.

The cost is weeks to months per model, at any plausible sampling budget. v6 is 1,055 problems, these are reasoning models that emit long chains of thought, and vendor protocols sample each problem repeatedly rather than once. Alibaba does not state its samples-per-problem or token budget, so this can only be bracketed: at 8 samples and 16k output tokens per sample you are generating roughly 135 million tokens, which at the ~41 tok/s measured further up this page is about five weeks of continuous generation. Push to 32k tokens and it passes three months. Double any of it for running 3.6 as a comparison. Move my assumptions wherever you like. No version of that arithmetic lands somewhere a person with one card is going.

And the contamination guarantee has expired for both models. LiveCodeBench’s whole design premise is freshness, and v6 covers problems published between May 2023 and April 2025. Both of these models shipped after that window, so the entire problem set predates both and there is no post-cutoff slice left for the memorization check to fire on. The specific property that makes a LiveCodeBench score trustworthy is the one it cannot offer here.

Put those together and the position is this: the headline gap between Qwen 3.8 and 3.6 sits on benchmarks that consumer hardware cannot run, that would take over a month per model if it could, half of whose baselines are single-sourced to the vendor, and one of whose Opus comparisons is the vendor’s own benchmark. Everyone quoting these numbers at you is quoting Alibaba. That includes the ones who sound certain.

None of which makes the numbers wrong. It makes them unaudited, which is a different thing, and worth knowing before you spend an evening acting on them.


Four things this run does not tell you

The quant enums differ, despite identical names. llama-bench reports 3.8 as Q4_K - Small and 3.6 as Q4_K - Medium. Their general.file_type values are 14 and 15. Same publisher, same UD-Q4_K_XL label, different underlying quant enum. Unsloth’s dynamic quants pick bit rates per tensor, so the top-line enum is a summary rather than a recipe, but it does mean these two files are not bit-for-bit comparable builds. Note the direction: 3.8 uses the smaller enum and is still 296 MiB bigger, which makes the extra block harder to argue away rather than easier.

block_count 65 is not 65 transformer layers. Both models are 64 layers deep, and Qwen’s card for 3.8 states “Number of Layers: 64” outright, same as 3.6’s. Block 64 in the 3.8 file is the MTP head, not another decoder layer. The raw count invites a “3.8 is deeper” reading that is simply wrong.

3.8’s GGUF is a Dynamic V3.0 preview. Unsloth’s card says so: “This GGUF uses Unsloth Dynamic V3.0 (preview).” Every other Unsloth row in our benchmark corpus is from the 2.0 generation. A preview quantization pipeline against a mature one is a confound I can name but not subtract, and it is the most likely home for that sub-one-percent generation residual.

Nothing here tells you what MTP does when you turn it on. llama-bench does not run speculation, so the block was loaded and idle for all four slots. Whether --spec-type draft-mtp works against this file on b10088, what acceptance rate it hits, and what it costs in KV cache once it is actually drafting are all untested. That’s the next bench, not this one.


What this measures, and what it doesn’t

Throughput, peak VRAM, and single-function coding accuracy, on one rig, at one quant, on one build, with speculation off. That is the entire claim.

The capability half is narrower than it sounds. HumanEval is 164 self-contained Python functions, and a model can be excellent at it while being mediocre at holding a 200-line refactor together. I have not measured agentic tool use, multi-file editing, long-context behaviour, non-Python languages, instruction-following, or anything resembling SWE-bench. I have not measured what MTP does to output quality once speculation is switched on.

So nothing here supports a sentence about how 3.8 behaves inside a coding agent, which is precisely the territory Alibaba’s numbers describe. Two axes are measured and flat; a third is claimed and unaudited. Anyone telling you today how much smarter 3.8-27B is in agentic use has not shown you a run you can reproduce, and neither have I.


The bottom line

If you’re running Qwen 3.6-27B on a 24GB card today, Qwen 3.8-27B at the same quant will load, will fit with the same headroom you’re used to, and will generate at the same speed you’re used to, within a percent that you will never notice. It asks for 254 MiB more VRAM than its predecessor and hands you an MTP block in the base file for it, which is a trade nobody running a 3090 needs to think about and anyone running a 16GB card should. On short-form Python, it solves the same problems to within a statistical tie.

So the answer on pulling 17.9 GB is not yet, and the reason matters more than the verdict. Both axes anyone can independently measure on hardware you own came back flat. The gain Alibaba describes sits on agentic benchmarks no consumer card can execute, half of whose 3.6 baselines exist only on the newer model’s own card. That gain may well be real. It just lives somewhere these tests cannot reach, and until someone runs a harness you can point at your own machine, taking it on faith costs you an evening and 17.9 GB.

Wait for one of two things: an independent agentic evaluation from someone running the weights on their own hardware, or a LiveCodeBench-style result from a harness a normal person can execute. The weights have been public since August 5 and the GGUFs since the 13th, so both are plausible within weeks.

The case for moving now is if you specifically do hard algorithmic or agentic work and you want to run your own trial against Alibaba’s figures. That is a legitimate bet, and it should be made knowingly rather than because a model card said 90.3.