Model reference · open weights
TLM is an open-weight language model from McGill-NLP. TLM-40M (FP32) weighs 83 MB; the smallest configuration that runs it is RTX 3060 12 GB.
Summary of the McGill-NLP/TLM-230M model card, 2026-10-01. The estimate below is for another build of the family.
What it is
| Released by | McGill-NLP |
|---|---|
| Released | 2026-08-28 |
| Parameters | 229M |
| VRAM | 83 MB for the weights |
What it runs on
| Card | Requests at once | Context max | Memory |
|---|---|---|---|
| 2K each | |||
| RTX 3060 12 GB | 292 | all 2K | 11.6 GB |
| RTX 4060 Ti 16 GB | 392 | all 2K | 15.4 GB |
| RTX 3090 24 GB | 604 | all 2K | 23.4 GB |
| RTX 4090 24 GB | 603 | all 2K | 23.4 GB |
| RTX 5090 32 GB | 806 | all 2K | 31.0 GB |
| L40S 48 GB | 1000+ | all 2K | 44.0 GB |
| A100 80 GB | 1000+ | all 2K | 78.2 GB |
| H100 80 GB | 1000+ | all 2K | 78.1 GB |
| RTX PRO 6000 Blackwell 96 GB | 1000+ | all 2K | 93.8 GB |
| DGX Spark (GB10) 128 GB unified | 1000+ | all 2K | 107 GB |
| H200 141 GB | 1000+ | all 2K | 138 GB |
| B200 180 GB | 1000+ | all 2K | 176 GB |
| Requests at once | 2K tokens each |
|---|---|
| 1 | 626 MB |
| 5 | 777 MB |
| 8 | 890 MB |
| 16 | 1.2 GB |
| 32 | 1.8 GB |
| 64 | 3.0 GB |
One card, with vLLM's small-card settings.
Builds
From the model card
A Tiered Language Model (TLM) pretrained with Tiered Alignment: one set of weights that exposes two behavioral tiers, toggled by a secret permutation key.
key_5pct.json, which permutes 5% of the
attention heads and MLP columns. The permutation is self-inverse, so applying it toggles
between the two tiers over the same underlying parameters.TLM-230M is the 240m rung of a scaling ladder. Its non-keyed counterpart
(identical architecture and token budget, trained without a key) is the baseline used for
all public-tier comparisons.
| File | What it is |
|---|---|
model.safetensors | Weights in the C1 (public) configuration |
key_5pct.json | The secret permutation key — swaps over attn_heads and mlp_cols |
config.json, tokenizer.json | GPT-Neo config; GPT-2 BPE tokenizer (vocab 50257) |
Optimizer state is not included; these checkpoints are for inference and evaluation.
The weights require GPTNeoForCausalLMTiered, not stock GPTNeoForCausalLM:
this architecture defines lm_head with bias=True, and loading through
AutoModelForCausalLM silently drops that trained bias.
from tiered.model import GPTNeoForCausalLMTiered
from tiered.permutation import load_key, apply_permutation, unapply_permutation
model = GPTNeoForCausalLMTiered.from_pretrained("McGill-NLP/TLM-230M")
key = load_key("key_5pct.json") # downloaded from this repo
# C1 (public) — the state the weights ship in
logits_public = model(input_ids).logits
apply_permutation(model, key) # -> C2 (keyed)
logits_keyed = model(input_ids).logits
unapply_permutation(model, key) # back to C1, bit-exactly
| Total parameters | 229,137,745 |
| Layers / hidden / heads | 16 / 768 / 12 |
| MLP ratio / context | 8 / 2048 |
| Training tokens | 22.91B (100x total params) |
| Steps / global batch | 49,948 / 224 seqs |
| Peak LR / warmup | 3.9e-4 / 1000 steps |
| Data | FineWeb (retain split) |
| Key coverage | 5% |
Architecture follows the DataDecide ladder (arXiv:2504.11393): interpolated between the 150M and 300M rungs (log-linear in total params, fraction 0.3033).
Repository names here are total parameter counts, rounded. The underlying DataDecide rung labels are not parameter counts, so the two orderings differ — the "90M" rung has 117M total parameters, more than the "100M" rung's 99M. Ordered by actual size, the ladder runs:
TLM-20M, TLM-40M, TLM-70M, TLM-100M, TLM-120M, TLM-180M, TLM-230M, TLM-650M
TLM-180M predates this ladder and uses 12 layers rather than 16, so it is not architecturally
part of it; treat it separately when fitting scaling curves.
Code: https://github.com/charbel08/permutation-alignment
Quoted from the model card on Hugging Face. The full card is behind the Hugging Face link above.