SLM-100M Português (LLaMA-style)

Small Language Model de ~100M parâmetros pré-treinado em ~2B tokens de português do FineWeb2 (subset PT). Projeto da disciplina Aprendizado Profundo II (PUCRS — Escola Politécnica).

Diferente do modelo anterior em inglês, este foi projetado especificamente para português: tokenizer BPE byte-level treinado em corpus PT, arquitetura ampliada (12 camadas, n_embd=768) e regularização adicional (z-loss).

Resultados

Métrica Valor
Val loss 3.183
Val perplexity 24.12
Best val_loss (durante treino) 3.112 (ppl 22.48)
Train loss final 3.143
Tokens vistos ~1.97B
Tempo de treino ~10.5h em RTX 5060 Ti
Throughput médio ~58K tokens/s

Curvas completas no Weights & Biases.

Arquitetura

Decoder-only transformer (estilo LLaMA), com algumas mudanças em relação ao modelo anterior em inglês para escala maior e melhor estabilidade:

Componente Escolha
Camadas (n_layer) 12
Dimensão (n_embd) 768
Heads de Query 12
Heads de Key/Value 4 (GQA, ratio 3:1)
Dim do FFN (SwiGLU) 2048 (≈8/3 × n_embd)
Context length 1024
Vocabulário 32.000
Positional Encoding RoPE (θ=10000)
Normalização RMSNorm (pre-norm, ε=1e-5)
Ativação SwiGLU
Embeddings Compartilhadas com LM head (tied)
Z-loss coeficiente 1e-4 (estabilidade do softmax final)

Total de parâmetros: 100.092.672 (~100M)

Diferenças vs modelo inglês de 55M

Aspecto Modelo EN (55M) Modelo PT (100M)
Camadas 10 12
n_embd 512 768
n_head / n_kv_head 8 / 4 12 / 4
Vocab 50.304 (GPT-2 BPE) 32.000 (BPE byte-level treinado em PT)
Z-loss não usado coef 1e-4

Dataset

FineWeb2 — subset português (HuggingFaceFW/fineweb-2)

Corpus web em português filtrado por qualidade, parte do pipeline FineWeb da HuggingFace. Usado em streaming até atingir ~2B tokens, divididos em:

  • Train: 2.100.000.085 tokens (~4.2 GB em uint16)
  • Val: 2.067.198 tokens (~4 MB)

Tokenizer

BPE byte-level treinado do zero no corpus FineWeb2-pt, com vocabulário de 32.000 tokens. Diferente do tokenizer GPT-2 usado no modelo anterior (que foi treinado em inglês e tinha eficiência ~2-3x pior em português), este tokenizer é otimizado para a distribuição de caracteres e padrões morfológicos do português brasileiro.

Comparativo de eficiência (tokens necessários para frase exemplo):

Frase GPT-2 BPE (50k) PT BPE (32k)
"O direito tributário brasileiro é complexo." 14 tokens ~10 tokens

Configuração de Treino

Hiperparâmetro Valor
Otimizador AdamW (β₁=0.9, β₂=0.95)
Weight decay 0.1 (seletivo: apenas em params 2D+)
LR pico → mínimo 6e-4 → 6e-5
Schedule Warmup linear 750 steps + cosine decay
Gradient clipping 1.0
Batch size (por step) 8 sequências
Gradient accumulation 16
Batch efetivo 128 sequências = 131.072 tokens/step
Max steps 15.000
Mixed precision bfloat16 (autocast)
Compilação torch.compile ativado

Como Usar

Este checkpoint requer o código do modelo do repositório: https://github.com/cjfbr/slm-pretraining

O tokenizer está incluído neste repositório HF (tokenizer.json), formato tokenizers da HuggingFace.

import torch
from tokenizers import Tokenizer
from huggingface_hub import hf_hub_download

from slm.model import GPT
from slm.config import ModelConfig

REPO = "cjfb75/slm-100m-pt-llama-style"

# Baixar tokenizer e checkpoint
tokenizer_path = hf_hub_download(REPO, "tokenizer.json")
ckpt_path = hf_hub_download(REPO, "pretrain_final.pt")

# Tokenizer
tokenizer = Tokenizer.from_file(tokenizer_path)

# Modelo
cfg = ModelConfig(
    vocab_size=32000,
    n_layer=12,
    n_embd=768,
    n_head=12,
    n_kv_head=4,
    ffn_hidden_dim=2048,
    block_size=1024,
)
model = GPT(cfg)
ckpt = torch.load(ckpt_path, weights_only=False, map_location="cuda")
model.load_state_dict(ckpt["model"])
model.eval().cuda()

# Geração
prompt = "A capital do Brasil é"
ids = tokenizer.encode(prompt).ids
input_ids = torch.tensor([ids], dtype=torch.long, device="cuda")
with torch.no_grad():
    out = model.generate(input_ids, max_new_tokens=100, temperature=0.8, top_k=50)
print(tokenizer.decode(out[0].cpu().tolist()))

Limitações Conhecidas

  • Modelo pequeno (~100M): capacidade limitada de raciocínio complexo ou conhecimento factual amplo
  • Pré-treino apenas: não passou por SFT ou RLHF, então pode alucinar fatos e não segue instruções consistentemente
  • Distribuição do FineWeb2: viés para texto web em geral; subdomínios como código fonte ou texto jurídico/médico podem ter qualidade reduzida
  • Repetição: comportamento típico de modelos pequenos pode ocorrer em geração longa; mitigado parcialmente por top_k e temperature adequados

Referências de Comparação

Modelo Params Tokens Val PPL em PT
Este modelo 100M 1.97B 24.1
Modelo prévio (EN→PT cross-lingual) 55M 524M EN (incoerente, ver análise)
Sabiá-7B (referência grande) 7B 1.4T ~15

Equipe

  • Cristiano Ferrazzo (PUCRS — Escola Politécnica)

Licença

MIT. Use livre para fins acadêmicos e comerciais.

Citação

Se usar este modelo em trabalho acadêmico:

@misc{slm100m_pt_2026,
  author = {Ferrazzo, Cristiano},
  title  = {SLM-100M Portuguese: Small Language Model for Brazilian Portuguese},
  year   = {2026},
  publisher = {HuggingFace},
  url    = {https://huggingface.co/cjfb75/slm-100m-pt-llama-style}
}
Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Dataset used to train cjfb75/slm-100m-pt-llama-style