Guía de fine-tune por LoRA — clonar estilo musical o vocal¶
Cuándo usar LoRA¶
- Adaptar el modelo base a una marca / artista / campaña sin reentrenar.
- Tamaño ≈ 10 MB por adapter (vs. 4 GB del DiT XL).
- Latencia de carga: <500 ms; cambio "en caliente" por petición.
Cuándo NO usar LoRA¶
- Para cambiar la arquitectura (más capas) → fine-tune completo.
- Si el dominio es radicalmente distinto al pre-train (e.g. audio binaural, sonidos de la naturaleza no musicales) — empezar por re-entrenar el VAE.
Recetario por caso de uso¶
1. Clonar un estilo de producción (ej. trap latino 2024 oscuro)¶
# Recoge 40-100 canciones de referencia (con licencia) de ~3 minutos cada una
python -m src.data.build_manifest /datasets/my_trap_pack \
data/manifests/trap_2024.jsonl --label-from parent
python -m src.lora.train_lora \
--config configs/ace_xl.yaml \
--base-ckpt checkpoints/dit_base/LATEST \
--manifest data/manifests/trap_2024.jsonl \
--output checkpoints/lora/trap_2024 \
--name trap_2024 \
--rank 16 --alpha 32 \
--steps 4000 --lr 1e-4 --batch-size 4
2. Clonar la firma tímbrica de una vocalista (con cesión escrita)¶
Cuidado legal: necesitas contrato firmado (Art. 51 LPI ES / 17 USC §201 US).
# Dataset: 3-5 horas de canto con anotaciones lyrics + MIDI alineado
# Pre-procesar con MFA para timestamps fonema-level (opcional pero recomendado)
python -m src.lora.train_lora \
--config configs/songgen.yaml \
--base-ckpt checkpoints/songgen_interleaving/LATEST \
--manifest data/manifests/vocalista_X.jsonl \
--output checkpoints/lora/vocalista_X \
--name vocalista_X \
--rank 8 --alpha 16 --steps 2000
Combinar con REPA usando m-hubert (utter-project/mHuBERT-147) para mejorar la
inteligibilidad multilingüe.
3. Adaptación rápida a un género regional (vallenato old-school)¶
python -m src.lora.train_lora \
--config configs/ace_xl.yaml \
--base-ckpt checkpoints/dit_base/LATEST \
--manifest data/manifests/vallenato_classic.jsonl \
--output checkpoints/lora/vallenato_oldschool \
--rank 4 --alpha 8 --steps 1000
Rank bajo (4) es suficiente para "empujar" el estilo sin alterar la musicalidad general.
Configurar el rank y alpha¶
| Caso | rank | alpha | steps | dataset h |
|---|---|---|---|---|
| Empuje estilístico sutil | 4 | 8 | 500-1000 | 1-2 |
| Estilo claro definido | 8 | 16 | 1500-2500 | 3-5 |
| Clonar firma tímbrica fuerte | 16 | 32 | 3000-5000 | 5-10 |
| Adaptación de dominio (folk regional) | 32 | 64 | 8000+ | 10-20 |
Regla práctica: alpha = 2 * rank. Subir alpha aumenta la "fuerza" del adapter.
Inferencia con LoRA cargado¶
import torch
from src.ace.pipeline import ACEPipeline
from src.lora.adapter import apply_lora, load_lora
pipe = ACEPipeline.factory(device="cuda")
apply_lora(pipe.dit, target_modules=["q", "v", "out", "mlp"], r=16, alpha=32)
load_lora(pipe.dit, "checkpoints/lora/trap_2024.lora.pt")
result = pipe.generate(spec, lyrics="...", n_steps=50, cfg_scale=4.0,
dcw_mode="double")
Vía API:
curl -X POST http://localhost:8000/api/v1/generate \
-d '{"prompt":"...","style_prompt":"trap_2024 dark","mode":"ace"}'
(El SmartRouter cargará el LoRA correspondiente si el style_prompt coincide
con un adapter registrado — implementar el matching en src/api/router.py
según tu nomenclatura.)
Fundir LoRA (merge) para servir en producción¶
from src.lora.adapter import LoRALinear
for m in pipe.dit.modules():
if isinstance(m, LoRALinear):
m.merge() # funde los pesos en el módulo base
Una vez fundido el adapter desaparece y el DiT queda con los pesos actualizados (no se puede "revertir"). Útil para reducir overhead de inferencia cuando un estilo es permanente.