You have decided to run a language model yourself. You open the model hub, type the family name you have heard about, and press enter. Here is what actually comes back, in download order, on the day this lesson was written:
Qwen/Qwen3.6-35B-A3B-FP8
nvidia/Qwen3.6-35B-A3B-NVFP4
Qwen/Qwen3.6-27B-FP8
Qwen/Qwen3.6-27B
unsloth/Qwen3.6-27B-NVFP4
cyankiwi/Qwen3.6-27B-AWQ-INT4
Lorbus/Qwen3.6-27B-int4-AutoRound
Qwen/Qwen3-Embedding-0.6B
unsloth/Qwen3-Coder-30B-A3B-Instruct-GGUF
Nine results. They are not nine versions of the same thing with different polish. Two of them cannot run on the server you were planning to use. One of them does not generate text at all. Three were not made by the company whose name is at the front. One will happily load and then produce nonsense in a chat interface, because it was never taught to hold a conversation.
Nothing on that list is labelled "the one you want." The information is all there, but it is written in a shorthand nobody sits you down and explains.
This matters more than it looks. In the lab that runs later in this chapter, we rented a GPU instance at $2.2421 an hour, downloaded a model, and started the server. Choosing the wrong line from that list would have meant paying for a thirty gigabyte download and then watching the server refuse to start, at which point you pay again to download the right one. The name is the only thing you get to read before you spend the money.
So this lesson teaches one skill: look at a model name and predict what it will do to your hardware. By the end you will be able to glance at Qwen/Qwen3.6-27B-FP8 and say, out loud, roughly how many gigabytes it will occupy, what kind of card it needs, whether it will answer a question or just continue your sentence, and which serving software will accept it.
Here is that string taken apart in the order you should read it. Click any part for what it commits you to.
Every other number in a model name depends on this one, so it is worth getting right rather than nodding along.
A parameter is a single number that the model learned during training. That is the whole definition. Not a fact, not a word, not a piece of knowledge you could look up. Just a number, usually something like 0.0317 or -1.2044.
Think of a very large mixing desk in a recording studio. It has dials. Turning a dial changes how loudly one instrument comes through. Training a model is the process of turning every dial, over and over, until the sound coming out matches what you wanted. Once training stops, the dials are frozen in place. Shipping a model means shipping the positions of all its dials.
A model with 27 billion parameters is a mixing desk with 27 billion dials.
Where do the dials come from? They come from the arithmetic the model does. When a model processes text, it repeatedly multiplies lists of numbers by grids of numbers. Each cell in each grid is one parameter. Stack a few hundred of those grids and the count reaches billions quickly.
You can count them yourself on something small enough to see. The code below builds a network with three layers and counts every learned number in it.
Run it. The tiny network has 130 parameters, and you can verify that by hand: four inputs times eight outputs is thirty two weights, plus eight biases, and so on. Nothing mysterious is happening. A production model does exactly this, with grids of several thousand by several thousand, repeated across dozens of layers.
So what does the parameter count tell you? Two things, and it is important to keep them separate.
It is a rough for capability. More dials means more capacity to represent patterns, which is why a 27B model generally reasons better than a 0.6B model. Rough, not reliable: training data and technique matter enormously, and a well trained small model routinely beats a badly trained large one.
It is an exact predictor of memory. This one is arithmetic, not judgement, and it is the reason the number is in the name at all. That is the next slide.
A parameter is a number, and a number has to be stored in some quantity of bytes. So:
memory for the weights = number of parameters x bytes per parameter
The second term is a choice. The same 27 billion learned values can be written down at different precisions, the way you can write pi as 3.14159265 or as 3.14. Fewer digits means less storage and a small loss of exactness.
| Format | Bytes per parameter | 27B model | What it is |
|---|---|---|---|
| FP32 | 4 | 108 GB | Full precision. Almost never used for serving. |
| BF16 / FP16 | 2 | 54 GB | The default a model ships in. |
| FP8 | 1 | 27 GB | Eight-bit floats. Needs a recent GPU. |
| INT4 / NVFP4 | 0.5 | 13.5 GB | Four-bit integers. Cheapest, most lossy. |
That table is the reason a model name carries both a size and a format. 27B tells you how many numbers. tells you how big each number is. You need both to know whether it fits.
Model names look arbitrary until you notice they are built from the same slots in the same order. Not every model fills every slot, and the slots are separated by hyphens, but the order is remarkably consistent across publishers.
publisher / family version - size [ -A active ] [ -specialisation ] [ -post-training ] [ -precision ] [ -format ]
Qwen / Qwen3.6 - 27B - FP8
unsloth / Qwen3 - 30B -A3B -Coder -Instruct -GGUF
Qwen / Qwen3 - 0.6B -Embedding
nvidia / Qwen3.6 - 35B -A3B - NVFP4

