Fine-Tuning SmolLM3-3B on a 16 GB Mac: MLX QLoRA, a Resume-Counter Bug, and Checkpoint Selection Doing Its Job
2026-07-30 · Ankit Aglawe

Parable-SmolLM3-3B is the sixth model in the Parable series and the first trained entirely on a consumer Mac: a 16 GB M1, MLX, QLoRA on a 4-bit quantized base. No cloud GPU touched the run. That constraint shaped everything worth writing down: the machine is also a workday machine, so the run had to pause at 07:35 when the day started and resume at 16:30 when it ended, and surviving that pause is where the story is.
The lane
The setup is deliberately small: SmolLM3-3B loaded 4-bit, 16 of 36 layers adapted, 6.7M trainable parameters (0.218%), a 4,096-token window over 4,076 real Claude Fable 5 agent-session rows, gradient checkpointing on, batch size 1. Peak memory 8.1 GB, which leaves the machine usable. Iteration budget: 1,200, with validation every 200 and adapter snapshots every 100.
The resume-counter bug
mlx_lm lora resumes cleanly from an adapter file with --resume-adapter-file, but it does not resume the iteration count. The counter restarts at 1, and the numbered snapshot files restart too: after our resume, the adapter directory contained 0000800_adapters.safetensors from the morning segment and a fresh 0000100_adapters.safetensors that is actually iteration ~980 of the run. Nothing in the tooling warns about either.
The consequence is silent: a driver script that passes --iters 1200 on every launch, which is the obvious way to write one, re-issues the full budget to the resumed run. Ours did. 880 iterations done plus 1,200 more is a 73% overshoot, roughly seven extra epochs on a 4,076-row corpus, on an adapter this small a straight road to memorization. The fix is one line of arithmetic (relaunch with --iters 300, the remainder), but only if you notice, and the only tell is a checkpoint filename that looks too small. If you run resumable MLX training, keep an iteration ledger outside the tool; the filenames will lie to you after every resume.
Checkpoint selection earning its keep
The run finished with validation loss 1.154 at iteration 200 of the final segment and 1.203 at the end, 300. The best checkpoint is not the last one: the tail of the budget was already past the useful minimum, and the driver's validation-loss pick quietly saved the release from shipping a slightly worse adapter. Held-out test loss against the base: 1.889 down to 1.115, a 41% reduction on 226 sessions the model never saw.
What a 4-bit base means, said plainly
Training ran against a 4-bit quantized base because 16 GB is the budget. The merge dequantizes to F16 safetensors, and the GGUF repo quantizes that down again, but no arithmetic recovers what the 4-bit base never had: every artifact of this run is capped at 4-bit-base quality. The model card states the same ceiling. What the Mac lane buys for that ceiling: zero GPU cost, full-machine control, and, because SmolLM3 is a supported llama.cpp architecture, GGUFs that run in stock Homebrew, Ollama, and LM Studio builds on day one.
The method details for the wider series, including why held-out trace loss is the gate and what it cannot tell you, are in the technical report. The full run history for this model, pause included, is in the training logs shipped with the artifacts repository.