The 8 GB Lab Book · Chapter 21

Choose the house SLM

Board
Jetson Orin Nano Super
Mode
15W
Summary
Qwen3-4B Q4 is the house model: tools 5 of 5, restraint 2 of 2. My score picked the 1.7B, and a gate I wrote after the runs overruled it.

What I expected

Three models competed for one seat. I expected that the bigger Qwen would win by my own formula, with better tool calls and the same chat. I thought that the task half would separate the models. I thought that the RAM half would break ties between models that were almost equal.

I also expected that 5 of 5 would mean 'reliable'. Those expectations were about the design, not about the models. All of them were incorrect.

The theory

A product ranks by its widest factor; a gate is a step

RAM LEFT FOR EYES, Qwen3-4B (arithmetic, MiB counted as tegrastats counts them)

usable 7.62 GB (board, 7,620 MiB)
- 2.4 idle floor (that day's reading, not logged) - 0.7 runtime = 4.52
- 4k KV: 4096 x 144 KB (Day 3) = 576 MiB = 0.58
- weights, back-solved: 2.43 GB
check: 2.43 GB / 4 B = 4.9 bit per weight
= 1.5 GB for eyes; with Day 25's measured 1,498 MiB floor it is 2.4

The product, unrounded

1.7B: 0.80 x 2.975 = 2.38
4B:   0.90 x 1.456 = 1.31
3B:   0.85 x 2.059 = 1.75
task term spans 0.80 to 0.90: 1.13x
GB term spans 1.46 to 2.98: 2.04x
= a 2x factor outranks a 13 % factor

The printed GB column is rounded. The score divided by the task term gives the GB that the script really used: 2.98 / 1.46 / 2.06. A check on the house model gives 2.43 GB x 10.7 = 26 GB/s. This is the pull of Chapter 2 again.

If the true invalid rate were 10 %, five calls (theory)

P(5 of 5 valid)
59 %
P(4 of 5)
33 %
what 5/5 proves
rate < 45 %
0.9^5 = 0.59 and 5 x 0.1 x 0.9^4 = 0.33: the two results I got are the two likeliest draws of one coin. (1 - p)^5 = 0.05 gives p = 45 %, so five clean calls only say 'under 45 %'. Under 1 % takes 300 clean calls: 0.99^300 = 0.05.

The setup

Run all three (board, ~25 min)
bash ~/day21_23.sh
for t in qwen3-1.7b qwen3-4b llama3.2-3b; do python3 -c "import json;print('$t',json.load(open('$HOME/slm/$t.json'))['summary'])"; done
Read a transcript
python3 -c "import json;[print(c['prompt'],'->',c['called'],c['pass']) for c in json.load(open('$HOME/slm/qwen3-4b.json'))['cases']]"
From qwen3-4b.json, the file the run wrote
"tag": "qwen3-4b"
"model": "~/models/Qwen3-4B-Q4_K_M.gguf"
"ctx": 4096
"start_ms": 22139.825
"grammar": false
"chat": [ ... ]
"tool": [ ... ]
"cases": [ ... ]
"summary": { "ttft_ms_chat_median": 161.625, "decode_tps_chat_median": 10.699, "tool_valid": ...

The measurement

WhatExpectedMeasuredNote
Qwen3-1.7B Q4: tools/5 · cases/10 · restraint/2-4 · 8 · 2TTFT 101 ms, 22.8 tok/s
Qwen3-4B Q4: tools/5 · cases/10 · restraint/2-5 · 8 · 2TTFT 162 ms, 10.7 tok/s
Llama-3.2-3B Q4: tools/5 · cases/10 · restraint/2-5 · 7 · 0TTFT 119 ms, 13.5 tok/s
Qwen3-1.7B Q4: RAM left for eyes-3.0 GB (estimate)usable - floor - weights - 4k KV - 0.7
Qwen3-4B Q4: RAM left for eyes-1.5 GB (estimate)usable - floor - weights - 4k KV - 0.7
Llama-3.2-3B Q4: RAM left for eyes-2.1 GB (estimate)usable - floor - weights - 4k KV - 0.7
score = task x GB left-2.38 / 1.31 / 1.75the score picks the 1.7B; the 5/5 tool gate picks the 4B
Measured on the board unless the row says estimate or predicted.
Three candidate house models: tool call emitted, regression, restraint, and RAM left for eyes (score in the labels)
Fig 21.1Three candidate house models: tool call emitted, regression, restraint, and RAM left for eyes (score in the labels).

One stacked bar, bottom up, house model resident

  • idle floor 2.4 GB, that day's reading; Day 25 logged 1,498 MiB
  • runtime 0.7 GB
  • weights Q4 2.43 GB
  • KV at 4k 576 MiB
  • eyes 1.5 GB left
The top slab is the score's big factor. The floor is whatever else was awake at the time (Chapter 5's list), and the 2.4 was read, not logged: Chapter 25 measured 1,498 MiB.
modeltools/5cases/10restr/2TTFT mstok/sGB leftscore
Qwen3-1.7B Q448210122.83.02.38
Qwen3-4B Q458216210.71.51.31
Llama-3.2-3B Q457011913.52.11.75
Measured: 15W, llama-server, Q4_K_M, 4k ctx, temperature 0. Tools, cases, restraint, TTFT and tok/s: on the board. GB left: an estimate, floor and two subtractions. Bold row: the house model. The restraint column is the robot column: 0 of 2 means a tool fired when nothing asked for one.

Where it broke

The formula ranked by RAM, because I let one factor change by 2x and the other factor by 13 %. I built a RAM contest and read it as a task score. It named the smallest model, as a RAM contest does. I added the gate afterward. The gate saved the decision, but it did not save the design.

The gate is five samples. 5 of 5 and 4 of 5 are one call apart, which is inside the noise of the coin above.

The biggest term of the score rests on a floor I read once and did not log. Chapter 25 measured the floor at 1,498 , 0.9 GB under the 2.4 I used here. With that floor the eyes slab of the 4B is 2.4 GB, not 1.5. The ranking does not move, but the room for a camera does.

Summary

  • The tool-call column separates the models more than the chat column. All three models can talk. Fewer models emit a tool call when a user asks for one and stay quiet when nothing was asked.
  • The RAM left for eyes is not a tie-breaker. It is half the score. Chapter 19 used it for vision tokens, and Chapter 25 uses it for voice. The house model must leave this RAM free.
  • Qwen3-4B Q4 is the house model for Days 22 to 25. Each chapter in that range uses it.
  • Write the gates before the score. Tool call emitted 5/5 and restraint 2/2 are pass/fail. They are not points. I learned this when I saw the score select the incorrect model.

Sources

These sources are not mine. Measured numbers came off my own board; specs, estimates and paper figures are labeled as such.

  • Jetson AI Lab Gemma 4-on-Jetson page (Nano → E2B)
  • Edge-LLM Nano bench table (Qwen3-0.6B/1.7B INT4)
  • Jetson AI Lab SLM tutorial list