# 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 MusicGen
model_size = "facebook/musicgen-medium" # small, medium ou large
duration_seconds = 10 # Duree de generation (secondes)
device = "cuda" # "cuda" ou "cpu"
temperature = 1.0 # Temperature de sampling (0.5-1.5)
# Configuration
generate_audio = True # Generer les fichiers audio
save_results = True # Sauvegarder les fichiers generes
test_melody_conditioning = True # Tester le melody conditioning
compare_models = False # Comparer small/medium (necessite plus de VRAM)MusicGen - Generation Musicale par IA
Module : 02-Audio-Advanced
Niveau : Intermediaire
Technologies : Meta MusicGen (AudioCraft), ~10 GB VRAM
Duree estimee : 45 minutes
Objectifs d’Apprentissage
Prerequis
- GPU NVIDIA avec au moins 10 GB VRAM (medium), 4 GB (small)
pip install audiocraft- Connaissances de base en traitement audio
Navigation : << 02-2 | Index | Suivant >>
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_size |
Variante de MusicGen | facebook/musicgen-medium |
duration_seconds |
Duree de generation | 10 secondes |
device |
Device d’exécution | cuda (GPU) ou cpu |
temperature |
Creativite du sampling | 1.0 (equilibre) |
generate_audio |
Activer la generation | True |
save_results |
Sauvegarder les WAV | True |
test_melody_conditioning |
Tester melody conditioning | True |
compare_models |
Comparer small/medium | False (couteux en VRAM) |
Note : Pour une première exécution, laissez les valeurs par defaut. Adjustez la temperature (0.8-1.2) pour explorer la creativite du modèle.
# Parameters
BATCH_MODE = "true"Introduction a MusicGen
MusicGen est un modèle de generation musicale developpe par Meta Research dans le cadre du projet AudioCraft. Contrairement aux modèles TTS (Text-to-Speech) qui generent de la parole, MusicGen genere de la musique instrumentale originale.
Architecture MusicGen
Text Description → Transformer Audio → Tokens Continus → EnCodec Decoder → Audio WAV
(1.5B params) (interleaved) (32kHz mono)
Innovations cles : - Tokens audio continus : Contrairement au discret tokens (VQ-VAE), MusicGen utilise des representations continues pour une meilleure qualite - Transformer mono-sequence : Generation rapide en une seule passe (pas d’auto-regression lente) - EnCodec integre : Decodeur audio haute qualite integre au modèle
Applications typiques
| Use case | Description | Exemple de prompt |
|---|---|---|
| Musique de fond | Videos, podcasts, presentations | “Calm ambient music, soft pads” |
| Prototypage musical | Idees melodieques, arrangements | “Jazz piano with walking bass” |
| Sound design | Ambiances, effets sonores | “Ethereal pads with reverb” |
| Education musicale | Demonstration de styles | “Classical orchestra, strings” |
Les paramètres Papermill definissent la variante du modèle (small, medium, large), la duree de generation et la temperature de sampling. La cellule suivante configure l’environnement et verifie la VRAM disponible.
# Setup environnement et imports
import os
import sys
import json
import time
import gc
from pathlib import Path
import warnings
warnings.filterwarnings('ignore', message='torch.nn.utils.weight_norm is deprecated')
from datetime import datetime
from typing import Dict, List, Any, Optional
import logging
import numpy as np
import soundfile as sf
from IPython.display import Audio, display, HTML
# 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' / 'musicgen'
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
# Configuration logging
logging.basicConfig(level=getattr(logging, debug_level))
logger = logging.getLogger('musicgen')
# Verification GPU
gpu_available = False
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 - MusicGen sera tres lent sur CPU")
if device == "cuda":
device = "cpu"
print("Fallback vers CPU")
except ImportError:
print("torch non installe")
device = "cpu"
print(f"\nMusicGen - Generation Musicale par IA")
print(f"Date : {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print(f"Mode : {notebook_mode}, Device : {device}")
print(f"Modele : {model_size}, Duree : {duration_seconds}s")
print(f"Temperature : {temperature}")
print(f"Sortie : GenAI/{OUTPUT_DIR.relative_to(GENAI_ROOT)}")Helpers audio importes
GPU : NVIDIA GeForce RTX 3090 (24.0 GB VRAM)
MusicGen - Generation Musicale par IA
Date : 2026-08-16 03:47:47
Mode : interactive, Device : cuda
Modele : facebook/musicgen-medium, Duree : 10s
Temperature : 1.0
Sortie : GenAI/outputs\audio\musicgen
Interpretation : Configuration de l’environnement
L’environnement est maintenant configure pour MusicGen.
| Composant | Statut | Rôle |
|---|---|---|
| GPU detecte | RTX 3090 (24 GB VRAM) | runtime machine-dep : acceleration de la generation (10-50x plus rapide que CPU) |
| Repertoire sortie | outputs/audio/musicgen/ |
Stockage des fichiers WAV generes |
| Helpers audio | Importes | Fonctions utilitaires pour lecture/sauvegarde |
| Logging | INFO niveau | Suivi des opérations et debugging |
Verification GPU : La presence d’un GPU NVIDIA avec CUDA est critique pour MusicGen. En mode CPU, runtime machine-dep : generation prendrait 10-50x plus de temps.
Note : Si aucun GPU n’est detecte, le notebook passera automatiquement en mode CPU mais affichera un avertissement sur runtime machine-dep : temps de generation elonges.
L’environnement est pret. La cellule suivante charge le fichier .env afin de recuperer le token HuggingFace necessaire pour telecharger les poids de MusicGen 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 des modèles GPU optionnels. Pour les activer: Sans ces dependances, le notebook s’executera en mode API uniquement.
Section 1 : Presentation de MusicGen
MusicGen est un modèle de generation musicale developpe par Meta dans le cadre du projet AudioCraft. Il genere de la musique mono-source de haute qualite a partir de descriptions textuelles.
Variantes disponibles
| Modèle | Paramètres | VRAM | Qualite | Vitesse |
|---|---|---|---|---|
musicgen-small |
300M | ~4 GB | Bonne | Rapide |
musicgen-medium |
1.5B | ~10 GB | Très bonne | Moyen |
musicgen-large |
3.3B | ~20 GB | Excellente | runtime machine-dep : lent |
musicgen-melody |
1.5B | ~10 GB | Très bonne | Moyen |
Modes de generation
| Mode | Description | Modèle requis |
|---|---|---|
| Text-to-music | Description textuelle -> musique | Tous |
| Melody conditioning | Melodie de reference + description -> musique | musicgen-melody |
| Continuation | Continuer un morceau existant | Tous |
# Chargement du modele MusicGen
print("CHARGEMENT DU MODELE MUSICGEN")
print("=" * 45)
musicgen_loaded = False
try:
from audiocraft.models import MusicGen
print(f"Chargement {model_size}...")
print(f"(Premier lancement : telechargement du modele)")
start_time = time.time()
musicgen = MusicGen.get_pretrained(model_size)
load_time = time.time() - start_time
musicgen_loaded = True
# Configuration de la generation
musicgen.set_generation_params(
duration=duration_seconds,
temperature=temperature,
top_k=250,
top_p=0.0, # Desactive si top_k > 0
cfg_coef=3.0 # Classifier-free guidance
)
print(f"Modele charge en {load_time:.1f}s")
print(f"Sample rate : {musicgen.sample_rate} Hz")
print(f"Duree configuree : {duration_seconds}s")
if gpu_available:
vram_used = torch.cuda.memory_allocated(0) / (1024**3)
print(f"VRAM utilisee : {vram_used:.2f} GB")
except ImportError:
print("audiocraft non installe")
print("Installation : pip install audiocraft")
except Exception as e:
print(f"Erreur lors du chargement : {type(e).__name__} - {str(e)[:200]}")CHARGEMENT DU MODELE MUSICGEN
=============================================
Chargement facebook/musicgen-medium...
(Premier lancement : telechargement du modele)
Modele charge en 8.7s
Sample rate : 32000 Hz
Duree configuree : 10s
VRAM utilisee : 4.10 GB
Interpretation : Chargement du modèle
Le chargement de MusicGen depend de la variante choisie (small/medium/large/melody).
| Aspect | Detail |
|---|---|
| Premier chargement | runtime machine-dep : telechargement depuis HuggingFace Hub (~1-10 GB selon modèle) |
| Chargements suivants | Cache local, beaucoup plus rapide |
| VRAM requise | 4 GB (small) a 20 GB (large) |
| Sample rate : 32 kHz | Qualite audio standard pour la musique generee |
En cas d’erreur : - ImportError: audiocraft : Installer avec pip install audiocraft - CUDA out of memory : Utiliser un modèle plus petit ou reduire la batch size - Connection error : Verifier la connexion internet pour le premier telechargement
Note technique : Le modèle reste en VRAM tant qu’il n’est pas explicitement supprime (
del musicgen). La liberation de la memoire est faite a la fin du notebook.
Section 2 : Generation text-to-music
La generation text-to-music est le mode principal de MusicGen. La description textuelle guide le style, les instruments, le tempo et l’ambiance.
Conseils pour les descriptions :
| Élément | Exemples | Impact |
|---|---|---|
| Genre | jazz, rock, classical, electronic | Style general |
| Instruments | piano, guitar, drums, synthesizer | Timbres |
| Tempo | slow, medium, fast, 120 BPM | Rythme |
| Ambiance | happy, melancholic, energetic, calm | Emotion |
| Qualite | high quality, lo-fi, crisp, warm | Production |
Generation text-to-music
Le code ci-dessous genere trois morceaux avec des styles différents pour demontrer la versatilite de MusicGen.
Descriptions choisies : 1. Jazz : Style instrumental avec piano et saxophone, tempo moyen 2. Ambient electronic : Musique d’ambiance calme, synthetiseurs, arpeges doux 3. Rock : Energie elevee, guitares electriques, batterie entrainante
Paramètres de generation : - duration : 10 secondes (configurable) - temperature : 1.0 (valeur par defaut, equilibre creativite/coherence) - top_k : 250 (filtre les 250 tokens les plus probables) - cfg_coef : 3.0 (fidelite a la description)
Processus : Pour chaque description, le code mesure le temps de generation, calcule la duree reelle, et affiche le ratio temps reel (generation / lecture).
# Generation text-to-music
print("GENERATION TEXT-TO-MUSIC")
print("=" * 45)
descriptions = [
"A happy upbeat jazz piece with piano and saxophone, medium tempo",
"Calm ambient electronic music with soft pads and gentle arpeggios",
"Energetic rock with electric guitar riffs and driving drums, high energy",
]
generation_results = {}
if musicgen_loaded and generate_audio:
for i, desc in enumerate(descriptions):
print(f"\n--- Morceau {i+1} ---")
print(f"Description : {desc}")
start_time = time.time()
wav = musicgen.generate([desc])
gen_time = time.time() - start_time
# wav shape: [batch, channels, samples]
samples = wav[0, 0].cpu().numpy()
sample_rate = musicgen.sample_rate
duration = len(samples) / sample_rate
generation_results[f"morceau_{i+1}"] = {
"description": desc,
"duration": duration,
"gen_time": gen_time
}
print(f" Duree : {duration:.1f}s | Temps de generation : {gen_time:.2f}s")
print(f" Ratio temps reel : {duration / gen_time:.2f}x")
display_audio_array(samples[:sample_rate * 3], sample_rate) # apercu ~3s embarque (clip complet sauvage localement, anti-bloat C.2)
if save_results:
filepath = OUTPUT_DIR / f"music_{i+1}_{desc[:30].replace(' ', '_')}.wav"
sf.write(str(filepath), samples, sample_rate)
print(f" Sauvegarde : {filepath.name}")
# Recapitulatif
print(f"\nRecapitulatif des generations :")
print(f"{'Morceau':<12} {'Duree (s)':<12} {'Temps gen (s)':<15} {'Description':<40}")
print("-" * 79)
for name, data in generation_results.items():
print(f"{name:<12} {data['duration']:<12.1f} {data['gen_time']:<15.2f} {data['description'][:40]}")
else:
print("Modele non charge ou generation desactivee")GENERATION TEXT-TO-MUSIC
=============================================
--- Morceau 1 ---
Description : A happy upbeat jazz piece with piano and saxophone, medium tempo
Duree : 10.0s | Temps de generation : 48.27s
Ratio temps reel : 0.21x
Sauvegarde : music_1_A_happy_upbeat_jazz_piece_with.wav
--- Morceau 2 ---
Description : Calm ambient electronic music with soft pads and gentle arpeggios
Duree : 10.0s | Temps de generation : 43.84s
Ratio temps reel : 0.23x
Sauvegarde : music_2_Calm_ambient_electronic_music_.wav
--- Morceau 3 ---
Description : Energetic rock with electric guitar riffs and driving drums, high energy
Duree : 10.0s | Temps de generation : 37.00s
Ratio temps reel : 0.27x
Sauvegarde : music_3_Energetic_rock_with_electric_g.wav
Recapitulatif des generations :
Morceau Duree (s) Temps gen (s) Description
-------------------------------------------------------------------------------
morceau_1 10.0 48.27 A happy upbeat jazz piece with piano and
morceau_2 10.0 43.84 Calm ambient electronic music with soft
morceau_3 10.0 37.00 Energetic rock with electric guitar riff
Les résultats montrent la capacite de MusicGen a generer de la musique instrumentale originale a partir de descriptions textuelles.
| Aspect | Valeur observee | Interpretation |
|---|---|---|
| Ratio temps reel | 0.24-0.27x (ce run) | La generation est plus lente que la lecture mais reste acceptable |
| Qualite audio | 32kHz mono | Qualite correcte pour demos et prototypage |
| Coherence texte | Bonne a très bonne | Le modèle suit les descriptions avec precision |
| Variabilite | Haute | Chaque generation est unique (non-déterministe) |
Analyse des exemples : 1. Jazz : Piano et saxophone dominants, rythme swing 2. Ambient : Pads synthetiques, evolution lente, atmospherique 3. Rock : Guitares electriques, batterie puissante, energie elevee
Points cles : - Les descriptions en anglais donnent les meilleurs résultats (langue d’entrainement) - La precision des termes musicaux influence la fidelite (instruments, tempo, ambiance) - Plus la description est detaillee, plus le résultat est spécifique
Note technique : La generation est stochastique - le même prompt peut donner des résultats différents a chaque appel. Cette variabilite est une feature, pas un bug.
Interpretation : Generation text-to-music
| Aspect | Valeur typique | Signification |
|---|---|---|
| Ratio temps reel | 0.24-0.27x (observe, GPU) | La generation musicale est plus lente que le TTS |
| Qualite audio | 32kHz mono | Qualite correcte pour la musique generee |
| Coherence | Bonne | La musique suit généralement bien la description |
Points cles : 1. Les descriptions en anglais donnent de meilleurs résultats (langue d’entrainement) 2. Plus la description est precise, plus le résultat est fidele 3. La generation est non-déterministe : deux appels donnent des résultats différents
Exercice 1 : Optimisation des Descriptions pour la Generation Musicale
Duree estimee : 15 minutes
La qualite de la musique generee par MusicGen depend directement de la precision de la description textuelle. Dans cet exercice, vous allez comparer des descriptions vagues vs detaillees et mesurer l’impact sur la coherence musicale.
Objectif : Pour un même style musical (jazz), rediger 3 descriptions de precision croissante (1 mot, 1 phrase, 1 description detaillee), generer l’audio pour chacune, et comparer la coherence du résultat.
Indices : - # Étape 1 : Ecrire 3 descriptions : “jazz”, “smooth jazz with saxophone”, “Smooth jazz piece with warm saxophone melody, walking bass line, gentle brush drums, slow tempo around 80 BPM” - # Étape 2 : Generer l’audio pour chaque description avec les mêmes paramètres (temperature=1.0, duration=8) - # Étape 3 : Calculer l’energie RMS et la variance de chaque audio comme indicateurs de coherence - # Indice : Une description plus precise devrait produire un signal plus stable (variance plus faible)
def compare_description_precision(descriptions, model, output_dir):
"""
Compare la qualite de generation selon la precision de la description.
Args:
descriptions (list): Liste de descriptions de precision croissante
model: Modele MusicGen charge
output_dir (Path): Repertoire de sauvegarde
Returns:
list: Liste de dictionnaires avec 'description', 'rms', 'variance'
"""
# TODO etudiant : implementer la comparaison
# Etape 1 : Pour chaque description, generer l'audio
# Etape 2 : Calculer RMS et variance de chaque signal
# Etape 3 : Sauvegarder et collecter les metriques
results = []
return results # TODO etudiant : retourner les resultats
# TODO etudiant : tester avec 3 descriptions de precision croissante
# jazz_descriptions = [
# "jazz",
# "smooth jazz with saxophone",
# "Smooth jazz piece with warm saxophone melody, walking bass line, gentle brush drums, slow tempo around 80 BPM"
# ]
# desc_results = compare_description_precision(jazz_descriptions, musicgen, OUTPUT_DIR)
# for r in desc_results:
# print(f"Desc: {r['description'][:40]:<42} RMS: {r['rms']:.4f} Var: {r['variance']:.6f}")
print("Exercice a completer")Exercice a completer
Section 3 : Paramètres de generation
Les paramètres de sampling influencent la diversite et la qualite de la musique generee.
| Paramètre | Valeur par defaut | Plage | Impact |
|---|---|---|---|
temperature |
1.0 | 0.5-1.5 | Diversite (bas=conservateur, haut=creatif) |
top_k |
250 | 0-1000 | Filtre les k tokens les plus probables |
top_p |
0.0 | 0.0-1.0 | Nucleus sampling (0 = desactive) |
cfg_coef |
3.0 | 1.0-10.0 | Fidelite a la description (haut=plus fidele) |
duration |
10 | 1-30 | Duree en secondes |
# Test des parametres de generation
print("TEST DES PARAMETRES")
print("=" * 45)
test_description = "A gentle classical piano melody, slow tempo, emotional"
temperatures = [0.5, 0.8, 1.0, 1.2]
param_results = {}
if musicgen_loaded and generate_audio:
print(f"Description : {test_description}")
print(f"Duree : {duration_seconds}s")
for temp in temperatures:
print(f"\nTemperature = {temp}")
musicgen.set_generation_params(
duration=duration_seconds,
temperature=temp,
top_k=250,
top_p=0.0,
cfg_coef=3.0
)
start_time = time.time()
wav = musicgen.generate([test_description])
gen_time = time.time() - start_time
samples = wav[0, 0].cpu().numpy()
sample_rate = musicgen.sample_rate
duration = len(samples) / sample_rate
# Mesure de la dynamique (indicateur indirect de diversite)
rms = np.sqrt(np.mean(samples**2))
peak = np.max(np.abs(samples))
dynamic_range = 20 * np.log10(peak / (rms + 1e-10))
param_results[temp] = {
"gen_time": gen_time,
"rms": rms,
"dynamic_range": dynamic_range
}
print(f" Temps : {gen_time:.2f}s | RMS : {rms:.4f} | Dynamic range : {dynamic_range:.1f} dB")
display_audio_array(samples[:sample_rate * 3], sample_rate) # apercu ~3s embarque (clip complet sauvage localement, anti-bloat C.2)
if save_results:
filepath = OUTPUT_DIR / f"temp_{temp:.1f}.wav"
sf.write(str(filepath), samples, sample_rate)
# Restaurer les parametres par defaut
musicgen.set_generation_params(
duration=duration_seconds,
temperature=temperature,
top_k=250,
top_p=0.0,
cfg_coef=3.0
)
# Tableau recapitulatif
print(f"\nRecapitulatif :")
print(f"{'Temperature':<14} {'Temps gen (s)':<15} {'RMS':<10} {'Dyn. range (dB)':<16}")
print("-" * 55)
for temp, data in param_results.items():
print(f"{temp:<14.1f} {data['gen_time']:<15.2f} {data['rms']:<10.4f} {data['dynamic_range']:<16.1f}")
else:
print("Modele non charge ou generation desactivee")TEST DES PARAMETRES
=============================================
Description : A gentle classical piano melody, slow tempo, emotional
Duree : 10s
Temperature = 0.5
Temps : 39.03s | RMS : 0.0077 | Dynamic range : 22.3 dB
Temperature = 0.8
Temps : 37.61s | RMS : 0.0285 | Dynamic range : 15.9 dB
Temperature = 1.0
Temps : 38.90s | RMS : 0.0715 | Dynamic range : 16.6 dB
Temperature = 1.2
Temps : 35.40s | RMS : 0.2030 | Dynamic range : 13.0 dB
Recapitulatif :
Temperature Temps gen (s) RMS Dyn. range (dB)
-------------------------------------------------------
0.5 39.03 0.0077 22.3
0.8 37.61 0.0285 15.9
1.0 38.90 0.0715 16.6
1.2 35.40 0.2030 13.0
Impact des paramètres de generation
Cette section teste systematiquement l’impact de la temperature sur le style musical genere.
Hypotheses : - Temperature basse (0.5) : runtime machine-dep : generation conservatrice, repetitive, previsible - Temperature moyenne (0.8-1.0) : Equilibre entre coherence et creativite - Temperature elevee (1.2+) : Generation audacieuse, parfois incoherente
Methodologie : 1. Fixer tous les paramètres sauf la temperature 2. Generer 4 versions de la même description 3. Mesurer les metriques audio : RMS (energie), dynamique (variance) 4. Comparer subjectivement la qualite musicale
Metriques mesurees : - RMS (Root Mean Square) : Energie moyenne du signal - Dynamic range : Différence entre crete et RMS (en dB)
Note : La temperature n’influence pas le temps de generation de maniere significative. Le cout computationnel est principal determine par la taille du modèle et la duree.
Interpretation : Paramètres de generation
| Temperature | Observation | Recommandation |
|---|---|---|
| 0.5 | Conservateur, peu varie | Quand on veut un résultat previsible |
| 0.8 | Bon equilibre | Usage general |
| 1.0 | Standard, creatif | Exploration, diversite |
| 1.2 | Très creatif, parfois incoherent | Experimentation |
Points cles : 1. runtime machine-dep : la temperature n’affecte pas significativement le temps de generation 2. Des temperatures elevees augmentent la diversite mais peuvent reduire la coherence 3. Le cfg_coef contrôle la fidelite a la description (3.0 est un bon defaut)
Exercice 2 : Exploration Systématique du Paramètre cfg_coef
Duree estimee : 15 minutes
Le paramètre cfg_coef (Classifier-Free Guidance) contrôle la fidelite de la musique generee par rapport a la description textuelle. Dans cet exercice, vous allez tester 4 valeurs de cfg_coef avec la même description et mesurer l’impact sur la dynamique audio.
Objectif : Fixer temperature=1.0, tester cfg_coef a 1.0, 3.0, 5.0 et 8.0, puis comparer la plage dynamique (dB) de chaque sortie.
Indices : - # Étape 1 : Utiliser musicgen.set_generation_params(cfg_coef=valeur) pour changer le paramètre - # Étape 2 : Pour chaque valeur, generer l’audio et calculer la plage dynamique : 20 * np.log10(peak / (rms + 1e-10)) - # Étape 3 : Un cfg_coef eleve produit une musique plus fidele a la description mais potentiellement plus plate dynamiquement - # Indice : La valeur par defaut 3.0 est un bon compromis ; les valeurs extremes (>7) peuvent produire des artefacts
def explore_cfg_coef(description, cfg_values, model, output_dir):
"""
Teste l'impact du cfg_coef sur la generation musicale.
Args:
description (str): Description textuelle de la musique
cfg_values (list): Liste de valeurs de cfg_coef a tester
model: Modele MusicGen charge
output_dir (Path): Repertoire de sauvegarde
Returns:
dict: Resultats {cfg_value: {'rms', 'peak', 'dynamic_range'}}
"""
# TODO etudiant : implementer l'exploration du cfg_coef
# Etape 1 : Pour chaque valeur, appeler model.set_generation_params(cfg_coef=valeur)
# Etape 2 : Generer l'audio avec model.generate([description])
# Etape 3 : Calculer RMS, peak et dynamic range pour chaque sortie
results = {}
return results # TODO etudiant : retourner les resultats
# TODO etudiant : tester avec une description et 4 valeurs de cfg_coef
# cfg_desc = "Gentle acoustic guitar with soft strings, calm and peaceful"
# cfg_vals = [1.0, 3.0, 5.0, 8.0]
# cfg_results = explore_cfg_coef(cfg_desc, cfg_vals, musicgen, OUTPUT_DIR)
# print(f"{'CFG Coef':<12} {'RMS':<10} {'Peak':<10} {'Dyn Range (dB)':<15}")
# for val, data in cfg_results.items():
# print(f"{val:<12.1f} {data['rms']:<10.4f} {data['peak']:<10.4f} {data['dynamic_range']:<15.1f}")
print("Exercice a completer")Exercice a completer
Section 4 : Melody conditioning
Le melody conditioning permet de fournir une melodie de reference que le modèle reproduira avec le style demande dans la description textuelle.
| Élément | Description |
|---|---|
| Entree melodie | Audio WAV avec la melodie de base |
| Entree texte | Description du style souhaite |
| Sortie | Musique combinant la melodie et le style |
Note : Le melody conditioning necessite le modèle
musicgen-melodyspécifique.
# Melody conditioning
print("MELODY CONDITIONING")
print("=" * 45)
if musicgen_loaded and generate_audio and test_melody_conditioning:
# Creer une melodie de reference simple (sinusoides)
print("Creation d'une melodie de reference synthetique...")
melody_sr = musicgen.sample_rate
t = np.linspace(0, duration_seconds, int(melody_sr * duration_seconds), endpoint=False)
# Melodie simple : Do-Mi-Sol-Do (arpege de Do majeur)
freqs = [261.63, 329.63, 392.00, 523.25] # C4, E4, G4, C5
melody_samples = np.zeros_like(t)
note_duration = duration_seconds / len(freqs)
for i, freq in enumerate(freqs):
start_idx = int(i * note_duration * melody_sr)
end_idx = int((i + 1) * note_duration * melody_sr)
note_t = t[start_idx:end_idx]
# Enveloppe ADSR simplifiee
envelope = np.minimum(1.0, (note_t - note_t[0]) * 10) * np.exp(-1.5 * (note_t - note_t[0]))
melody_samples[start_idx:end_idx] = 0.5 * np.sin(2 * np.pi * freq * note_t) * envelope
melody_path = OUTPUT_DIR / "melody_reference.wav"
sf.write(str(melody_path), melody_samples, melody_sr)
print(f"Melodie de reference : {melody_path.name} ({duration_seconds}s)")
display_audio_array(melody_samples[:melody_sr * 3], melody_sr) # apercu ~3s embarque (clip complet sauvage localement, anti-bloat C.2)
# Chargement du modele melody (si different)
melody_model_name = "facebook/musicgen-melody"
if model_size != melody_model_name:
print(f"\nChargement du modele melody ({melody_model_name})...")
try:
melody_model = MusicGen.get_pretrained(melody_model_name)
melody_model.set_generation_params(
duration=duration_seconds,
temperature=temperature
)
melody_model_loaded = True
except Exception as e:
print(f"Erreur : {str(e)[:100]}")
print("Utilisation du modele principal sans conditioning")
melody_model_loaded = False
else:
melody_model = musicgen
melody_model_loaded = True
# Generation avec melody conditioning
style_descriptions = [
"Jazz version with saxophone and piano",
"Electronic ambient version with synthesizers and reverb",
]
if melody_model_loaded:
import torchaudio
melody_tensor, _ = torchaudio.load(str(melody_path))
melody_tensor = melody_tensor.unsqueeze(0) # [1, channels, samples]
for i, style in enumerate(style_descriptions):
print(f"\nStyle : {style}")
start_time = time.time()
wav = melody_model.generate_with_chroma(
descriptions=[style],
melody_wavs=melody_tensor,
melody_sample_rate=melody_sr
)
gen_time = time.time() - start_time
samples = wav[0, 0].cpu().numpy()
print(f" Temps : {gen_time:.2f}s")
display_audio_array(samples[:musicgen.sample_rate * 3], musicgen.sample_rate) # apercu ~3s embarque (clip complet sauvage localement, anti-bloat C.2)
if save_results:
filepath = OUTPUT_DIR / f"melody_style_{i+1}.wav"
sf.write(str(filepath), samples, musicgen.sample_rate)
# Liberation modele melody si charge separement
if model_size != melody_model_name:
del melody_model
gc.collect()
if gpu_available:
torch.cuda.empty_cache()
else:
print("Modele melody non disponible")
else:
print("Melody conditioning desactive ou modele non charge")MELODY CONDITIONING
=============================================
Creation d'une melodie de reference synthetique...
Melodie de reference : melody_reference.wav (10s)
Chargement du modele melody (facebook/musicgen-melody)...
Style : Jazz version with saxophone and piano
Temps : 24.41s
Style : Electronic ambient version with synthesizers and reverb
Temps : 21.90s
Approche technique du melody conditioning
Le melody conditioning repose sur l’extraction du chromagram de la melodie de reference.
| Étape | Description | Sortie |
|---|---|---|
| 1. Chargement audio | Fichier WAV reference | Tensor [channels, samples] |
| 2. Extraction chroma | Analyse des frequences fondamentales | Representation chromatique (12 tons) |
| 3. Fusion | Combinaison chroma + description textuelle | Generation conditionnee |
Avantages du melody conditioning : - Preserve la structure melodique (notes, rythme) - Change l’arrangement (instruments, style, ambiance) - Permet de créer des variations sur un thème
Melodie synthetique de reference : Le code ci-dessous genere une melodie simple (arpege Do-Mi-Sol-Do) pour demontrer le concept sans fichier audio externe.
Note technique : Le modèle
musicgen-melodyest specifiquement entraine pour cette tâche. Les autres modèles peuvent generer avecgenerate_with_chroma()mais avec des résultats moins fideles.
Interpretation : Melody conditioning
| Aspect | Observation | Signification |
|---|---|---|
| Fidelite melodique | Bonne | La melodie de base est recognaissable |
| Adaptation de style | Très bonne | Les instruments et l’ambiance changent |
| Temps de generation | Similaire | Le conditioning n’ajoute pas de surcout majeur |
Points cles : 1. Le melody conditioning extrait le chroma (contenu melodique) de la reference 2. L’arrangement et les instruments sont determines par la description textuelle 3. Le modèle musicgen-melody est specifiquement entraine pour cette tâche
Exercice 3 : Generation de Musique avec Melodie Personnalisee
Duree estimee : 15 minutes
Le melody conditioning permet de combiner une melodie de reference avec un style musical decrit par texte. Dans cet exercice, vous allez créer une melodie synthetique personnalisee et la faire rejouer par MusicGen dans 2 styles différents.
Objectif : Créer une melodie basee sur une gamme pentatonique (Do-Re-Mi-Sol-La), la sauvegarder, puis generer 2 versions avec des descriptions de style contrastées (classique et electronique).
Indices : - # Étape 1 : Définir les frequences de la gamme pentatonique de Do majeur : 261.63, 293.66, 329.63, 392.00, 440.00 Hz - # Étape 2 : Créer un signal audio avec np.sin(2 * np.pi * freq * t) et une enveloppe d’amortissement pour chaque note - # Étape 3 : Sauvegarder la melodie en WAV, puis appeler melody_model.generate_with_chroma() avec 2 descriptions différentes - # Indice : Utiliser torchaudio.load() pour charger la melodie en tensor avant de la passer au modèle
def create_pentatonic_melody(duration, sample_rate, output_path):
"""
Cree une melodie basee sur la gamme pentatonique et la sauvegarde.
Args:
duration (float): Duree totale en secondes
sample_rate (int): Frequence d'echantillonnage
output_path (Path): Chemin de sauvegarde WAV
Returns:
np.array: Le signal audio genere
"""
# TODO etudiant : generer les notes de la gamme pentatonique
# Etape 1 : Definir les frequences [261.63, 293.66, 329.63, 392.00, 440.00]
# Etape 2 : Repartir equitablement la duree entre les notes
# Etape 3 : Ajouter une enveloppe d'amortissement (exponential decay)
result = None # TODO etudiant : remplacer par le signal genere
return result
# TODO etudiant : creer la melodie et la sauvegarder
# pent_melody = create_pentatonic_melody(10, 32000, OUTPUT_DIR / "pentatonic_melody.wav")
# TODO etudiant : charger le modele musicgen-melody et generer 2 versions
# Style 1: "Classical string quartet, elegant and refined"
# Style 2: "Electronic synthwave with heavy bass and reverb"
print("Exercice a completer")Exercice a completer
# Mode interactif - Generation personnalisee
if notebook_mode == "interactive" and not skip_widgets:
print("MODE INTERACTIF - GENERATION MUSICALE PERSONNALISEE")
print("=" * 55)
print("\nDecrivez la musique que vous souhaitez generer :")
print("(Laissez vide pour passer a la suite)")
print("Exemple : 'A calm acoustic guitar melody with soft percussion'")
try:
user_desc = input("\nDescription : ")
if user_desc.strip() and musicgen_loaded:
user_duration = input(f"Duree [{duration_seconds}s] (1-30) : ").strip()
user_duration = int(user_duration) if user_duration else duration_seconds
user_duration = max(1, min(30, user_duration))
musicgen.set_generation_params(
duration=user_duration,
temperature=temperature,
top_k=250,
cfg_coef=3.0
)
print(f"\nGeneration en cours ({user_duration}s)...")
start_time = time.time()
wav = musicgen.generate([user_desc])
gen_time = time.time() - start_time
samples = wav[0, 0].cpu().numpy()
print(f"Genere en {gen_time:.2f}s")
display_audio_array(samples[:musicgen.sample_rate * 3], musicgen.sample_rate) # apercu ~3s embarque (clip complet sauvage localement, anti-bloat C.2)
if save_results:
ts = datetime.now().strftime('%Y%m%d_%H%M%S')
filepath = OUTPUT_DIR / f"custom_{ts}.wav"
sf.write(str(filepath), samples, musicgen.sample_rate)
print(f"Sauvegarde : {filepath.name}")
# Restaurer la duree par defaut
musicgen.set_generation_params(
duration=duration_seconds,
temperature=temperature,
top_k=250,
cfg_coef=3.0
)
else:
print("Mode interactif ignore")
except (KeyboardInterrupt, EOFError):
print("Mode interactif interrompu")
except Exception as e:
error_type = type(e).__name__
if "StdinNotImplemented" in error_type or "input" in str(e).lower():
print("Mode interactif non disponible (execution automatisee)")
else:
print(f"Erreur : {error_type} - {str(e)[:100]}")
else:
print("Mode batch - Interface interactive desactivee")MODE INTERACTIF - GENERATION MUSICALE PERSONNALISEE
=======================================================
Decrivez la musique que vous souhaitez generer :
(Laissez vide pour passer a la suite)
Exemple : 'A calm acoustic guitar melody with soft percussion'
Mode interactif non disponible (execution automatisee)
Interpretation : Mode interactif
Le mode interactif permet d’experimenter librement avec MusicGen en dehors des exemples predefinis.
| Aspect | Detail |
|---|---|
| Input utilisateur | Description textuelle libre + duree optionnelle |
| Flexibilite | Test rapide d’idees musicales sans modifier le code |
| Personnalisation | Ajustement dynamique des paramètres de generation |
| Sauvegarde | Fichiers nommes avec timestamp pour suivi |
Workflow recommande : 1. Commencer avec une description simple 2. Ajuster progressivement la temperature (0.8 → 1.0 → 1.2) 3. Affiner la description avec des termes plus spécifiques 4. Sauvegarder les versions prometteuses
Note pratique : Les descriptions en anglais donnent systematiquement de meilleurs résultats. Utilisez des traducteurs si necessaire.
Bonnes pratiques et guide de generation
Rediger de bonnes descriptions
| Élément | Bon exemple | Mauvais exemple |
|---|---|---|
| Genre | “Smooth jazz with piano” | “Jazz” |
| Ambiance | “Melancholic and introspective” | “Triste” |
| Instruments | “Acoustic guitar, soft drums, double bass” | “Guitare” |
| Tempo | “Slow tempo, around 70 BPM” | “Lent” |
Limites actuelles
| Limite | Description | Contournement |
|---|---|---|
| Duree max ~30s | Le modèle genere des extraits courts | Concatener plusieurs generations |
| Mono uniquement | Pas de stereo natif | Post-traitement avec panning |
| Pas de paroles | Genere uniquement de la musique instrumentale | Combiner avec un modèle TTS |
| Anglais | Les descriptions en anglais sont les plus efficaces | Traduire les descriptions |
Toutes les generations musicales sont maintenant terminees. La cellule suivante recapitule les résultats de la session et libere la VRAM occupee par MusicGen.
# Statistiques de session et prochaines etapes
print("STATISTIQUES DE SESSION")
print("=" * 45)
print(f"Date : {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print(f"Modele : {model_size}")
print(f"Device : {device}")
print(f"Duree configuree : {duration_seconds}s")
print(f"Temperature : {temperature}")
print(f"Modele charge : {'Oui' if musicgen_loaded else 'Non'}")
if gpu_available:
vram_current = torch.cuda.memory_allocated(0) / (1024**3)
print(f"VRAM utilisee : {vram_current:.2f} GB")
if save_results:
saved = list(OUTPUT_DIR.glob('*.wav'))
total_size = sum(f.stat().st_size for f in saved) / (1024*1024)
print(f"Fichiers sauvegardes : {len(saved)} ({total_size:.1f} MB) dans GenAI/{OUTPUT_DIR.relative_to(GENAI_ROOT)}")
# Liberation memoire
if musicgen_loaded:
print(f"\nLiberation du modele...")
del musicgen
gc.collect()
if gpu_available:
torch.cuda.empty_cache()
print(f"Memoire liberee")
print(f"\nPROCHAINES ETAPES")
print(f"1. Decouvrir la separation de sources avec Demucs (02-4)")
print(f"2. Comparer tous les modeles audio (03-1)")
print(f"3. Construire un pipeline vocal complet (03-2)")
print(f"4. Creer des compositions multi-etapes (04-3)")
print(f"\nNotebook MusicGen termine - {datetime.now().strftime('%H:%M:%S')}")STATISTIQUES DE SESSION
=============================================
Date : 2026-08-16 03:53:50
Modele : facebook/musicgen-medium
Device : cuda
Duree configuree : 10s
Temperature : 1.0
Modele charge : Oui
VRAM utilisee : 4.16 GB
Fichiers sauvegardes : 10 (6.1 MB) dans GenAI/outputs\audio\musicgen
Liberation du modele...
Memoire liberee
PROCHAINES ETAPES
1. Decouvrir la separation de sources avec Demucs (02-4)
2. Comparer tous les modeles audio (03-1)
3. Construire un pipeline vocal complet (03-2)
4. Creer des compositions multi-etapes (04-3)
Notebook MusicGen termine - 03:53:50
Synthese de la session MusicGen
Architecture technique
| Composant | Rôle | Impact |
|---|---|---|
| Encodeur audio | Transforme l’audio en tokens continus | Permet au modèle de travailler avec des representations abstraites |
| Transformer | Genere les tokens musicaux sequentiellement | Capture les dependances temporelles et harmoniques |
| Decodeur EnCodec | Reconstruit l’audio depuis les tokens | Assure la qualite audio finale |
Flux de generation
Description textuelle → Tokenisation → Transformer → Tokens audio → Decodeur → WAV
↑
Temperature, top_k, top_p
Points cles retenus
- Text-to-music : Description → musique instrumentale originale
- Melody conditioning : Melodie reference + style → arrangement personnalise
- Paramètres :
temperature: contrôle la creativite (0.5-1.5)cfg_coef: fidelite a la description (1.0-10.0)top_k/top_p: stratégie de sampling
- Modèles : small (4GB), medium (10GB), large (20GB), melody (10GB)
Limitations connues
| Limite | Cause | Contournement |
|---|---|---|
| Duree ~30s max | Architecture du modèle | Concatener plusieurs generations |
| Mono uniquement | Entrainement mono | Post-traitement stereo |
| Pas de voix | Modèle instrumental uniquement | Combiner avec TTS |
| Anglais prefere | Données d’entrainement | Traduire descriptions |
CHALLENGE BONUS - Musique pour Scène Vidéo
Points : 0.5 pts
Objectif
Générer la musique de fond pour une scène vidéo spécifique avec des contraintes de style.
Ce que vous avez appris
La Section 3 montre l’impact des paramètres: - temperature : Diversité (0.5 = conservateur, 1.2 = créatif) - cfg_coef : Fidélité à la description - duration : Durée en secondes
Critères de succes
-
- “Intro de podcast tech, énergique mais pro”
- “Tutoriel calme, ambiance lo-fi”
- “Suspense, scène d’investigation”
-
- Version A:
temperature=0.7,cfg_coef=3.0 - Version B:
temperature=1.0,cfg_coef=5.0
- Version A:
Contraintes techniques
- Durée: 8 secondes
- Modèle:
musicgen-medium(oumusicgen-smallsi VRAM limitée) - Noter: fidélité au contexte (1-5), qualité audio (1-5)
Soumission : PR avec titre “Challenge #6 - [Votre Nom]”, description, paramètres testés et justification du choix