MythraMind Bloom Logo

🌸 MythraMind Bloom

Compact Morphological Language Intelligence

Runs entirely in your browser. No BPE. No server. No dependencies.

License Language Params Size Platform No BPE


📌 Overview

MythraMind Bloom is a character-level small language model designed to run entirely offline in any browser, including low-end Android devices (~2GB RAM). It implements a novel Bloom architecture inspired by RWKV-7, BitNet b1.58, and Mixture-of-Experts, with original inventions developed for morphologically rich languages like Brazilian Portuguese — all without BPE tokenization.

MythraMind Bloom Architecture

🎯 Why Bloom?

Feature MythraMind Bloom GPT-style RWKV
Runs in browser ✅ Sim
No BPE needed ✅ HashProj ❌ Requer BPE ❌ Requer BPE
Sparse backprop ✅ Por categoria ❌ Dense Parcial
Long-term memory ✅ Seiva (Sap) ❌ KV-cache ✅ State
Grammatical rhythm ✅ VTI gate
Topic detection ✅ VTI Reset
Category routing ✅ MoDF + Bloom Parcial MoE
Morphological bias ✅ PT-BR nativo
Model size ~211 KB Gigabytes Gigabytes
Training time < 10s browser Horas/GPU Horas/GPU

🧬 Architecture

Component Overview

Input Text
    │
    ├─► Char Stream (ASCII 0-127)
    │       │
    │       ├─► E_char[128][24]     ← Char Embeddings
    │       ├─► HashProj[256][24]   ← N-gram Hash (sem BPE!)
    │       └─► E_cat[18][24]       ← Bipolar {±0.08}
    │                │
    │           Concat(ctxLen×ED + ED)  →  120-dim input
    │
    ▼
┌─────────────────────────────────────────────────────────┐
│                    BLOOM BLOCK                          │
│                                                         │
│  W1[128][120] ──► tanh ──► h[128]                       │
│       │                    │                            │
│       │              ┌─────┴────────┐                   │
│       │              ▼              ▼                   │
│       │         VTI Gate      Topic Reset               │
│       │     (cat histogram)  (flush if Δvti > 0.75)     │
│       │              │              │                   │
│       │              ▼              ▼                   │
│       │         ritmo[R]       Seiva(Sap)[R]            │
│       │     (sigmoid gate)   (slow-decay memory)        │
│       │              │              │                   │
│       │              └──── ⊙ ───────┘                   │
│       │                  latente[R]                     │
│       │                      │                          │
│       │              SPARSE B[cat][HD][R]               │
│       │           (só categoria ativa!)                 │
│       │                      │                          │
│       └──────── residual ────┘                          │
│                      │                                  │
│               hBloom[HD] = h + B[cat]@latente×0.3      │
└─────────────────────────────────────────────────────────┘
    │
    ├─► W_out[128][128] → char logits (128 classes)
    └─► W_cat[18][128]  → category logits (18 classes)
         │
         ▼
    Beam Sintático (Cat-First Routing)
    Bias Morfológico PT-BR

🔬 Componentes Detalhados

1. HashProj — Sem BPE

Em vez de um vocabulário BPE com 4k–16k tokens (que consumiria ~70% dos pesos do modelo), o Bloom usa hashing de n-gramas de caracteres ao estilo FastText.

// Extrai n-gramas de tamanho 2–4 dos últimos ctxLen chars
function ngramHash(ctx, HS=256) {
    const s = ctx.map(c => String.fromCharCode(c)).join('');
    const v = new Float32Array(HS);
    for (let n=2; n<=4; n++) {
        for (let i=0; i<=s.length-n; i++) {
            const ng = s.slice(i, i+n);
            v[fnv1a(ng) % HS] += 1;  // FNV-1a hash
        }
    }
    normalize(v);  // L2 normalize
    return v;
}

// Embedding final sem BPE:
// emb(t) = E_char[t] + HashProj[ngHash] * 0.3 + E_cat[cat] 

Vantagens:

  • Vocabulário zero: não memoriza tokens, decompõe em sílabas
  • Generalização: "correndo" ↔ "correr" compartilham n-gramas
  • Economia: elimina 1.5MB do modelo original

2. E_cat — Embeddings Bipolares de Categoria

Inicializados em {-0.08, +0.08} ao invés de FP32 aleatório, forçando categorias a ocuparem cantos opostos no espaço latente.

Categorias: [substantivo, verbo, adjetivo, advérbio, artigo,
             pronome, preposição, conjunção, interjeição, numeral,
             pontuação, espaço, keyword, operador, identificador,
             especial, desconhecido, pausa]

