Views
No views yet
mlx-community/whisper-large-v3-mlx para Apple Silicon (MLX).
Se eliminaron 25 bloques Transformer (15 encoder + 10 decoder) partiendo de un estudio de ablación bloque a bloque sobre un corpus médico en español.| Original | Slim | |
|---|---|---|
| Encoder blocks | 32 | 17 |
| Decoder blocks | 32 | 22 |
| Parámetros | ~1.55 B | ~0.97 B |
weights.npz | ~3.1 GB | 1.97 GB |
n_mels | 128 | 128 |
n_vocab | 51866 | 51866 |
slim_metadata.json):[1, 2, 3, 4, 8, 9, 10, 11, 12, 13, 14, 15, 18, 19, 21][3, 7, 8, 11, 13, 18, 24, 26, 29, 30]⚠️ Este checkpoint es una poda one-shot agresiva SIN reentrenamiento posterior. Sirve como punto de partida para knowledge distillation o fine-tuning con LoRA. Sin recuperación, el WER colapsa — no usar en producción tal cual. Para un pipeline funcional, reentrena con destilación (teacher =whisper-large-v3) o LoRA sobre tu dominio.
pip install mlx>=0.22.0 mlx-whisper>=0.4.0 huggingface_hub numpy soundfile1from huggingface_hub import snapshot_download
2
3model_path = snapshot_download(repo_id="MrZeggers/whisper-slim-mlx")
4print(model_path)
5# ~/.cache/huggingface/hub/models--MrZeggers--whisper-slim-mlx/snapshots/<hash>hf download MrZeggers/whisper-slim-mlx --local-dir ./whisper-slim-mlxmlx-whispermlx_whisper.load_models.load_model lee config.json + weights.npz directamente:1from huggingface_hub import snapshot_download
2from mlx_whisper.load_models import load_model
3from mlx_whisper.tokenizer import get_tokenizer
4from mlx_whisper.audio import load_audio, pad_or_trim, log_mel_spectrogram
5import mlx.core as mx
6
7model_path = snapshot_download(repo_id="MrZeggers/whisper-slim-mlx")
8model = load_model(model_path)
9
10tokenizer = get_tokenizer(multilingual=True, language="es", task="transcribe")
11
12audio = load_audio("mi_audio.wav")
13audio = pad_or_trim(audio)
14mel = log_mel_spectrogram(audio, n_mels=128) # ¡128 mels!
15mel = mx.expand_dims(mel, 0) # [1, n_frames, 128]
16
17# Encoder
18audio_features = model.encoder(mel)
19
20# Decoder greedy
21sot = [tokenizer.sot, tokenizer.language_token, tokenizer.transcribe, tokenizer.no_timestamps]
22tokens = mx.array([sot])
23for _ in range(224):
24 logits = model.decoder(tokens, audio_features)
25 next_tok = mx.argmax(logits[:, -1, :], axis=-1, keepdims=True)
26 tokens = mx.concatenate([tokens, next_tok], axis=-1)
27 if next_tok.item() == tokenizer.eot:
28 break
29
30text = tokenizer.decode(tokens[0].tolist()[len(sot):-1])
31print(text)whisper-slim-mlx/
├── config.json # dims MLX (n_audio_layer=17, n_text_layer=22, n_mels=128)
├── weights.npz # pesos remapeados a los nuevos índices de bloque
├── slim_metadata.json # qué bloques se mantuvieron/eliminaron
└── README.mdweights.npz re-numera los bloques retenidos a índices contiguos (0..n-1), de modo que load_model puede cargarlos sin modificaciones. alignment_heads también se recalcula para el nuevo número de capas de decoder.1from mlx_whisper.load_models import load_model
2from train_mlx import apply_lora, load_checkpoint # tu script
3
4model = load_model(model_path)
5model = apply_lora(model) # Q/V en cada bloque superviviente
6load_checkpoint(model, "ruta/al/checkpoint-LoRA")apply_lora debe recorrer los bloques por índice del modelo slim (0..16 en encoder, 0..21 en decoder), no por el índice original.ablacion_capas.py) sobre un set de 66 audios médicos en español. Se eliminaron los bloques con delta_WER < 0.5pp al ser anulados individualmente. La literatura (Distil-Whisper, Whisper Turbo, NASH) sugiere que una estrategia más robusta pasa por proteger el encoder y podar el decoder por selección uniforme, reentrenando entre rondas — este checkpoint conserva la poda cruda como baseline experimental.1@article{radford2022whisper,
2 title={Robust Speech Recognition via Large-Scale Weak Supervision},
3 author={Radford, Alec and Kim, Jong Wook and Xu, Tao and Brockman, Greg and McLeavey, Christine and Sutskever, Ilya},
4 journal={arXiv:2212.04356},
5 year={2022}
6}