Reading this figure. At the top the name is one string. Below it, the same string is pulled apart into its four parts, each drawn as a different shape so you can tell them apart at a glance: a seal for who built it, a chevron for which generation, a stack of discs for how many numbers, and a caliper for how wide each number is. The four rounded chips near the bottom are the extra parts that appear on longer names.
Publisher. The text before the slash is the account that uploaded it, and it answers a question that matters: is this the original, or somebody's re-release? Qwen/Qwen3.6-27B-FP8 is the vendor's own quantized build. cyankiwi/Qwen3.6-27B-AWQ-INT4 is a community member's four-bit conversion of the same base model. The community build may be excellent. It may also have been quantized with a calibration set that suits somebody else's workload and quietly damages yours. Prefer the vendor's own build when one exists, and when you use a community build, read what they say about how they made it.
Look at these two models side by side:
Qwen/Qwen3.6-27B reads as twenty seven billion parameters.Qwen/Qwen3.6-35B-A3B reads as thirty five billion parameters, then A3B.A3B means three billion active parameters. The model has 35 billion in total, but any single token only passes through about 3 billion of them.
This is a mixture-of-experts model. Instead of one large block of arithmetic that every token goes through, the layer is split into many smaller specialist blocks, and a small router network picks a couple of them per token. The rest sit idle for that token, then get used for a different token later.
Go back to the mixing desk. A dense model is one enormous desk, and every song is mixed through all of it. A mixture-of-experts model is a room containing thirty desks, where each song is routed to the two most suitable ones. You still had to buy thirty desks, and they all still take up floor space, but each song only occupies two.
That analogy carries the exact consequence you need:
Memory is set by the total. Speed is set by the active.
You must hold all 35 billion parameters in GPU memory, because the router might send the next token to any expert and there is no time to fetch one from disk. But the arithmetic per token is only what 3 billion parameters cost, so generation is much faster than the total size suggests.
Two models can have identical architecture, identical parameter count and identical file size, and behave completely differently, because of what happened in the final stage of training. That stage is what this slot in the name records.
Base. Trained only to continue text. Give it "The capital of France is" and it will produce "Paris." Give it "What is the capital of France?" and it may produce three more questions, because a document containing that question plausibly continues with more questions. A base model is not broken when it does this. It is doing exactly its job, which is not the job you wanted. Base models are raw material for , not for products.
Instruct (also Chat, also -it for "instruction tuned"). The same model after being taught to treat your text as a request and respond to it. This is what you want for essentially every application. When a name has no post-training suffix at all, check the model card, because publishers increasingly ship the instruct-tuned version as the default and only mark the base version explicitly.
Thinking (also Reasoning). Trained to produce a chain of intermediate reasoning before its final answer. This is worth knowing about before you deploy one, because the reasoning is emitted as tokens. You pay for those tokens, they take time, and by default they may appear in the response.
We saw this directly in the lab. Asked a two sentence question with a 120 token limit, the model spent its entire budget thinking and never reached the answer:
reply : Here's a thinking process:
1. **Analyze User Input:**
- **Topic:** KV cache in an LLM server
- **Question:** What is it? Why does it grow with conversation length?
- **Constraint:** Exactly two sentences.
2. **Define KV Cache (Key-Value Cache):**
- In transformer-based LLMs, attention mechanisms compute keys (K) and values (V)...
tokens: 33 in / 120 out
Thirty three tokens in, one hundred and twenty out, and not one of them was the answer. The fix is a serving parameter that disables thinking for requests that do not need it, and once we set it the same question answered directly:
The last slots on a name are the ones people most often get wrong, because two different ideas share the same territory.
Precision is how many bits each parameter uses. FP8 is eight-bit floating point. INT4 and NVFP4 are four-bit. Lower precision means less memory and faster arithmetic, at some cost in accuracy that ranges from unmeasurable to serious depending on the method and the workload.
Format is how the file is packaged and therefore which software can open it. This is the part that silently wastes an afternoon.
| Marker | Precision | Made by | Runs on |
|---|---|---|---|
| (none) | BF16 | the vendor | anything |
FP8 | 8-bit float | usually the vendor | vLLM, TensorRT-LLM, on a recent data centre GPU |
NVFP4 |
Everything above becomes concrete the moment you rent a card. Here is exactly what happened when we did.
We rented a g6e.2xlarge on AWS, which carries a single NVIDIA L40S. The marketing figure for that card is 48 GB. What the driver actually reports is different:

Reading this figure. The output of nvidia-smi on the rented machine. The number that matters is 46,068 MiB of memory, which is what the driver reports rather than the 48 GB printed on the spec sheet. The last line is the serving software version.
46,068 MiB, which is 44.99 GiB. The gap between 48 and 45 is the usual difference between a marketing gigabyte and a binary gibibyte. Once the driver and CUDA context take their share, the serving framework reported only 44.39 GiB actually available.
Now apply the lesson. Qwen/Qwen3.6-27B is 55.6 GB. It cannot fit, and no amount of configuration changes that. Qwen/Qwen3.6-27B-FP8 is 30.9 GB. It fits. So the FP8 build was not a performance optimisation or a nice-to-have, it was the only one of the two that was possible on this card.

Reading this figure. First the downloaded model as it sits on disk, then the card it has to fit into, then the arithmetic for both builds side by side. This is the entire sizing decision on one screen.
Here is where every gigabyte went once the server was running. These are measured values from the server's own startup log, not estimates:
Names carry information, but they do not carry all of it. Here is a failure that no amount of name reading would have predicted, and it is instructive precisely because of that.
With the right model, the right precision and a card with room to spare, the server refused to start:

Reading this figure. The server refusing to start. It reports how much memory it found, then explains that this model needs one Mamba cache block for every concurrent request, that there is room for 191 of them, and that it had been told to accept 256.
Read the error. It says each concurrent request needs one Mamba cache block, and there is room for 191, but the server was configured to accept 256 at once.
Mamba is not a transformer component. It is a different mechanism for handling sequences, and Qwen3.6 is a hybrid: partly attention, partly Mamba. Nothing in the string Qwen3.6-27B-FP8 tells you that. You find out from the model card, or from the error.
The consequence is worth carrying forward. The maximum number of simultaneous requests this model can serve was set by its architecture, not by the size of the GPU. Lowering the concurrency limit to 128 fixed it immediately. But if you had planned capacity by dividing GPU memory by expected conversation size, your plan was wrong before you started.
This is also the point of the version slot in the name. Qwen3 was a conventional transformer. Qwen3.6 is a hybrid. Same family, one decimal apart, and a serving constraint that did not exist before.
The name determines the hardware, the hardware has an hourly price, and the hourly price only becomes a per-token price once you know how busy the box is. This is where self-hosting is either brilliant or a mistake, and the name alone will not tell you which.
We benchmarked the running server at four concurrency levels. Every number below is measured on the box described above, at $2.2421 per hour:

Reading this figure. One row per concurrency level. Read down the throughput columns and the numbers climb; read down the columns and they climb too. The top and bottom rows of this table are the entire argument for and against self-hosting.
| Concurrent requests | Output tokens/sec | P99 time to first token | Cost per 1M output tokens |
|---|---|---|---|
| 1 | 16.62 | 142 ms | $37.47 |
| 4 | 71.52 | 483 ms | $8.71 |
| 16 | 226.33 | 1.85 s |
Go back to the search results from the first slide. You can now read all of them.
| Name | What it tells you |
|---|---|
Qwen/Qwen3.6-27B | Vendor build, 27B dense, BF16 by default, 55.6 GB. Needs more than one 48 GB card. |
Qwen/Qwen3.6-27B-FP8 | Vendor build, same model at 8 bits, 30.9 GB. Fits one L40S. Needs Ada or newer. |
Qwen/Qwen3.6-35B-A3B-FP8 | Vendor, mixture-of-experts, 35B held in memory, ~3B active. Bigger and faster. |
nvidia/Qwen3.6-35B-A3B-NVFP4 | NVIDIA's 4-bit build. Smallest of the MoE options, newest hardware required. |
cyankiwi/Qwen3.6-27B-AWQ-INT4 | Community 4-bit build, ~14 GB. Check how it was calibrated. |
Lorbus/Qwen3.6-27B-int4-AutoRound |
5 questions - Score 80% to pass
You have a GPU that reports 46,068 MiB. Which of these will fit its weights with room left over for a KV cache?
Qwen3.6-35B-A3B has more total parameters than Qwen3.6-27B. Compared to the 27B dense model, what should you expect?
You download unsloth/Qwen3-Coder-30B-A3B-Instruct-GGUF onto a GPU server running vLLM and it will not load. What is the most likely reason?
A model card says the file is 30.9 GB, but 27 billion parameters at one byte each should be 27.0 GB. Why the extra 3.9 GB?
Your self-hosted server costs $2.2421 an hour and sustains 16.62 output tokens per second with one user, or 431.12 with sixty four. What does this tell you about when self-hosting makes sense?
FP8Now the honest part, which most explanations skip. The formula gives round numbers, and the real files are not round. Here are the actual sizes reported by the model hub for the two builds we care about:
| Repository | Formula predicts | Actually is | Weight files |
|---|---|---|---|
Qwen/Qwen3.6-27B | 54.0 GB | 55.6 GB | 15 |
Qwen/Qwen3.6-27B-FP8 | 27.0 GB | 30.9 GB | 66 |
The BF16 build is 3 percent over. The FP8 build is 14 percent over. Neither is a rounding error, and the gap is worth understanding because it is where people who trust the formula get caught.
Three things account for it. First, "27B" is a marketing round number; the true count is somewhat above 27 billion. Second, quantization is never applied to the whole model. The table, the final output layer and the normalisation layers are sensitive, so they usually stay at higher precision while only the big internal grids drop to eight bits. Third, a quantized model has to carry extra bookkeeping: for every block of weights it stores a scale factor used to reconstruct the original range, and those scales are themselves numbers that take space. That is also why the FP8 build has 66 weight files against 15: the quantized layout is stored in far more, far smaller pieces.
The practical rule that survives all of this:
Take the parameter count, multiply by the bytes per parameter, then add 15 percent. Treat the result as the floor, never the total.
The floor matters because weights are not the only thing on the card. That is two slides from now.

