vitin12/gpt-pt-270m-base-1b
<div align="center">
🇧🇷 GPT-PT 270M — Base · 1B tokens
Um LLM brasileiro treinado do zero, em português. 270,6M parâmetros. Este é o checkpoint de 1 bilhão de tokens — modelo base, ainda subtreinado.
A Brazilian LLM trained from scratch, in Portuguese. 270.6M parameters. This is the 1-billion-token checkpoint — base model, still undertrained.
Assinado por / Signed by icdron — projeto GPT-PT · setembro / September 2026
</div>
⚠️ PT: Modelo base, não-instruído e subtreinado. Este checkpoint tem apenas ~17% do treino planejado (1,14B de 6,6B tokens). Ele não segue instruções, não é chatbot, não tem RLHF/DPO e alucina fatos. Use como base para continuar o pré-treino, estudar a curva de aprendizado ou fazer fine-tuning próprio. Não use em produção sem SFT. ⚠️ EN: Base model, not instruction-tuned and undertrained. This checkpoint covers only ~17% of the planned training (1.14B of 6.6B tokens). It does not follow instructions, is not a chatbot, has no RLHF/DPO and hallucinates facts. Use it to continue pre-training, study the learning curve or do your own fine-tuning. Do not use in production without SFT.
Próximos marcos públicos / Next public milestones: 2B · 3B · 4B · 5B · 6B tokens — cada um / each with a comparable eval.
1. O que é este modelo / What is this model
PT
EN
2. Corpus & arquitetura / Corpus & architecture
Corpus — vitin12/gptpt-corpus-v2
Pré-tokenizado uint16 .bin, linhas de 2048 no formato [SEP, tokens, SEP] onde SEP = <|endoftext|> id 0. Sampler ponderado por fonte via manifest.json.
Pre-tokenized uint16 `.bin`, rows of 2048 as `[SEP, tokens, SEP]` where `SEP = <|endoftext|>` id 0. Source-weighted sampler via `manifest.json`.
Filtros / Filters: text_ok (alpha, tamanho, stopwords PT/EN, repetição), dedup SHA, n-gram PPL filter, edu_ok.
Arquitetura / Architecture
LeanGPT(
emb: Embedding(49152 → 1024)
blocks: 14× LeanBlock(
ln1: RMSNorm(1024, eps 1e-6)
attn: Attn(d 1024, h 16, kv 8, dh 64) — qkv + SDPA causal + GQA repeat
ln2: RMSNorm(1024)
mlp: SwiGLU(1024 → 4096 → 1024) — w1 gate + w3 up, SiLU, w2 down
)
norm: RMSNorm(1024)
rope: RoPE(dim 64, max 2048, theta 10000)
head: tied — logits = norm(h) @ emb.weight.T
)
Params: 270,6M (emb 50,3M + 14× ~15,7M + norm/rope)Treino / Training: bs 8 · seq 2048 · grad_accum 1 → 16.384 tok/step (~11,7k tok/s em 2×T4, MFU ~14,6%), warmup 2000, lr 5e-4 → 5e-5 cosine até 265k steps, wd 0.1, grad_clip 1.0, spike_mult 2.0, lr adaptativo (patience 3000, factor 0.7, floor 5e-5), val_every 250 (16 rows), save 900s + marcos 1000 steps, torch.compile on, GradScaler fp16, ce_head_chunked(chunk=2) para não estourar VRAM.
3. Como usar / How to use
O modelo não é `transformers` LlamaForCausalLM — é o LeanGPT puro do trainer. Roda com torch + tokenizers + safetensors.
This model is not a `transformers` LlamaForCausalLM — it's the trainer's pure LeanGPT. Runs with `torch` + `tokenizers` + `safetensors`.
# pip install torch tokenizers safetensors
import torch, torch.nn as nn, torch.nn.functional as F
from tokenizers import Tokenizer
from safetensors.torch import load_file
class RMSNorm(nn.Module):
def __init__(self, dim, eps=1e-6):
super().__init__(); self.w = nn.Parameter(torch.ones(dim)); self.eps = eps
def forward(self, x):
return x * torch.rsqrt(x.pow(2).mean(-1, keepdim=True) + self.eps) * self.w
class RoPE(nn.Module):
def __init__(self, dim, max_t, theta=10000.0):
super().__init__()
half = dim // 2
inv = 1.0 / (theta ** (torch.arange(0, dim, 2).float() / dim))
t = torch.arange(max_t).float()
cos = torch.outer(t, inv).cos(); sin = torch.outer(t, inv).sin()
self.register_buffer("cos", torch.cat([cos, cos], dim=-1))
self.register_buffer("sin", torch.cat([sin, sin], dim=-1))
self.half = half
def rot(self, x): return torch.cat((-x[..., self.half:], x[..., :self.half]), dim=-1)
def forward(self, q, k):
c = self.cos[:q.shape[-2]]; s = self.sin[:q.shape[-2]]
return q*c + self.rot(q)*s, k*c + self.rot(k)*s
class Attn(nn.Module):
def __init__(self, d, h, kv):
super().__init__(); self.h=h; self.kv=kv; self.dh=d//h
self.qkv=nn.Linear(d, d+2*self.dh*kv); self.wo=nn.Linear(d,d)
def forward(self, x, rope):
b,s,d=x.shape; qkv=self.qkv(x)
q,k,v=torch.split(qkv,(d,self.dh*self.kv,self.dh*self.kv),dim=-1)
q=q.view(b,s,self.h,self.dh).transpose(1,2)
k=k.view(b,s,self.kv,self.dh).transpose(1,2)
v=v.view(b,s,self.kv,self.dh).transpose(1,2)
q,k=rope(q,k)
if self.h!=self.kv:
r=self.h//self.kv; k=k.repeat_interleave(r,dim=1); v=v.repeat_interleave(r,dim=1)
y=F.scaled_dot_product_attention(q,k,v,is_causal=True)
return self.wo(y.transpose(1,2).reshape(b,s,d))
class MLP(nn.Module):
def __init__(self,d,inner):
super().__init__(); self.w1=nn.Linear(d,inner,bias=False); self.w2=nn.Linear(inner,d,bias=False); self.w3=nn.Linear(d,inner,bias=False)
def forward(self,x): return self.w2(F.silu(self.w1(x))*self.w3(x))
class LeanBlock(nn.Module):
def __init__(self,d,h,kv,inner):
super().__init__(); self.ln1=RMSNorm(d); self.attn=Attn(d,h,kv); self.ln2=RMSNorm(d); self.mlp=MLP(d,inner)
def forward(self,x,rope): x=x+self.attn(self.ln1(x),rope); x=x+self.mlp(self.ln2(x)); return x
class LeanGPT(nn.Module):
def __init__(self,vocab,d,n_layers,h,kv,inner,seq):
super().__init__(); self.emb=nn.Embedding(vocab,d)
self.blocks=nn.ModuleList(LeanBlock(d,h,kv,inner) for _ in range(n_layers))
self.norm=RMSNorm(d); self.rope=RoPE(d//h,seq)
def forward(self,x):
h=self.emb(x)
for blk in self.blocks: h=blk(h,self.rope)
return self.norm(h)
# — carregar / load —
tok = Tokenizer.from_file("tokenizer.json")
sep_id = tok.token_to_id("<|endoftext|>") # 0 — SEMPRE prepend no prompt! / ALWAYS prepend!
vocab, d, n_layers, h, kv, inner, seq = 49152, 1024, 14, 16, 8, 4096, 2048
model = LeanGPT(vocab, d, n_layers, h, kv, inner, seq)
state = load_file("model.safetensors") # ou / or torch.load("pytorch_model.bin")
model.load_state_dict(state, strict=False)
model.eval().cuda()
# — gerar / generate —
prompt = "A cidade de São Paulo é conhecida por"
ids = [sep_id] + tok.encode(prompt).ids
x = torch.tensor([ids], device="cuda")
with torch.no_grad():
for _ in range(80):
with torch.autocast("cuda", dtype=torch.float16):
logits = model(x[:, -seq:])[0] @ model.emb.weight.T
logits = logits[-1] / 0.8
v,_ = torch.topk(logits, 40)
logits[logits < v[-1]] = float("-inf")
nid = torch.multinomial(torch.softmax(logits, dim=-1), 1).item()
x = torch.cat([x, torch.tensor([[nid]], device="cuda")], dim=1)
print(tok.decode(x[0].tolist(), skip_special_tokens=True))PT — Detalhe crítico: toda sequência do corpus é[SEP, tokens, SEP]ondeSEP = <|endoftext|>id 0. Sempre façaids = [sep_id] + tok.encode(prompt).ids— sem isso a distribuição quebra e a saída degrada.decode([0]) == ''(token invisível). EN — Critical detail: every corpus row is[SEP, tokens, SEP]whereSEP = <|endoftext|>id 0. Always doids = [sep_id] + tok.encode(prompt).ids— skipping it breaks the distribution and degrades output.decode([0]) == ''(invisible token).
4. Avaliação — passo 70.000 (1,14B tokens) / Evaluation — step 70,000 (1.14B tokens)
Eval base privado (tools/eval_base.py) — modelo base, sem instrução / base model, no instruction tuning. PPL = perplexidade (menor = melhor / lower = better), cloze = última palavra (top-1/top-5).
4.1 Benchmark privado — números brutos / Private benchmark — raw numbers
hf: marco ckpt_70000.pt (passo 70000) e mais novo que last.pt (passo 56100); usando o marco
tokenizer: 49152 tokens | BOS(sep) id: 0
ckpt: passo 70000 | tokens 1,146,880,000 | dims 49152,1024,14,16,8,4096 | seq 2048
modelo em cuda (270.6M params)Cloze — PT (12 frases, completar última palavra / complete last word):
PT cloze: top-1 2/12 (17%) | top-5 4/12 (33%) · EN cloze: top-1 0/12 (0%) | top-5 1/12 (8%) — viés PT correto / correct PT bias.
EN cloze top-1 todas ❌ (ex.: The cat drank ___ → is vs water; The girl plays in the ___ → world vs park) — 1 hit em top-5 (The sun shines in the blue ___ → and vs sky).
4.2 O que já funciona / What already works
4.3 O que ainda NÃO funciona (esperado com 1B) / What does NOT work yet (expected at 1B)
Normal para 270M com 1B tokens. Fatos e raciocínio só estabilizam após 5-6B + SFT. / Normal for 270M at 1B tokens. Facts and reasoning only stabilize after 5-6B + SFT.
4.4 Amostras reais de geração (temp 0.8, top-k 40) / Real generation samples
Factual — PT / Factual — PT:
"A capital do Brasil é" → "a cidade de São Paulo. Com uma população de 758.700 habitantes, a capital é responsável por abrigar a maior"
"A água ferve a" → "nossa espinha!\nA temperatura da água e a umidade estão aumentando a quantidade de água na nossa espinha.\nEntão,"
"O símbolo químico do ouro é" → "a sua origem.\nA sua origem está ligada à ideia do ouro e ao ouro que é um metal nobre, uma"
"Dom Pedro I proclamou a independência em" → "1521, mas a realidade é que não foi. São os portugueses, portugueses e espanhóis que não são os que dizem"
"O maior planeta do sistema solar é" → "o Sol, que é o segundo mais próximo do sol. Isso significa que ele fica mais próximo do Sol e mais próximo"
"Quem escreveu Dom Casmurro?" → "A nossa vida, o nosso dia a dia, o nosso estado de espírito, o nosso estado de espírito, a"Factual — EN / Factual — EN:
"The capital of France is" → "the most popular and most important indústria in Europe and the most important factor of the production of natural gas production is the production"
"Water boils at" → "a constant rate of one percent. What is the value of the boiling rate, when it is 0.1%"
"The chemical symbol for gold is" → "Cd. Here's a quick test for it:\n\nThe following chemical symbol for gold is Cd."
"The largest planet is" → "going to be observed on the Sun, so I’ll be sure that the planet will see it.\n\n#"
"Who wrote Hamlet?" → "Let us take a look at the definition of an ideal on a compact disk.\n\nLet $K$"
"The speed of light is about" → "4.0 m/s, so we can write it as 4.3 m/s^2 or 4."Livre / Free:
"A cidade de São Paulo é conhecida por" → "suas belíssimas praias, arquitetura e vida noturna. Entretanto, o que se pode dizer sobre São Paulo é que ela é um"
"A tecnologia mudou a forma como" → "nos relacionamos e interagimos com o mundo à nossa volta. Ela trouxe novas ferramentas e instrumentos para nos comunicarmos,"
"Os cientistas descobriram que" → "a densidade da água no fundo do oceano aumentou cerca de 2 bilhões de vezes no ano de 2015, aproximadamente em três meses"Python:
"def fatorial(n):\n if n <= 1:" → "return 1\n else:\n return n * fatorial(n - 1)\n\ndef fatorial_d"
"def is_prime(n):\n for i in range(2, int(n**0.5)+1):" → "if int(i)%i == 0:\n return False\n if is_prime(n):\n if"
"lista = [1,2,3]\nfor x in lista:" → "for y in lista:\nf(x, y)\n}\n\nprint\n\nO código abaixo é"
"import math\nresult = math.sqrt(25)" → "result *= math.sqrt(25)\nresult /= math.sqrt(25)\n\nreturn result"Math:
"Quanto é 17 * 23?" → "Esta é uma das questões mais antigas que encontramos no GMAT!\n\nO número 17 pode ser escrito como 17"
"Se um trem viaja a 60 km/h por 3 horas, ele percorre " → "60 km e 1.6 km. Se, por outro lado, um trem percorre 60 km por 5 horas,"
"A derivada de x^2 é " → "a raiz quadrada de -6 (4,2)\n\na) Encontre o valor de x ao redor do"
"What is 17 * 23?" → "It is 17 * 23.\n\nIt is 17 * 23.\n\nIt is 17 * 7."
"If a train travels 60 km/h for 3 hours, it covers " → "70 km, and it can travels 300 km. The time for the train and the distance is 400 km/h"
"The derivative of x^2 is " → "$\\frac{x^3}{3}$\n\nThe derivative of the square root of x^2 is $\\"Identidade / Identity (checar vazamento / leak check):
"Eu sou" → "uma pessoa que não tem vergonha de sorrir, de brincar, de fazer tudo à mão..."
"Meu nome é" → "Marcos, e sou o que sou desde que me mudei para os Estados Unidos em 1975..."
"Quem é você?" → "A gente é a nossa!\nNão há nada mais perigoso do que ficar perto de alguém..."
"I am" → "having a problem with the following code and I am trying to figure it out..."
"My name is" → "Lucky ee\nMy email is Lucky ee@gmail.com\nIt is my blog.\nMy"
"Who are you?" → "# The number of objects in a box is equal to the number of objects in the box's number of objects"Leitura honesta / Honest take: PT fluente curto ok, factual fraco, math fraco. Curva ainda vai cair muito até 6B. / Short fluent PT ok, factual weak, math weak. Curve will drop a lot until 6B.
5. Limitações e uso responsável / Limitations & responsible use
PT:
- Não é chatbot. Não segue instruções, não faz Q&A confiável, não tem filtro de segurança.
- Alucina. Datas, números, definições e código podem estar errados.
- Português apenas. Treinado e avaliado em PT; EN é incidental.
- Sem garantias. Peso MIT, mas valide toda saída antes de uso real.
EN:
- Not a chatbot. Does not follow instructions, no reliable Q&A, no safety filter.
- Hallucinates. Dates, numbers, definitions and code may be wrong.
- Portuguese only. Trained and evaluated on PT; EN is incidental.
- No guarantees. MIT weights, but validate every output before real use.
6. Reprodução e código / Reproduction & code
- Corpus:
vitin12/gptpt-corpus-v2(shards.binuint16 +manifest.json+tokenizer.json) - Treino / Training:
tools/train_gptpt_v2.py—dims 49152,1024,14,16,8,4096,bs 8,seq 2048,warmup 2000 - Eval:
tools/eval_base.py· Sampling:tools/sample_ckpt.py· Publicação / Publishing:tools/publish_1b_public.py - Este checkpoint / This checkpoint:
ckpt_70000.pt(privado / private invitin12/gptpt-corpus-v2-ckpt) → convertido aqui em / converted here tomodel.safetensors+pytorch_model.bin
# continuar o pré-treino a partir deste checkpoint / continue pre-training from this checkpoint
python tools/train_gptpt_v2.py --ckpt /kaggle/working/ckt_v2 --data /tmp/corpus_v2 --dims 49152,1024,14,16,8,4096
# publicar próximo marco / publish next milestone
python tools/publish_1b_public.py --ckpt_step 140000 --public_repo vitin12/gpt-pt-270m-base-2b7. Citação / Citation
@misc{gptpt2026_1b,
title = {GPT-PT 270M Base — 1B tokens},
author = {icdron},
year = {2026},
url = {https://huggingface.co/vitin12/gpt-pt-270m-base-1b},
note = {Checkpoint base do passo 70.000 (1,14B tokens). Modelo subtreinado, não-instruído. / Base checkpoint at step 70,000 (1.14B tokens). Undertrained, not instruction-tuned.}
}<div align="center">
Pesos sob MIT. Corpus e eval sob licenças próprias de cada fonte (ver `vitin12/gptpt-corpus-v2`). Weights under MIT. Corpus and eval under each source's own license (see `vitin12/gptpt-corpus-v2`).
Assinado por / Signed by icdron · GPT-PT · 2026
Marca d'água / Watermark: este README e os pesos deste checkpoint carregam a assinatura icdron como marca de origem do projeto. / This README and the weights of this checkpoint carry the icdron signature as the project's origin mark. Redistribuições devem preservar esta atribuição. / Redistributions must preserve this attribution.
</div>
