Saltar a contenido

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.