Reading this figure. Three vessels, one for each way of writing the same 27 billion numbers down. The liquid is the real download size, and the dashed red line is what the card actually holds. BF16 pours straight over the top. FP8 and INT4 both fit, and the empty space above each of them is what is left over for the conversations.
The same 27 billion numbers at four precisions, with what the formula predicts beside what actually downloads.
And here is the procedure itself, which you can run on any name before downloading anything.
Family and version. Qwen3 and Qwen3.6 are different architectures, not the same architecture with better training. This is not cosmetic. Later in this lesson you will see a server refuse to start because Qwen3.6 contains a component that Qwen3 did not have. A version bump can change what hardware and what serving software you need.
Size. The parameter count, as covered. Note 0.6B uses the same slot as 27B, so the slot tells you nothing by itself until you read the number.
Active parameters. The -A3B marker. This is the single most misread part of a model name and it gets its own slide next.
Specialisation. Coder, Embedding, VL, Math, Guard. This slot changes what the model is for, sometimes completely. Qwen3-Embedding-0.6B does not generate text at all; it turns text into vectors for search. If you point a chat application at it, nothing sensible happens. VL means vision and language, so the model accepts images as well as text.
Post-training. Instruct, Chat, Base, Thinking, it. Covered two slides from now.
Precision and format. FP8, NVFP4, AWQ-INT4, int4-AutoRound, GGUF. Covered three slides from now. These two are separate ideas that often sit next to each other: precision is how small each number is, format is how the file is packaged and therefore which software can open it.
Qwen3.6-27B |
|---|
Qwen3.6-35B-A3B |
|---|
| Total parameters | 27B | 35B |
| Active per token | 27B | ~3B |
| Memory needed | smaller | larger |
| Speed per token | slower | faster |
Read that table twice, because it inverts the intuition the name gives you. The model with the bigger number in its name needs more memory and runs faster. People pick the 35B expecting it to be the heavyweight option and are surprised when it outruns the 27B. People pick it on a card sized for a 27B model and it does not load at all.

Reading this figure. On the left, one solid cell: every token passes through all 27 billion parameters. On the right, fifteen cells of which two are working and thirteen sit idle while still occupying memory. The four gauges underneath say the same thing in numbers. The mixture-of-experts model takes up more memory and does less arithmetic per token, which is why it can be both bigger and faster.
The comparison that inverts most people's intuition:

