PT

Executar o Whisper no Mac: legendas sem passar pela nuvem

Como executamos o Whisper no Mac com WhisperKit e Core ML: porquê no dispositivo, que modelo escolhemos, os 3 minutos do primeiro carregamento, o disco e o idioma.

Nicolas Ricardi8 min de leitura

Em resumo

  • O JustRec cria as legendas com o Whisper a correr no Mac através do WhisperKit, por isso a sua voz nunca sai do computador.
  • Usamos uma build Core ML comprimida do Whisper large-v3 turbo com cerca de 626 MB, descarregada uma vez.
  • O primeiro carregamento demorou cerca de três minutos e muito espaço temporário em disco, porque o Core ML especializa o modelo para o seu chip; depois disso carrega em segundos.
  • A transcrição começa a partir da faixa do microfone assim que carrega em parar, em paralelo com a exportação do vídeo.

Pode executar o Whisper num Mac totalmente no dispositivo: os pesos do modelo são open source, e o WhisperKit corre-os através do Core ML em Apple Silicon. É assim que o JustRec cria legendas para cada gravação sem enviar um segundo de áudio a ninguém. A seguir: como o configurámos, que modelo escolhemos e o que nos surpreendeu (uma transferência de 626 MB, um primeiro carregamento de cerca de três minutos e, uma vez, um disco cheio).

Porque é que as legendas tinham de correr no Mac

A promessa da nossa página inicial é simples: a sua voz nunca é enviada para uma IA externa. Os nossos utilizadores gravam trabalho para clientes: uma revisão de design com nomes no ecrã, um orçamento explicado linha a linha, um bug no painel de administração de um cliente. Enviar esse áudio para uma API de transcrição significaria mais uma empresa a tratar dados dos clientes deles, mais uma linha numa política de privacidade e mais uma coisa para explicar a um cliente cuidadoso. Manter a voz no Mac encaixa no resto do produto, que é local-first e guarda as cópias partilhadas na UE.

Também havia razões práticas:

  • Sem custo por minuto. Uma API na nuvem cobra cada minuto de áudio. No Mac, o custo é a eletricidade do utilizador.
  • Funciona offline. Depois de descarregar o modelo, as legendas funcionam num comboio.
  • Legendas antes do carregamento. A transcrição pode começar no momento em que carrega em parar, enquanto o vídeo ainda está a ser exportado.

Escrevemos uma comparação mais longa e não técnica em transcrição local ou na nuvem. Este artigo é o lado da engenharia.

WhisperKit e Core ML

O Whisper é o modelo de reconhecimento de fala da OpenAI, publicado com o código e os pesos sob a licença MIT. Trata do reconhecimento de fala multilingue e da identificação do idioma, que é o que precisamos para legendas na língua em que fala.

Para o correr bem num Mac, precisa dele em formato Core ML, para poder usar o Neural Engine e a GPU. Usamos o WhisperKit, parte do SDK Swift open source da Argmax (licença MIT). Descarrega builds Core ML do Whisper a partir do Hugging Face, guarda-as em cache localmente e dá-lhe uma API Swift para transcrição com timestamps por palavra e deteção de atividade de voz. Exige o macOS 14, abaixo do nosso mínimo de macOS 15.

Também olhámos para o SpeechAnalyzer da própria Apple. É promissor, mas precisa do macOS 26, e o JustRec suporta o macOS 15. O WhisperKit corre em todo o lado onde a nossa app corre.

Escolher o modelo

O Whisper existe em vários tamanhos, e o compromisso é o do costume: modelos maiores são mais precisos e mais lentos. A tabela da própria OpenAI:

Tamanhos do modelo Whisper, tal como a OpenAI os publica
Tamanho Parâmetros Memória necessária Velocidade relativa
tiny 39 M cerca de 1 GB cerca de 10x
base 74 M cerca de 1 GB cerca de 7x
small 244 M cerca de 2 GB cerca de 4x
medium 769 M cerca de 5 GB cerca de 2x
large 1550 M cerca de 10 GB 1x
turbo 809 M cerca de 6 GB cerca de 8x

Do README de openai/whisper, consultado em novembro de 2026. A velocidade relativa compara os modelos entre si, não com um Mac.

O turbo é a linha interessante: perto do modelo large, com cerca de metade dos parâmetros e muitas vezes a velocidade. Num Mac, porém, não descarrega estes checkpoints PyTorch. Descarrega uma conversão Core ML, e a Argmax publica muitas variantes. Algumas do repositório deles, com o tamanho de cada transferência:

