SAC-1 ยท Mini MoE para atendimento e vendas
raqIA โ IA em blocos
Primeiro language model aberto da raqIA: um Small Language Model (SLM) com arquitetura Mixture-of-Experts treinado do zero para o dominio de atendimento ao cliente e vendas em portugues brasileiro.
| dado | valor |
|---|---|
| Parametros totais | 12.4 M |
| Parametros ativos/token | ~5 M (top-2 de 8 experts) |
| Vocabulario | 1 024 tokens (BPE treinado do zero) |
| Contexto maximo | 256 tokens |
| Licenca | Apache-2.0 |
| Idioma | Portugues brasileiro |
| Dominio | Atendimento ao cliente, SAC, vendas |
Arquitetura
Transformer decoder-only com camadas MoE alternadas, construido inteiramente do zero em PyTorch puro โ sem dependencias de frameworks de LLM.
Embedding (1024 vocab, 256 dim)
|
v
+--[ Transformer Block x6 ]--+
| RMSNorm |
| Causal Self-Attention |
| - 8 heads, d_head=32 |
| - RoPE positional enc. |
| RMSNorm |
| FFN (alternado): |
| - Camadas 0,2,4: MoE |
| 8 experts, top-2 |
| SwiGLU activation |
| Load balancing loss |
| - Camadas 1,3,5: Dense |
| SwiGLU activation |
+---------+-------------------+
|
v
RMSNorm
LM Head (weight tying)
Detalhes tecnicos
- RoPE (Rotary Position Embedding) em vez de position embeddings aprendidos
- RMSNorm em vez de LayerNorm (mais eficiente)
- SwiGLU activation no feed-forward (melhor que ReLU/GELU)
- Weight tying entre embedding e LM head (reduz parametros)
- Load balancing loss para distribuir tokens entre experts
- Mixed precision (FP16) durante treinamento
Benchmark
Avaliado com 904 perguntas em 8 categorias, simulando cenarios reais de atendimento.
Resultado global
| Metrica | Valor |
|---|---|
| Score composto | 85.7% |
| Contains Match | 87.8% |
| Coherence | 98.9% |
| Domain Relevance | 84.8% |
Por categoria
| Categoria | Contains Match | Coherence | Score | N |
|---|---|---|---|---|
| FAQ exata | 100% | 100% | 100% | 100 |
| Conversa multi-turno | 100% | 100% | 100% | 100 |
| Objeccao de vendas | 100% | 100% | 100% | 104 |
| Script de vendas | 100% | 90% | 86.5% | 100 |
| Completar frase | 92% | 100% | 85.9% | 100 |
| FAQ parafraseada | 79.3% | 100% | 80.5% | 150 |
| Dominio relevante | 86% | 100% | 75% | 100 |
| Classificacao de intencao | 62% | 100% | 68.4% | 150 |
Distribuicao de scores
90-100%: 531 (58.7%) ######################################
70-89%: 263 (29.1%) #####################
50-69%: 0 ( 0.0%)
30-49%: 104 (11.5%) ########
0-29%: 6 ( 0.7%) #
Uso rapido
Requisitos
torch>=2.0
Nenhuma outra dependencia. Tudo e PyTorch puro.
Inferencia
import torch
from model import MiniMoELM
from tokenizer import BPETokenizer
device = "cuda" if torch.cuda.is_available() else "cpu"
# Carrega
tokenizer = BPETokenizer()
tokenizer.load("tokenizer_data")
checkpoint = torch.load("checkpoints/best_model.pt", map_location=device, weights_only=False)
model = MiniMoELM(checkpoint["config"]).to(device)
model.load_state_dict(checkpoint["model_state_dict"])
model.eval()
# Gera
prompt = "cliente: qual o prazo de entrega? atendente:"
input_ids = [2] + tokenizer.encode(prompt) # 2 = <bos>
input_tensor = torch.tensor([input_ids], dtype=torch.long).to(device)
output = model.generate(input_tensor, max_new_tokens=80, temperature=0.7)
print(tokenizer.decode(output[0].tolist()))
Chat interativo
python generate.py
Demo em batch
python generate.py --demo
Treinamento
Treinado do zero em uma NVIDIA RTX 3060 (12 GB).
| Parametro | Valor |
|---|---|
| Optimizer | AdamW (betas=0.9, 0.95) |
| Learning rate | 3e-4 com warmup + cosine decay |
| Warmup steps | 500 |
| Batch size | 64 |
| Precisao | Mixed (FP16) |
| Gradient clipping | 1.0 |
| Loss final (train) | 0.25 |
| Perplexidade final | 1.3 |
Dataset
Corpus sintetico de atendimento/vendas em PT-BR contendo:
- Conversas completas cliente-atendente (5 cenarios, multi-turno)
- FAQ com 10 pares pergunta-resposta
- 35 perguntas tipicas de clientes
- 40 respostas de atendentes
- 20 scripts de vendas
- 8 pares objeccao-resposta
- Combinacoes e augmentations (~3.900 textos no total)
Tokenizer
BPE (Byte Pair Encoding) treinado do zero no corpus do dominio.
- 1.024 tokens no vocabulario
- 5 tokens especiais:
<pad>,<unk>,<bos>,<eos>,<sep> - Treinado em 0.1s
Estrutura do repositorio
SAC-1/
config.py # Configuracao do modelo
model.py # Arquitetura MoE completa
tokenizer.py # Tokenizer BPE from scratch
dataset.py # Dataset sintetico de atendimento
train.py # Script de treinamento
generate.py # Inferencia e chat interativo
benchmark_qa.py # Benchmark de 904 perguntas
tokenizer_data/ # Pesos do tokenizer
checkpoints/ # Pesos do modelo
Limitacoes
- Dataset pequeno: treinado com ~3.900 textos sinteticos. Para producao, precisaria de dados reais de atendimento.
- Vocabulario reduzido (1.024 tokens): cobertura linguistica limitada. Palavras fora do dominio viram
<unk>. - Contexto curto (256 tokens): conversas longas sao truncadas.
- Generalizacao limitada: 62% de acuracia em perguntas com intencao parafraseada mostra que o modelo memoriza mais do que generaliza.
- Nao e um chatbot de producao: e um modelo de pesquisa e demonstracao da arquitetura MoE.
Por que construir do zero?
Este modelo existe para demonstrar que e possivel construir uma arquitetura MoE completa โ tokenizer, modelo, treinamento e avaliacao โ do zero, sem depender de modelos pre-treinados ou frameworks prontos.
A raqIA acredita em transparencia tecnica: publicamos os numeros reais, incluindo onde o modelo erra.
Citacao
@misc{raqia2026sac1,
title = {SAC-1: Mini MoE Language Model para Atendimento e Vendas},
author = {raqIA},
year = {2026},
url = {https://huggingface.co/Raqia32/sac-1},
note = {Small Language Model com Mixture-of-Experts treinado do zero}
}
Links
- Site: raqia.ia.br
- Modelos abertos: huggingface.co/Raqia32
- EPI-1 (detector de EPI): Raqia32/epi-1
- EPI-2 (detector de EPI v2): Raqia32/epi-2
Feito pela raqIA โ IA em blocos, montada para a sua operacao.
raqia.ia.br
Evaluation results
- Contains Match on raqIA QA Benchmark (904 perguntas)self-reported87.800
- Coherence on raqIA QA Benchmark (904 perguntas)self-reported98.900
- Domain Relevance on raqIA QA Benchmark (904 perguntas)self-reported84.800
- Score Composto on raqIA QA Benchmark (904 perguntas)self-reported85.700