The improvement cycle
A model proposes lines, the checker labels them, and the labelled examples train the next model—all running on CUDA GPUs.

How the cycle works
Once you have a consistent, rules-based checker, training data costs almost nothing to create. A local 9B model generates many seven-syllable lines on 215 themes, and the rules engine immediately labels each one. A valid line becomes a positive example, an invalid line a hard negative, and a valid–invalid pair on the same theme becomes a preference pair for DPO. We can generate around 700 checker-approved lines per hour, for no more than the electricity cost, and train with QLoRA in around 15 minutes.
The results
Bangor AI's main measure is valid-seven-syllable: a seven-syllable line containing valid cynghanedd, on themes unseen during training. We distinguish all generated lines (raw), lines not memorised from training data (novel), and novel lines without invented words (novel and clean):
| Adapter | Raw valid-at-7 | Novel | Novel-clean |
|---|---|---|---|
| Initial pilot (SFT ~2k examples) | 18.0% | 13.0% | 9.5% |
| SFT v2 (cycle 1) | 39.5% | 14.0% | — |
| DPO round 2 | 48.0% | 16.0% | 5.5% |
| DPO round 3 | 65.0% | 23.0% | 16.5% |
Three rounds were completed in one day. Each used around 30 minutes of CUDA GPU compute, plus a few pennies of API calls for judging. As the model improved, the proportion of valid lines in collected data rose from 20% to 43%.
Four ways the model exploited the measures
- Memorised repetition: on new themes, the model recycled valid lines from training data. Of 79 accepted lines, 48 were memorised rather than newly composed. The response was to check novelty against a snapshot of the training data in every evaluation.
- Empty meaning: some lines were formally valid but unrelated to the theme, repeatedly returning to phrases such as ‘hedd yr heddiw’. A semantic judge was added to score relevance, and that score was used to choose between answers.
- Invented words: the model coined words such as ‘gwinoth’ and ‘hudod’, which the checker accepted. A novel-and-clean measure was therefore added, alongside a penalty for unknown words.
- Excessive repetition: by the fifth DPO round on the model's own output, 89.5% of raw lines were valid but there were only three unique new lines . This suggests self-training reaches its limit after three or four rounds, after which external data or reinforcement learning that keeps the model close to its starting point is needed.
Form and meaning
We put the fine-tuned local model and a commercial model (Claude Opus 4.8) through the same protocol: one attempt, no feedback loop:
| Model | Raw valid-at-7 | Valid + relevant + novel |
|---|---|---|
| Local 9B (DPO r3) | 65.0% | 1.0% |
| Claude Opus 4.8 | 20.0% | 13.5% |
The results show a distinction between form and meaning. The fine-tuned 9B model scored 65.0% on form, compared with Claude's 20.0%; for valid, novel, thematically relevant lines, Claude scored 13.5% and the local model 1.0%. This suggests a system that combines both approaches is worth testing: a general model to propose meaning, with the local model and checker assisting with form.
A starting point for improvement
The propose-and-check cycle has given us a useful starting point. In one early example, a general model proposed lines, the checker identified faults, and the model tried again. Twenty-three of 32 attempts were valid, and the process ended with a two-couplet cywydd without formal errors according to the checker. That does not prove mastery of the craft; its main value is a clear starting point for measuring whether each subsequent round improves form, meaning, variety and consistency:
Y llu a ddaw draw i drig
Daw gwên, yn llawen ei lliw
Da yw'r hedd, da yw'r heddiw
llusg · sain · sain · croes — every line validated by the rules engine; no faults
Project repository: BangorAI/cynghanedd → · Background on the judge: the rules engine →
