Compose — Música & produção de áudio
Três módulos no dispositivo cobrem o lado de música e produção de áudio do speech-swift, todos executando nativamente em Apple Silicon via MLX ou CoreML. MAGNeT gera clipes de música de 30 segundos a partir de um prompt de texto. Separação de fontes (Open-Unmix) divide uma faixa estéreo em quatro stems (vocais / bateria / baixo / outros). Aprimoramento de voz (DeepFilterNet3) remove ruído de fundo da fala em tempo real.
| Módulo | Tarefa | Backend | Saída | CLI |
|---|---|---|---|---|
| MAGNeT | Texto → música | MLX (INT4 / INT8) | 30 s @ 32 kHz mono | speech compose |
| Open-Unmix | Separação de stems | MLX | 4 stems @ 44,1 kHz estéreo | speech separate |
| DeepFilterNet3 | Supressão de ruído | CoreML (Neural Engine) | 48 kHz, tempo real | speech denoise |
MAGNeT — geração de música a partir de texto
Port MLX Swift do MAGNeT da Meta (Masked Audio Generation with a Single Non-Autoregressive Transformer). Gera clipes de 30 s de música mono a 32 kHz a partir de um prompt em inglês de forma livre — "happy rock", "energetic EDM with synth lead", ou texto descritivo rico para resultados mais limpos.
Arquitetura
Três componentes carregados, baixados na primeira chamada:
| Componente | Função | Origem |
|---|---|---|
| LM decodificador MAGNeT | Transformer mascarado não-autorregressivo sobre 4 codebooks de EnCodec. 24 camadas (Small, 300M) ou 48 (Medium, 1.5B). Projeções Q/K/V/out quantizadas + lineares 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 condicionamento de texto. FP32 (apenas caminho do codificador; sem decodificador, sem cabeça LM). | t5-base |
| Decodificador EnCodec 32 kHz | Decodificador SEANet (Conv1d / ConvTranspose1d / ResnetBlock / LSTM de 2 camadas) + RVQ Euclidiano de 4 codebooks. Mapeia os tokens discretos do LM de volta para uma forma de onda de 32 kHz. | mlx-community/encodec-32khz-float32 |
Decodificação paralela mascarada
Ao contrário de seu parente autorregressivo MusicGen, MAGNeT executa 50 passagens diretas no total (divisão padrão [20, 10, 10, 10] entre os 4 codebooks) com re-mascaramento programado por cosseno, recozimento de orientação sem classificador e janelas de atenção locais por estágio. O estágio 0 tem self-attention completa; estágios 1–3 usam uma janela local |q − k| ≤ 5 porque codebooks superiores apenas refinam detalhes.
Variantes
| Variante | Parâmetros | LM em disco | Pico RSS | Tempo (série 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 abaixo de 1,0 = mais rápido que o tempo real. A quantização mal move o wall-clock — a atenção domina, não as projeções lineares — então o ganho prático do INT4 é em memória e não em latência.
Início 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 (recozida, padrão 3,0), --top-p (padrão 0,9), --cfg-max / --cfg-min (padrão 10,0 / 1,0), --steps "20,10,10,10" (iterações por codebook), --seed.
Tags curtas como "happy rock" funcionam mas parecem fracas. Prompts descritivos que mencionam instrumentos + andamento + humor melhoram notavelmente a coerência — em nosso teste de qualidade, o prompt mais rico deu uma taxa de cruzamento por zero mais alta (0,116 vs 0,093, ou seja, mais detalhes de alta frequência) e zero clipping. Compare:
"happy rock"— fraco"energetic upbeat rock anthem with electric guitar riffs, driving drums, bass groove"— mais rico, geralmente melhor
Pacotes & licença
Todos os quatro pacotes MLX derivam de facebook/magnet-small-30secs e facebook/magnet-medium-30secs e herdam a licença da Meta: CC-BY-NC 4.0 — apenas uso não comercial. O áudio gerado carrega a mesma restrição.
Separação de fontes — Open-Unmix (4 stems)
Open-Unmix HQ / UMX-L portado para MLX. Divide uma mixagem estéreo em quatro stems — vocais, bateria, baixo, outros instrumentos — via preditores BiLSTM por stem e um pós-filtro Wiener-EM multicanal, todos executando de ponta a ponta em MLX através da STFT inversa. RTF real ~0,031 (32× mais rápido que o tempo real) em série M para 30 s de áudio.
# 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]
Arquitetura completa, ajuste e notas de benchmark no guia de separação de fontes.
Aprimoramento de voz — DeepFilterNet3
DeepFilterNet3 no Neural Engine (CoreML). Remove ruído de fundo da fala a 48 kHz em tempo real com um modelo de 2,1M parâmetros — pequeno o suficiente para rodar junto a um pipeline ASR como etapa de pré-processamento.
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)
Configuração completa no guia de aprimoramento de voz.
Escolhendo a ferramenta certa
| Você quer… | Use |
|---|---|
| Gerar música a partir de um prompt de texto | MAGNeT (speech compose) |
| Extrair vocais ou bateria de uma faixa existente | Open-Unmix (speech separate) |
| Limpar fala ruidosa antes da transcrição | DeepFilterNet3 (speech denoise) |
| Converter texto em voz (síntese de voz) | VoxCPM2 or Qwen3-TTS |