Algumas builds Core ML do Whisper da Argmax
Variante Tamanho da transferência Notas
small cerca de 216 MB Rápido e leve; menos preciso
distil-large-v3 cerca de 594 MB Modelo large destilado
large-v3-v20240930 (turbo) cerca de 547 MB ou 626 MB Duas builds comprimidas do large-v3 turbo
large-v3 cerca de 947 MB O modelo large completo

Tamanhos do repositório argmaxinc/whisperkit-coreml no Hugging Face, consultado em novembro de 2026.

Usamos o large-v3-v20240930_626MB. O nome v20240930 corresponde à versão em que a OpenAI acrescentou o large-v3 turbo, que a OpenAI descreve como uma versão otimizada do large-v3, com transcrição mais rápida e perda mínima de precisão. A configuração confirma o truque: o encoder completo de 32 camadas, mas só 4 camadas no decoder.

Porquê este? Precisávamos que o italiano saísse bem, não só o inglês, e com este modelo o italiano estava correto nos nossos testes. No nosso Mac de desenvolvimento, transcreveu cerca de 15 segundos de áudio em 3 segundos. É também o modelo que a Argmax usa nos exemplos do seu próprio README.

O custo é o tamanho: 626 MB é muito para pedir a uma app que, de resto, é pequena. Descarregamo-lo uma vez, para a pasta Application Support da app, e dizemos ao utilizador o que está a acontecer.

O primeiro carregamento: três minutos e um disco cheio

A transferência não foi a parte lenta. Da primeira vez que carregámos o modelo, demorou cerca de três minutos até transcrever o que quer que fosse, e usou muito espaço temporário em disco. Uma vez, encheu o disco.

  1. Primeiro carregamento

    Cerca de três minutos até à primeira palavra

    Mais muito espaço temporário em disco. Uma vez, encheu o disco.

  2. A causa

    Especialização do Core ML

    O modelo é compilado para o seu chip no primeiro carregamento e guardado em cache fora da app.

  3. A mudança

    Carregá-lo durante a configuração

    O modelo é descarregado e carregado uma vez durante a configuração inicial, por isso a espera acontece antes da primeira gravação.

A própria documentação do WhisperKit explica porquê. Os modelos Core ML são descarregados num formato independente do dispositivo e têm de ser «especializados» para o seu chip antes de correr. O Core ML faz isto da primeira vez que o modelo carrega e guarda os ficheiros especializados em cache no disco, fora da app. É a Apple que gere essa cache, e ela é apagada depois de cada atualização do sistema ou se o modelo não for usado durante muito tempo. Quando a cache é aproveitada, o carregamento demora segundos: cerca de 3 segundos no nosso caso.

O que mudámos depois de perceber isto:

  1. Preparar o modelo durante a configuração inicial. Enquanto dá as permissões e escolhe um atalho, o JustRec descarrega o modelo, carrega-o uma vez e depois liberta-o. Os três minutos acontecem antes da sua primeira gravação, não depois.
  2. Mostrar o progresso. A transferência mostra o progresso, para que uma primeira transferência grande não pareça uma app bloqueada.
  3. Contar com isto outra vez depois das atualizações do macOS. Como a cache pode ser limpa, a primeira transcrição depois de uma atualização pode voltar a ser lenta. É normal.
  4. Deixar espaço em disco. Se o seu Mac está quase cheio, é no passo de especialização que vai senti-lo.

Da gravação ao ficheiro de legendas

O processo é curto, e a maior parte do trabalho está nos pormenores.

O áudio da faixa certa. Gravamos o microfone e o áudio do sistema em ficheiros separados (o artigo sobre o ScreenCaptureKit explica porquê). Para as legendas usamos só o microfone, ou o áudio do sistema se não houver microfone. Assim, não há sons de notificações nem bandas sonoras de vídeos a confundir o modelo, e a transcrição pode começar logo em vez de esperar pelo MP4 exportado.

16 kHz mono. O Whisper espera áudio mono a 16 kHz. Lemos a faixa com um AVAssetReaderAudioMixOutput que converte à medida que lê. Se uma gravação tem várias partes de microfone (mudou de microfone a meio), são colocadas nas suas horas reais de início e as falhas são preenchidas com silêncio, para que os timestamps fiquem alinhados com o vídeo.

let options = DecodingOptions(
    language: code,               // nil significa "detetar"
    detectLanguage: code == nil,
    skipSpecialTokens: true,
    wordTimestamps: true,
    chunkingStrategy: .vad        // dividir pela atividade de voz
)
let results = try await pipe.transcribe(audioArray: samples, decodeOptions: options)

