// how it works
Committed is a complete pipeline, not just a model. I started from CommitChronicle (roughly 10.7M real GitHub commits) and wrote a filter to extract clean, single-file diffs paired with well-formed Conventional Commit subjects, normalizing them into a consistent training target. I fine-tuned Qwen3 with QLoRA on the result — first the 1.7B, then the 0.6B on the identical recipe — evaluated each against its un-tuned base on a multi-metric harness with an LLM judge I validated against my own hand-ratings, then served them locally through llama.cpp with grammar-constrained decoding that guarantees every output is syntactically valid. Most of the work was the data, not the model, and all four stages (data, training, evaluation, serving) are here.
// results
I fine-tuned two sizes on the identical pipeline — Qwen3-1.7B and a smaller Qwen3-0.6B — and evaluated each against its un-tuned base on a 442-example test sample, scored by a DeepSeek (deepseek-chat)judge on four orthogonal axes and reweighted to the test split's true commit-type distribution. All four arms share the same judge, so every comparison below is apples-to-apples.
The default. It matches the 1.7B on commit-type and faithfulness at roughly a third the parameters — a smaller download and faster local inference. The honest trade: slightly vaguer messages (specificity 0.55 vs 0.67).
Both base models share the same dominant failure mode — “feat-collapse”: they label the overwhelming majority of diffs as feat (86.7% for the 0.6B base, 95.5% for the 1.7B), regardless of what the change actually did. Because fix commits alone make up about 49% of real-world commits, a model that almost never predicts fix scores below a trivial always-fix baseline (0.489) on reweighted type accuracy — which is exactly what both bases do (0.15 and 0.13). Fine-tuning breaks the collapse: feat-share drops under 10% and type accuracy clears the floor for both sizes.
The one axis the fine-tunes give something up on is specificity. The 1.7B fine-tune trades down from its base (0.81 → 0.67) as it adopts the terse, normalized subject style of the training targets, and the smaller 0.6B is vaguer still (0.55). It's a real trade-off, traceable to a normalization choice in the training data, and the next iteration targets it. Otherwise the two fine-tunes are close — graded 2.09 (0.6B) vs 2.14 (1.7B) — so the 0.6B gets most of the quality at roughly a third the size.
An LLM judge is only trustworthy if it agrees with a human. I hand-rated 50 examples blind and validated the DeepSeek judge against them:
Three axes land at moderate-to-substantial agreement (κ ≈ 0.56–0.61); specificity is the weakest (κ 0.34), so specificity-driven differences carry the most judge uncertainty. Two honest caveats: these DeepSeek-judged numbers are not comparable to earlier Gemini-judged figures (only the deltas within the table above are valid), and n=50 gives wide confidence intervals.
// sample outputs
// run it locally
Committed runs entirely on your machine — no API, no diff ever leaving your laptop. It defaults to the 0.6B (a smaller, faster download); the 1.7B is available when you want maximum specificity. Install it once, pipe a diff in, and get a commit message back:
Both serve as a quantized GGUF through llama.cpp on CPU — the first run downloads the weights once (~397 MB), then it's fully offline. The hosted demo above runs the model you pick with the toggle.