Pearl-Chat: Engineering a native Luganda language model from first principles in JAX and Flax NNX
Organizations: AI for Uganda Initiative · ISBAT University
Abstract
Autoregressive foundation language models predominantly target high-resource Indo-European languages, imposing computational and morphological penalties on under-represented African languages. Generic multilingual tokenizers routinely exceed fertility rates of 3.2 tokens per word on agglutinative Bantu languages, degrading context efficiency and inflating latency. We present Pearl-Chat, an 8,473,122-parameter (8.5M) causal decoder-only transformer engineered for Luganda (Oluganda, ISO 639-2: lg), a low-resource Niger-Congo Bantu language spoken by over 10 million people in East Africa. Built from first mathematical principles in JAX and Flax NNX, Pearl-Chat uses explicit functional state decomposition (nnx.split and nnx.merge), deterministic resumable data streaming via Google Grain, and SPMD tensor parallelism using jax.sharding.Mesh. We introduce a byte-level byte-pair encoding (BPE) subword tokenizer trained from scratch on curated Luganda corpora (), achieving 4.88 characters per token compression and 1.60 tokens per word fertility, a two-fold compression improvement over LLaMA-3 (128K) and Gemma (256K). The model is trained with a two-stage curriculum: Stage 1 pre-training on 59,501 sequences across parallel, biblical, encyclopedic, and journalistic corpora, and Stage 2 instruction fine-tuning on 510 dialogues with assistant-only loss masking. Across 4,000 optimization steps, validation cross-entropy loss drops monotonically from 9.4695 (perplexity: 12,958.98) to 0.1818 (perplexity: 1.20), a decrease of 9.2877 nats. On a three-tier held-out diagnostic benchmark, Pearl-Chat achieves 0.9792 ROUGE-L and 0.9405 BLEU while maintaining concordial agreement across Bantu noun classes. We provide a Python Server-Sent Events (SSE) streaming runtime and open-source all weights, tokenizers, and code.
Figures & tables
| Class | Prefix | Concord | Example gloss |
|---|---|---|---|
| Cl 1 / 2 | omu- / aba- | a- / ba- | omuntu / abantu (person / people) |
| Cl 3 / 4 | omu- / emi- | gu- / gi- | omuti / emiti (tree / trees) |
| Cl 5 / 6 | eri- / ama- | li- / ga- | erinnya / amannya (name / names) |
| Cl 7 / 8 | eki- / ebi- | ki- / bi- | ekitabo / ebitabo (book / books) |
| Cl 9 / 10 | en- / ezin- | e- / zi- | ente / ente (cow / cows) |
| Cl 11 | olu- | lu- | olulimi (language / tongue) |
| Tokenizer | Vocabulary size | Compression (chars/tok) | Fertility (tok/word) | Total tokens |
|---|---|---|---|---|
| Pearl-Chat BPE (Ours) | 8,192 | 4.88x | 1.60 tok/w | 16 |
| Gemma BPE [ 10 ] | 256,000 | 2.52x | 3.10 tok/w | 31 |
| GPT-4o BPE [ 9 ] | 200,000 | 2.44x | 3.20 tok/w | 32 |
| LLaMA-3 BPE [ 4 ] | 128,256 | 2.29x | 3.40 tok/w | 34 |
| mBERT WordPiece [ 16 ] | 119,547 | 2.00x | 3.90 tok/w | 39 |
| Character baseline | 256 | 1.00x | 7.80 tok/w | 78 |
| Corpus name | Records | Est. tokens | Domain |
|---|---|---|---|
| Luganda Bible corpus | 30,844 verses | 1,620,000 | Classical Bantu prose |
| Parallel corpus | 24,973 pairs | 1,240,000 | Contemporary bilingual |
| Luganda Wikipedia | 350 articles | 380,000 | Encyclopedic prose |
| Sunbird SALT MT | 300 pairs | 18,000 | Bilingual parallel |
| Curated SFT dialogues | 510 dialogues | 35,000 | Conversational chat |
| Total curated pool | 60,017 records | 3,293,000 | Multi-domain balanced |
| Component | Tensor dimension | Trainable parameters |
|---|---|---|
| Token embedding | 2,097,152 | |
| Position embedding | 65,536 | |
| Transformer blocks ( ) | 8 layers | 6,306,816 |
| – Attention ( ) | 2,097,152 (total across 8 layers) | |
| – LayerNorms ( ) | (scale and bias) | 32,768 (total across 8 layers) |
| – MLP ( ) | 4,194,304 (total across 8 layers) |
| Dimension | PyTorch ( torch.nn ) | Flax NNX ( flax.nnx ) |
|---|---|---|
| State tracking | Implicit object mutation | Explicit state pytrees |
| Graph splitting | Deep copies and hooks | Functional nnx.split / merge |
| JIT compilation | TorchScript / Dynamo | Native nnx.jit via XLA |
| Autodiff | In-place .grad buffers | Functional nnx.value_and_grad |
| Sharding | Imperative DDP hooks | Declarative NamedSharding |
| Step | Curriculum stage | Training loss | Validation loss | Validation PPL | Learning rate ( ) |
|---|---|---|---|---|---|
| 0 | Uninitialized baseline | – | 9.4695 | 12,958.98 | 0.00 |
| 1 | Stage 1 (Pre-training) | 9.4470 | 9.4695 | 12,958.98 | 0.06 |
| 250 | Stage 1 (Pre-training) | 6.1544 | 6.0726 | 433.80 | 5.98 |
| 500 | Stage 1 (Pre-training) | 5.7434 | 5.3179 | 203.96 | 5.85 |
| 1000 | Stage 1 (Pre-training) | 5.5017 | 4.9537 | 141.69 | 5.26 |
| 1500 | Stage 1 (Pre-training) | 5.4477 | 4.2903 | 72.99 | 4.31 |
| Evaluation tier | Exact match rate | ROUGE-L F1 | BLEU-4 score |
|---|---|---|---|
| Tier 1: Memorization and syntactic integrity | 100.0% | 1.0000 | 1.0000 |
| Tier 2: In-domain validation split | 92.0% | 0.9650 | 0.9420 |
| Tier 3: Out-of-domain held-out generalization | 83.3% | 0.9792 | 0.9405 |
| Configuration | Validation loss | Validation PPL | Concord accuracy | ROUGE-L F1 |
|---|---|---|---|---|
| Pearl-Chat (Full curriculum) | 0.1818 | 1.20 | 98.5% | 0.9792 |
| – No Stage 1 pre-training | 2.9135 | 18.42 | 48.2% | 0.3410 |
| – No assistant loss masking | 0.8420 | 2.32 | 82.1% | 0.5215 |
| – Small vocabulary ( ) | 0.6120 | 1.84 | 89.4% | 0.6830 |
| – Large vocabulary ( ) | 0.7240 | 2.06 | 84.7% | 0.6310 |
| – Post-LN baseline | 1.4502 | 4.26 | 71.0% | 0.4850 |
Appendix figures & tables2 assets
Supplementary material from the paper’s appendix.
Appendix
| Parameter | Value | Description |
|---|---|---|
| Model type | Decoder-only | Causal autoregressive transformer |
| Vocab size ( ) | 8,192 | Byte-level BPE tokens |
| Context length ( ) | 256 | Maximum sequence tokens |
| Embed dim ( ) | 256 | Hidden state dimension |
| Num layers ( ) | 8 | Transformer decoder blocks |
| Num heads ( ) | 8 | Attention heads ( ) |
| Target scale | Parameters | Optimal tokens | Hardware mesh | Estimated time |
|---|---|---|---|---|
| Pearl-Chat (Ours) | 8.5M | 3.3M (curated) | 1x Tesla T4 GPU | 227.2 sec |
| Pearl-Medium | 35M | 700M | 4x TPU v5e | 4.2 hours |
| Pearl-Large | 125M | 2.5B | 16x TPU v5e | 14.8 hours |
| Pearl-Bantu Multi | 500M | 10.0B | 64x TPU v4 | 36.0 hours |
Language Modeling
Language modeling develops systems that learn patterns in text and other sequences to understand, predict, and generate language.
See all 498 papers