
A história do TatuEngine — dos RT Cores dos sonhos ao agente autopoiético com 252× de speedup
⚡ A engine que começou com uma pergunta absurda
“GPUs modernas têm RT Cores parados 99% do tempo. E se a gente usasse eles pra processar redes neurais?”
Foi essa provocação que deu origem ao TatuEngine em junho de 2026. A visão era hipnotizante: cada peso vira uma lente refratora dentro de uma BVH, o token de entrada é um raio disparado contra a geometria, e a inferência é a luz passando pelo sistema — a resposta nasce da interferência coerente de ondas. Aprender? Esculpir o caminho por onde a luz passa.
Trinta e poucos dias depois, o projeto tem 302 commits, um modelo BitMamba-2 1B rodando em GPU 252× mais rápido que CPU, 400+ testes e um agente autopoiético com 8 subsistemas. Mas o caminho até aqui começou com o sonho morrendo no primeiro dia.
🧠 Contexto — o sonho OptiX
O stack planejado era ambicioso:
- OptiX 7 pra aceleração de ray tracing
- Mamba 2.8B como modelo base
- GGUF como formato de modelo
- MCP como protocolo de API
O Sprint 1 construiu tudo ao redor dessa visão: src/core com pipeline lock-free e triple buffering, src/rt com headers OptiX 9.1 compilando PTX, src/mamba com SSM kernel CUDA, src/field_theory com o protótipo do Campo de Fase (wave.h, interference.h, optimize.h). Documentação da época: PLANO_MESTRE.md e CARVEKNOWLEDGE.md — ambos refletindo uma visão que nunca funcionaria no ambiente real.
🔧 A luta — o sonho que morreu no WSL2
O baque: RT Cores não existem no WSL2
O WSL2 não tem suporte a RT Cores. A libnvoptix.so.1 dentro do WSL é um proxy DXCore de 14KB que não exporta a function table do OptiX:
optixInit() → OPTIX_ERROR_ENTRY_SYMBOL_NOT_FOUND
Duas semanas tentando contornar. O que salvou: CUDA funciona nativamente no WSL (ioctl NVIDIA direto). RT Cores não — mas CUDA Cores, sim. Foi a primeira lição: não force uma tecnologia onde ela não encaixa.
O segundo muro: 27 GB de lentes
Converter a rede de 1B parâmetros pra BVH como TriangleLens custaria 27 GB — impossível pra VRAM de 12 GB. A solução foi o pipeline híbrido bridge_matmul: as matmuls pesadas (in_proj, out_proj, lm_head) rodam em CUDA lendo os tensores originais, e o estado SSM (conv1d, RMSNorm, step) fica na CPU:
CPU: embedding → RMSNorm → conv1d+SiLU → SSM step → residual
GPU (bridge_matmul): in_proj → out_proj → lm_head
E aqui veio outra descoberta: o Mamba SSM é inerentemente sequencial — h(t) = f(h(t-1), x(t)). Diferente de transformers (KV cache paralelizável), só dá pra paralelizar as matmuls; o step é CPU-bound. O gargalo virou a comunicação CPU↔GPU entre tokens.
O NaN que quase virou lenda
Softplus com float32 estoura: expf(89.0) = inf. Uma linha salvou dois dias de debug:
// antes: softplus(x) = log1p(expf(x)) → inf pra x > 89
// depois: log1pf(expf(-dt_x)) para x > 0
O marco: 50257/50257 logits bit-a-bit
A validação que provou que o híbrido funcionava: 50257 logits idênticos entre bridge_matmul e o ground truth CPU, bit por bit.
Block Codec: 114× de compressão
A descoberta que mudou o jogo: em vez de 1 TriangleLens por peso, blocos ternários 32×32 compactados em 288 bytes cada. 893 mil blocos, 245 MB no total vs 27.26 GB float32 — 114× de compressão, bit-a-bit idêntico (tolerância ULP).
GPU Block-Traversal: 252× de speedup
O kernel block_traverse_kernel usa 32 threads/CTA, 1 row_block por grid block, warp shuffle reduction (__shfl_xor_sync) + shared memory, sem atomics:
| Pipeline | CPU | GPU | Speedup |
|---|---|---|---|
| Inferência 1 token | 10.552 ms | 41.9 µs | 252× |
| Traversal 16 raios | 74.2 ms | 0.52 ms | 146× |
| Bake 100K células | ~70 ms | 4.8 ms | 15× |
💡 Resolução — o agente autopoiético
Com a inferência resolvida, o TatuEngine virou agente. O GenerationContext reúne os subsistemas que fazem o modelo se auto-avaliar e usar ferramentas:
- 🧬 Immunosystem — detecta atrator fixo (H<0.15, Δh<0.001) e injeta perturbação senoidal adaptativa
- 💾 LTM Associativo — memória por cos_sim no espaço latente do SSM (HIGH=0.85)
- 🛠️ ToolUse — detecta
`<|tool:nome|>args<|/tool|>`no texto gerado e executa via sandbox - 🥞 GoalStack — raciocínio recursivo com checkpoint/restore (max_depth=3)
- 🛡️ SafetyGuard — invariância de Noether (drift < 0.001, E < 0.60)
- ⚛️🎯 GoalHamiltonian — supervisor semântico com cos_sim(h_t, root_goal)
-
- RealityAnchor, AutoCalibration, FailureIndex, MetaCognition
E o Sandbox Híbrido pra proteger as tools de arquivo — path validation, size/type enforcement, 3 níveis de isolamento:
class SandboxLevel(Enum):
"""Níveis de isolamento do sandbox, compatíveis com ToolPermission."""
SAFE = "safe"
PROMPT = "prompt"
RESTRICTED = "restricted"
DENIED = "denied"
51/51 testes passando — verifiquei agora mesmo: 51 passed in 0.13s.
📊 Métricas
| Métrica | Junho (nascimento) | Hoje |
|---|---|---|
| Commits | 1 | 302 |
| Testes | 0 | 400+ C++ (30 suites) + 51 sandbox |
| Speedup GPU | ❌ (OptiX não funcionava) | 252× block-traversal |
| Compressão | 27.26 GB (float32) | 245 MB (block codec, 114×) |
| Pipeline | Conceitual | Híbrido CPU/GPU bit-a-bit |
| Agente | 0 subsistemas | 8 subsistemas |
| Modelo | Mamba 2.8B (planejado) | BitMamba-2 1B (funcional, 621 MB) |
| Sandbox | não existia | 3 níveis, 51/51 testes |
🎯 Aprendizados
- Não force uma tecnologia onde ela não encaixa — OptiX no WSL custou ~2 semanas; a abordagem híbrida (bridge_matmul + block codec) foi descoberta em 3 dias e resolveu.
- Modelos ternários nativos vs pós-treino — ternarizar um float32 depois do treino destrói a coerência. O BitMamba-2 funciona porque nasceu com pesos ternários.
- O SSM não é um transformer — não adianta paralelizar o que é sequencial por natureza. O ganho real está em acelerar as matmuls e aceitar que o step é CPU-bound.
- AutoTrainer converge rápido demais — o sistema atinge 99.5% de qualidade em 14 steps e o AutoTrainer fica ocioso, não porque está quebrado, mas porque o sistema já está resolvido.