klon8-base: a two-layer sound-word canvas model for Thai klon pad (กลอนแปด)
This is the checkpoint of the paper Single-Sample Decoding of a Two-Layer Sound-Word Canvas Model for Thai Klon Pad (Worasait Suwannik, 2026, manuscript). Given a short topic it writes one four-line klon pad stanza.
The model is a masked language model over a fixed canvas: 12 topic cells and four lines of up to 10 cells, one cell per pronounced syllable. A sound layer (onset, rime, tone) carries the form constraints, which the decoder enforces as hard masks (syllable counts, the three rhyme links, line-final tones); a word layer of whole words carries the text, so no word is cut into pieces. The body is WangchanBERTa-base. The paper's method, called Base-0.4, draws one sample per topic at temperature 0.4, with no best-of-N selection, reranking or repair.
Files
| File | What it is |
|---|---|
model_h24/model.pt |
weights, 24-epoch model (sha256 53ef5c171d9bda7dc0b93a2c40cd842f2d5837467c77963f7cfc64cd19f6bcbe, the checksum quoted in the paper) |
model_h24/config.json, TRAINED, train.log |
model configuration and the training log |
lexicon.json |
the open vocabulary: 62,665 words with their pronounced syllables |
allow.json |
allowlist of the decoder's stutter ban |
g2p_cache.json |
pronunciation cache (word -> phonemes) that makes decoding reproducible |
config.json, configuration_klon8.py, modeling_klon8.py |
the transformers wrapper |
src/ |
the project's generation code, used by the wrapper |
SHA256SUMS |
checksums of the weight and data files above |
Use
With the transformers package (the repository ships its own model code, hence trust_remote_code=True):
pip install torch transformers sentencepiece protobuf pythainlp
pip install --no-deps tltk
pip install nltk gensim sklearn-crfsuite scikit-learn pandas requests matplotlib
tltk is installed with --no-deps because its package metadata pins scikit-learn~=1.2.0, which cannot be
installed on recent Python versions (pip then fails while building scikit-learn); it works with current scikit-learn,
and the third line installs what it imports. pip may still print a warning about that pin; it can be ignored.
from transformers import AutoModel
model = AutoModel.from_pretrained("voraseth/klon8-base", trust_remote_code=True)
for r in model.generate_poem("ห้องเรียนใต้ทะเล", n=3, seed=0): # seeds 0, 1, 2 at temperature 0.4
print(r["poem"], r["form_pass"], "\n")
With seed 0 the first stanza is
เปิดห้องเรียนใต้ทะเลในตอนใหม่
ให้สนุกหัวใจไม่สับสน
ประสบการณ์ชีวิตอุทิศตน
เป็นหนึ่งคนที่อยู่คู่ทะเล
generate_poem(topic, n=1, seed=0, temperature=None) returns a list of dicts (poem, lines, form_pass,
form_failures, seed, ...); generate_poems(topics, seed=0) writes one stanza per topic. temperature=0.8 gives a
richer vocabulary with more lexical errors (the paper's Base-0.8).
Notes:
- The checkpoint is not a standard architecture, so it has no
forwardfor general use: a poem is produced by the project's own decoder (src/in this repository, unchanged from the paper's code), which the wrapper calls. - The first load also downloads the WangchanBERTa encoder the model is built on.
- Device: an NVIDIA GPU (cuda) when available, then the Apple GPU (mps), otherwise CPU; pass
device="cuda","mps"or"cpu"tofrom_pretrainedto choose, or callmodel.to(device)after loading. Tested on mps and CPU; CUDA has not been tested. The decoder's masks and sampling run on the CPU, so a GPU speeds up only the network pass. - Decoding is deterministic given the weights and the seed, and the wrapper returns exactly the stanzas of the paper's decode. A stanza takes about 1.6 seconds on a laptop GPU.
src/holds the generation code and the model and training code (src/scripts/twolayer_canvas.py). The data-building and evaluation scripts of the paper are available from the author.
Evaluation (from the paper)
On 78 held-out forum titles, one sample per title, judged by three independent runs of an LLM judge (Claude Opus 5.5) in the same pools as human stanzas written for the same topics:
| Model, T = 0.4 | Human verse | |
|---|---|---|
| Passes form, clean and on topic ("all three") | 70.5% | 76.9% |
| Lexically clean (all four lines) | 85.9% | 87.2% |
| On topic (alignment >= 4 of 5) | 84.6% | 91.0% |
| Passes the form checker | 98.7% | 92.3% |
The difference in all-three is -6.4 points (95% CI [-19.2, +6.4]). No generated line of the 78 stanzas occurs verbatim in the training or test corpora.
Limitations
- The language is plainer than human verse: fewer rare words, more repetition of content words and of the topic.
- The numbers above are judgments of one LLM judge family, not of expert readers; in a small blind check a human reader flagged more lines than the judge.
- One form (klon pad), single stanzas, modern forum register.
- Output is machine-written verse and should be labelled as such.
Training data
About 49,000 klon pad stanzas of modern verse publicly posted by members of a Thai verse forum, with the thread title as the topic. The verse itself is not redistributed here; this repository holds weights and word lists only.
Licence
The weights are derived from WangchanBERTa, whose authors provide their pretrained weights under CC-BY-SA 4.0 (Lowphansirikul et al., 2021); this checkpoint is released under the same licence.
Credit and citation
The research was directed by Worasait Suwannik; the programs were produced by Claude, Anthropic's AI model.
@unpublished{suwannik2026klonpad,
author = {Suwannik, Worasait},
title = {Single-Sample Decoding of a Two-Layer Sound--Word Canvas Model for Thai Klon Pad},
year = {2026},
note = {Manuscript}
}
- Downloads last month
- 26