nanodiff-50m-base / README.md
Sebasdi's picture
Upload README.md with huggingface_hub
0c59b27 verified
|
Raw
History Blame Contribute Delete
4.71 kB
---
library_name: pytorch
tags:
- diffusion-language-model
- masked-diffusion
- llada
- text-generation
- nanodiff
datasets:
- HuggingFaceFW/fineweb-edu
language:
- en
pipeline_tag: text-generation
---
# nanoDiff 50M — base
A **masked diffusion language model** trained with the LLaDA recipe, from the
[nanoDiff](https://github.com/BY571/nanoDiff) project — a minimal, hackable
"nanoGPT for diffusion LLMs" built for learning how diffusion LMs train.
This is the **base model** — pretrained on raw web text only. It has **no
instruction tuning**: it continues documents, it does not answer questions.
See *Intended use* below.
## TL;DR
| | |
|---|---|
| Architecture | Masked diffusion LM (LLaDA recipe), bidirectional Transformer |
| Parameters | ~88M total · ~50M non-embedding (tied input/output embeddings) |
| Training data | FineWeb-Edu, ~2.1B tokens (~1 epoch) |
| Validation | NLL-bound **3.92** nats/token · perplexity **~50.6** |
| Hardware | NVIDIA DGX-Spark (GB10), ~12 h wall-clock |
## Provenance
- **Code:** https://github.com/BY571/nanoDiff
- **Trained at commit:** `de6c9a2`
- **Config:** `pretrain/configs/50m.py`
- **Reproduce:** `python scripts/prepare_data.py --out-dir data/fineweb_edu --num-tokens 2_000_000_000`
then `python pretrain/train.py --config pretrain/configs/50m.py`
## Architecture
A decoder-style Transformer with **bidirectional** self-attention (the one
architectural change from an autoregressive GPT — a diffusion LM denoises all
positions at once, so attention is not causally masked).
| Hyperparameter | Value |
|---|---|
| Layers | 7 |
| Attention heads | 12 |
| Embedding dim (`n_embd`) | 768 |
| Context length (`block_size`) | 1024 |
| Positional encoding | RoPE |
| Vocabulary | 50304 (GPT-2 BPE 50257 + `[MASK]`@50257 + padding to a multiple of 64) |
| Embeddings | tied (input = output) |
| Total parameters | ~88M (50M non-embedding) |
## Training objective
Masked (absorbing-state) diffusion, following
[LLaDA](https://arxiv.org/abs/2502.09992):
- **Forward process:** each token is independently replaced by `[MASK]` with
probability `t ~ U(0, 1)`.
- **Model:** predicts the clean tokens at all masked positions in one pass.
Time-free parameterization — `t` is *not* fed to the model.
- **Loss:** cross-entropy over masked positions, weighted by `1/t` and
normalized by sequence length (an upper bound on the negative log-likelihood).
## Training setup
| | |
|---|---|
| Dataset | FineWeb-Edu, tokenized with GPT-2 BPE, uint16 memmap |
| Tokens seen | ~2.1B (16,000 iters × batch 128 × 1024 ctx) |
| Optimizer | AdamW (β1 0.9, β2 0.95, weight decay 0.1, grad clip 1.0) |
| LR schedule | WSD — warmup 500, stable, linear decay over the final 3000 iters |
| Peak / min LR | 1.2e-3 → 1e-5 |
| Batch size | 128 sequences (no gradient accumulation) |
| Precision | bf16 autocast |
| Compilation | `torch.compile` (default mode) |
| Hardware | NVIDIA DGX-Spark (GB10), single device |
| Wall-clock | ~12 hours |
## Results
Offline evaluation (`eval.py`, 500 batches) on the FineWeb-Edu validation split:
- **NLL-bound: 3.92 nats/token**
- **Perplexity: ~50.6**
## Intended use
This is a **research / learning artifact**, not a product.
- ✅ A base model to **supervised-fine-tune** (the LLaDA SFT recipe masks only
the response tokens).
- ✅ Studying masked-diffusion training and sampling dynamics.
- ❌ Not an instruction-following model. Prompt it with **document-shaped**
text ("The capital of France is", "A recipe for bread:"), not questions.
## Sampling — important
Small diffusion LMs collapse into repetition loops ("the capital of France is
the capital of France is…") under the default low-confidence remasking sampler.
This is a **logit-level bias**, not model weakness. Use a **frequency
repetition penalty** when sampling:
```bash
python sample.py --ckpt nanodiff-50m-base.pt \
--prompt "The capital of France is" --rep-penalty 3.0
```
`rep_penalty` subtracts `penalty × token_count` from each token's logits.
`chat.py` and `sample.py` default it to `3.0`. With it, the same weights
produce varied, fluent English.
## Limitations
- **Confabulates freely.** At 50M non-embedding params on 2.1B tokens, factual
recall is unreliable ("founded by Louis XIV in 1515"). It learned English
syntax, not a world model.
- Coherence degrades on harder prompts.
- English only; FineWeb-Edu domain.
- Base model — no alignment, no safety tuning.
## Citation
Built on the LLaDA recipe:
```bibtex
@article{nie2025llada,
title = {Large Language Diffusion Models},
author = {Nie, Shen and others},
journal = {arXiv preprint arXiv:2502.09992},
year = {2025}
}
```