Ace-Step v1.5 - Generation Musicale avec Paroles

Module : 02-Audio-Advanced
Niveau : Intermediaire
Technologies : ACE-Step v1.5 (Hybrid LM + DiT), <4 GB VRAM (cpu_offload)
Duree estimee : 45 minutes

Objectifs d’Apprentissage

Prerequis

  • GPU NVIDIA avec au moins 4 GB VRAM (cpu_offload actif), 6 GB sans offload
  • pip install git+https://github.com/ace-step/ACE-Step.git
  • Connaissances de base en generation audio (voir 02-3-MusicGen)

Navigation : << 02-8 | Index | Suivant >>

# Parametres Papermill - JAMAIS modifier ce commentaire

# Configuration notebook
notebook_mode = "interactive"        # "interactive" ou "batch"
skip_widgets = False               # True pour mode batch MCP
debug_level = "INFO"

# Parametres ACE-Step
model_checkpoint = None            # None = auto-download depuis HuggingFace
audio_duration = 30.0              # Duree de generation (secondes)
device = "cuda"                    # "cuda" ou "cpu"
cpu_offload = False                # Offload CPU (activer pour <4 GB VRAM)
dtype = "bfloat16"                 # Precision (bfloat16 ou float16)
infer_step = 60                    # Etapes d'inference (qualite vs vitesse)
guidance_scale = 15.0              # Fidelite au prompt
scheduler_type = "euler"           # Scheduler (euler, euler_dy)
cfg_type = "apg"                   # CFG type (apg, cfg, cfg_star)
omega_scale = 10.0                 # Echelle omega pour guidance
seed = 42                          # Graine aleatoire (-1 pour random)

# Configuration
generate_audio = True              # Generer les fichiers audio
save_results = True                # Sauvegarder les fichiers generes
test_multilingual = True           # Tester la generation multilingue
# Parameters
BATCH_MODE = "true"

Paramètres Papermill et configuration

Cette cellule définit les paramètres modifiables pour différentes utilisations du notebook.

Mode Papermill : Les variables peuvent etre surchargees lors de l’exécution batch via Papermill (-p param valeur).

Paramètre Rôle Valeur par defaut
model_checkpoint Chemin vers les poids du modèle None (auto-download)
audio_duration Duree de generation 30 secondes
device Device d’exécution cuda (GPU) ou cpu
cpu_offload Offload CPU pour faible VRAM True
infer_step Étapes d’inference 60
guidance_scale Fidelite au prompt 15.0
cfg_type Type de CFG apg (adaptatif)
seed Graine aleatoire 42

Note : Pour une première exécution, laissez les valeurs par defaut. Le paramètre cpu_offload=True est recommande si votre GPU a moins de 8 GB VRAM.

# Parameters
BATCH_MODE = "false"                # affichage des apercus audio embarques (players jouables GitHub)

Les paramètres Papermill configurent le modèle ACE-Step (checkpoint, precision, offload), la duree de generation, et les paramètres de sampling (guidance_scale, infer_step, cfg_type). La cellule suivante configure l’environnement et verifie la VRAM disponible.

Introduction a ACE-Step v1.5

ACE-Step est un modèle de generation musicale open-source (licence Apache 2.0) qui combine une architecture hybride Language Model (LM) + Diffusion Transformer (DiT). Contrairement a MusicGen qui genere uniquement de la musique instrumentale, ACE-Step genere des chansons completes avec paroles.

Architecture ACE-Step

Tags de genre + Paroles structurees → LM Encoder → DiT Diffusion → VAE Decoder → Audio WAV
                                        (3.5B params)    (denoising)     (44.1kHz stereo)

Innovations cles : - Architecture hybride LM + DiT : Le LM encode le texte et les paroles, le DiT genere les spectrogrammes - Paroles structurees : Support natif des tags [verse], [chorus], [bridge], [intro], [outro] - Multilingue : 50+ langues supportees (anglais, francais, espagnol, allemand, japonais, etc.) - Faible VRAM : <4 GB avec cpu_offload, runtime machine-dep : generation rapide (<10s pour 4 min sur RTX 3090)

Comparaison avec les alternatives

Critere ACE-Step v1.5 MusicGen YuE SongGen2
Paroles Oui (structurees) Non Oui Oui
Architecture LM + DiT Transformer Flow matching Diffusion
Paramètres 3.5B (base) 1.5B (medium) Variable Variable
VRAM <4 GB (offload) ~10 GB (medium) 10-24 GB 10-24 GB
Duree max ~4 min ~30s ~2 min ~2 min
Langues 50+ Anglais principal Multi Multi
Licence Apache 2.0 MIT Apache 2.0 Variable

Applications typiques

Use case Description Exemple
Chanson complete Generation avec paroles et musique Chanson pop avec couplets/refrains
Musique de fond Pistes instrumentales avec ou sans paroles Jingle, podcast
Prototypage musical Idees melodieques avec structure Demo rapide d’un concept
Education Demonstration de styles multilingues Comparaison jazz/francais vs rock/anglais
# Setup environnement et imports
import warnings
# Bruit de warnings tiers (prefixes = chemins site-packages) : filtrage cible
warnings.filterwarnings("ignore", message="Failed to find CUDA.*")
warnings.filterwarnings("ignore", category=FutureWarning, module="torch.nn.utils.weight_norm")
warnings.filterwarnings("ignore", message=".*TorchCodec AudioEncoder.*")

import os
import sys
import json
import time
import gc
from pathlib import Path
from datetime import datetime
from typing import Dict, List, Any, Optional

import numpy as np
from IPython.display import Audio, display, HTML, Markdown

# Import helpers GenAI
GENAI_ROOT = Path.cwd()
while GENAI_ROOT.name != 'GenAI' and len(GENAI_ROOT.parts) > 1:
    GENAI_ROOT = GENAI_ROOT.parent

HELPERS_PATH = GENAI_ROOT / 'shared' / 'helpers'
if HELPERS_PATH.exists():
    sys.path.insert(0, str(HELPERS_PATH.parent))
    try:
        from helpers.audio_helpers import (
            play_audio, save_audio, display_audio_array
        )
        print("Helpers audio importes")
    except ImportError:
        print("Helpers audio non disponibles - mode autonome")

# Repertoires
OUTPUT_DIR = GENAI_ROOT / 'outputs' / 'audio' / 'acestep'
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)

# Verification GPU
gpu_available = False
gpu_name = "N/A"
gpu_vram = 0.0
try:
    import torch
    gpu_available = torch.cuda.is_available()
    if gpu_available:
        gpu_name = torch.cuda.get_device_name(0)
        gpu_vram = torch.cuda.get_device_properties(0).total_memory / (1024**3)
        print(f"GPU : {gpu_name} ({gpu_vram:.1f} GB VRAM)")
    else:
        print("GPU non disponible - ACE-Step sera tres lent sur CPU")
        if device == "cuda":
            device = "cpu"
            print("Fallback vers CPU")
except ImportError:
    print("torch non installe")
    device = "cpu"

# Import ACE-Step avec installation fallback
acestep_loaded = False
try:
    from acestep.pipeline_ace_step import ACEStepPipeline
    acestep_loaded = True
    # Logs ACE-Step (loguru) : INFO logge des chemins machine -> WARNING
    from loguru import logger as _acestep_logger
    _acestep_logger.remove()
    _acestep_logger.add(sys.stderr, level="WARNING")
    print("ACE-Step importe avec succes")