Reading this figure. A real request to the server we built, with the thinking step switched off. The model names the two phases of inference and says which of them is limited by memory . The last line is the token count, which is the thing you are billed on.
The lesson generalises past this one model. A post-training suffix changes the shape of the output, not just its quality, and output shape is what your application code has to parse, your cost model has to price, and your budget has to absorb.
One question, three builds of the same model, three different shapes of answer:
| 4-bit float |
| NVIDIA or community |
| NVIDIA runtimes on very recent cards |
AWQ-INT4 | 4-bit integer | usually community | vLLM and others, with an AWQ kernel |
GPTQ | 4-bit integer | usually community | vLLM and others, with a GPTQ kernel |
GGUF | various | community | llama.cpp and Ollama, not vLLM |
That last row is the one to memorise. GGUF is a container format built for llama.cpp, which is what Ollama uses underneath. It is superb for running a model on a laptop. Hand a GGUF file to vLLM on a server and you will spend a while wondering why nothing works. unsloth/Qwen3-Coder-30B-A3B-Instruct-GGUF is not a worse model than the vendor build; it is a build aimed at an entirely different runtime.
There is also a hardware precondition that names do not state. FP8 needs a GPU with hardware support for eight-bit floats, which in practice means Ada Lovelace, Hopper or newer. On an older card an FP8 build either refuses to load or falls back to emulation and runs slower than the BF16 version it was supposed to improve on.
A note on where models come from at all. Downloading weights and running them yourself is one of four routes to an endpoint, and it is not automatically the right one:
The reason you can move between all four is that they nearly all speak the same OpenAI-compatible interface. Changing provider is usually changing a base URL, an API key and a model string. That interchangeability is what makes the decision reversible, and it is why it is worth understanding rather than guessing.
Precision and format sit next to each other and are not the same thing:
And the four routes to an endpoint, only one of which is the one this chapter builds:
| Component | Measured |
|---|---|
| Card capacity reported by driver | 46,068 MiB (44.99 GiB) |
| Available to the framework after driver and context | 44.39 GiB |
Ceiling we set (gpu-memory-utilization 0.94) | 41.73 GiB |
| Model weights | 28.51 GiB, loaded in 3.13 seconds |
| CUDA graph pool | 0.67 GiB |
| 10.3 GiB, which is 146,773 tokens | |
| Activations and working space | the remainder, roughly 2.25 GiB |

Reading this figure. Six lines lifted straight from the server's own startup log. They show the checkpoint size, how much GPU memory the weights actually took and how long they took to load, how much was left over for the KV cache, and how many tokens of conversation that works out to.
The line that changes how you think is the KV cache at 10.3 GiB. That memory is not weights. It holds the intermediate state for every conversation currently in flight, and it grows with how long the conversations are and how many are running at once. It is the reason "will the model fit" is the wrong question. The right question is "will the model fit and leave enough room for the traffic", and the answer to that one is not in the name at all.

Reading this figure. Forty five dots, one gibibyte each, coloured by whatever claimed them. The weights are the first colour and they run out about two thirds of the way through, which is the whole point: the model name predicted that block and nothing else on the card.
The same ledger as a stack, where you can open each layer for what it holds and why it grows:
Getting to that state took three and a half minutes of GPU time before a single request was answered:
The failure, and the general lesson underneath it:
| $2.75 |
| 64 | 431.12 | 16.92 s | $1.44 |
Sit with those two extreme rows. The same model, on the same card, costs twenty six times more per token when it serves one user at a time than when it serves sixty four. Nothing about the model changed. You are renting the card by the hour either way, so an idle card is a card you are paying for and not using.
And look at what the cheap row costs you. At sixty four concurrent requests, one request in a hundred waits almost seventeen seconds before it produces its first token. For a batch job that is fine. For a chat interface it is unusable.
So the honest summary of self-hosting economics is this: it is cheap only if you keep the GPU busy, and keeping the GPU busy is paid for in tail latency. A team with steady, high volume, latency-tolerant traffic will beat managed API pricing comfortably. A team with spiky, low volume, interactive traffic will pay $37 per million tokens for the privilege of running their own server, which is worse than simply buying the tokens.
The whole experiment, from launch to termination, took 0.89 hours and cost $1.99.
Before the numbers, here is what one request actually touches, and where the money is counted:
The four measurements side by side, with the cost of each:
| Another community 4-bit build by a different method. Compare, do not assume. |
unsloth/Qwen3.6-27B-NVFP4 | Community NVFP4 repackaging of the vendor model. |
Qwen/Qwen3-Embedding-0.6B | Not a chat model at all. Turns text into vectors. Different job entirely. |
unsloth/Qwen3-Coder-30B-A3B-Instruct-GGUF | Older family, code specialised, MoE, instruction tuned, GGUF so llama.cpp or Ollama, not vLLM. |
Three habits will keep you out of trouble.
Read the publisher before the model. A community repackaging is a different artifact from the vendor's own build, even when every other segment of the name is identical.
Multiply before you download. Parameters times bytes per parameter, plus fifteen percent, and compare that against what your card actually reports rather than what the spec sheet advertises. Thirty gigabytes is several minutes and real money to fetch.
Treat the name as necessary and not sufficient. It told us the size, the precision and the vendor. It did not tell us the model was a hybrid architecture with a hard concurrency ceiling. Read the model card, and expect the first launch to teach you something the name did not.