Compose — Música y producción de audio
Tres módulos en el dispositivo cubren la parte de música y producción de audio de speech-swift, todos ejecutándose nativamente en Apple Silicon mediante MLX o CoreML. MAGNeT genera clips de música de 30 segundos a partir de un prompt de texto. Separación de fuentes (Open-Unmix) divide una pista estéreo en cuatro stems (voces / batería / bajo / otros). Mejora de voz (DeepFilterNet3) elimina ruido de fondo del habla en tiempo real.
| Módulo | Tarea | Backend | Salida | CLI |
|---|---|---|---|---|
| MAGNeT | Texto → música | MLX (INT4 / INT8) | 30 s @ 32 kHz mono | speech compose |
| Open-Unmix | Separación de stems | MLX | 4 stems @ 44,1 kHz estéreo | speech separate |
| DeepFilterNet3 | Supresión de ruido | CoreML (Neural Engine) | 48 kHz, tiempo real | speech denoise |
MAGNeT — generación de música desde texto
Port a MLX Swift del MAGNeT de Meta (Masked Audio Generation with a Single Non-Autoregressive Transformer). Genera clips de 30 s de música mono a 32 kHz a partir de un prompt en inglés en formato libre — "happy rock", "energetic EDM with synth lead", o texto descriptivo rico para obtener mejores resultados.
Arquitectura
Tres componentes cargados, descargados en la primera llamada:
| Componente | Rol | Origen |
|---|---|---|
| LM decodificador MAGNeT | Transformer enmascarado no autorregresivo sobre 4 codebooks de EnCodec. 24 capas (Small, 300M) o 48 (Medium, 1.5B). Proyecciones Q/K/V/out cuantizadas + lineales FFN (MLX-affine, grupo 64). | aufklarer/MAGNeT-{Small,Medium}-30secs-MLX-{4,8}bit |
| Codificador de texto T5-base | Codificador de 110M parámetros para condicionamiento de texto. FP32 (solo ruta del codificador; sin decodificador, sin cabeza LM). | t5-base |
| Decodificador EnCodec 32 kHz | Decodificador SEANet (Conv1d / ConvTranspose1d / ResnetBlock / LSTM de 2 capas) + RVQ Euclidiano de 4 codebooks. Mapea los tokens discretos del LM de vuelta a una forma de onda de 32 kHz. | mlx-community/encodec-32khz-float32 |
Decodificación paralela enmascarada
A diferencia de su hermano autorregresivo MusicGen, MAGNeT ejecuta 50 pasadas hacia adelante en total (división por defecto [20, 10, 10, 10] entre los 4 codebooks) con re-enmascaramiento programado por coseno, recocido de guía sin clasificador y ventanas locales de atención por etapa. La etapa 0 tiene self-attention completa; las etapas 1–3 usan una ventana local |q − k| ≤ 5 porque los codebooks superiores solo refinan detalles.
Variantes
| Variante | Parámetros | LM en disco | RSS pico | Tiempo (serie M, 30 s) | RTF |
|---|---|---|---|---|---|
small-int4 | 300M | 287 MB | ~1.4 GB | ~10.8 s | 0.36× |
small-int8 | 300M | 425 MB | ~1.5 GB | ~11 s | 0.37× |
medium-int4 | 1.5B | 1.36 GB | ~2.2 GB | ~36 s | 1.20× |
medium-int8 | 1.5B | 2.10 GB | ~3.0 GB | ~36 s | 1.20× |
RTF inferior a 1,0 = más rápido que el tiempo real. La cuantización apenas mueve el tiempo de pared — la atención domina, no las proyecciones lineales — por lo que la ganancia práctica de INT4 es memoria en lugar de latencia.
Inicio rápido
import MAGNeTMusicGen
let model = try await MAGNeTMusicGen.fromPretrained(variant: .smallInt4)
let pcm = model.generate(text: "energetic upbeat rock anthem with electric guitar riffs, driving drums, bass groove")
// pcm: [Float] length 960_000 (30 s × 32 kHz mono)
try WAVWriter.write(samples: pcm, sampleRate: 32_000,
to: URL(fileURLWithPath: "out.wav"))
CLI
# Default: small-int4 (~10 s on M-series for 30 s of audio)
speech compose "happy rock" -o happy_rock.wav
# Larger model — better prompt following, ~3.5× slower
speech compose "lo-fi hip hop with mellow piano and warm vinyl crackle" \
--variant medium-int4 -o lofi.wav
# Reproducible
speech compose "energetic EDM with synth lead" --seed 42 -o edm.wav
Flags: --variant {small,medium}-{int4,int8}, --temperature (recocida, por defecto 3,0), --top-p (por defecto 0,9), --cfg-max / --cfg-min (por defecto 10,0 / 1,0), --steps "20,10,10,10" (iteraciones por codebook), --seed.
Las etiquetas cortas como "happy rock" funcionan pero se sienten pobres. Los prompts descriptivos que mencionan instrumentos + tempo + estado de ánimo mejoran notablemente la coherencia — en nuestra prueba de calidad, el prompt más rico dio una tasa de cruce por cero más alta (0,116 vs 0,093, es decir, más detalle de alta frecuencia) y cero clipping. Compara:
"happy rock"— pobre"energetic upbeat rock anthem with electric guitar riffs, driving drums, bass groove"— más rico, generalmente mejor
Paquetes y licencia
Los cuatro paquetes MLX se derivan de facebook/magnet-small-30secs y facebook/magnet-medium-30secs y heredan la licencia de Meta: CC-BY-NC 4.0 — solo uso no comercial. El audio generado lleva la misma restricción.
Separación de fuentes — Open-Unmix (4 stems)
Open-Unmix HQ / UMX-L portado a MLX. Divide una mezcla estéreo en cuatro stems — voces, batería, bajo, otros instrumentos — mediante predictores BiLSTM por stem y un post-filtro Wiener-EM multicanal, todo ejecutándose de extremo a extremo en MLX a través de la STFT inversa. RTF en condiciones reales ~0,031 (32× más rápido que el tiempo real) en la serie M para 30 s de audio.
# Split mix.wav into vocals/drums/bass/other.wav next to it
speech separate mix.wav
# Or keep stems together
speech separate mix.wav --output stems/
import SourceSeparation
let separator = try await SourceSeparator.fromPretrained()
let stems = try separator.separate(audio: stereoSamples, sampleRate: 44_100)
// stems.vocals, stems.drums, stems.bass, stems.other — each [Float]
Arquitectura completa, ajuste y notas de benchmark en la guía de separación de fuentes.
Mejora de voz — DeepFilterNet3
DeepFilterNet3 en el Neural Engine (CoreML). Elimina ruido de fondo del habla a 48 kHz en tiempo real con un modelo de 2,1M parámetros — lo suficientemente pequeño para ejecutarse junto a un pipeline de ASR como paso de preprocesamiento.
speech denoise noisy.wav -o clean.wav
import SpeechEnhancement
let enhancer = try await SpeechEnhancer.fromPretrained()
let clean = try enhancer.enhance(audio: noisy, sampleRate: 48_000)
Configuración completa en la guía de mejora de voz.
Elegir la herramienta adecuada
| Quieres… | Usa |
|---|---|
| Generar música desde un prompt de texto | MAGNeT (speech compose) |
| Extraer voces o batería de una pista existente | Open-Unmix (speech separate) |
| Limpiar habla ruidosa antes de la transcripción | DeepFilterNet3 (speech denoise) |
| Convertir texto a voz (síntesis de voz) | VoxCPM2 or Qwen3-TTS |