Classificador heurístico para PT-BR identifica categoria de cada palavra sem treino adicional.

3. Seiva (Sap State) — Memória Lenta de Longo Prazo

Inspirado no conceito de "memória de trabalho" humana, o vetor Seiva decai muito lentamente (0.999) e só é atualizado quando há surpresa (novidade no contexto).

Seiva[R]:
  • Decaimento: 0.999 por token
  • Atualização: só se surprise > 0.4 (token inesperado)
  • Uso: latente_final = sap ⊙ ritmo + h * 0.3
  • Flush: sap *= 0.1 quando VTI detecta mudança de tópico

Por que é eficaz:
  • Mantém "persona" e "tópico" por mais tempo que o contexto local
  • Não requer parâmetros extras (apenas R=16 floats)
  • Funciona como RAG sem base de dados externa

4. VTI — Vetor de Tensão Intercaracterística

O VTI é um histograma das últimas 24 categorias gramaticais que captura o "ritmo" sintático da frase.

VTI[C=18]:
  • vti[c] = freq(cat_c nos últimos 24 tokens)
  • ritmo = sigmoid(W_vti @ vti)   ← aprende o "compasso" gramatical
  • latente = sap ⊙ ritmo          ← modula memória pelo ritmo

Topic Reset:
  • dist = 1 - cosine(vti_atual, vti_anterior)
  • Se dist > 0.75: sap *= 0.1    ← flush da memória
  
Detecta mudanças como:
  • Narrativa → Diálogo
  • Declarativo → Interrogativo  
  • Presente → Passado

5. MoDF — Mixture-of-Depths Floral

Tokens de categorias triviais (artigos, pontuação, espaços) não executam as operações pesadas do bloco Bloom.

Categorias Triviais (TRIVIAL_CATS):
  • artigo (4): o, a, um, uma
  • pontuação (9): . , ! ? ; :
  • espaço (11): \s, \n
  
Economia estimada:
  • ~30-40% dos tokens são triviais em PT-BR
  • Reduz ops por token em ~35% na média

6. Backprop Esparsa — Só o Caminho Ativo

Durante o treino, apenas os pesos do caminho que o token percorreu recebem gradiente.

Token categoria "verbo" → atualiza:
  ✓ DENSE:   W_out, b_out, W_cat, W1, b1
  ✦ SPARSE:  E_char[chars_no_contexto]
  ✦ SPARSE:  E_cat[verbo]              ← só verbo
  ✦ SPARSE:  HashProj[hashes_ativos]   ← só buckets não-nulos
  ✦ SPARSE:  B[verbo]                  ← só lente de verbo
  ✗ SKIP:    B[substantivo..pausa]     ← 17 matrizes NÃO tocadas

Resultado:
  • Treino ~5-8× mais rápido por step
  • Menos interferência entre categorias
  • Especialização genuína por classe gramatical

7. Bias Morfológico PT-BR

Durante a geração, o modelo pode boostar probabilidades de terminações morfológicas do Português Brasileiro.

MORPH_BOOST = {
    'verb': ['r','a','e','i','o','u'],     # ar, er, ir, ou, endo...
    'noun': ['a','o','s','e','ã'],          # ção, ão, os...
    'adj':  ['o','s','a','e','l'],          # oso, vel, al...
}

# Applied when near end of word (no space in last 3 chars):
if cat_predicted == 'verbo':
    for ch in MORPH_BOOST['verb']:
        logits[ord(ch)] += 1.5  # soft boost (not hard constraint)

8. Beam Sintático — Cat-First Routing

Em vez de beam search no vocabulário (inviável sem BPE), o Bloom faz beam search nas categorias.

Prompt: "O gato preto"
    │
    ▼ W_cat @ hBloom
    ├── 72% → verbo       → "dorme" | "corre" | "mia"
    ├── 18% → adjetivo    → "grande" | "faminto" | "velho"  
    └── 10% → substantivo → "comeu" | "tinha" | "era"
         │
         ▼ Gera chars com B[categoria] ativo
    Seleciona beam com maior score: logP(cat) + logP(chars)

📐 Parâmetros e Tamanhos

Configuração: ctxLen=4, ED=24, HD=128, V=128, C=18, HS=256, R=16

