Homebrewed SLMs: Autoregressive and Masked Diffusion Language Models Built at Home for Portuguese
Organizations: Department of Mathematics Federal Institute of Brasília Brasília, Brazil
Abstract
Building a language model of one's own no longer requires a data centre. This tutorial trains one from scratch, tokenizer included, on one consumer GPU, and shows how to tell whether it is good for the tasks of a specialist domain. It proposes no new method. It releases a tested Python package and two notebooks in Brazilian Portuguese with autoregressive and masked diffusion generation on one network, a preregistered comparison protocol, legal tasks built from text alone with a Kneser-Ney floor and public yardsticks, reference numbers for models of 11 to 12M parameters, and a catalogue of defects that only measurement revealed. On Brazilian prose and federal laws, at minutes per run, the autoregressive mode peaks at 64 epochs over the same text and then memorises it, while masked diffusion improves up to 256. At their best points on test, the diffusion bound exceeds the autoregressive likelihood by 0.06 bits per byte, within the preregistered minimum effect. On held-out laws and on acts published after training, the model ties a 6-gram floor in likelihood on the same windows, and it loses to the floor at continuing those acts. It beats the floor at detecting tampered text, and fills cross-references more often than the floor and public models of 160M and 630M parameters, only in decrees, a genre absent from training, where those scorers stay near or below chance, and in filling the blank only when each group weighs the same, since per item it ties the 630M model. On laws, the public models, trained with about 5x10^2 to 10^5 times its compute, lead in tampered text and continuation. The blind human reading is preregistered and not part of this version.
Figures & tables
| Resource | Language | Tokenizer | Generation | Evaluation | Prereg. | Code licence |
| Annotated Transformer | English, German | BPE of the original setup | Encoder–decoder | BLEU | No | MIT |
| nanoGPT | English | GPT-2 BPE reused, or characters | Autoregressive | Validation loss | No | MIT |
| Cramming | English | WordPiece trained on the data | None, masked encoder | GLUE | No | MIT |
| TinyStories | English, synthetic | GPT-Neo BPE reused | Autoregressive | Grading by GPT-4 | No | Data CDLA-Sharing 1.0 |
| BabyLM | English | Participant’s choice | Participant’s choice | BLiMP, (Super)GLUE and others | No | Varies |
| This tutorial | Portuguese | Byte-level BPE trained on the data | Autoregressive and masked diffusion, one network | Kneser–Ney floor, public yardsticks, four domain tasks, calibration | Yes, hashed | CC BY-NC-SA 4.0 |
| Box | Module (gloss) | Responsibility | Checks |
| 0 | config (configuration) | Validated configuration of corpus, tokenizer, network, mode and budget | |
| 1 | dados (data) | Domain adapters, cleaning, segmentation, block split, proper-name lists | Corpus G0 to G5 |
| 2 | tokenizador (tokenizer) | Tokenizer contract, didactic BPE, library adapter | Tokenizer G0 to G5 |
| 3 | janelas (windows) | Windows of tokens per document, with [EOS] and padding predicted | Formulation G1, G2 |
| 4 | mascaramento (masking) | Stratified draw of and masking of exactly positions | Formulation G0 |
| 5 | modelo (model) | Transformer with causal or bidirectional attention, [MASK] logit at | Formulation G0 |
| Task | Items | Groups | Share of groups for power 0.8 |
| T1 Filling in the blank | 337 | 130 | 0.655 |
| T2 Inserted or own provision | 3,095 (313 inserted) | 643 | 0.570 |
| T3 Tampered text | 1,185 | 469 | 0.581 |
| T4 Continuation | 2,251 | 615 | 0.571 |
| Epochs | Seeds | Autoregressive | Diffusion | 95% interval | Randomization | |
| 1 | 5 | 2.692 | 2.808 | 0.115 | ||
| 4 | 5 | 2.314 | 2.767 | 0.453 | ||
| 16 | 5 | 1.955 | 2.748 | 0.793 | ||
| 64 | 5 | 1.806 | 2.167 | 0.361 | ||
| 256 | 6 | 2.851 | 1.825 | 0.031 |
| Tokenizer | Epochs | Bits per byte | Difference to BPE | |
| BPE, | 16 | 256 | 1.954 | |
| Bytes, | 5.1 | 256 | 2.751 | |
| Bytes, | 4.5 | 911 | 3.368 | |
| BPE, | 256 | 256 | 2.849 | |
| Bytes, | 81.3 | 256 | 1.849 | |
| Bytes, | 71.8 | 911 | 1.840 |
| Epochs | Seeds | Autoregressive | Diffusion | 95% interval | Randomization | |
| 1 | 5 | 2.242 | 3.113 | 0.871 | ||
| 4 | 5 | 1.626 | 2.994 | 1.368 | ||
| 16 | 5 | 1.101 | 2.046 | 0.945 | ||
| 64 | 5 | 1.066 | 1.329 | 0.263 | ||
| 256 | 6 | 1.487 | 1.135 | 0.031 |
| ECE | Selective at 0.9 | Deletion AUC | ||||||||
| Corpus | Mode | Epochs | fitted | ROC AUC | Coverage | Kept | Importance | Random | ||
| A | AR | 1 | 0.95 | 0.014 | 0.022 | 0.647 | 0.000 | 0/5 | 0.562 | 0.811 |
| A | AR | 4 | 0.96 | 0.012 | 0.025 | 0.748 | 0.000 | 0/5 | 0.234 | 0.702 |
| A | AR | 16 | 0.98 | 0.016 | 0.022 | 0.747 | 0.016 | 5/5 | 0.163 | 0.669 |
| A | AR | 64 | 1.18 | 0.106 | 0.030 | 0.779 | 0.029 | 5/5 | 0.102 | 0.501 |
| A | AR | 256 | 2.19 | 0.398 | 0.014 | 0.792 | 0.013 | 4/6 | 0.080 | 0.328 |
| Scorer | T1 Filling in the blank | T2 Inserted or own | T3 Tampered text | T4 Continuation |
| All acts | 130 groups | 643 groups | 469 groups | 615 groups |
| 6-gram floor | 0.241 [0.179, 0.301] | 0.502 [0.488, 0.515] | 0.497 [0.456, 0.537] | 1.355 [1.324, 1.385] |
| autoregressive | 0.399 [0.349, 0.450] | 0.467 [0.442, 0.492] | 0.559 [0.528, 0.589] | 1.425 [1.383, 1.468] |
| masked diffusion | 0.310 [0.258, 0.361] | 0.502 [0.476, 0.529] | 0.550 [0.523, 0.578] | 1.852 [1.816, 1.888] |
| TeenyTinyLlama 160M | 0.269 [0.205, 0.331] | 0.541 [0.495, 0.588] | 0.567 [0.527, 0.607] | 0.791 [0.779, 0.804] |
| Tucano 160M | 0.294 [0.227, 0.358] | 0.510 [0.491, 0.529] | 0.458 [0.419, 0.498] | 0.737 [0.726, 0.748] |
| T1 accuracy by class | Picks the most frequent | Accuracy in decrees | ||||||
| Scorer | Numbers, laws (29) | Cross-ref., laws (77) | Cross-ref., decrees (231) | T1 of 4 options | T3 of 2 versions | T1, single- item groups | T3, single- item groups | T3, other groups |
| 6-gram floor | 0.379 | 0.286 | 0.234 | 0.487 | 0.557 | 0.149 | 0.377 | 0.695 |
| autoregressive | 0.345 | 0.395 | 0.410 | 0.476 | 0.676 | 0.385 | 0.482 | 0.659 |
| masked diffusion | 0.425 | 0.301 | 0.314 | 0.689 | 0.699 | 0.234 | 0.526 | 0.580 |
| TeenyTinyLlama 160M | 0.517 | 0.481 | 0.294 | 0.309 | 0.586 | 0.179 | 0.475 | 0.639 |
| Tucano 160M | 0.621 | 0.390 | 0.329 | 0.243 | 0.422 | 0.194 | 0.294 | 0.682 |
| Score | Selective coverage | |||
| Decider | T2 | T3 | T2 | T3 |
| TF-IDF with logistic regression (floor) | 0.544 [0.487, 0.600] | 0.573 [0.553, 0.593] | ||
| autoregressive checkpoint | 0.499 [0.459, 0.539] | 0.501 [0.500, 0.503] | 0.90% (0.89) | 2.29% (0.51) |
| masked diffusion checkpoint | 0.488 [0.441, 0.536] | 0.514 [0.511, 0.517] | 0.05% (0.67) | 0.59% (0.54) |
| Laya multilingual, fine-tuned | 0.485 [0.446, 0.524] | 0.500 [0.494, 0.506] | 0.00% | 0.00% |
| Laya multilingual, no fine-tuning | 0.515 [0.494, 0.535] | 0.499 [0.492, 0.505] | ||
| Check | What it detected | Fix |
| Length test with exact conditionals | If diffusion receives the document length without paying for it, it gains the entropy of the length, 0.856 nat (1.235 bits) per document in the test, matched within | Predict [EOS] and padding in both modes |
| Weight of the loss | Weight unbounded near , infinite variance without a cut-off, and the cut-off truncates the bound | Number-of-masks form, weight at most ( Propositions 1 and 2 ) |
| Logit gradient in fp16 | With one masked token per sequence and scale , the logit gradient exceeds the fp16 maximum of 65,504 for the mean over masked tokens with weight at batch 2, 4 and 64 | Number-of-masks form, peak bounded by scale over batch, 16,384 at batch 4 |
| Precision sentinel | Median per-tensor error of 1.38 and 1.45, maximum 7.11, against a margin of 0.05, caused by dropout in the sentinel itself | Both passes of the sentinel in eval mode, with a test |
| Range of the sampling noise | In fp16 the uniform draw has 2,048 values and the largest Gumbel noise is 7.62, against 16.64 in fp32 and 36.74 in fp64 | Categorical draws in float64 [ Zheng et al., 2024 ] |
| Enumeration of all sequences | With a free [MASK] logit the distribution sums to 0.5906 instead of 1, and with a target visible to its own prediction to 1.2837 | [MASK] logit at |
Appendix figures & tables2 assets
Supplementary material from the paper’s appendix.
Appendix
| Check | Criterion | State |
| Formulation G0 | Enumeration of all orders, distribution sums to 1 within , NELBO bounds the exact value, injected defects fail | Passed. Defects give 0.5906 and 1.2837 |
| Formulation G1 | Length test through the package iterator, difference within | Passed |
| Formulation G2 | Padding fraction measured before fixing | , 12.2% padding |
| Tokenizer G0, G2 | Equal merges and ids, vocabulary rule on the real held-out text | Passed, (A), (B) |
| Tokenizer G3, G4 | Training and encoding times and equality on the Colab CPU | Not in this version |
| Corpus G1, G3 | Segmentation and minimum block (A), pages, volume and largest group (B) | Passed. B: 444 of 444 pages, 4.76 MB, largest group 5.78% |
| Autoregressive | Diffusion | ||||
| Learning rate | Dropout | 16 epochs | 256 epochs | 16 epochs | 256 epochs |
| 0 | 1.953 | 4.853 | 2.750 | 1.843 | |
| 0.1 | 1.931 | 3.668 | 2.756 | 1.863 | |
| 0.2 | 1.953 | 2.850 | 2.763 | 1.930 | |
| 0 | 1.939 | 5.602 | 2.752 | 1.873 | |
| 0.1 | 1.851 | 4.271 | 2.747 | 1.826 | |
Language Modeling
Language modeling develops systems that learn patterns in text and other sequences to understand, predict, and generate language.
See all 522 papers