Dos timestamps das palavras a legendas legíveis. Os segmentos do Whisper são muitas vezes demasiado longos para uma legenda. Pedimos timestamps por palavra e reconstruímos as legendas nós próprios: no máximo 84 caracteres e 6 segundos por legenda, uma quebra depois de um ponto final ou de um ponto de interrogação quando a linha já tem algum comprimento, e duas linhas equilibradas em comprimento. As legendas que se sobrepõem são cortadas, para que nunca apareçam duas ao mesmo tempo.

Dois ficheiros ao lado do vídeo. O resultado é guardado em SRT e VTT, ao lado do MP4 na sua biblioteca. Quando partilha, o VTT vai com o vídeo; se as legendas ficarem prontas depois do carregamento, são acrescentadas ao link quando estiverem prontas. As primeiras palavras também passam a ser o título sugerido do vídeo.

Se quer fazer o mesmo nas suas gravações com qualquer ferramenta, o nosso guia para adicionar legendas a uma gravação de ecrã no Mac percorre as opções.

Deteção do idioma

Nas Definições, as legendas podem ficar em automático, italiano ou inglês. Em automático, o Whisper identifica o idioma antes de transcrever, e registamos o que detetou. Funciona para as línguas que o JustRec suporta, incluindo inglês, italiano, espanhol, francês, alemão e português, o que conta para as agências que trabalham além-fronteiras.

A deteção automática tem os pontos fracos do costume: gravações muito curtas, gravações que começam em silêncio ou alguém que muda de língua a meio. Se fala sempre a mesma língua, defina-a à mão e o palpite desaparece.

O que diríamos a outro programador

Lançar o Whisper numa app para Mac

  • Escolha o modelo pelas línguas dos seus utilizadores, não pelos benchmarks em inglês.
  • Conte com o primeiro carregamento: transferência, depois especialização do Core ML, depois o trabalho a sério.
  • Faça esse primeiro carregamento durante a configuração inicial, com o progresso visível.
  • Transcreva a faixa de áudio mais limpa que tiver, não a mistura final.
  • Construa as suas legendas a partir dos timestamps das palavras; os segmentos em bruto leem-se mal.
  • Teste com pouco espaço em disco e depois de uma atualização do macOS.

O que vem a seguir

As legendas traduzidas estão previstas: a transcrição fica no Mac, e a tradução também ficaria. Também estamos de olho no SpeechAnalyzer da Apple para o dia em que o nosso macOS mínimo o permitir.

Para perceber porque é que as legendas importam a quem vê, leia legendas para vídeos: vistos mesmo com o som desligado. Para tudo o resto que a app faz, a lista de funcionalidades tem tudo num só sítio.

Fontes

Perguntas frequentes

É possível executar o Whisper num Mac sem a nuvem?

Sim. Os pesos do Whisper são open source, com licença MIT, e bibliotecas como o WhisperKit convertem-nos para Core ML para correrem localmente em Apple Silicon. Depois de o modelo ser descarregado uma vez, a transcrição não precisa de ligação à internet.

Que tamanho tem o modelo Whisper?

Depende da variante. Entre as builds Core ML da Argmax, o small tem cerca de 216 MB e o large-v3 completo cerca de 947 MB. O JustRec usa uma build comprimida do large-v3 turbo com cerca de 626 MB.

Porque é que o primeiro carregamento do Whisper é tão lento num Mac?

Da primeira vez que o modelo é carregado, o Core ML especializa-o para o seu chip concreto e guarda o resultado em cache no disco. Com o nosso modelo, isso demorou cerca de três minutos. Os carregamentos seguintes usam a cache e demoram poucos segundos, até uma atualização do macOS a limpar.

O Whisper deteta o idioma automaticamente?

Sim, o Whisper consegue identificar o idioma falado antes de transcrever. Se fala sempre a mesma língua, defini-la à mão evita um ou outro palpite errado em gravações curtas ou com várias línguas.

O JustRec envia a minha voz para um serviço de IA?

Não. As legendas são geradas no seu Mac por um modelo de conversão de voz em texto que corre localmente. Só o ficheiro de legendas é carregado com o vídeo quando o partilha.

Escrito por

Nicolas Ricardi

Maker of JustRec, at Nube

Nicolas makes JustRec at Nube, a web studio in Italy. He built it for the videos Nube sends to its own clients: design reviews, handovers and quotes explained in a few minutes instead of a meeting.

www.wearenube.dev
Nos bastidores