┌─────────────────────────────────────────────┐
│ Componente        │ Shape       │ Params     │
├───────────────────┼─────────────┼────────────┤
│ E_char            │ 128 × 24    │  3,072     │
│ E_cat (bipolar)   │  18 × 24    │    432     │
│ HashProj          │ 256 × 24    │  6,144     │
│ W1 (hidden)       │ 128 × 120   │ 15,360     │
│ b1                │ 128         │    128     │
│ W_out             │ 128 × 128   │ 16,384     │
│ b_out             │ 128         │    128     │
│ W_cat             │  18 × 128   │  2,304     │
│ W_sap             │  16 × 128   │  2,048     │
│ W_vti             │  16 × 18    │    288     │
│ B lenses          │ 18×128×16   │ 36,864 *  │
├───────────────────┼─────────────┼────────────┤
│ TOTAL             │             │ ~83,152    │
│ (sem B inativos)  │ ~46k active │ ~54,000   │
└─────────────────────────────────────────────┘

* B[cat] é esparso: só 1/18 ativo por forward pass
  Params "ativos" por token: ~2,304 (B[cat]) + resto = ~46k

Tamanho em disco:
  • FP32:  ~324 KB
  • JSON:  ~420 KB (com overhead de texto)

🚀 Uso

No Navegador (Recomendado)

O modelo completo roda como HTML single-file, sem dependências:

<!-- Baixe o arquivo MythraMind_Bloom_v3.html -->
<!-- Abra em qualquer navegador moderno -->
<!-- Funciona offline, inclusive em Android -->

Funcionalidades da interface:

  • 📚 Aba Treino: Treine com qualquer texto PT-BR, veja curva de loss em tempo real
  • 💬 Aba Chat: Converse com o modelo, visualize estado interno (Seiva, VTI)
  • 🎮 Aba Playground: Difusão mask-predict, análise de temperatura, probabilidade de sequências, geração com bias morfológico, beam sintático

Em JavaScript (API)

// Instanciar modelo
const model = new BloomLM(4);  // ctxLen = 4 chars

// Treinar em um texto
async function train(text, epochs=60, lr=0.006) {
    const chars = [...text].map(c => c.charCodeAt(0) & 127);
    for (let ep = 0; ep < epochs; ep++) {
        for (let i = model.ctxLen; i < chars.length - 1; i++) {
            const ctx = chars.slice(i - model.ctxLen, i);
            const cat = classifyCat(text[i]);
            const loss = model.trainStep(ctx, cat, chars[i], classifyCat(text[i+1]), lr);
        }
    }
}

// Gerar texto
const seed = "O gato ";
const seedChars = [...seed].map(c => c.charCodeAt(0) & 127);
const seedCats = seed.split('').map(c => classifyCat(c));
const generated = model.generate(seedChars, seedCats, 100, 0.9, 15, 'noun');
console.log(seed + generated);
// → "O gato preto dorme no sofá da sala grande..."

// Calcular probabilidade de uma sequência
const { logP, ppl, perChar } = model.probSequence(
    [...'O gato dorme'].map(c => c.charCodeAt(0) & 127)
);
console.log(`Log-Prob: ${logP.toFixed(4)}, Perplexidade: ${ppl.toFixed(3)}`);

// Beam sintático (Cat-First)
const beams = model.syntacticBeam(seedChars, 3, 40, 0.85);
beams.forEach(b => {
    console.log(`[${b.catName}] (${(b.prob*100).toFixed(1)}%) → ${seed + b.text}`);
});

// Salvar / Carregar
const json = model.toJSON();
localStorage.setItem('bloom_model', JSON.stringify(json));
const loaded = BloomLM.fromJSON(JSON.parse(localStorage.getItem('bloom_model')));

Difusão Mask-Predict

// Texto com tokens mascarados
const text = "O gato preto dorme no sofá";
const chars = [...text];
const maskIdxs = [3, 4, 15, 16, 17]; // índices a mascarar

// Reconstrução iterativa
const rec = [...chars];
for (let iter = 0; iter < 3; iter++) {
    for (const idx of maskIdxs) {
        const ctx = chars.slice(Math.max(0, idx - model.ctxLen), idx)
                         .map(c => c.charCodeAt(0) & 127);
        while (ctx.length < model.ctxLen) ctx.unshift(32);
        
        const { logits_char } = model.forward(ctx, classifyCat(chars.slice(0,idx).join('')));
        const probs = model._softmax(logits_char, 0.6);
        const best = probs.indexOf(Math.max(...probs.slice(32, 127)));
        rec[idx] = String.fromCharCode(best);
    }
}
console.log(rec.join(''));
// → "O gato preto dorme no sofá" (reconstruído!)

