Como funciona
Transcrever áudio com Whisper, dentro do seu navegador
A página roda um modelo aberto de reconhecimento de fala, o Whisper, dentro da aba do seu navegador, então quem faz o trabalho é o seu dispositivo e o seu arquivo nunca é enviado. Com o seu primeiro arquivo, ela baixa deste site um motor e o modelo, e o navegador guarda o modelo para os próximos arquivos quando tem espaço.
Três passos, todos dentro do seu navegador
1. Seu navegador lê o arquivo
Onde o arquivo pode ser lido em partes, um worker da sua aba pega a faixa de som 30 segundos por vez; senão, a página decodifica o arquivo inteiro de uma vez. De todo modo, o som vira o mono a 16 kHz que o modelo espera.
2. O Whisper transcreve em janelas
O motor, whisper.cpp compilado para WebAssembly, transcreve uns três minutos de som por vez e entrega à página o texto de cada janela.
3. A página organiza o texto
As palavras são agrupadas em parágrafos nas pausas, com uma marcação de tempo em cada um se você quiser, prontas para pesquisar, copiar ou salvar em TXT.
O modelo: Whisper, base ou small
O Whisper é um modelo de reconhecimento de fala que a OpenAI publicou em 2022, com código e pesos sob a licença MIT. Ele escuta o som em trechos de 30 segundos e escreve as palavras, com os tempos de cada segmento. Este site oferece dois tamanhos:
- O modelo menor (o padrão) é o Whisper base no formato de quantização de 5 bits do whisper.cpp (q5_1). É o download mais leve.
- O modelo maior é o Whisper small no formato de 8 bits (q8_0): um download maior, que precisa de mais memória.
A quantização arredonda os pesos do modelo para menos bits, o que deixa os arquivos menores. Ainda não publicamos como os dois tamanhos se comparam neste motor, idioma por idioma: primeiro medimos, depois descrevemos. O menu de idiomas lista os idiomas que podem ser indicados ao Whisper; na detecção automática, o motor escolhe o idioma na primeira janela que tem fala e mantém para o resto do arquivo.
O motor: whisper.cpp compilado para WebAssembly
O modelo roda no whisper.cpp, uma versão de código aberto do Whisper escrita em C/C++, que compilamos para WebAssembly (um formato de programa que qualquer navegador atual executa) com uma pequena interface nossa. Existem três versões, e a página tenta nesta ordem:
- WebGPU, se o seu navegador oferece um adaptador gráfico com os recursos que o motor precisa. Ainda não medimos essa versão em uma placa de vídeo de verdade, então não afirmamos nada sobre ela.
- WebAssembly em várias threads, uma por núcleo lógico que o navegador informa. As threads exigem que a aba esteja isolada de outras origens, e os cabeçalhos do site garantem isso.
- WebAssembly em uma thread, quando não há threads disponíveis ou o navegador informa um único núcleo lógico. O resultado é do mesmo tipo.
Se uma versão não inicia, ou se a versão WebGPU falha no meio do trabalho, a página reinicia o motor na versão seguinte e continua. A linha acima da transcrição mostra qual versão fez o trabalho.
O que a página baixa, e quando
Ao abrir a página, só são baixados a página e os arquivos dela. O motor, o leitor de mídia, um modelo e o detector de voz chegam deste site quando você adiciona o primeiro arquivo. Só uma versão do motor é mantida: a versão WebGPU toma o lugar de uma versão de CPU quando inicia com um dispositivo de GPU. Os tamanhos estão em MB, e 1 MB são 1.000.000 de bytes:
| Arquivo | Tamanho | Quando |
|---|---|---|
| Motor, versão WebGPU | cerca de 3,4 MB | Seu primeiro arquivo, tentada primeiro quando o navegador oferece um adaptador WebGPU utilizável |
| Motor, versão de CPU: com várias threads ou com uma thread (uma das duas) | cerca de 1,5 MB | Seu primeiro arquivo, a menos que a versão WebGPU inicie com um dispositivo de GPU; e sempre que a versão WebGPU falhar durante o trabalho |
| Modelo menor (Whisper base, formato de 5 bits), o padrão | 59,7 MB em 3 partes | Seu primeiro arquivo com ele |
| Modelo maior (Whisper small, formato de 8 bits) | 264,5 MB em 13 partes | Só se você escolher |
| Detector de voz (Silero VAD) | 0,9 MB | Seu primeiro arquivo |
| Leitor de mídia (Mediabunny), parte dos scripts da página | cerca de 0,3 MB | Seu primeiro arquivo |
Os modelos chegam em partes de no máximo 20 MiB (um MiB são 1.048.576 bytes, então 20 MiB são uns 21 MB), porque a hospedagem não serve nenhum arquivo acima de 25 MiB. Antes de o motor usar uma parte, o navegador confere a impressão digital SHA-256 dela, então um download corrompido é recusado em vez de gerar uma transcrição errada. As partes verificadas ficam no Cache Storage do navegador quando ele tem espaço para elas, e assim o próximo arquivo, e a próxima visita, não baixam de novo.
Por que sua gravação nunca é enviada
Cada passo acontece dentro da sua aba, o site não tem nenhum endereço que possa receber um arquivo e a página só pode se conectar a este site. A verificação de que sua gravação não é enviada fica na página de privacidade e segurança, com os passos para você mesmo acompanhar as requisições.
Como um arquivo longo é lido e transcrito
Uma gravação de uma hora ocupa uns 115 MB de som depois de decodificada em mono a 16 kHz (3.600 segundos x 16.000 amostras x 2 bytes, ou o dobro nos números de 32 bits com que o motor trabalha). Por isso, onde o arquivo pode ser lido em partes, a página não decodifica o arquivo inteiro de uma vez. Um segundo worker abre o arquivo com o Mediabunny e lê a faixa de som 30 segundos por vez: o Mediabunny decodifica o som comprimido com o decodificador do próprio navegador, e o som sem compressão, como o de um arquivo WAV, ele mesmo. O worker só entrega o pedaço seguinte quando o motor está pronto para ele.
Os pedaços se juntam em janelas de uns três minutos. Cada janela termina no centro do meio segundo mais silencioso dos 15 segundos antes da marca de três minutos, para pôr o corte numa pausa e não dentro de uma palavra, e as janelas se seguem sem buracos nem sobreposição. Um pequeno detector de voz marca os trechos com fala de cada janela, e assim o modelo pula o silêncio em vez de escrever palavras por cima dele. Cada janela é transcrita com as últimas palavras antes dela, no máximo 200 caracteres, como contexto (prompt), com a intenção de dar ao modelo a frase que o corte pode ter partido, e os tempos voltam para o relógio do arquivo.
Quando uma janela termina, os parágrafos dela aparecem na página, então você já pode ler e pesquisar enquanto o resto continua. Quando o arquivo não pode ser lido em partes, porque o Mediabunny não abre o contêiner dele ou porque o seu navegador não tem um decodificador que leia o som dele em partes, a página decodifica o arquivo inteiro de uma vez com o decodificador do próprio navegador, sem o Mediabunny, e aí recusa os que passam de 500 MB ou de 1 hora.
Como os parágrafos e as marcações de tempo são feitos
O Whisper devolve segmentos de texto com tempo de início e de fim, e um tempo para cada palavra. A página junta esses segmentos em parágrafos: um novo começa numa pausa de 2 segundos ou mais, medida pelos tempos das palavras de cada lado, e um parágrafo que passa de uns 600 caracteres termina no próximo fim de frase. Não há identificação de falantes, então uma quebra de parágrafo indica uma pausa ou um trecho longo de fala, nunca uma troca de voz.
A marcação de tempo de um parágrafo é o tempo de início da primeira palavra, escrito como [hh:mm:ss] e arredondado para baixo no segundo. Ela é aproximada: serve para achar um trecho na gravação, não para legendas. Copiar o texto e Baixar TXT escrevem os mesmos parágrafos, separados por uma linha em branco e com as marcações de tempo quando elas estão visíveis.
Por que o tempo varia
Quem faz o trabalho é o seu dispositivo, na versão que a página conseguiu iniciar, então o mesmo arquivo leva um tempo em um notebook novo e outro em um antigo, e o modelo e a duração da gravação também pesam. Por isso a página não promete velocidade. Assim que o motor informa o primeiro progresso, a página mede quantos segundos de trabalho cada segundo de som custa no seu dispositivo, suaviza isso entre as janelas para que um momento lento não distorça a conta, e mostra o tempo que falta.
O que o seu dispositivo precisa
- Um navegador atual com WebAssembly. Chrome, Edge, Firefox e Safari têm; nosso teste automático roda no Chromium.
- Memória livre: o motor mantém o modelo na memória enquanto roda, e o modelo maior precisa de mais. Não damos nenhum número antes de medir.
- Conexão em toda visita: a página precisa dela para abrir, e o seu primeiro arquivo também baixa o motor e o modelo. Não há modo offline. Quando o navegador tem espaço, ele guarda o modelo, e os próximos arquivos e visitas pulam esse download.
Os componentes de código aberto do motor, os modelos e o leitor de mídia aparecem com suas licenças na página de créditos.
Perguntas sobre o motor
É o mesmo Whisper que a OpenAI publicou?
É o mesmo modelo: a OpenAI publicou o código e os pesos do Whisper sob a licença MIT. Esta página usa esses pesos no formato de arquivo do projeto de código aberto whisper.cpp, quantizados (guardados com menos bits por peso) para o download ficar menor. O motor é o whisper.cpp compilado para WebAssembly, não o código Python da OpenAI, e nenhuma requisição vai para a OpenAI.
Ele usa minha placa de vídeo?
Ele tenta. Se o seu navegador oferece WebGPU com os recursos que o motor precisa, a página baixa e inicia primeiro a versão WebGPU. Se essa versão não registra nenhum dispositivo de GPU, não inicia ou falha durante o trabalho, a página baixa uma versão de CPU e continua com ela. Nossas máquinas de teste não têm GPU utilizável, então a versão WebGPU real nunca rodou em uma GPU nos nossos testes: a passagem para uma versão de CPU é testada com falhas de WebGPU simuladas, e nessas máquinas a página vai direto para uma versão de CPU. A linha acima da transcrição mostra qual versão fez o trabalho.
Por que o modelo foi baixado de novo?
Seu navegador guarda o modelo no Cache Storage deste site até você apagar os dados do site, ou até o próprio navegador apagar para liberar espaço. Depois disso, o próximo arquivo baixa o modelo de novo. O que o seu navegador guarda e como apagar explica em detalhes.
O que acontece quando eu clico em Cancelar?
A página para o motor na hora, fechando o worker em que ele roda, e descarta os parágrafos feitos até ali. O próximo arquivo inicia um motor novo e pega o modelo do armazenamento do navegador, onde o navegador o guardou quando tinha espaço, então o modelo não é baixado de novo.
Fontes
- OpenAI, repositório do Whisper: O código do modelo, a licença MIT e a tabela de tamanhos (base e small).
- Radford et al., Robust Speech Recognition via Large-Scale Weak Supervision (2022): O artigo que apresenta o Whisper.
- whisper.cpp: A versão em C/C++ do Whisper que o motor compila para WebAssembly (versão 1.9.4, com uma linha acrescentada na versão do motor com várias threads, indicada na página de créditos), e seus arquivos de modelo quantizados.
- Silero VAD: O detector de atividade de voz que encontra os trechos com fala.
- Mediabunny: A biblioteca de mídia que lê o seu arquivo em partes quando consegue, decodificando o som comprimido com o decodificador do navegador e o som sem compressão ela mesma.
- MDN, AudioDecoder (WebCodecs): O decodificador do próprio navegador, que transforma o som comprimido em amostras.
- MDN, CacheStorage: Onde as partes verificadas do modelo ficam guardadas entre visitas.
- web.dev, Making your website cross-origin isolated using COOP and COEP: Por que o site envia esses cabeçalhos: as threads de WebAssembly precisam de SharedArrayBuffer.
- Cloudflare Workers, Limits: O limite de 25 MiB por arquivo estático, o motivo de os modelos chegarem em partes.
Teste com uma gravação
A transcrição acontece no seu navegador. Seu arquivo nunca sai do seu dispositivo.