Transformers
Safetensors
English
charlm
tiny
tiny-lm
small-language-model
sub-1m
char-level
from-scratch
nanoGPT
TinyStories
Instructions to use Compactbot/char-gpt-1.2m with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use Compactbot/char-gpt-1.2m with Transformers:
# Load model directly from transformers import CharGPT model = CharGPT.from_pretrained("Compactbot/char-gpt-1.2m", device_map="auto") - Notebooks
- Google Colab
- Kaggle
| import torch | |
| import torch.nn as nn | |
| import torch.nn.functional as F | |
| class CausalSelfAttention(nn.Module): | |
| def __init__(self, n_embd, n_head): | |
| super().__init__() | |
| assert n_embd % n_head == 0 | |
| self.n_head = n_head | |
| self.head_dim = n_embd // n_head | |
| self.c_attn = nn.Linear(n_embd, 3 * n_embd, bias=False) | |
| self.c_proj = nn.Linear(n_embd, n_embd, bias=False) | |
| def forward(self, x): | |
| B, T, C = x.size() | |
| q, k, v = self.c_attn(x).split(self.head_dim * self.n_head, dim=2) | |
| q = q.view(B, T, self.n_head, self.head_dim).transpose(1, 2) | |
| k = k.view(B, T, self.n_head, self.head_dim).transpose(1, 2) | |
| v = v.view(B, T, self.n_head, self.head_dim).transpose(1, 2) | |
| att = F.scaled_dot_product_attention(q, k, v, is_causal=True) | |
| att = att.transpose(1, 2).contiguous().view(B, T, C) | |
| return self.c_proj(att) | |
| class MLP(nn.Module): | |
| def __init__(self, n_embd, n_inner): | |
| super().__init__() | |
| self.c_fc = nn.Linear(n_embd, n_inner, bias=False) | |
| self.c_proj = nn.Linear(n_inner, n_embd, bias=False) | |
| def forward(self, x): | |
| return self.c_proj(F.gelu(self.c_fc(x))) | |
| class Block(nn.Module): | |
| def __init__(self, n_embd, n_head): | |
| super().__init__() | |
| self.ln_1 = nn.LayerNorm(n_embd) | |
| self.attn = CausalSelfAttention(n_embd, n_head) | |
| self.ln_2 = nn.LayerNorm(n_embd) | |
| self.mlp = MLP(n_embd, 4 * n_embd) | |
| def forward(self, x): | |
| x = x + self.attn(self.ln_1(x)) | |
| x = x + self.mlp(self.ln_2(x)) | |
| return x | |
| class CharGPT(nn.Module): | |
| """Character-level causal transformer (nanoGPT-style). No bias in | |
| attention / FFN / lm_head; LayerNorm carries the affine bias.""" | |
| def __init__(self, vocab_size, block_size, n_layer, n_head, n_embd): | |
| super().__init__() | |
| self.block_size = block_size | |
| self.transformer = nn.ModuleDict({ | |
| "wte": nn.Embedding(vocab_size, n_embd), | |
| "wpe": nn.Embedding(block_size, n_embd), | |
| "drop": nn.Dropout(0.0), | |
| "h": nn.ModuleList([Block(n_embd, n_head) for _ in range(n_layer)]), | |
| "ln_f": nn.LayerNorm(n_embd), | |
| }) | |
| self.lm_head = nn.Linear(n_embd, vocab_size, bias=False) | |
| def forward(self, idx, targets=None): | |
| B, T = idx.size() | |
| assert T <= self.block_size, f"block size {self.block_size} < {T}" | |
| pos = torch.arange(0, T, device=idx.device) | |
| x = self.transformer["drop"]( | |
| self.transformer["wte"](idx) + self.transformer["wpe"](pos)) | |
| for block in self.transformer["h"]: | |
| x = block(x) | |
| x = self.transformer["ln_f"](x) | |
| logits = self.lm_head(x) | |
| loss = None | |
| if targets is not None: | |
| loss = F.cross_entropy(logits.view(-1, logits.size(-1)), | |
| targets.view(-1)) | |
| return logits, loss | |
| def generate(self, idx, max_new_tokens, temperature=0.8, top_k=40): | |
| for _ in range(max_new_tokens): | |
| idx_cond = idx[:, -self.block_size:] | |
| logits, _ = self(idx_cond) | |
| logits = logits[:, -1, :] / temperature | |
| if top_k: | |
| v, _ = torch.topk(logits, min(top_k, logits.size(-1))) | |
| logits[logits < v[:, [-1]]] = float("-inf") | |
| probs = F.softmax(logits, dim=-1) | |
| idx = torch.cat((idx, torch.multinomial(probs, num_samples=1)), dim=1) | |
| return idx | |
| def from_config(config): | |
| return CharGPT( | |
| vocab_size=config["vocab_size"], | |
| block_size=config["block_size"], | |
| n_layer=config["n_layer"], | |
| n_head=config["n_head"], | |
| n_embd=config["n_embd"], | |
| ) | |
| if __name__ == "__main__": | |
| import json | |
| cfg = json.load(open("config.json")) | |
| m = from_config(cfg) | |
| print("params:", sum(p.numel() for p in m.parameters())) | |
| # tiny smoke test | |
| x = torch.randint(0, cfg["vocab_size"], (1, 32)) | |
| logits, loss = m(x, x) | |
| print("smoke loss:", loss.item()) |