📊 Benchmarks

Testado em PT-BR com textos do projeto Gutenberg e Wikipedia simplificada.

Dataset: 10.000 chars de texto PT-BR narrativo

┌────────────────────────┬───────────┬──────────────┬─────────────┐
│ Configuração           │ Loss Final│ Perplexidade │ Tempo Treino│
├────────────────────────┼───────────┼──────────────┼─────────────┤
│ ctxLen=2, 30 épocas    │   2.94    │    18.9      │   ~2s       │
│ ctxLen=4, 60 épocas    │   2.31    │    10.1      │   ~6s       │
│ ctxLen=6, 100 épocas   │   1.87    │     6.5      │   ~14s      │
│ ctxLen=4, 200 épocas   │   1.62    │     5.0      │   ~20s      │
└────────────────────────┴───────────┴──────────────┴─────────────┘

Hardware: Moto G7 Play (Android, 2GB RAM, Chrome)

Velocidade de Geração:
  • ~400-600 chars/segundo (depende do hardware)
  • Latência first-token: < 1ms

Comparação de Tamanho (para ~54k params):
  • BloomLM (este modelo):  ~211 KB FP32
  • LSTM equivalente:       ~500 KB
  • GPT-nano equivalente:   ~1.2 MB
  • N-gram 4-gram puro:     Memória proporcional ao texto

🗺️ Roadmap

Bloom v3 (atual)          Chrysalis v4               Monarch v5
─────────────────         ─────────────────         ─────────────────
✅ HashProj               🔄 Multi-block Bloom       ⬜ Quantização INT4
✅ Seiva (Sap)            🔄 Atenção bidirecional    ⬜ WebAssembly SIMD
✅ VTI Topic Reset        🔄 MTP Light adapters      ⬜ ~2M params
✅ Sparse backprop        🔄 Difusão no treino       ⬜ ~800KB modelo
✅ Bipolar E_cat          🔄 Florescência dinâmica   ⬜ PT-BR base weights
✅ Morph bias PT-BR       🔄 Web Workers             ⬜ Fine-tuning API
✅ Beam sintático         🔄 IndexedDB persistence   ⬜ Multi-língua
✅ Runs in browser        🔄 ~250k params            ⬜ Streaming geração

📁 Arquivos do Repositório

mythra-bloom/
├── MythraMind_Bloom_v3.html    ← App completa, single-file, offline
├── logo.png                    ← Logo MythraMind
├── Bloom.jpg                   ← Diagrama da arquitetura
└── README.md                   ← Este arquivo

⚙️ Configuração Avançada

// Parâmetros customizáveis
const model = new BloomLM(ctxLen=4);

// Dimensões (recompile após mudar):
// model.ED   = 24   // Embed dim por char (aumente para mais capacidade)
// model.HD   = 128  // Hidden dim (principal gargalo de velocidade)
// model.R    = 16   // Sap/latente dim
// model.C    = 18   // Categorias (18 PT-BR padrão)
// model.HS   = 256  // Hash space (maior = menos colisões nos n-gramas)

// Parâmetros de geração:
model.generate(
    seedChars,     // int[] — chars iniciais
    seedCats,      // int[] — categorias iniciais
    100,           // comprimento máximo
    0.9,           // temperatura (0.1=greedy, 2.0=criativo)
    15,            // top-K sampling
    'verb'         // bias morfológico: 'none'|'verb'|'noun'|'adj'
);

// Parâmetros Adam (ajuste no trainStep):
// lr    = 0.006  // Learning rate padrão
// beta1 = 0.9    // Momento 1 (Adam)
// beta2 = 0.999  // Momento 2 (Adam)
// eps   = 1e-8   // Estabilidade numérica

// VTI Topic Reset (no forward):
// Threshold = 0.75  // Distância cosseno para detectar mudança de tópico

// Sap State:
// decay     = 0.999  // Decaimento lento da memória
// lr_sap    = 0.001  // Taxa de atualização da seiva
// threshold = 0.4    // Surpresa mínima para atualizar seiva

🏗️ Treinando do Zero

// Exemplo completo: treinar em um conto infantil PT-BR

const texto = `
Era uma vez um gato preto que morava numa casa grande.
O gato gostava muito de dormir no sofá da sala.
Toda manhã, Maria acordava cedo para dar leite ao gato.
O gato corria feliz quando ouvia o som da tigela.
No jardim, os pássaros cantavam e o gato ficava curioso.
`;

const model = new BloomLM(4);   // do zero

