~/fba-lab/lab/qwen-c/06-generate

FBALab

Code · architecture · study mode

AboutRoadmapSpeedrun
FBALab

Study mode — no GPU required.

Interactive LLM training & inference lab.

Qwen CAboutContactTermsPrivacyCookiesCommunity

© 2026 FBA Lab

Contact · contact@bubblspace.com · +91 75061 55016

INFERENCE SIMULATION

Qwen3 Pure C — 6 · Generate loop

running
◷run_viz.c▸build_sampler()◎learner⌁06-generate$no GPU
weights
Load the model
The 4 GB weight file is mapped into memory in milliseconds. No copying — the OS pages in only what inference needs.
run_viz.c · stage 01–02
load
runtime
Run inference
Your prompt flows through 28 layers of attention and computation, one token at a time.
stage 03–04
forward
active
output
Generate text
The model scores all 151,936 possible next words and picks one. Then repeats.
stage 05–06
1/6
Blocks
Quick summary

After forward() produces 151,936 raw scores, the sampler decides how to pick one — temperature controls how random the choice is, from always-pick-the-best to weighted random selection.

Full explanation below the code →

fba-lab — run_viz.c · build_sampler()executing
$ build_sampler(temp=0.8, topp=0.9)greedy | temperature | nucleus top-psampler initialized ✓
Explanation

What is build_sampler()? forward() gives us 151,936 scores — one per possible next token. But how do we turn those scores into a single choice? That's the sampler's job. The choice of sampling strategy has a huge effect on the model's behavior.

Temperature in plain English: Temperature (named after thermodynamics) controls randomness. At temperature 0, always pick the highest-scoring token — deterministic, good for coding or factual questions. At temperature 1.0, sample proportionally to the probability each token was assigned — some randomness, natural-feeling text. At temperature 2.0, more adventurous choices, sometimes creative, sometimes incoherent.

Top-p (nucleus sampling): top-p adds another filter: only consider tokens whose cumulative probability reaches topp (e.g., 0.9). This cuts off the long tail of very unlikely tokens — preventing occasional random nonsense without eliminating all creativity.

Why allocate scratch buffers here? The sampler is initialized once and reused for every token. Its scratch buffers (probabilities array, sorting workspace) are allocated here, not inside sample() — avoiding per-token allocation overhead.

Why it matters

Same forward() can drive greedy CLI, creative writing, or reproducible benchmarks — policy lives here.

Think about

In plain English, what does temperature actually control about the model's word choices?

// architecture

Live diagram

100%
Startup (main)load_configbuildPrefillall prompt tokensforward()Samplertop-p / tempDecodeone tokenOutputstream textemit_sampleJSONL stderrDecode loop (one token per step)pos advances: prefill 0..N → decode N+1, N+2, …
← 5 · Tokenizer7 · GEMV, not GEMM →
Step 6 of 10Skill: The Forward Pass
01Blueprint02Load weights03Buffers04Forward pass05Tokenizer06Generate loop07GEMV, not GEMM08Every op a kernel09Attention & memory10Prefill vs decode