CoolFace
Modelpublic

vitin12/gpt-pt-270m-base-1b

sourceHugging Facemitupdated 10d agoView on Hugging Face
1likes230downloads
Model Card

<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

CampoValor
Nomegpt-pt-270m-base-1b — checkpoint do passo 70.000
Parâmetros270,6M
ArquiteturaDecoder-only causal LM — LeanGPT (Llama-style): RMSNorm + RoPE + GQA + SwiGLU + tied embeddings
Dimensõesvocab 49.152 · d 1024 · 14 camadas · 16 heads (8 KV, GQA) · inner 4096 · seq 2048
TokenizerBPE próprio 49.152 tokens, treinado no próprio corpus (`<endoftext> id **0** = BOS/SEP, decode([0]) == ''`)
Corpusvitin12/gptpt-corpus-v26,61B tokens, 3,23M linhas de 2048, 32 shards (13 fontes, ver §2)
Tokens vistos1.146.880.000 (70k steps × 8 bs × 2048 seq) — ~17% do corpus
Treino2× T4 no Kaggle, torch.compile, ce_head_chunked (sem materializar logits 2048×49k), fp16 + GradScaler, lr 5e-4 → 5e-5 cosine (warmup 2000) + LR adaptativo
Licença pesosMIT — use, adapte, redistribua
Formatomodel.safetensors + pytorch_model.bin + tokenizer.json + config.json
Assinaturaicdron — watermark _icdron_watermark nos pesos + signature: icdron no config.json + este README

EN

FieldValue
Namegpt-pt-270m-base-1b — checkpoint at step 70,000
Parameters270.6M
ArchitectureDecoder-only causal LM — LeanGPT (Llama-style): RMSNorm + RoPE + GQA + SwiGLU + tied embeddings
Dimsvocab 49,152 · d 1024 · 14 layers · 16 heads (8 KV, GQA) · inner 4096 · seq 2048
TokenizerCustom BPE 49,152 tokens, trained on the corpus itself (`<endoftext> id **0** = BOS/SEP, decode([0]) == ''`)
Corpusvitin12/gptpt-corpus-v26.61B tokens, 3.23M rows of 2048, 32 shards (13 sources, see §2)
Tokens seen1,146,880,000 (70k steps × 8 bs × 2048 seq) — ~17% of corpus
Training2× T4 on Kaggle, torch.compile, ce_head_chunked (no full 2048×49k logits), fp16 + GradScaler, lr 5e-4 → 5e-5 cosine (warmup 2000) + adaptive LR
Weights licenseMIT — use, adapt, redistribute
Formatmodel.safetensors + pytorch_model.bin + tokenizer.json + config.json
Signatureicdron_icdron_watermark tensor in weights + signature: icdron in config.json + this README

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`.

Fonte / SourceHF datasetKindmax_docsPeso sampler
gigaverbo_v2Polygl0t/gigaverbo-v2pt7M0.7×
gigaverbo_synthPolygl0t/gigaverbo-v2-synthpt5M2.0×
openwebmathopen-web-math/open-web-mathen_math1.2M2.0×
wikipedia_ptwikimedia/wikipedia (20231101.pt)pt1.2M1.2×
fineweb2_porHuggingFaceFW/fineweb-2 (por_Latn)pt4M0.7×
faquadnicholasKluge/faquad-nli-parquetqa60k2.0×
starcoder_pybigcode/starcoderdata (python)code2M2.0×
enemmaritaca-ai/enemqa20k2.0×
gigaverbo_sftPolygl0t/gigaverbo-v2-sft (multi)chat1.5M2.0×
fable5AnkitAI/fable-5-traces-sft-chatmlchat_en1M0.7×
oasst1_ptOpenAssistant/oasst1 (pt-BR)qa400k2.0×
gutenberg_ptmanu/project_gutenberg (pt)book1.5k1.2×
c4_ptallenai/c4 (pt)pt1.5M0.7×
Total6,61B tokens / 3,23M rows / 32 shards

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`.

python
# 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] onde SEP = <|endoftext|> id 0. Sempre faça ids = [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] where SEP = <|endoftext|> id 0. Always do ids = [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)
SuitePT PPL (loss)EN PPL (loss)Nota / Note
Básico / Basic (25 frases/sents)82.0 (4.406)174.2 (5.160)PT >> EN ✓
Continuação / Continuation (14)16.9 (2.825)57.9 (4.059)PT curto já bom / PT short already good
Factual cont. (6)100.2 (4.607)49.0 (3.892)ainda quebrado / still broken
Python cont. (4)11.4 (2.433)excelente / excellent
Math cont. (6)577.5 (6.359)catastrófico / catastrophic

Cloze — PT (12 frases, completar última palavra / complete last word):

Prefixo / PrefixGoldTop-1Hit
O gato bebeu ___águaágua✅ OK
A menina brinca no ___parquejardim~ top-5
O cachorro corre atrás da ___bolaporta
O sol brilha no céu ___azulnoturno~
Ela comprou flores para a ___mãefesta
O menino lê um livro na ___escolabiblioteca
Nós comemos pão com ___manteigapão
O professor ensina ___matemáticaa
O pássaro canta na ___árvoresua
O carro está na ___garagemgaragem✅ OK
O peixe nada no ___lagomar
A casa é grande e ___bonitao
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

Métrica / MetricValor / ValueInterpretação / Interpretation
PT básico / BasicPPL 82.0Bem melhor que 27k do step 200 do projeto antigo; ainda longe de 30-40 (coerente) / Much better than 27k at step 200 of the old project; still far from 30-40 (coherent)
Cont. PT / PT cont.PPL 16.9Modela bem continuação curta em PT / Models short PT continuation well
Python cont.PPL 11.4Excelente — oversample de código funciona / STARCoder 2× oversampling works
Cloze PT17% / 33%Acerta água, garagem; jardim≈parque em top-5 / Hits água, garagem; jardim≈parque in top-5
Viés PT >> EN / PT biasPT 82 vs EN 174 · cont 16.9 vs 57.9Não virou modelo inglês / Did not become an English model
Identidade / IdentityEu sou / Quem é você? / Who are you? não vaza / no leakGera genérico, sem "sou Claude/GPT" / Generic output, no "I'm Claude/GPT"

4.3 O que ainda NÃO funciona (esperado com 1B) / What does NOT work yet (expected at 1B)

Métrica / MetricPPLEstado / Status
Factual PT (capital, água ferve, Au, 1822, Júpiter, Dom Casmurro)100.2Quebrado / Broken
Factual EN (Paris, 100°, Au, Júpiter, Hamlet, luz)49.0Melhor por acaso do corpus EN / Better by accident (EN-heavy corpus)
Math (17×23, trem 60·3, derivada x²)577.5Catastrófico / Catastrophic
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 .bin uint16 + manifest.json + tokenizer.json)
  • Treino / Training: tools/train_gptpt_v2.pydims 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 in vitin12/gptpt-corpus-v2-ckpt) → convertido aqui em / converted here to model.safetensors + pytorch_model.bin
bash
# 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-2b

7. Citação / Citation

bibtex
@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>