charlm

October 10, 2026 (2w ago)

Stack: Python, PyTorch, pytest, mypy, GitHub Actions, semantic-release · Repo: Axeloooo/charlm

Problem

charlm builds one progression on one task, generating names: a bigram table made by counting, a neural bigram, an embedding MLP, the same MLP with BatchNorm, and a WaveNet-style model that fuses context hierarchically. The layers (Linear, BatchNorm1d, Embedding and others) are written by hand in the style of torch.nn, without using torch.nn.Module.

It is an installable package with a CLI, and the 32,033-name dataset ships inside it.

Architecture diagram

  names.txt (package data)
      |
      v
  load_words --> build_vocab (27 symbols) --+
      |                                     |
      v                                     v
  split_words 80/10/10, seed 42      build_mlp / build_wavenet
      |                              (vocab_size, block_size, generator)
      +--> CountBigram --> nll + samples            |
      |                                             v
      +--> build_dataset(block_size) --------> train
                                               minibatch SGD,
                                               lr / 10 after 75%
                                                  |        |
                                                  v        v
                                            evaluate    sample
                                         train/dev/test  until "."
 
  Tests only:  NeuralBigram (one-hot @ W)   backprop.py (manual backward)

layers.py provides Linear, BatchNorm1d (2D and 3D input, running stats), Tanh, Embedding, FlattenConsecutive and Sequential. The WaveNet stack is Embedding, then three blocks of FlattenConsecutive(2), Linear, BatchNorm and Tanh that shrink the context 8, 4, 2, 1, then a final Linear. backprop.py is a separate hand-derived backward pass for a 2-layer BatchNorm MLP, checked against autograd in tests.

Key decisions

Challenges

Results

Links