Loading…
Loading…
A 53-million parameter GPT model trained from scratch on TinyStories dataset. This model implements a Pre-LayerNorm (Pre-LN) transformer architecture and serves as a demonstration of efficient training on Apple Silicon using the MLX framework.
Model Format: PyTorch (cross-platform compatible)
Training Framework: Apple MLX (exported to PyTorch for universal compatibility)
Best for: Educational demonstrations, research, and fine-tuning on specific domains
This model uses Pre-LayerNorm architecture, different from standard GPT-2's Post-LN:
# Pre-LN (this model)
x = x + attn(ln(x))
x = x + ff(ln(x))
# vs Post-LN (standard GPT-2)
x = ln(x + attn(x))
x = ln(x + ff(x))
Pre-LN provides better training stability and is used in modern transformers (GPT-3, PaLM, LLaMA).
Measured on Apple M2 Pro (16GB unified memory):
| Metric | Value |
|---|---|
| Model Size | 53.0M parameters |
| Memory (fp32) | 202.1 MB |
| Memory (fp16) | 101.1 MB |
| Training Throughput | 27,355 tokens/sec |
| Batch Processing | 13.36 batches/sec (batch=4, seq=512) |
| Inference Speed | 169.9 tokens/sec |
| Generation Latency | ~0.59s per 100 tokens |
| Activation Memory | 843 MB (batch=4, seq=512) |
Note: All benchmarks measured at checkpoint 20000 (this release).
from transformers import AutoTokenizer, AutoModelForCausalLM
# Load model and tokenizer (requires trust_remote_code for custom architecture)
tokenizer = AutoTokenizer.from_pretrained("jacksuuuu/tinystories")
model = AutoModelForCausalLM.from_pretrained(
"jacksuuuu/tinystories",
trust_remote_code=True
)
# Generate text
prompt = "Once upon a time"
inputs = tokenizer(prompt, return_tensors="pt")
outputs = model.generate(
**inputs,
max_length=100,
temperature=0.8,
top_k=50,
do_sample=True,
pad_token_id=tokenizer.eos_token_id
)
text = tokenizer.decode(outputs[0], skip_special_tokens=True)
print(text)
Prompt: "Once upon a time"
Generated:
Once upon a time, the boy named Lily and his dog named Max went for a walk.
They ran and ran, but they kept each and got very tired. Suddenly the way,
Max saw something shiny on the ground. He pointed the shiny to his owner and
explained, "What does this?"
Max meowed and said, "I don't sign, Max. The sign is too small and it's
important to learn."
Note: This model generates coherent short stories and educational content. While grammatically imperfect due to its small size (53M params), it demonstrates good narrative flow and vocabulary learned from FineWebEdu dataset.
NanoGPTLMHeadModel(
(transformer): NanoGPTModel(
(token_embedding): Embedding(50257, 384)
(position_embedding): Embedding(512, 384)
(blocks): ModuleList(
(0-7): 8 x NanoGPTBlock(
(ln1): LayerNorm((384,), eps=1e-05)
(attn): NanoGPTAttention(
(qkv_proj): Linear(384, 1152)
(out_proj): Linear(384, 384)
)
(ln2): LayerNorm((384,), eps=1e-05)
(ff): FeedForward(
(fc1): Linear(384, 1536)
(fc2): Linear(1536, 384)
)
)
)
(ln_f): LayerNorm((384,), eps=1e-05)
)
(lm_head): Linear(384, 50257)
)
Note: token_embedding and lm_head weights are tied (shared), reducing effective parameters from 53M to 43M unique weights.
{
"vocab_size": 50257,
"d_model": 384,
"n_layers": 8,
"n_heads": 8,
"d_ff": 1536,
"context_length": 512,
"dropout": 0.1,
"batch_size": 12,
"learning_rate": 3e-4,
"weight_decay": 0.1,
"max_iters": 20000
}
Primary use cases:
Not recommended for:
This model was trained on FineWebEdu, which contains diverse web content. Users should:
If you use this model, please cite:
@software{nanogpt_mlx_2025,
author = {JackSu},
title = {NanoGPT MLX: 53M Parameter Pre-LN Transformer},
year = {2025},
url = {https://huggingface.co/jacksuuuu/tinystories}
}
MIT License - See repository for details.