CoolFace
Modelpublic

neoemu/parakeet-tdt-0.6b-v3-ptBR-coreml

sourceHugging Facecc-by-4.0updated 1mo agoView on Hugging Face
0likes10downloads
Model Card

Parakeet TDT 0.6B v3 pt-BR — CoreML (FluidAudio)

Conversão para CoreML do fine-tune em português brasileiro do Parakeet TDT 0.6B v3, no formato de artefatos que a FluidAudio consome. Roda na Neural Engine de Apple Silicon.

Atribuição

Este modelo é um trabalho derivado em três camadas, todas sob CC-BY-4.0:

  1. 1.Modelo base: `nvidia/parakeet-tdt-0.6b-v3` — NVIDIA
  2. 2.Fine-tune pt-BR: `alexandreacff/parakeet-tdt-0.6b-v3-ptBR` — checkpoint parakeet-tdt-0.6b-v3-datasets-ptbr-e-podcasts.nemo
  3. 3.Conversão para CoreML: scripts de `FluidInference/mobius` (models/stt/parakeet-tdt-v3-0.6b/coreml)

Nenhum peso foi retreinado aqui. O trabalho desta publicação é a conversão e a validação.

Conteúdo

arquivotamanhoobservação
Encoder.mlmodelc568 MBquantizado int8-linear por canal
Decoder.mlmodelc23 MB
JointDecisionv3.mlmodelc12 MBvariante single step, com saídas top_k_ids/top_k_logits
Preprocessor.mlmodelc620 KBshape flexível (1..240000 amostras)
parakeet_vocab.json135 KB8192 tokens, marcador ▁ já convertido em espaço

Total: 603 MB.

Uso

swift
import FluidAudio

// O caminho precisa TERMINAR em `parakeet-tdt-0.6b-v3`:
// AsrModels.load(from:) remove o último componente e o reanexa a partir do repo.
let models = try await AsrModels.load(from: directory, version: .v3, encoderPrecision: .int8)
let manager = AsrManager(config: .default)
try await manager.loadModels(models)

Medições

Corpus próprio de reuniões reais em pt-BR: 13 fatias, 57,5 min, 5.355 palavras de referência revisada por humano, 10 reuniões distintas, canais de áudio de sistema e de microfone. O corpus não é público (contém fala de terceiros).

motorWER agregadoWER holdoutRTFx
este modelo (CoreML, int8)16,53%17,71%421
mesmo checkpoint em ONNX (onnx-asr)18,65%21,16%~25
WhisperKit large-v3-turbo (CoreML)19,80%23,08%7
parakeet-tdt-0.6b-v3 base (CoreML)23,51%—274

Pico de memória: 176 MB. WER normalizada (NFKC, minúsculas com locale pt-BR, equivalência de variantes numéricas).

Duas ressalvas honestas sobre esses números:

  • —As referências foram revisadas por humano a partir de rascunhos gerados por um modelo desta mesma família, o que enviesa a comparação a favor deste modelo. A vantagem real é, portanto, menor ou igual à medida.
  • —A comparação com o ONNX usa segmentação de áudio longo diferente (VAD externo contra o janelamento interno da FluidAudio). Parte da diferença é do janelamento, não do modelo.

Limitações conhecidas

  • —Só português. O modelo base é multilíngue (25 idiomas); este fine-tune não é. Áudio em inglês não degrada — ele volta transcrito como português fonético, com confiança: "We deployed the new cluster last week and the team is monitoring the error rate closely" volta como "Nós amplamos uma cluster na noite e o teu teatro está monitorando a área constante". O mesmo áudio no modelo base sai perfeito. Não use com detecção automática de idioma; use só quando o idioma for sabidamente pt-BR.
  • —Jargão técnico: erra nomes de domínio ("Kubernetes" → "gubernetes"). Mitigável com o CTC vocabulary boosting da FluidAudio, não testado em pt-BR.
  • —Pontuação depende do modo: em áudio curto (ditado) o modelo pontua e capitaliza normalmente; no caminho de áudio longo da FluidAudio (janela deslizante) a saída volta sem pontuação nenhuma. Medido nos dois modos; a causa não foi investigada.
  • —Ao carregar, o runtime emite E5RT ... slice_by_index: zero shape error; não impede o funcionamento e não foi investigado.

Reprodução

Ambiente exato importa: com numpy 2.x a conversão falha em "only 0-dimensional arrays can be converted to Python scalars". Use o uv.lock do mobius (Python 3.10.12, torch 2.7.0, numpy 1.26.4, coremltools 9.0b1).

bash
uv sync --frozen
python convert-parakeet.py --nemo-path <checkpoint.nemo> --output-dir out/
python quantize_coreml.py --input-dir out/ --output-root quant/ -c linear -m encoder
xcrun coremlcompiler compile quant/int8-linear/parakeet_encoder.mlpackage compiled/

O JointDecisionv3.mlmodelc vem de parakeet_joint_decision_single_step.mlpackage (entradas encoder_step/decoder_step), não de parakeet_joint_decision.mlpackage. O vocabulário sai de model.joint.vocabulary com o marcador ▁ trocado por espaço.