Eu lembro a primeira vez que rodei o Whisper da OpenAI no meu notebook. Foram uns bons segundos de espera, a ventoinha ligou, e o modelo “base” já pedia 145 MB só de pesos. Funcionou? Funcionou. Mas nunca me pareceu algo que eu pudesse jogar dentro de um smartwatch ou rodar no navegador sem pensar duas vezes.
A Cactus Compute resolveu esse problema de um jeito que beira o absurdo: um modelo de speech-to-text que ocupa 16.9 MB, roda em CPU pura, não tem dependência externa e ainda bate o Whisper base em vários benchmarks. O nome é Whistle, e desde que apareceu no Hacker News a comunidade dev não parou de falar sobre ele.
O que é o Whistle (e por que 16.9 MB impressiona tanto)
Whistle é um modelo de reconhecimento automático de fala (ASR) criado pela Cactus Compute. Ele faz três coisas:
- Transcreve áudio em 16 kHz mono (até 30 segundos por passada)
- Retorna timestamps por palavra, com scores de probabilidade
- Gera embeddings de fala (uma saída do encoder a cada 80ms)
Tudo isso num único arquivo .cact de 16.9 MB. Pra dar contexto: o Whisper base da OpenAI ocupa 145.3 MB. O Moonshine Tiny v2, que já era considerado pequeno, pesa 41.9 MB. O Whistle é 8.6x menor que o Whisper base.
E não estamos falando de um modelo que sacrificou tudo em nome do tamanho. A taxa de erro de palavras (WER) do Whistle lidera em datasets como LibriSpeech test-clean, LibriSpeech test-other, SPGISpeech, Earnings-22 e na média do FLEURS. Ele fica atrás do Whisper base em TED-LIUM, AMI e na média do MLS, mas o trade-off é ridiculamente favorável quando você olha pra diferença de tamanho.
Os números que fazem o Whisper parecer lento
Vou jogar os benchmarks na mesa porque eles falam por si:
| Métrica | Whistle (16.9 MB) | Whisper Base (145.3 MB) | Moonshine Tiny v2 (41.9 MB) |
|---|---|---|---|
| Time to first token (M4 Pro CPU) | 11.1 ms | 73.2 ms | 22.8 ms |
| Velocidade de decode | 1.319 tokens/s | 266 tokens/s | 262 tokens/s |
| Tamanho do modelo | 16.9 MB | 145.3 MB | 41.9 MB |
Olha esses números com calma. O Whistle chega ao primeiro token em 11.1 milissegundos. O Whisper base demora 73.2 ms, quase 7 vezes mais. Na velocidade de decodificação, é goleada: 1.319 tokens por segundo contra 266 do Whisper. Isso é 5x mais rápido, rodando em CPU.
Esses testes foram feitos num Apple M4 Pro, sem GPU, sem acelerador neural. CPU pura. O modelo foi avaliado contra 86.174 utterances usando os normalizadores do Whisper, então a comparação é justa.
A arquitetura por trás dos 16.9 MB
Aqui é onde a coisa fica interessante pra quem gosta de entender o “como”. O Whistle não é simplesmente um Whisper comprimido. É uma arquitetura diferente, pensada desde o zero pra ser pequena e rápida.
Encoder: Simple Attention com Monarch Hadamard MLP
O encoder usa 8 blocos de Simple Attention. Até aí, nada revolucionário. O pulo do gato está no que substitui as redes feed-forward tradicionais: Monarch Hadamard MLPs.
Se você nunca ouviu falar de Monarch matrices, a ideia é decompor matrizes densas em produtos de matrizes esparsas estruturadas. O resultado prático? Você consegue representar transformações complexas usando muito menos parâmetros, sem perder capacidade expressiva de forma significativa. Combinadas com a transformação de Hadamard (que é computacionalmente barata, basicamente multiplicações e somas), essas camadas conseguem fazer o trabalho pesado com uma fração dos pesos.
Decoder: Laddered Attention com Cross-Attention Gated
O decoder tem 8 blocos de Laddered Attention com largura 512. Usa 8 query heads para 2 KV heads (grouped-query attention), o que reduz drasticamente a memória necessária durante a inferência. A conexão entre encoder e decoder acontece via gated cross-attention.
Esse design “laddered” (escalonado) significa que as camadas não são todas iguais. Cada profundidade pode funcionar como um modelo deployável independente, indo de 2 a 20 camadas. Pra o Whistle, escolheram 8 camadas como o sweet spot entre qualidade e tamanho.
Quantização: 2.125 bits por peso
Sim, você leu certo. Enquanto a maioria dos modelos usa quantização de 4 ou 8 bits, o Whistle opera a 2.125 bits por peso usando o formato proprietário “Cactus Quants”. São técnicas de quantização extrema que a Cactus Compute desenvolveu internamente.
Pra comparar: um modelo float32 usa 32 bits por peso. O Whistle usa 2.125. Isso é uma compressão de 15x apenas na quantização, antes de contar os ganhos arquiteturais.
Beam Search com Keyword Biasing
O sistema de decodificação usa beam search com 5 beams e um recurso particularmente útil: keyword biasing via autômato de Aho-Corasick. Na prática, isso significa que você pode fornecer uma lista de palavras-chave (nomes de produtos, termos técnicos, jargão do seu domínio) e o modelo vai priorizar essas palavras durante a transcrição.
Isso é um game-changer pra aplicações verticais. Imagina rodar speech-to-text num sistema médico e poder biasar o modelo pra reconhecer nomes de medicamentos corretamente. Ou num call center e priorizar o vocabulário da empresa. Com o Whisper, você precisa de post-processing ou fine-tuning. Com o Whistle, é um parâmetro na chamada.
7 idiomas, detecção automática
O Whistle suporta sete idiomas: inglês, alemão, francês, espanhol, italiano, holandês e polonês. A detecção de idioma é automática, então você não precisa especificar qual língua está sendo falada.
“Mas e o português?”
Boa pergunta. Não está na lista. Pra quem precisa de transcrição em pt-BR, o Whisper ainda é a escolha óbvia por cobrir 99 idiomas. Mas se o seu caso de uso envolve qualquer um dos sete idiomas suportados e você precisa de velocidade, tamanho reduzido ou execução offline, o Whistle é imbatível.
A Cactus Compute já sinalizou que mais idiomas estão no roadmap. Considerando que o modelo treina em datasets do FLEURS (que cobre dezenas de línguas), é questão de tempo até vermos expansão.
Na prática: como usar o Whistle
A instalação é direta via pip:
pip install cactus-needle
E a transcrição mais simples do mundo:
import needle
result = needle.transcribe("audio.wav")
print(result["text"])
Pronto. Duas linhas. Se você quer timestamps por palavra:
import needle
result = needle.transcribe("audio.wav")
for word in result["words"]:
print(f"{word['text']} [{word['start']:.2f}s - {word['end']:.2f}s] (prob: {word['probability']:.2f})")
Via CLI também funciona:
needle --model whistle.cact --audio clip.wav
E aqui é onde o design da Cactus Compute brilha: o Whistle roda dentro do mesmo engine C++ do Needle, o modelo de texto da empresa. O mesmo binário pode carregar um .cact de fala ou de texto. Isso significa que você pode construir um pipeline onde o áudio entra, é transcrito pelo Whistle, e o texto resultante vai direto pro Needle processar tool calls ou extrair dados estruturados. Tudo local, tudo em CPU, tudo em menos de 50 MB.
import needle
@needle.tool
def agendar_reuniao(data: str, participantes: list):
"Agenda uma reunião com os participantes na data especificada."
return {"status": "agendado", "data": data}
agent = needle.Needle(tools=[agendar_reuniao])
# Transcreve o áudio
texto = needle.transcribe("comando_voz.wav")["text"]
# Processa com o agente
resultado = agent.run(texto)
print(resultado["results"])
De voz pra tool call em milissegundos. Sem servidor, sem API, sem internet.
17 plataformas suportadas (incluindo RISC-V e WASI)
A lista de plataformas onde o Whistle roda é impressionante:
- macOS (ARM64)
- Linux (ARM64, x86_64)
- Windows (ARM)
- Android
- iOS
- watchOS
- Browser (WebAssembly)
- WASI Components
- RISC-V
- MIPS
Isso não é uma lista teórica. O Needle (engine que roda o Whistle) tem binários pré-compilados pra cada plataforma. Você pode gerar o executável específico com:
needle build --platform macos-arm64
O suporte a watchOS e browser é particularmente relevante. Imagina um Apple Watch fazendo transcrição de voz localmente, sem mandar nada pro servidor. Ou uma aplicação web que transcreve áudio direto no navegador do usuário, sem nenhum dado saindo da máquina.
Pra cenários de privacidade (saúde, jurídico, financeiro), isso é ouro.
O ecossistema Cactus: quando voz e texto convergem
O Whistle não existe isolado. Ele faz parte do ecossistema Needle, que inclui:
| Componente | Função | Tamanho |
|---|---|---|
| Needle (texto) | Tool calls, extração JSON, embeddings | 8 a 29 MB |
| Whistle (fala) | Transcrição, timestamps, embeddings de áudio | 16.9 MB |
Os dois compartilham o mesmo formato de container (.cact), o mesmo engine C++ e o mesmo sistema de quantização. Um único binário pode carregar speech, text ou ambos.
A visão da Cactus Compute é clara: um modelo fundacional de automação pra dispositivos tiny. Pensa em robôs, carros, smart homes, microcontroladores. Dispositivos que não podem depender de internet ou de um GPU server na nuvem.
O Needle (modelo de texto) já se mostrou competitivo: supera modelos 10x maiores em benchmarks de tool-calling mobile e empata com modelos 2 a 3x maiores em extração de dados. Combinado com o Whistle, você tem um sistema completo de voz pra ação em menos de 50 MB.
Quando usar o Whistle (e quando não usar)
Vou ser direto:
Use o Whistle quando:
- Precisa de transcrição em um dos 7 idiomas suportados
- O dispositivo tem recursos limitados (sem GPU, pouca RAM)
- Latência é crítica (aplicações real-time, assistentes de voz)
- Privacidade é requisito (dados não podem sair do dispositivo)
- Precisa de keyword biasing pra vocabulário específico
- Quer integrar voz com tool calls ou processamento de texto local
Não use o Whistle quando:
- Precisa de suporte a português, japonês, mandarim ou qualquer idioma fora dos 7
- Trabalha com áudios muito longos (o limite é 30 segundos por passada)
- Precisa de diarização (quem falou o quê), o Whistle não faz isso
- O ambiente permite usar GPU e tamanho não é restrição. Nesse caso, modelos maiores como o Whisper large-v3 ainda são mais precisos
Whistle vs. Whisper vs. Moonshine: a comparação completa
Pra quem quer ver os números lado a lado nos benchmarks de WER (Word Error Rate, quanto menor melhor):
| Dataset | Whistle | Whisper Base | Moonshine Tiny v2 |
|---|---|---|---|
| LibriSpeech test-clean | Melhor | 3º | 2º |
| LibriSpeech test-other | Melhor | 3º | 2º |
| SPGISpeech | Melhor | 2º | 3º |
| Earnings-22 | Melhor | 2º | 3º |
| FLEURS (média) | Melhor | 2º | 3º |
| TED-LIUM | 3º | Melhor | 2º |
| AMI | 3º | 2º | Melhor |
| MLS (média) | 3º | Melhor | 2º |
O Whistle lidera em 5 dos 8 datasets. Perde em TED-LIUM (palestras longas com vocabulário acadêmico), AMI (reuniões com múltiplos falantes e ruído) e MLS (leitura de audiobooks em múltiplos idiomas). Faz sentido: esses são cenários que favorecem modelos maiores com mais contexto.
Mas repare no padrão. O Whistle domina nos datasets que refletem cenários reais de produção: conversas financeiras (Earnings-22), ditados claros (LibriSpeech), transcrições profissionais (SPGISpeech) e idiomas variados (FLEURS). Exatamente os casos de uso onde um modelo on-device precisa brilhar.
E tudo isso com um modelo que é literalmente do tamanho de uma foto de alta resolução. Cabe num POST request. Cabe no cache L3 de processadores modernos. Cabe em qualquer lugar.
O futuro da IA on-device
O Whistle é sintomático de uma tendência que acelerou muito em 2026: modelos cada vez menores rodando cada vez melhor em hardware cada vez mais limitado. Não é só a Cactus Compute. Vimos o Gemma 4 do Google rodando no Raspberry Pi, LLMs no navegador com WebGPU, modelos de 1-bit com 8 bilhões de parâmetros em 1 GB de RAM.
A narrativa de que “IA precisa de datacenter” está morrendo. E rápido.
O que torna o Whistle particularmente significativo é que ele não sacrifica usabilidade em nome do tamanho. A API é limpa, a integração com o Needle é transparente, o suporte a plataformas é amplo. É um produto, não um paper acadêmico que funciona só no notebook do pesquisador.
Os pesos estão disponíveis no Hugging Face sob licença Apache 2.0. O código-fonte do engine está no GitHub. Não tem pegadinha, não tem modelo freemium com feature lock. É open source de verdade.
Pra quem desenvolve aplicações de voz e sempre dependeu de APIs na nuvem ou modelos pesados: vale o teste. 16.9 MB, zero dependências, 11ms pro primeiro token. Esses são números que mudam o que é possível construir.
Fonte de inspiração: Whistle: Speech to Text in 16.9 MB (Cactus Compute)













