Um modelo de 14MB que faz tool calling? Sério?
Eu já vi modelos de IA rodando em celular. Já vi modelos comprimidos, quantizados, destilados. Mas quando o Needle2 da Cactus Compute apareceu no topo do Hacker News com a promessa de rodar tool calling agêntico em 14 megabytes, minha primeira reação foi: “isso não funciona de verdade.”
Spoiler: funciona. Com ressalvas, claro, porque nada na vida é perfeito. Mas o que a Cactus Compute conseguiu fazer aqui é genuinamente impressionante, e vale entender o porquê.
Enquanto todo mundo está obsecado em escalar modelos para trilhões de parâmetros, a Cactus foi na direção oposta. Pegou 45 milhões de parâmetros, comprimiu tudo em 2 bits, e criou um binário único de 14MB que roda em Raspberry Pi, smartwatch, robô, e até microcontroladores ESP32. A sessão inteira consome 28MB de RAM. Pra colocar em perspectiva: o favicon do seu site provavelmente pesa mais que esse modelo.
O que é o Needle2 (e o que ele não é)
Antes de qualquer coisa: o Needle2 não é um ChatGPT de bolso. Ele não vai escrever poesia, debater filosofia ou fingir que tem sentimentos. Ele foi projetado pra uma coisa específica: tool calling. Recebe um comando, identifica qual ferramenta usar, extrai os parâmetros corretos, e retorna uma chamada de função estruturada em JSON.
Pense nele como o cérebro mínimo viável de um assistente de voz local. Alguém fala “acende a luz da sala”, e o Needle2 traduz isso pra {"function": "set_light", "params": {"room": "living_room", "state": "on"}}. Sem mandar nada pra nuvem, sem latência de rede, sem expor seus dados.
O modelo original (Needle 1) tinha 26 milhões de parâmetros. A versão 2 subiu pra 45M, mas manteve o mesmo peso de 14MB graças a uma técnica de quantização proprietária chamada Cactus Quants, que comprime tudo pra 2 bits durante o treinamento, e não depois. Essa diferença é crucial, e vou explicar por quê.
A arquitetura por trás: Simple Attention Networks
A maioria dos LLMs usa a arquitetura Transformer clássica: camadas de atenção intercaladas com redes feed-forward (MLPs). O Needle2 joga metade disso fora.
A Cactus Compute desenvolveu o que chamam de Simple Attention Networks (SAN). A ideia central é que tool calling é fundamentalmente um problema de recuperação e montagem: o modelo precisa encontrar qual ferramenta combina com o pedido e extrair os valores dos argumentos. Não precisa “raciocinar” no sentido clássico.
A arquitetura do Needle2 tem 27 camadas com largura de 512 e inclui componentes que você não encontra em modelos convencionais:
| Componente | O que faz |
|---|---|
| Hadamard MLP | Substitui o MLP tradicional por transformadas Walsh-Hadamard, que misturam canais sem ler pesos |
| Engram Memory | 8 milhões de parâmetros armazenados como tabelas de n-gramas com hash, sem aritmética no decode |
| Grouped Query Attention | Atenção agrupada pra reduzir consumo de memória |
| Multi-lane Hyper-connections | Múltiplos caminhos residuais pra flexibilidade de roteamento |
| Sliding Window de 256 tokens | KV cache limitado pra manter memória constante |
A transformada Walsh-Hadamard é particularmente interessante. Em vez de multiplicações matriciais pesadas, ela faz mixagem de canais com operações de soma e subtração. O custo computacional cai drasticamente: 70 MFLOPs por token, contra 87 a 540 MFLOPs dos competidores.
# Comparação de FLOPs por token
Needle2: 70 MFLOPs
FunctionGemma: 87 MFLOPs (270M params)
Granite-350M: 210 MFLOPs
Qwen-0.6B: 540 MFLOPs
O sistema de Engram é outro truque engenhoso. São tabelas de n-gramas pré-computadas que funcionam como uma memória fixa. Durante a inferência, o modelo simplesmente faz lookup nessas tabelas sem nenhuma operação aritmética. É como ter um dicionário embutido que o modelo consulta instantaneamente.
Cactus Quants: por que quantizar durante o treino muda tudo
A quantização pós-treino é o que todo mundo faz. Você treina um modelo em FP16 ou BF16, depois comprime pra INT8 ou INT4 pra deploy. Funciona bem pra modelos grandes. Pra modelos pequenos, é um desastre.
Quando você quantiza um modelo de 45M parâmetros pra 2 bits depois do treino, a perda de qualidade é catastrófica. Os pesos simplesmente não têm redundância suficiente pra absorver o erro de arredondamento.
A abordagem da Cactus é diferente: Cactus Quants treina o modelo já em 2 bits desde o início. Pesos, ativações e KV cache, tudo em precisão reduzida durante o pretraining e o post-training. O modelo aprende a compensar a baixa precisão durante o treinamento, em vez de ser forçado a lidar com ela depois.
O resultado prático:
- Pesos armazenados como códigos de 2 bits
- Expansão acontece apenas nos registradores vetoriais durante a inferência
- Caminho aritmético end-to-end em INT8
- Grammar-based token pruning que pula até 98% das projeções de vocabulário
Essa última parte merece destaque. Como o modelo sabe que a saída precisa ser um JSON válido com campos específicos, ele usa gramáticas compiladas a partir dos schemas JSON pra podar o vocabulário em cada passo de decode. Se o próximo token precisa ser o nome de uma ferramenta, por que avaliar 50 mil tokens possíveis? O modelo avalia só os que fazem sentido.
Benchmarks: onde o Needle2 brilha (e onde tropeça)
Números falam mais que marketing. A Cactus publicou resultados em vários benchmarks de tool calling:
| Benchmark | Needle2 (45M) | FunctionGemma (270M) | Observação |
|---|---|---|---|
| Mobile Actions (961 rows) | 63.7% | – | Comandos mobile reais |
| DroidCall (200 rows) | 17.0% | 17.5% | Praticamente empatado |
| Seal-Tools In-Domain (700) | 32.6% | – | Cenários multi-call complexos |
| Seal-Tools Out-of-Domain | 28.7% | – | Generalização pra ferramentas novas |
| BFCL v4 (3,641 tasks) | 42.6% | – | Output bem-formado: 93.4% |
O modelo “troca vitórias” com modelos de 270M a 2.6B parâmetros, sendo 5x a 70x menor. Em cenários de single-shot function calling, ele compete de igual pra igual. Em cenários conversacionais multi-turn, os modelos maiores levam vantagem.
A taxa de output bem-formado de 93.4% no BFCL v4 é impressionante pra um modelo desse tamanho. Significa que em quase todos os casos, a saída é JSON válido com os campos certos. Pode errar o valor do parâmetro, mas a estrutura está correta.
Velocidade: 500 tokens por segundo no Raspberry Pi
Aqui é onde o Needle2 fica absurdo:
# Tokens por segundo (decode)
Raspberry Pi 5: 500+ tok/s
Samsung A-Series (<$200): 300-700 tok/s
Meta Quest 3S: 400-1,500 tok/s
Apple Vision Pro: 400-1,500 tok/s
# Prefill
Raspberry Pi 5: 800+ tok/s
Geral: 4,300 tok/s
Quinhentos tokens por segundo. Num Raspberry Pi. Que custa menos de cem dólares.
Pra tool calling, onde a resposta típica tem 20 a 50 tokens, isso significa tempo de resposta abaixo de 100 milissegundos. Mais rápido que qualquer API na nuvem, porque não tem rede no caminho.
E o consumo energético reflete essa eficiência. A Cactus reporta que o Needle2 consome 7x a 85x menos operações computacionais por token comparado com competidores, o que se traduz diretamente em vida útil de bateria pra dispositivos que precisam ficar ligados o tempo todo.
Na prática: o que dá pra fazer (e o que não dá)
O caso de uso mais óbvio é automação residencial. Um smart speaker rodando Needle2 localmente pode:
from needle import Needle
model = Needle()
@model.tool
def set_light(room: str, brightness: int = 100, color: str = "white"):
"""Control room lighting"""
pass
@model.tool
def set_thermostat(temperature: float, mode: str = "auto"):
"""Adjust climate control"""
pass
result = model("acende a luz da cozinha com 50% de brilho")
# {"function": "set_light", "room": "kitchen", "brightness": 50}
A API é surpreendentemente limpa. Decorators definem as ferramentas, e o modelo faz o parsing. Suporta constraints via needle.Field com ranges, patterns e limites. E pra catálogos com mais de cinco ferramentas, um retrieval head seleciona as top-5 mais relevantes por turno.
O Pebble Index 01, um smart ring, já usa o Needle em produção. Converte comandos de voz em ações sem dependência de rede. Isso não é protótipo de laboratório.
Mas os testes da comunidade do Hacker News revelaram limitações reais. Quando alguém pediu “make it warmer”, o modelo respondeu setando o modo de resfriamento pra 65°F, com a justificativa de que “‘warmer’ implies need for cooling.” Quando alguém digitou “HN”, o modelo decidiu trancar a porta da frente.
Esses bugs são hilários, mas revelam um ponto importante: o Needle2 é um modelo de domínio restrito. Ele funciona muito bem quando as descrições das ferramentas são precisas e o escopo é estreito. Quando você joga linguagem natural ambígua ou fora do domínio, ele se perde.
Fine-tuning em minutos (literalmente)
Essa é talvez a feature mais prática do Needle2. Com 45M de parâmetros, o fine-tuning roda em hardware de consumidor:
# Gera dados sintéticos a partir do schema das suas tools
needle generate-data --tools schema.json --num-samples 500 --output data.jsonl
# Fine-tune com LoRA (rank e alpha ajustáveis)
needle finetune data.jsonl --epochs 3 --lora-rank 16
# Compila modelo quantizado final
needle build checkpoints/needle2.pkl \
--lora checkpoints/needle_lora.pkl \
--out meu_modelo_custom.cact
Três comandos. O adapter LoRA é mergeado nos pesos base antes da quantização, e o resultado é um único binário deployável. Sem dependências externas, sem runtime Python na ponta.
A Cactus também oferece geração sintética de dados de treinamento. Você passa o schema das suas ferramentas, e o pipeline gera exemplos variados de como usuários poderiam invocar cada uma. Depois é só rodar o fine-tune e deployar.
Pra quem trabalha com IoT ou automação, isso muda o jogo. Em vez de depender de um modelo genérico que pode ou não entender seus comandos, você treina um modelo específico pro seu domínio em questão de minutos.
O elefante na sala: confidence scores
O Needle2 inclui um head de confiança que retorna um score de 0 a 1 pra cada resposta. A ideia é usar isso pra decidir se processa localmente ou escala pra um modelo na nuvem.
Na teoria, ótimo. Na prática, a comunidade questionou se esses scores são realmente calibrados. O modelo às vezes gera respostas incorretas com confiança baixa, mas sem um padrão consistente. Um score de 0.3 não necessariamente significa “não confie nessa resposta”, pode significar “a pergunta era ambígua” ou simplesmente “não sei”.
Pra produção, a recomendação é combinar o confidence score com validação do schema de saída. Se o JSON é válido e o confidence é alto, processa. Se qualquer um falhar, escala pra nuvem.
Onde rodar: de microcontroladores a headsets VR
A lista de hardware suportado é impressionante:
- Microcontroladores: ESP32-S3, STM32H7, NXP i.MX RT (com RAM externa)
- Wearables: Smart rings, smartwatches
- Celulares: Budget phones abaixo de $200
- SBCs: Raspberry Pi 5
- VR: Meta Quest 3S, Apple Vision Pro
- Robótica: Qualquer plataforma com CPU ARM ou x86
O binário roda em Cortex-M, x86, RISC-V e WebAssembly. Sem dependências. Um único arquivo de 14MB que você copia pro dispositivo e executa.
Pra instalar via Python (desenvolvimento e prototipagem):
pip install cactus-needle
O engine baixa os pesos do Hugging Face automaticamente na primeira execução. Pra deploy em produção, você compila o binário C++ sem dependências.
A tendência: IA saindo da nuvem
O Needle2 não existe isolado. Faz parte de um movimento maior onde IA está migrando da nuvem pra ponta.
Na semana passada cobrimos o Maple-Preview rodando 20B a 120 tok/s no iPhone. Antes disso, o Ante que roda em 15MB de RAM. A direção é clara: modelos especializados e pequenos rodando localmente pra tarefas específicas, com modelos grandes na nuvem como fallback pra o que exige raciocínio pesado.
A vantagem não é só performance. É privacidade. Um modelo que roda no seu dispositivo não envia seus comandos de voz pra servidor nenhum. Não grava suas conversas. Não treina com seus dados. Num mundo onde até assistentes de voz “locais” mandam áudio pra nuvem, ter 14MB de IA genuinamente offline é um diferencial real.
Como usar no seu projeto
Se você quer experimentar, o caminho mais rápido é:
pip install cactus-needle
from needle import Needle
# Inicializa (baixa pesos automaticamente na primeira vez)
model = Needle()
# Define suas ferramentas com decorators
@model.tool
def send_message(contact: str, text: str):
"""Send a text message to a contact"""
pass
@model.tool
def set_alarm(time: str, label: str = "Alarm"):
"""Set an alarm for a specific time"""
pass
@model.tool
def play_music(song: str = None, genre: str = None, shuffle: bool = False):
"""Play music with optional filters"""
pass
# Testa
response = model("manda mensagem pro João dizendo que chego em 10 minutos")
print(response)
# {"function": "send_message", "contact": "João", "text": "chego em 10 minutos"}
O código está no GitHub com licença Apache 2.0 (o modelo base) e MIT (o código). Os pesos estão no Hugging Face.
Pra quem quer ir além do protótipo, o fluxo de fine-tuning + deploy como binário C++ é o caminho. Gera dados sintéticos, treina, compila, e deploya um único arquivo sem dependências.
O que esperar daqui pra frente
A Cactus Compute está num ponto interessante. Provaram que tool calling não precisa de modelos gigantes. Mostraram que 45M de parâmetros, bem treinados e bem quantizados, competem com modelos de 270M a 2.6B.
As limitações são reais: linguagem natural ambígua ainda quebra o modelo, o confidence scoring precisa de calibração melhor, e o fine-tuning é praticamente obrigatório pra qualquer deployment sério. Mas pra quem trabalha com IoT, automação, ou qualquer cenário onde latência e privacidade importam mais que versatilidade, o Needle2 é a ferramenta certa pro trabalho.
Quarenta e cinco milhões de parâmetros. Quatorze megabytes. Quinhentos tokens por segundo num Raspberry Pi. Às vezes, menor realmente é melhor.
Fonte de inspiração: Needle 2 – Cactus Compute