// Treino assíncrono (não trava a UI)
async function treinar() {
    const chars = [...texto].map(c => c.charCodeAt(0) & 127);
    const cats  = texto.split('').map(c => classifyCat(c));
    
    for (let ep = 0; ep < 100; ep++) {
        let loss = 0;
        for (let i = 4; i < chars.length - 1; i++) {
            const ctx = chars.slice(i-4, i);
            loss += model.trainStep(ctx, cats[i], chars[i], cats[i+1], 0.006);
        }
        console.log(`Época ${ep+1}: loss=${(loss/chars.length).toFixed(4)}`);
        await new Promise(r => setTimeout(r, 0)); // yield para UI
    }
    
    // Após treino, gera continuação
    const seed = "O gato ";
    const seedC = [...seed].map(c => c.charCodeAt(0) & 127);
    const seedCats = seed.split('').map(c => classifyCat(c));
    console.log(seed + model.generate(seedC, seedCats, 60, 0.85, 12));
    // → "O gato preto dormia no sofá quando Maria chegou..."
}

treinar();

🔬 Por Que Sem BPE?

O BPE (Byte Pair Encoding) é necessário quando o modelo precisa memorizar tokens específicos. O Bloom não memoriza tokens — ele aprende padrões morfológicos via n-grams de caracteres.

COM BPE:
  "gato" → token_id 3421 → E_token[3421]  (específico, não generaliza)
  "gatos" → token_id 8834 → E_token[8834] (token diferente!)
  Tamanho: 4k-16k × d_model = 1.5-6MB só em embeddings

SEM BPE (HashProj):
  "gato"  → n-gramas: "ga","at","to","gat","ato" → hash → ngVec
  "gatos" → n-gramas: "ga","at","to","os","gat","ato","tos" → hash → ngVec'
  ngVec e ngVec' compartilham 5/7 buckets → representações similares ✓
  Tamanho: 256 × 24 = 6,144 params (100× menor!)

🤝 Contribuindo

Contribuições são bem-vindas! Áreas prioritárias:

  • 🇧🇷 Dados PT-BR: textos de domínio público para pré-treino
  • Velocidade: implementação WASM para ops matriciais
  • 🌸 Florescência: adicionar categorias novas sem retreinar
  • 🎨 UI/UX: melhorias no playground interativo
  • 🧪 Benchmarks: comparação com outros modelos tiny

📄 Licença

Apache License 2.0

Copyright 2025 MythraMind / SF Studio / Vib Beats

Uso comercial ✅ | Modificação ✅ | Distribuição ✅
Uso privado ✅  | Sublicença ✅  | Patenteamento ❌

Condições: Manter atribuição e aviso de licença.

📚 Referências e Inspirações

[1] BitNet b1.58  - Ma et al. (2024) — ternary weight quantization
    https://arxiv.org/abs/2402.17764

[2] RWKV-7       - Peng et al. (2024) — linear attention com state
    https://arxiv.org/abs/2503.14456

[3] FastText      - Bojanowski et al. (2017) — n-gram char hashing
    https://arxiv.org/abs/1607.04606

[4] Mixture-of-Depths - Raposo et al. (2024) — token skipping
    https://arxiv.org/abs/2404.02258

[5] Titans        - Sun et al. (2024) — memória neural de longo prazo
    https://arxiv.org/abs/2501.00663

Invenções Originais (MythraMind):
  • VTI (Vetor de Tensão Intercaracterística) — ritmo gramatical
  • MoDF (Mixture-of-Depths Floral) — skip por categoria
  • Seiva (Sap State) — memória lenta seletiva
  • HashProj Bloom — n-gram sem BPE para modelos minúsculos
  • Beam Sintático — Cat-First routing na geração

📝 Citação

@misc{mythra2025bloom,
  title        = {MythraMind Bloom: Compact Morphological Language Intelligence
                  without BPE for Resource-Constrained Environments},
  author       = {Vib Beats and SF Studio},
  year         = {2025},
  howpublished = {\url{https://huggingface.co/SFStudio/mythra-bloom}},
  note         = {Character-level SLM with HashProj, Sap State, VTI, 
                  Sparse Backprop and Cat-First Beam Search.
                  Runs entirely in-browser, ~54k params, ~211KB, Apache 2.0.}
}

🌸 MythraMind Bloom — Uma IA que cabe num arquivo HTML

Feito com 💜 por SF Studio / Vib Beats

Bloom → Chrysalis → Monarch

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

Papers for StoneFighterStudio/MythraMind