Cheat Sheet — Model Accuracy & AI Performance

The numbers, formulas, and decision rules to have at your fingertips — the interview-whiteboard quick reference. Definitions are in GLOSSARY.md.


Quantization formulas

Affine (asymmetric):   Q(x) = clamp(round(x/s) + z, q_min, q_max)
                       x̂   = s · (Q(x) − z)
Scale:                 s = (x_max − x_min) / (q_max − q_min)
Zero-point:            z = q_min − round(x_min / s)
Symmetric (z=0):       s = max(|x|) / q_max
Quant error bound:     |Q(x) − x| ≤ s/2     → smaller s = smaller error
dtyperangenotes
INT8 signed−128 … 127symmetric default
INT8 unsigned0 … 255asymmetric; don't cast to int8 before dequant — overflow!
INT4−8 … 7 (or 0 … 15)weight-only (GPTQ/AWQ); needs error comp / salient protection
NF416 normal-spaced levelsQLoRA base dtype

PTQ vs QAT: try PTQ first (fast, little data). Reach for QAT when PTQ's accuracy drop is too big (often INT4, or sensitive layers). Mixed precision (sensitive layers high, rest low) is usually the best size/accuracy point.

Memory math: params × bytes/param. 7B model → FP16 ≈ 14 GB, INT8 ≈ 7 GB, INT4 ≈ 3.5 GB. (Plus the KV cache, which grows with sequence length — quantize/bound it on edge.)

Floating-point formats

formatexp bitsmantissa bitsuse
FP32823baseline / accumulation
FP16510range-limited, precise-ish
BF1687FP32's range, less precision — training-stable

Rule: accumulate in higher precision than you store. Reductions (softmax, sum) in FP32 even when activations are FP16/BF16.

Roofline (the master diagram)

Arithmetic Intensity (AI) = FLOPs / bytes moved
Attainable perf = min( peak_FLOPs/s , peak_BW × AI )

AI low  → MEMORY-bound  → fix: fusion, quantization, layout, FlashAttention
AI high → COMPUTE-bound → fix: better matmul, more cores, higher clocks

Most LLM inference is memory-bound (weight loading at batch 1; the N×N attention matrix) — which is why FlashAttention and quantization win. Don't optimize FLOPs on a memory-bound kernel.

Profiling discipline

1. WARM UP (discard first iters — compile/alloc/cache)
2. measure MANY iters, take the MEDIAN (not mean — outliers)
3. know your clock: CPU time ≠ device time ≠ wall time; self ≠ total
4. find the regime (roofline) BEFORE choosing a fix

Top recurring perf bugs: CPU↔device sync (.item()/.cpu() in a hot loop), hidden dtype casts, non-contiguous copies from reshapes, kernel-launch overhead (many tiny ops), unfused elementwise chains.

Inference optimizations (when each wins)

TechniqueWins onIdea
FlashAttentionlong seq, memory-boundtile + online softmax; never materialize N×N. Exact.
KV cacheautoregressive decodereuse past K/V; O(1)/token attention (memory grows w/ len)
Speculative decodinglatency, batch 1small draft proposes, big model verifies in parallel. Exact.
Continuous batchingserver throughputevict finished + admit new each step; keep HW saturated
Quantizationmemory-bound / fitmove fewer bytes; fit the model in memory

Edge (batch 1, power-limited): FlashAttention ✅, quantization ✅✅, KV-cache quant ✅, spec-decode (if draft fits memory) ☑, continuous batching ➖ (server-side).

FX graph dialects (the silent bug)

capturenode ops you seeexample target
symbolic_trace(module)call_module"l1", "act"
Dynamo (default)call_function (torch fns)torch.relu, torch._C._nn.linear
make_fx / aotcall_function (aten)aten.linear.default

A pass that matches the wrong dialect silently does nothing (no fusion, 0 NPU nodes). Match by function identity AND aten string to be robust. Fuse only when the producer has 1 user.

NPU mental model (Qualcomm)

LOVES : static shapes · dense regular dataflow · fixed-point (INT8/INT4) · supported ops · on-chip
HATES : dynamic shapes · data-dependent control flow · gather/scatter (MoE) · unsupported ops · DRAM round-trips
  • Coverage = % compute on NPU. Treat as a vital sign; one unsupported hot op → CPU fallback → latency death.
  • Fixed-point accumulator can overflow — size scales carefully.
  • Budget is joules, not just ms (power ↔ thermal throttle ↔ latency).
  • Sim validates accuracy; trust the device for performance; reconcile when they diverge.

Consistency: every optimization must be verified

quantize  → eval accuracy delta (P09)
compile/fuse/export → numerical-equivalence check vs eager (atol/rtol)
spec-decode → bit-exact to base model
deploy to NPU → eval ON DEVICE (numerics differ from sim)

Fast-but-wrong is a shipped bug. No optimization is "done" until its accuracy is proven.

Evaluation rigor

report: score + variance/CI + baseline delta + per-example churn (not a lone number)
reproducible: fixed seed/data/config
is-it-real?: bootstrap CI / McNemar (paired); effect must exceed the noise band
Pareto: accuracy vs latency is a FRONTIER; ship at the KNEE for the device's budget
regression CI: block merges that drop accuracy below threshold

The lab verification convention (this track)

# tests import `lab` (your code) if present, else `solution`:
pytest test_*.py            # against your lab.py (NotImplementedError until you fill it)
# to verify the reference solution, shadow lab.py with solution.py, then pytest.

Heavy/proprietary deps (C++ toolchain, TensorFlow, TVM, Qualcomm AI Hub SDK) make a few labs skip gracefully rather than fail — read the code and run them where the toolchain exists.