except ImportError:
    print("ACE-Step non installe. Tentative d'installation...")
    try:
        import subprocess
        result = subprocess.run(
            [sys.executable, "-m", "pip", "install", "git+https://github.com/ace-step/ACE-Step.git"],
            capture_output=True, text=True, timeout=300
        )
        if result.returncode == 0:
            print("ACE-Step installe avec succes")
            from acestep.pipeline_ace_step import ACEStepPipeline
            acestep_loaded = True
        else:
            print(f"Installation echouee : {result.stderr[:200]}")
            display(Markdown("**Installation manuelle requise** :\n```bash\npip install git+https://github.com/ace-step/ACE-Step.git\n```"))
    except Exception as e:
        print(f"Erreur d'installation : {type(e).__name__} - {str(e)[:200]}")
        display(Markdown("**Installation manuelle requise** :\n```bash\npip install git+https://github.com/ace-step/ACE-Step.git\n```"))

print(f"\nACE-Step v1.5 - Generation Musicale avec Paroles")
print(f"Date : {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print(f"Mode : {notebook_mode}, Device : {device}")
print(f"Duree : {audio_duration}s, Infer steps : {infer_step}")
print(f"Guidance scale : {guidance_scale}, CFG type : {cfg_type}")
print(f"CPU offload : {cpu_offload}, Seed : {seed}")
print(f"Sortie : {OUTPUT_DIR.relative_to(GENAI_ROOT).as_posix()}")
Helpers audio importes
GPU : NVIDIA GeForce RTX 3090 (24.0 GB VRAM)
ACE-Step non installe. Tentative d'installation...
ACE-Step installe avec succes

ACE-Step v1.5 - Generation Musicale avec Paroles
Date : 2026-08-16 03:35:21
Mode : interactive, Device : cuda
Duree : 30.0s, Infer steps : 60
Guidance scale : 15.0, CFG type : apg
CPU offload : False, Seed : 42
Sortie : outputs/audio/acestep

Interpretation : Configuration de l’environnement

L’environnement est maintenant configure pour ACE-Step.

Composant Statut Rôle
GPU detecte Variable (si disponible) runtime machine-dep : acceleration de la generation
ACE-Step Importe ou instruction d’installation Pipeline de generation musicale
Repertoire sortie outputs/audio/acestep/ Stockage des fichiers WAV generes
CPU offload Active par defaut Permet de fonctionner avec <4 GB VRAM

Avantage cle d’ACE-Step : Contrairement a MusicGen (10 GB VRAM pour medium) ou SongGen2 (10-24 GB), ACE-Step peut fonctionner sur des GPU modestes grace au cpu_offload. Cela le rend accessible sur des cartes comme la GTX 1060 6 GB.

Note : Si ACE-Step n’a pas pu etre installe automatiquement, le notebook continuera en mode de demonstration avec des messages informatifs. Aucune erreur ne sera levee.

L’environnement est pret. La cellule suivante charge le fichier .env afin de recuperer le token HuggingFace necessaire pour telecharger les poids du modèle depuis le Hub.

# Chargement robuste de la configuration .env
from dotenv import load_dotenv
import os
# Recherche du .env dans tous les parents (pour Papermill qui change le cwd)
current_path = Path.cwd()
env_loaded = False
for _ in range(10):
    env_path = current_path / ".env"
    if env_path.exists():
        load_dotenv(env_path)
        print(f".env charge depuis: {env_path.parent.name}/{env_path.name}")
        env_loaded = True
        break
    if current_path.name == "GenAI" or len(current_path.parts) <= 1:
        break
    current_path = current_path.parent
if not env_loaded:
    print("WARNING: .env non trouve, utilisation variables environnement")
.env charge depuis: GenAI/.env

Dependances GPU Optionnelles

Ce notebook utilise un modèle GPU optionnel (ACE-Step). Pour l’activer :

pip install git+https://github.com/ace-step/ACE-Step.git

Sans ces dependances, le notebook s’executera en mode demonstration avec des messages informatifs.

Section 1 : Architecture d’ACE-Step et chargement du modèle

ACE-Step v1.5 utilise une architecture hybride qui combine deux paradigmes de generation :

Composants de l’architecture

Composant Rôle Details
LM Encoder Encode le texte (genre + paroles) Representations sémantiques riches
DiT (Diffusion Transformer) Genere les spectrogrammes Processus de denoising iteratif
VAE Decoder Decode les spectrogrammes en audio Sortie 44.1 kHz stereo
CFG/APG Guide la generation vers le prompt Classifier-free guidance adaptatif

Paramètres de generation cles

Paramètre Plage Impact
infer_step 20-100 Qualite (plus = meilleur mais plus lent)
guidance_scale 3-30 Fidelite au prompt (plus = plus fidele)
cfg_type apg, cfg, cfg_star Stratégie de guidance
omega_scale 1-20 Intensite du guidance
scheduler_type euler, euler_dy Algorithmes de sampling
# Chargement du modele ACE-Step
print("CHARGEMENT DU MODELE ACE-STEP v1.5")
print("=" * 50)

pipeline = None

if acestep_loaded:
    try:
        print(f"Configuration : dtype={dtype}, cpu_offload={cpu_offload}")
        print(f"(Premier lancement : telechargement du modele depuis HuggingFace)")
        start_time = time.time()

        pipeline = ACEStepPipeline(
            checkpoint_dir=model_checkpoint,
            dtype=dtype,
            cpu_offload=cpu_offload,
            overlapped_decode=False,
        )
        load_time = time.time() - start_time

        print(f"Modele charge en {load_time:.1f}s")
        print(f"CPU offload : {'Actif' if cpu_offload else 'Desactive'}")

        if gpu_available:
            vram_used = torch.cuda.memory_allocated(0) / (1024**3)
            print(f"VRAM utilisee : {vram_used:.2f} GB")

    except Exception as e:
        print(f"Erreur lors du chargement : {type(e).__name__} - {str(e)[:200]}")
        display(Markdown(f"**Erreur de chargement** : `{type(e).__name__}`\n\nCause probable : VRAM insuffisante ou modele non telecharge. Essayez `cpu_offload=True`."))
        pipeline = None
else:
    print("ACE-Step non disponible - mode demonstration")
    print("Pour installer : pip install git+https://github.com/ace-step/ACE-Step.git")
    print("\nLe notebook continuera en affichant les parametres et configurations")
    print("sans generation audio reelle.")
CHARGEMENT DU MODELE ACE-STEP v1.5
==================================================
Configuration : dtype=bfloat16, cpu_offload=False
(Premier lancement : telechargement du modele depuis HuggingFace)
Modele charge en 0.0s
CPU offload : Desactive
VRAM utilisee : 0.00 GB

Interpretation : Chargement du modèle

Le chargement d’ACE-Step differe de MusicGen par sa gestion de la memoire.

Aspect Detail
Premier chargement Telechargement depuis HuggingFace Hub (~7 GB pour le modèle base)
Chargements suivants Cache local, runtime machine-dep : chargement rapide
VRAM requise <4 GB avec cpu_offload, ~6 GB sans offload
CPU offload Deplace les couches non utilisees vers la RAM CPU

Comparaison VRAM :

Modèle VRAM minimale VRAM recommandee
ACE-Step (cpu_offload) 4 GB 6 GB
ACE-Step (full GPU) 6 GB 8 GB
MusicGen medium 10 GB 12 GB
SongGen2 10 GB 24 GB

Note technique : Le cpu_offload reduit la VRAM au prix d’une vitesse de generation legerement inferieure. Sur un GPU avec 8+ GB, desactiver cpu_offload runtime machine-dep : accelere la generation de 30-50%.

Section 2 : Generation text-to-song

La generation text-to-song est le mode principal d’ACE-Step. Contrairement a MusicGen (instrumental uniquement), ACE-Step genere des chansons avec paroles structurees.

Format des paroles

Les paroles utilisent des tags de structure pour guider le modèle :

Tag Rôle Position typique
[intro] Introduction instrumentale Debut
[verse] Couplet (narration) Après intro ou chorus
[chorus] Refrain (melodie principale) Après verse
[bridge] Pont musical (contraste) Milieu du morceau
[outro] Conclusion Fin

Conseils pour les prompts :

Élément Exemples Impact
Genre pop, rock, jazz, electronic, rap, blues Style general
Instruments piano, guitar, synthesizer, drums Timbres
Ambiance upbeat, melancholic, energetic, calm Emotion
Langue Francais, English, Espanol Langue des paroles
# Generation text-to-song : 3 exemples de styles differents
print("GENERATION TEXT-TO-SONG")
print("=" * 50)

song_examples = [
    {
        "name": "Chanson francaise",
        "prompt": "pop, chanson francaise, piano, melodique, tendre",
        "lyrics": (
            "[verse]\n"
            "Sous le ciel de Paris, les nuages s'envolent\n"
            "Les reves se melent au vent du matin\n"
            "Une melodie douce comme une parole\n"
            "Guide mes pas sur ce chemin\n"
            "\n"
            "[chorus]\n"
            "Et la musique berce mes pensees\n"
            "Dans cette ville de lumiere et de beaute\n"
            "Les notes dansent comme des etoiles\n"
            "Sur les toits, la nuit s'envole"
        ),
    },
    {
        "name": "Electronic upbeat",
        "prompt": "electronic, upbeat, synthesizer, dance, energetic",
        "lyrics": (
            "[intro]\n"
            "\n"
            "[verse]\n"
            "Neon lights flash across the floor\n"
            "Bass is pumping, craving more\n"
            "Digital heartbeat in the air\n"
            "Lose yourself without a care\n"
            "\n"
            "[chorus]\n"
            "We are the sound, we are the night\n"
            "Synthesizer taking flight\n"
            "Feel the rhythm in your soul\n"
            "Let the music take control"
        ),
    },
    {
        "name": "Jazz vocal",
        "prompt": "jazz, smooth, saxophone, piano, warm vocals",
        "lyrics": (
            "[verse]\n"
            "Smoke curls up from the corner bar\n"
            "A saxophone wails beneath the stars\n"
            "Whiskey on ice and a velvet tone\n"
            "Playing for lovers who dance alone\n"
            "\n"
            "[chorus]\n"
            "Midnight blue and a mellow groove\n"
            "Nothing to lose, nothing to prove\n"
            "Just the piano and a softly sung line\n"
            "In this jazz club where time unwinds"
        ),
    },
]

generation_results = {}

if pipeline is not None and generate_audio:
    for i, song in enumerate(song_examples):
        print(f"\n--- Morceau {i+1} : {song['name']} ---")
        print(f"Prompt : {song['prompt']}")
        print(f"Paroles : {song['lyrics'][:80]}...")

        try:
            seed_str = str(seed) if seed >= 0 else ""
            start_time = time.time()

            result = pipeline(
                audio_duration=audio_duration,
                prompt=song["prompt"],
                lyrics=song["lyrics"],
                infer_step=infer_step,
                guidance_scale=guidance_scale,
                scheduler_type=scheduler_type,
                cfg_type=cfg_type,
                omega_scale=omega_scale,
                manual_seeds=seed_str,
                guidance_interval=0.5,
                guidance_interval_decay=0,
                min_guidance_scale=3,
                use_erg_tag=True,
                use_erg_lyric=True,
                use_erg_diffusion=True,
                oss_steps="",
                guidance_scale_text=0.0,
                guidance_scale_lyric=0.0,
            )
            gen_time = time.time() - start_time

            # Le resultat est un chemin de fichier WAV
            # ACE-Step v1.5 retourne [chemin_wav, params_dict]
            if isinstance(result, list) and result and isinstance(result[0], str):
                result = result[0]

            if isinstance(result, str) and os.path.exists(result):
                import soundfile as sf
                audio_data, sr = sf.read(result)
                duration = len(audio_data) / sr

                generation_results[f"morceau_{i+1}"] = {
                    "name": song["name"],
                    "prompt": song["prompt"],
                    "duration": duration,
                    "gen_time": gen_time,
                    "sample_rate": sr,
                    "file": result,
                }

                print(f"  Duree : {duration:.1f}s | Temps : {gen_time:.2f}s")
                print(f"  Ratio temps reel : {duration / gen_time:.2f}x")
                print(f"  Sample rate : {sr} Hz")

                # Lecture audio (desactivee en mode batch)
                if BATCH_MODE != "true":
                    display_audio_array(audio_data[:sr*3].T if audio_data.ndim > 1 else audio_data[:sr*3], sr)  # apercu ~3s embarque (clip complet sauve localement)

                # Sauvegarde optionnelle
                if save_results:
                    save_path = OUTPUT_DIR / f"acestep_{i+1}_{song['name'].replace(' ', '_')}.wav"
                    sf.write(str(save_path), audio_data, sr)
                    print(f"  Sauvegarde : {save_path.name}")

            elif isinstance(result, tuple):
                # Certains pipelines retournent (audio, sr)
                audio_data, sr = result
                if isinstance(audio_data, np.ndarray):
                    duration = audio_data.shape[-1] / sr
                else:
                    import torch as _torch
                    if isinstance(audio_data, _torch.Tensor):
                        audio_data = audio_data.cpu().numpy()
                    duration = audio_data.shape[-1] / sr

                generation_results[f"morceau_{i+1}"] = {
                    "name": song["name"],
                    "prompt": song["prompt"],
                    "duration": duration,
                    "gen_time": gen_time,
                    "sample_rate": sr,
                }

                print(f"  Duree : {duration:.1f}s | Temps : {gen_time:.2f}s")
                print(f"  Ratio temps reel : {duration / gen_time:.2f}x")

                if BATCH_MODE != "true":
                    display_audio_array(audio_data[:sr*3], sr)  # apercu ~3s embarque (clip complet sauve localement)

            else:
                print(f"  Format de resultat inattendu : {type(result)}")

        except Exception as e:
            print(f"  Erreur : {type(e).__name__} - {str(e)[:200]}")
            display(Markdown(f"**Erreur de generation** : `{type(e).__name__}` - Verifiez la VRAM disponible et les parametres."))

    # Recapitulatif
    if generation_results:
        print(f"\nRecapitulatif des generations :")
        print(f"{'Morceau':<12} {'Style':<20} {'Duree (s)':<12} {'Temps gen (s)':<15}")
        print("-" * 60)
        for name, data in generation_results.items():
            print(f"{name:<12} {data['name']:<20} {data['duration']:<12.1f} {data['gen_time']:<15.2f}")
else:
    print("Modele non charge ou generation desactivee")
    print("\nExemples qui auraient ete generes :")
    for i, song in enumerate(song_examples):
        print(f"  {i+1}. {song['name']} : {song['prompt']}")
    print("\nInstallation : pip install git+https://github.com/ace-step/ACE-Step.git")
GENERATION TEXT-TO-SONG
==================================================

--- Morceau 1 : Chanson francaise ---
Prompt : pop, chanson francaise, piano, melodique, tendre
Paroles : [verse]
Sous le ciel de Paris, les nuages s'envolent
Les reves se melent au vent...
  Duree : 29.9s | Temps : 61.08s
  Ratio temps reel : 0.49x
  Sample rate : 48000 Hz
  Sauvegarde : acestep_1_Chanson_francaise.wav

--- Morceau 2 : Electronic upbeat ---
Prompt : electronic, upbeat, synthesizer, dance, energetic
Paroles : [intro]

[verse]
Neon lights flash across the floor
Bass is pumping, craving mor...
  Duree : 29.9s | Temps : 9.00s
  Ratio temps reel : 3.32x
  Sample rate : 48000 Hz
  Sauvegarde : acestep_2_Electronic_upbeat.wav

--- Morceau 3 : Jazz vocal ---
Prompt : jazz, smooth, saxophone, piano, warm vocals
Paroles : [verse]
Smoke curls up from the corner bar
A saxophone wails beneath the stars
W...
  Duree : 29.9s | Temps : 9.48s
  Ratio temps reel : 3.16x
  Sample rate : 48000 Hz
  Sauvegarde : acestep_3_Jazz_vocal.wav

Recapitulatif des generations :
Morceau      Style                Duree (s)    Temps gen (s)  
------------------------------------------------------------
morceau_1    Chanson francaise    29.9         61.08          
morceau_2    Electronic upbeat    29.9         9.00           
morceau_3    Jazz vocal           29.9         9.48           

Interpretation : Generation text-to-song

Les résultats montrent la capacite d’ACE-Step a generer des chansons completes avec paroles et musique.

Aspect Valeur observee Interpretation
Ratio temps reel Variable selon GPU Plus rapide que MusicGen pour des morceaux longs
Qualite audio 44.1 kHz stereo Superieur a MusicGen (32 kHz mono)
Paroles Structurees avec tags Avantage cle par rapport a MusicGen (instrumental uniquement)
Duree Jusqu’a 4 minutes Bien superieur a MusicGen (~30s)

Analyse des exemples : 1. Chanson francaise : Piano melodique, voix tendre, respect de la structure couplet/refrain 2. Electronic upbeat : Synthesiseurs, rythme dance, energie elevee, voix rythmee 3. Jazz vocal : Saxophone chaud, piano smooth, ambiance smoke-filled club

Points cles : - Les tags de structure ([verse], [chorus]) guident l’arrangement musical - La combinaison prompt + paroles permet un contrôle fin du résultat - La generation multilingue fonctionne naturellement (pas besoin de traduire les descriptions)

Note technique : La generation est stochastique - le même prompt avec la même graine donne des résultats reproductibles, mais sans graine les résultats varient.

Exercice 1 : Creation de paroles structurees multilingues

Objectif : Implementer une fonction qui genere des paroles structurees (avec tags [verse], [chorus, [bridge]) dans une langue donnee, adaptees a un style musical précis.

ACE-Step supporte 50+ langues et utilise des tags de structure pour guider la generation. Le formatage des paroles (placement des tags, longueur des sections, coherence thematique) influence directement la qualite du résultat.

Indices : - Les tags [verse] (narration), [chorus] (refrain), [bridge] (contraste) structurent le morceau - [intro] et [outro] sont généralement instrumentaux - Chaque section devrait contenir 2-6 lignes de texte - Le thème des paroles doit etre coherent avec le style musical decrit dans le prompt - # Étape 1 : Définir la structure (verse-chorus-verse-chorus ou autre) - # Étape 2 : Generer les paroles pour chaque section selon le thème et la langue - # Étape 3 : Assembler avec les tags de structure - # Étape 4 : Verifier la coherence thematique et la longueur - # Indice : Un refrain plus court et memorisable qu’un couplet donne de meilleurs résultats

# Exercice 1 : Creation de paroles structurees multilingues
# TODO etudiant : Creer des paroles structurees pour ACE-Step

def create_structured_lyrics(theme="liberte", style="pop, piano, melancolique",
                            language="fr", structure=None):
    """
    Cree des paroles structurees avec tags ACE-Step pour un theme et style donnes.
    
    Args:
        theme: Theme des paroles ("amour", "voyage", "liberte", "nature", etc.)
        style: Description du style musical (tags separes par virgules)
        language: Code langue ("fr", "en", "es", "ja", etc.)
        structure: Liste de sections ex: ["verse", "chorus", "verse", "chorus"]
                   Si None, utilise ["verse", "chorus", "bridge", "chorus"]
    
    Returns:
        dict: {"prompt": str, "lyrics": str, "theme": str, "language": str}
    """
    # TODO etudiant : Definir la structure par defaut
    if structure is None:
        structure = []  # TODO etudiant : structure par defaut
    
    # TODO etudiant : Ecrire les paroles pour chaque section
    # Indice : Chaque section doit avoir 2-6 lignes coherentes avec le theme
    sections = {}  # TODO etudiant : {"verse": ["ligne1", ...], "chorus": [...], ...}
    
    # TODO etudiant : Assembler les paroles avec les tags
    # Indice : "[verse]\nligne1\nligne2\n\n[chorus]\nligne1\n..."
    lyrics = None  # TODO etudiant
    
    return {
        "prompt": style,
        "lyrics": lyrics,
        "theme": theme,
        "language": language,
    }

# Test
result = create_structured_lyrics(theme="voyage", style="folk, acoustic guitar, doux", language="fr")
if result["lyrics"]:
    print(f"Theme : {result['theme']} | Langue : {result['language']}")
    print(f"Style : {result['prompt']}")
    print(f"\nParoles :\n{result['lyrics']}")
else:
    print("Exercice a completer")
Exercice a completer

Section 3 : Exploration des paramètres de generation

Les paramètres de generation d’ACE-Step influencent la qualite, la fidelite et la diversite du résultat.

Paramètres cles a explorer

Paramètre Valeur par defaut Plage testee Impact attendu
guidance_scale 15 5 / 15 / 25 Fidelite au prompt (bas=libre, haut=fidele)
infer_step 60 30 / 60 / 90 Qualite audio (plus=meilleur mais plus lent)
cfg_type apg apg / cfg Stratégie de guidance
omega_scale 10 5 / 10 / 15 Intensite du guidance

Hypotheses : - guidance_scale bas (5) : Generation libre, moins fidele au prompt - guidance_scale haut (25) : Très fidele au prompt, possiblement rigide - infer_step bas (30) : Generation rapide, qualite reduite - infer_step haut (90) : Generation lente, meilleure qualite

# Test des parametres de generation
print("TEST DES PARAMETRES DE GENERATION")
print("=" * 50)

test_prompt = "pop, acoustic guitar, gentle, romantic"
test_lyrics = (
    "[verse]\n"
    "Strumming softly in the night\n"
    "Stars are shining burning bright\n"
    "Every chord tells a story\n"
    "Of a love that feels like glory\n"
    "\n"
    "[chorus]\n"
    "Play me a song of tomorrow\n"
    "Wave away the sorrow\n"
    "Let the melody carry us through\n"
    "Every note a promise new"
)

# Configurations a tester
param_configs = [
    {"label": "gs=5, steps=60", "guidance_scale": 5, "infer_step": 60},
    {"label": "gs=15, steps=60", "guidance_scale": 15, "infer_step": 60},
    {"label": "gs=25, steps=60", "guidance_scale": 25, "infer_step": 60},
    {"label": "gs=15, steps=30", "guidance_scale": 15, "infer_step": 30},
    {"label": "gs=15, steps=90", "guidance_scale": 15, "infer_step": 90},
]

param_results = {}

if pipeline is not None and generate_audio:
    print(f"Prompt : {test_prompt}")
    print(f"Duree : {audio_duration}s")

    for config in param_configs:
        label = config["label"]
        print(f"\n--- {label} ---")

        try:
            start_time = time.time()
            result = pipeline(
                audio_duration=audio_duration,
                prompt=test_prompt,
                lyrics=test_lyrics,
                infer_step=config["infer_step"],
                guidance_scale=config["guidance_scale"],
                scheduler_type=scheduler_type,
                cfg_type=cfg_type,
                omega_scale=omega_scale,
                manual_seeds=str(seed) if seed >= 0 else "",
                guidance_interval=0.5,
                guidance_interval_decay=0,
                min_guidance_scale=3,
                use_erg_tag=True,
                use_erg_lyric=True,
                use_erg_diffusion=True,
                oss_steps="",
                guidance_scale_text=0.0,
                guidance_scale_lyric=0.0,
            )
            gen_time = time.time() - start_time

            # Analyser le resultat
            # ACE-Step v1.5 retourne [chemin_wav, params_dict]
            if isinstance(result, list) and result and isinstance(result[0], str):
                result = result[0]

            if isinstance(result, str) and os.path.exists(result):
                import soundfile as sf
                audio_data, sr = sf.read(result)
                duration = len(audio_data) / sr
            else:
                duration = audio_duration
                sr = 44100

            param_results[label] = {
                "gen_time": gen_time,
                "duration": duration,
                "guidance_scale": config["guidance_scale"],
                "infer_step": config["infer_step"],
            }

            print(f"  Temps : {gen_time:.2f}s | Duree : {duration:.1f}s | Ratio : {duration/gen_time:.2f}x")

            if BATCH_MODE != "true":
                if isinstance(result, str) and os.path.exists(result):
                    display_audio_array(audio_data[:sr*3].T if audio_data.ndim > 1 else audio_data[:sr*3], sr)  # apercu ~3s embarque (clip complet sauve localement)

        except Exception as e:
            print(f"  Erreur : {type(e).__name__} - {str(e)[:200]}")
            param_results[label] = {"error": str(e)[:100]}

    # Tableau recapitulatif
    if param_results:
        print(f"\nRecapitulatif :")
        print(f"{'Config':<20} {'Temps (s)':<12} {'Duree (s)':<12} {'Ratio':<10}")
        print("-" * 55)
        for label, data in param_results.items():
            if "error" not in data:
                print(f"{label:<20} {data['gen_time']:<12.2f} {data['duration']:<12.1f} {data['duration']/data['gen_time']:<10.2f}")
            else:
                print(f"{label:<20} ERREUR : {data['error']}")
else:
    print("Modele non charge ou generation desactivee")
    print("\nConfigurations qui auraient ete testees :")
    for config in param_configs:
        print(f"  {config['label']}")
    print("\nImpact attendu :")
    print("  guidance_scale bas (5) : Plus creatif, moins fidele au prompt")
    print("  guidance_scale haut (25) : Tres fidele, possiblement rigide")
    print("  infer_step bas (30) : Rapide, qualite reduite")
    print("  infer_step haut (90) : Lent, meilleure qualite")
TEST DES PARAMETRES DE GENERATION
==================================================
Prompt : pop, acoustic guitar, gentle, romantic
Duree : 30.0s

--- gs=5, steps=60 ---
  Temps : 7.93s | Duree : 29.9s | Ratio : 3.77x

--- gs=15, steps=60 ---
  Temps : 8.16s | Duree : 29.9s | Ratio : 3.67x

--- gs=25, steps=60 ---
  Temps : 9.68s | Duree : 29.9s | Ratio : 3.09x

--- gs=15, steps=30 ---
  Temps : 4.76s | Duree : 29.9s | Ratio : 6.28x

--- gs=15, steps=90 ---
  Temps : 12.56s | Duree : 29.9s | Ratio : 2.38x

Recapitulatif :
Config               Temps (s)    Duree (s)    Ratio     
-------------------------------------------------------
gs=5, steps=60       7.93         29.9         3.77      
gs=15, steps=60      8.16         29.9         3.67      
gs=25, steps=60      9.68         29.9         3.09      
gs=15, steps=30      4.76         29.9         6.28      
gs=15, steps=90      12.56        29.9         2.38      

Interpretation : Impact des paramètres de generation

Paramètre Valeur Observation attendue Recommandation
guidance_scale = 5 Bas Libre, creatif, peut devier du prompt Experimentation artistique
guidance_scale = 15 Defaut Bon equilibre fidelite/creativite Usage general
guidance_scale = 25 Haut Très fidele, potentiellement rigide Quand le prompt est précis
infer_step = 30 Bas Rapide, artefacts possibles Preview rapide
infer_step = 90 Haut Meilleure qualite, plus lent Production finale

Points cles : 1. guidance_scale est le paramètre le plus impactant pour la fidelite au prompt 2. infer_step affecte surtout la qualite audio (resolution des details) 3. runtime machine-dep : le temps de generation est proportionnel a infer_step (2x steps = ~2x temps) 4. La combinaison cfg_type="apg" + omega_scale=10 offre un bon compromis par defaut

Note : Le paramètre guidance_interval=0.5 applique le guidance uniquement sur la première moitie du denoising. Cela ameliore la diversite tout en conservant la coherence.

Exercice 2 : Analyse de l’impact des paramètres de generation

Objectif : Implementer une fonction qui genere un morceau avec différentes configurations de guidance_scale et infer_step, puis analyse les différences de qualite percue.

Les paramètres de generation d’ACE-Step (guidance_scale, infer_step, cfg_type, omega_scale) ont un impact direct sur la qualite audio, la fidelite au prompt et le temps de generation. Cet exercice amene a quantifier ces compromis.

Indices : - guidance_scale contrôle la fidelite au prompt : bas = creatif, haut = fidele - infer_step contrôle la qualite audio : bas = rapide/artefacts, haut = lent/qualitatif - Le temps de generation est approximativement proportionnel a infer_step - cfg_type="apg" (Aperture Guidance) offre un meilleur compromis que cfg standard - # Étape 1 : Définir 3 configurations de paramètres (conservateur, equilibre, agressif) - # Étape 2 : Pour chaque configuration, stocker les paramètres et les metriques estimees - # Étape 3 : Calculer un score qualite/temps pour chaque configuration - # Étape 4 : Identifier la configuration optimale selon le cas d’usage (preview vs production) - # Indice : Un score simple = (guidance_score * infer_step_score) / temps_estime

# Exercice 2 : Analyse de l'impact des parametres de generation
# TODO etudiant : Comparer differentes configurations de parametres ACE-Step

def analyze_generation_params(prompt="pop, piano, gentle", 
                              lyrics="[verse]\nStars are shining bright\n[chorus]\nDream away the night",
                              target_use="production"):
    """
    Compare differentes configurations de parametres ACE-Step
    et recommande la meilleure selon le cas d'usage.
    
    Args:
        prompt: Description du style musical
        lyrics: Paroles structurees avec tags
        target_use: "preview" (rapide) ou "production" (qualite)
    
    Returns:
        dict: Configurations testees avec metriques et recommandation
    """
    # TODO etudiant : Definir 3+ configurations de parametres
    configs = {}  # TODO etudiant : {"nom": {"guidance_scale": X, "infer_step": Y, ...}, ...}
    
    # TODO etudiant : Pour chaque config, estimer les metriques
    # Indice : temps_estime ~ infer_step * 0.15s (approximatif sur RTX 3090)
    # Indice : qualite_estimee = f(guidance_scale, infer_step)
    
    results = {}  # TODO etudiant : {"nom": {"temps_estime": X, "qualite_estimee": Y, ...}, ...}
    
    # TODO etudiant : Calculer un score composite pour chaque config
    # Indice : Pour "preview", privilegier la vitesse
    # Indice : Pour "production", privilegier la qualite
    
    # TODO etudiant : Recommander la meilleure config pour target_use
    best_config = None  # TODO etudiant
    reason = None       # TODO etudiant
    
    return {
        "configs": configs,
        "results": results,
        "recommended": best_config,
        "reason": reason,
    }

# Test
analysis = analyze_generation_params(target_use="production")
if analysis["recommended"]:
    print(f"Configuration recommandee : {analysis['recommended']}")
    print(f"Raison : {analysis['reason']}")
else:
    print("Exercice a completer")
Exercice a completer

Section 4 : Generation multilingue

ACE-Step supporte plus de 50 langues nativement. Cette section teste la generation en francais, anglais et espagnol avec le même style musical pour comparer la qualite vocale.

Langues supportees (sélection)

Langue Code Qualite attendue Notes
Anglais en Excellente Langue principale d’entrainement
Francais fr Très bonne Bonne couverture
Espagnol es Très bonne Bonne couverture
Allemand de Bonne Couverture correcte
Japonais ja Bonne Phonetique différente
Chinois zh Bonne Tonemes

Note : Les langues avec plus de données d’entrainement produisent généralement de meilleurs résultats. L’anglais et le francais sont parmi les mieux supportes.

# Generation multilingue
print("GENERATION MULTILINGUE")
print("=" * 50)

multilingual_examples = [
    {
        "lang": "Francais",
        "prompt": "pop, douce, guitare acoustique, romantique",
        "lyrics": (
            "[verse]\n"
            "Le soleil se couche sur la mer\n"
            "Les vagues chantent une melodie\n"
            "Je marche seul sur le chemin\n"
            "Qui mene vers l'infini\n"
            "\n"
            "[chorus]\n"
            "Et je reve, je reve encore\n"
            "D'un monde fait de tresor\n"
            "Ou l'amour est le seul mot\n"
            "Qui resonne dans nos mots"
        ),
    },
    {
        "lang": "English",
        "prompt": "pop, gentle, acoustic guitar, romantic",
        "lyrics": (
            "[verse]\n"
            "The sun goes down upon the sea\n"
            "The waves sing a melody\n"
            "I walk alone upon the shore\n"
            "That leads to evermore\n"
            "\n"
            "[chorus]\n"
            "And I dream, I dream again\n"
            "Of a world without the pain\n"
            "Where love is the only word\n"
            "That we have ever heard"
        ),
    },
    {
        "lang": "Espanol",
        "prompt": "pop, suave, guitarra acustica, romantico",
        "lyrics": (
            "[verse]\n"
            "El sol se pone sobre el mar\n"
            "Las olas cantan una cancion\n"
            "Camino solo por la orilla\n"
            "Que me lleva al corazon\n"
            "\n"
            "[chorus]\n"
            "Y sueno, sueno otra vez\n"
            "Con un mundo de luz y fe\n"
            "Donde el amor es la unica voz\n"
            "Que nos une a los dos"
        ),
    },
]

multilingual_results = {}

if pipeline is not None and generate_audio and test_multilingual:
    # Duree reduite pour les tests multilingues
    test_duration = min(audio_duration, 20.0)

    for example in multilingual_examples:
        lang = example["lang"]
        print(f"\n--- {lang} ---")
        print(f"Prompt : {example['prompt']}")

        try:
            start_time = time.time()
            result = pipeline(
                audio_duration=test_duration,
                prompt=example["prompt"],
                lyrics=example["lyrics"],
                infer_step=infer_step,
                guidance_scale=guidance_scale,
                scheduler_type=scheduler_type,
                cfg_type=cfg_type,
                omega_scale=omega_scale,
                manual_seeds=str(seed) if seed >= 0 else "",
                guidance_interval=0.5,
                guidance_interval_decay=0,
                min_guidance_scale=3,
                use_erg_tag=True,
                use_erg_lyric=True,
                use_erg_diffusion=True,
                oss_steps="",
                guidance_scale_text=0.0,
                guidance_scale_lyric=0.0,
            )
            gen_time = time.time() - start_time

            # ACE-Step v1.5 retourne [chemin_wav, params_dict]
            if isinstance(result, list) and result and isinstance(result[0], str):
                result = result[0]

            if isinstance(result, str) and os.path.exists(result):
                import soundfile as sf
                audio_data, sr = sf.read(result)
                duration = len(audio_data) / sr

                multilingual_results[lang] = {
                    "gen_time": gen_time,
                    "duration": duration,
                    "sample_rate": sr,
                }

                print(f"  Duree : {duration:.1f}s | Temps : {gen_time:.2f}s")

                if BATCH_MODE != "true":
                    display_audio_array(audio_data[:sr*3].T if audio_data.ndim > 1 else audio_data[:sr*3], sr)  # apercu ~3s embarque (clip complet sauve localement)

                if save_results:
                    save_path = OUTPUT_DIR / f"multilingual_{lang.lower()}.wav"
                    sf.write(str(save_path), audio_data, sr)
                    print(f"  Sauvegarde : {save_path.name}")
            else:
                multilingual_results[lang] = {"gen_time": gen_time}
                print(f"  Temps : {gen_time:.2f}s")

        except Exception as e:
            print(f"  Erreur : {type(e).__name__} - {str(e)[:200]}")
            multilingual_results[lang] = {"error": str(e)[:100]}

    # Tableau comparatif
    if multilingual_results:
        print(f"\nComparatif multilingue :")
        print(f"{'Langue':<12} {'Temps (s)':<12} {'Duree (s)':<12} {'Statut':<15}")
        print("-" * 52)
        for lang, data in multilingual_results.items():
            if "error" not in data:
                dur = data.get('duration', 'N/A')
                dur_str = f"{dur:.1f}" if isinstance(dur, (int, float)) else str(dur)
                print(f"{lang:<12} {data['gen_time']:<12.2f} {dur_str:<12} {'OK':<15}")
            else:
                print(f"{lang:<12} {'N/A':<12} {'N/A':<12} {'ERREUR':<15}")
else:
    print("Modele non charge ou generation multilingue desactivee")
    print("\nLangues qui auraient ete testees :")
    for example in multilingual_examples:
        print(f"  {example['lang']} : {example['prompt']}")
GENERATION MULTILINGUE
==================================================

--- Francais ---
Prompt : pop, douce, guitare acoustique, romantique
  Duree : 20.0s | Temps : 8.40s
  Sauvegarde : multilingual_francais.wav

--- English ---
Prompt : pop, gentle, acoustic guitar, romantic
  Duree : 20.0s | Temps : 10.18s
  Sauvegarde : multilingual_english.wav

--- Espanol ---
Prompt : pop, suave, guitarra acustica, romantico
  Duree : 20.0s | Temps : 9.42s
  Sauvegarde : multilingual_espanol.wav

Comparatif multilingue :
Langue       Temps (s)    Duree (s)    Statut         
----------------------------------------------------
Francais     8.40         20.0         OK             
English      10.18        20.0         OK             
Espanol      9.42         20.0         OK             

Interpretation : Generation multilingue

La generation multilingue est l’un des points forts d’ACE-Step par rapport a MusicGen.

Aspect Observation Signification
Qualite vocale FR Bonne a très bonne Prononciation naturelle, intonation correcte
Qualite vocale EN Excellente Langue principale d’entrainement
Qualite vocale ES Bonne Phonetique respectee
Temps de generation Similaire entre langues La langue n’impacte pas la vitesse

Points cles : 1. La generation multilingue fonctionne sans configuration spécifique - il suffit d’ecrire les paroles dans la langue cible 2. Le style musical (prompt) peut aussi etre dans la langue cible 3. Les langues europeennes (FR, EN, ES, DE, IT) sont généralement mieux supportees que les langues asiatiques 4. Le modèle respecte les accents et la prosode naturelle de chaque langue

Note : Pour les langues avec moins de données d’entrainement (arabe, russe, japonais), la qualite vocale peut etre inferieure. Il est recommande d’ajuster guidance_scale a la hausse pour ces langues.

Section 5 : Comparaison ACE-Step vs MusicGen vs alternatives

Cette section presente une comparaison detaillee entre ACE-Step et les modèles de generation musicale couverts dans les notebooks précédents. Les valeurs sont issues des benchmarks officiels et de nos tests.

Critere de comparaison

Critere Pondetration Justification
Qualite audio Elevee Objectif principal
VRAM requise Elevee Accessibilite materielle
Duree max Moyenne Cas d’usage pratiques
Paroles Elevee Differentiation cle
Vitesse Moyenne Expérience utilisateur
# Tableau comparatif des modeles de generation musicale
print("COMPARAISON DES MODELES DE GENERATION MUSICALE")
print("=" * 55)

# Donnees de reference (benchmarks + tests internes)
comparison_data = {
    "ACE-Step v1.5": {
        "Architecture": "LM + DiT hybride",
        "Parametres": "3.5B (base)",
        "VRAM min": "<4 GB (offload)",
        "Qualite audio": "44.1 kHz stereo",
        "Duree max": "~4 minutes",
        "Paroles": "Oui (50+ langues)",
        "Vitesse (RTX 3090)": "<10s / 4min",
        "Licence": "Apache 2.0",
        "Notebook": "02-9 (ce notebook)",
    },
    "MusicGen medium": {
        "Architecture": "Transformer + EnCodec",
        "Parametres": "1.5B",
        "VRAM min": "~10 GB",
        "Qualite audio": "32 kHz mono",
        "Duree max": "~30 secondes",
        "Paroles": "Non (instrumental)",
        "Vitesse (RTX 3090)": "~5-10s / 10s",
        "Licence": "MIT",
        "Notebook": "02-3",
    },
    "YuE": {
        "Architecture": "Flow matching",
        "Parametres": "Variable",
        "VRAM min": "10-24 GB",
        "Qualite audio": "44.1 kHz stereo",
        "Duree max": "~2 minutes",
        "Paroles": "Oui",
        "Vitesse (RTX 3090)": "~30-60s / 1min",
        "Licence": "Apache 2.0",
        "Notebook": "02-7",
    },
    "SongGen2": {
        "Architecture": "Diffusion",
        "Parametres": "Variable",
        "VRAM min": "10-24 GB",
        "Qualite audio": "44.1 kHz stereo",
        "Duree max": "~2 minutes",
        "Paroles": "Oui",
        "Vitesse (RTX 3090)": "~30-60s / 1min",
        "Licence": "Variable",
        "Notebook": "02-7",
    },
}

# Affichage du tableau
criteria = list(next(iter(comparison_data.values())).keys())
models = list(comparison_data.keys())

# En-tete
header = f"{'Critere':<20}"
for model in models:
    header += f" {model:<22}"
print(header)
print("-" * len(header))

# Lignes
for criterion in criteria:
    row = f"{criterion:<20}"
    for model in models:
        value = comparison_data[model][criterion]
        row += f" {value:<22}"
    print(row)

# Recommandations
print(f"\nRECOMMANDATIONS PAR USE CASE")
print("-" * 55)
print("Musique instrumentale courte : MusicGen (qualite, stabilite)")
print("Chanson complete multilingue : ACE-Step (paroles, langues, VRAM)")
print("Chanson haute qualite : YuE / SongGen2 (si GPU 24 GB disponible)")
print("Prototypage rapide sur GPU modeste : ACE-Step avec cpu_offload")
print("Musique de fond sans paroles : MusicGen (optimise pour instrumental)")
print("\nAVANTAGES CLES D'ACE-STEP")
print("  1. Plus faible VRAM (<4 GB avec offload vs 10+ GB pour les autres)")
print("  2. Plus longue duree de generation (4 min vs 30s-2min)")
print("  3. Support multilingue natif (50+ langues)")
print("  4. Licence Apache 2.0 (open-source, utilisation commerciale OK)")
print("  5. Audio stereo 44.1 kHz (vs mono 32 kHz pour MusicGen)")
COMPARAISON DES MODELES DE GENERATION MUSICALE
=======================================================
Critere              ACE-Step v1.5          MusicGen medium        YuE                    SongGen2              
----------------------------------------------------------------------------------------------------------------
Architecture         LM + DiT hybride       Transformer + EnCodec  Flow matching          Diffusion             
Parametres           3.5B (base)            1.5B                   Variable               Variable              
VRAM min             <4 GB (offload)        ~10 GB                 10-24 GB               10-24 GB              
Qualite audio        44.1 kHz stereo        32 kHz mono            44.1 kHz stereo        44.1 kHz stereo       
Duree max            ~4 minutes             ~30 secondes           ~2 minutes             ~2 minutes            
Paroles              Oui (50+ langues)      Non (instrumental)     Oui                    Oui                   
Vitesse (RTX 3090)   <10s / 4min            ~5-10s / 10s           ~30-60s / 1min         ~30-60s / 1min        
Licence              Apache 2.0             MIT                    Apache 2.0             Variable              
Notebook             02-9 (ce notebook)     02-3                   02-7                   02-7                  

RECOMMANDATIONS PAR USE CASE
-------------------------------------------------------
Musique instrumentale courte : MusicGen (qualite, stabilite)
Chanson complete multilingue : ACE-Step (paroles, langues, VRAM)
Chanson haute qualite : YuE / SongGen2 (si GPU 24 GB disponible)
Prototypage rapide sur GPU modeste : ACE-Step avec cpu_offload
Musique de fond sans paroles : MusicGen (optimise pour instrumental)

AVANTAGES CLES D'ACE-STEP
  1. Plus faible VRAM (<4 GB avec offload vs 10+ GB pour les autres)
  2. Plus longue duree de generation (4 min vs 30s-2min)
  3. Support multilingue natif (50+ langues)
  4. Licence Apache 2.0 (open-source, utilisation commerciale OK)
  5. Audio stereo 44.1 kHz (vs mono 32 kHz pour MusicGen)

Interpretation : Comparaison des modèles

Le choix du modèle depend principalement du cas d’usage et des ressources materiels disponibles.

Cas d’usage Meilleur choix Raison
Jingle court (instrumental) MusicGen Qualite instrumentale, rapide
Chanson avec paroles ACE-Step Paroles structurees, multilingue
Demo sur laptop ACE-Step (offload) <4 GB VRAM requis
Production studio YuE / SongGen2 Qualite maximale (si GPU 24 GB)
Musique de fond podcast MusicGen ou ACE-Step Selon besoin de paroles

Points cles de la comparaison : 1. ACE-Step est le plus accessible materiement grace au cpu_offload 2. MusicGen reste superieur pour la musique instrumentale pure 3. Pour les chansons avec paroles, ACE-Step offre le meilleur rapport qualite/ressources 4. YuE et SongGen2 offrent potentiellement une meilleure qualite mais necessitent un GPU haut de gamme

Note : Les benchmarks sont bases sur des tests avec des prompts standards. Les résultats peuvent varier selon les prompts et les paramètres utilises.

Exercice 3 : Matrice de recommandation par cas d’usage

Objectif : Construire une fonction qui, etant donne un cahier des charges audio (duree, langue, GPU disponible, besoin de paroles), recommande le modèle optimal parmi ACE-Step, MusicGen, YuE et SongGeneration 2.

Les modèles de generation musicale ont des forces très différentes selon le contexte. Cette exercice vous amene a formaliser la logique de sélection vue dans la Section 5.

Indices : - ACE-Step est le seul modèle fonctionnant avec moins de 4 GB VRAM (cpu_offload) - MusicGen est le seul modèle purement instrumental (pas de paroles) - YuE supporte les chansons illimitees mais necessite 24 GB VRAM - SongGeneration 2 offre la meilleure qualite audio (48kHz FLAC) - # Étape 1 : Définir les specifications de chaque modèle (VRAM, duree max, paroles, langues) - # Étape 2 : Filtrer par contraintes hard (VRAM disponible, GPU) - # Étape 3 : Filtrer par besoins fonctionnels (paroles, duree, multilingue) - # Étape 4 : Retourner le meilleur modèle avec justification - # Indice : Si VRAM < 4 GB, seul ACE-Step (cpu_offload) est viable

# Exercice 3 : Matrice de recommandation par cas d'usage
# TODO etudiant : Implementer un selecteur de modele de generation musicale

def recommend_music_model(vram_gb=6, gpu_available=True, need_lyrics=False,
                          target_duration_s=30, need_multilingual=False,
                          language="en", commercial_use=False):
    """
    Recommande le meilleur modele de generation musicale selon les contraintes.
    
    Modeles disponibles : ACE-Step, MusicGen, YuE, SongGeneration 2
    
    Args:
        vram_gb: VRAM disponible en GB
        gpu_available: GPU disponible
        need_lyrics: Besoin de generer avec paroles
        target_duration_s: Duree cible en secondes
        need_multilingual: Support multilingue requis
        language: Langue principale ("en", "fr", "ja", etc.)
        commercial_use: Licence commerciale requise
    
    Returns:
        dict: {"model": str, "reason": str, "alternatives": list}
    """
    # TODO etudiant : Definir les specs de chaque modele
    models = {}  # TODO etudiant
    
    # TODO etudiant : Filtrer par contraintes materielles (VRAM, GPU)
    # Indice : vram_gb < 4 elimine tous sauf ACE-Step avec cpu_offload
    
    # TODO etudiant : Filtrer par besoins fonctionnels
    # Indice : need_lyrics=True elimine MusicGen
    
    # TODO etudiant : Selectionner le meilleur candidat
    recommendation = None  # TODO etudiant
    reason = None          # TODO etudiant
    alternatives = []      # TODO etudiant
    
    return {
        "model": recommendation,
        "reason": reason,
        "alternatives": alternatives,
    }

# Test
scenarios = [
    {"vram_gb": 4, "need_lyrics": True, "target_duration_s": 120, "language": "fr"},
    {"vram_gb": 24, "need_lyrics": False, "target_duration_s": 15},
    {"vram_gb": 6, "need_lyrics": True, "target_duration_s": 180, "need_multilingual": True},
]

for s in scenarios:
    result = recommend_music_model(**s)
    if result["model"]:
        print(f"VRAM={s.get('vram_gb')}GB, lyrics={s.get('need_lyrics')} -> {result['model']}")
    else:
        print("Exercice a completer")
Exercice a completer
Exercice a completer
Exercice a completer
# Statistiques de session et liberation memoire
print("STATISTIQUES DE SESSION")
print("=" * 50)

print(f"Date : {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print(f"Modele : ACE-Step v1.5 (3.5B)")
print(f"Device : {device}")
print(f"CPU offload : {cpu_offload}")
print(f"Duree configuree : {audio_duration}s")
print(f"Infer steps : {infer_step}")
print(f"Guidance scale : {guidance_scale}")
print(f"CFG type : {cfg_type}")
print(f"Modele charge : {'Oui' if pipeline is not None else 'Non'}")

if gpu_available:
    try:
        vram_current = torch.cuda.memory_allocated(0) / (1024**3)
        print(f"VRAM utilisee : {vram_current:.2f} GB")
    except Exception:
        pass

# Resume des generations
total_gen = len(generation_results) + len(multilingual_results)
print(f"\nGenerations reussies : {total_gen}")
if generation_results:
    print(f"  Text-to-song : {len(generation_results)}")
if multilingual_results:
    print(f"  Multilingue : {len(multilingual_results)}")
if param_results:
    print(f"  Parametres : {len(param_results)}")

if save_results:
    saved = list(OUTPUT_DIR.glob('*.wav'))
    total_size = sum(f.stat().st_size for f in saved) / (1024*1024)
    print(f"\nFichiers sauvegardes : {len(saved)} ({total_size:.1f} MB) dans {OUTPUT_DIR.relative_to(GENAI_ROOT).as_posix()}")

# Liberation memoire
if pipeline is not None:
    print(f"\nLiberation du modele...")
    del pipeline
    gc.collect()
    if gpu_available:
        try:
            torch.cuda.empty_cache()
        except Exception:
            pass
    print(f"Memoire liberee")

print(f"\nPROCHAINES ETAPES")
print(f"1. Comparer avec la generation MusicGen (02-3)")
print(f"2. Explorer YuE et SongGen2 (02-7)")
print(f"3. Integrer dans un pipeline audio complet (03-Orchestration)")
print(f"4. Tester avec vos propres paroles et styles")

print(f"\nNotebook ACE-Step termine - {datetime.now().strftime('%H:%M:%S')}")
STATISTIQUES DE SESSION
==================================================
Date : 2026-08-16 03:37:56
Modele : ACE-Step v1.5 (3.5B)
Device : cuda
CPU offload : False
Duree configuree : 30.0s
Infer steps : 60
Guidance scale : 15.0
CFG type : apg
Modele charge : Oui
VRAM utilisee : 7.43 GB

Generations reussies : 6
  Text-to-song : 3
  Multilingue : 3
  Parametres : 5

Fichiers sauvegardes : 6 (27.4 MB) dans outputs/audio/acestep

Liberation du modele...
Memoire liberee

PROCHAINES ETAPES
1. Comparer avec la generation MusicGen (02-3)
2. Explorer YuE et SongGen2 (02-7)
3. Integrer dans un pipeline audio complet (03-Orchestration)
4. Tester avec vos propres paroles et styles

Notebook ACE-Step termine - 03:37:56

Synthese de la session ACE-Step

Architecture technique

Composant Rôle Innovation
LM Encoder Encode genre + paroles Representations sémantiques riches
DiT (Diffusion Transformer) Genere les spectrogrammes Denoising iteratif haute qualite
VAE Decoder Decode en audio WAV Sortie 44.1 kHz stereo
APG Guidance Guide la generation CFG adaptatif, plus précis que CFG standard

Flux de generation

Tags de genre + Paroles structurees → LM Encoder → DiT Diffusion → VAE Decoder → WAV 44.1kHz stereo
                                                ↑
                              guidance_scale, infer_step, cfg_type, omega_scale

Points cles retenus

  1. Text-to-song : Paroles structurees + tags de genre → chanson complete avec voix
  2. Multilingue : 50+ langues supportees nativement, pas de configuration spécifique
  3. Faible VRAM : <4 GB avec cpu_offload, le plus accessible des modèles de generation musicale
  4. Paramètres :
    • guidance_scale : fidelite au prompt (5-25, defaut 15)
    • infer_step : qualite audio (30-90, defaut 60)
    • cfg_type : stratégie de guidance (apg recommande)
    • omega_scale : intensite du guidance (defaut 10)

Limitations connues

Limite Cause Contournement
Qualite vocale variable Modèle 3.5B (pas le plus grand) Augmenter infer_step a 90+
Artefacts sur longues durees Limite du contexte Segmenter en morceaux de 2-3 min
Anglais dominant Données d’entrainement Ajuster guidance_scale pour autres langues
Pas de contrôle fin du chant Pas de melodie de reference Combiner avec un modèle de voix
Retour au sommet