204 lines
6.0 KiB
Markdown
204 lines
6.0 KiB
Markdown
# 🎼 Classification avec Essentia (Optionnel)
|
|
|
|
## État actuel
|
|
|
|
Le système fonctionne **sans Essentia** en utilisant uniquement Librosa pour l'extraction de features audio.
|
|
|
|
**Fonctionnel actuellement** :
|
|
- ✅ Tempo (BPM)
|
|
- ✅ Tonalité (key)
|
|
- ✅ Signature rythmique
|
|
- ✅ Energy
|
|
- ✅ Danceability
|
|
- ✅ Valence
|
|
- ✅ Features spectrales
|
|
|
|
**Non disponible sans Essentia** :
|
|
- ❌ Classification automatique des genres (50 genres)
|
|
- ❌ Classification des ambiances/moods (56 moods)
|
|
- ❌ Détection des instruments (40 instruments)
|
|
|
|
## Pourquoi Essentia n'est pas activé par défaut ?
|
|
|
|
La version `essentia-tensorflow==2.1b6.dev1110` spécifiée n'existe pas sur PyPI. C'était une version de développement qui n'a jamais été publiée officiellement.
|
|
|
|
## Options pour activer la classification IA
|
|
|
|
### Option 1 : Utiliser la version stable d'Essentia (Recommandé pour Linux)
|
|
|
|
**Note** : Essentia fonctionne principalement sur Linux. Sur macOS ARM64, il peut y avoir des problèmes de compatibilité.
|
|
|
|
```bash
|
|
# Modifier requirements.txt
|
|
# Remplacer:
|
|
essentia-tensorflow==2.1b6.dev1110
|
|
|
|
# Par:
|
|
essentia==2.1b6.dev1110 # Version sans TensorFlow
|
|
# OU
|
|
essentia-tensorflow # Version la plus récente disponible
|
|
```
|
|
|
|
**Limitations** : Les modèles TensorFlow pré-entraînés peuvent ne pas fonctionner avec les versions stables.
|
|
|
|
### Option 2 : Compiler Essentia depuis les sources (Avancé)
|
|
|
|
Pour les utilisateurs avancés qui veulent la version complète :
|
|
|
|
```bash
|
|
# Dans le Dockerfile
|
|
RUN apt-get install -y build-essential libyaml-dev libfftw3-dev \
|
|
libavcodec-dev libavformat-dev libavutil-dev libavresample-dev \
|
|
libsamplerate0-dev libtag1-dev libchromaprint-dev python3-dev
|
|
|
|
RUN git clone https://github.com/MTG/essentia.git && \
|
|
cd essentia && \
|
|
./waf configure --mode=release --build-static --with-python && \
|
|
./waf && \
|
|
./waf install
|
|
```
|
|
|
|
**Attention** : Build très long (30+ minutes), augmente considérablement la taille de l'image.
|
|
|
|
### Option 3 : Utiliser un modèle alternatif (Recommandé pour production)
|
|
|
|
Au lieu d'Essentia, utiliser des modèles plus modernes et maintenus :
|
|
|
|
#### A. **Hugging Face Transformers**
|
|
|
|
```python
|
|
# Dans requirements-minimal.txt, ajouter:
|
|
transformers==4.36.0
|
|
torch==2.1.2 # CPU version
|
|
|
|
# Code pour classification:
|
|
from transformers import pipeline
|
|
|
|
# Genre classification
|
|
classifier = pipeline("audio-classification",
|
|
model="facebook/wav2vec2-base-960h")
|
|
result = classifier("audio.wav")
|
|
```
|
|
|
|
#### B. **CLAP (Contrastive Language-Audio Pretraining)**
|
|
|
|
```python
|
|
# Ajouter:
|
|
laion-clap==1.1.4
|
|
|
|
# Code:
|
|
import laion_clap
|
|
model = laion_clap.CLAP_Module(enable_fusion=False)
|
|
model.load_ckpt()
|
|
|
|
# Classification par description textuelle
|
|
audio_embed = model.get_audio_embedding_from_filelist(["audio.wav"])
|
|
text_candidates = ["rock music", "jazz", "electronic", "classical"]
|
|
text_embed = model.get_text_embedding(text_candidates)
|
|
similarity = audio_embed @ text_embed.T
|
|
```
|
|
|
|
#### C. **Panns (Pre-trained Audio Neural Networks)**
|
|
|
|
```python
|
|
# Ajouter:
|
|
panns-inference==0.1.0
|
|
|
|
# Code:
|
|
from panns_inference import AudioTagging
|
|
at = AudioTagging(checkpoint_path=None, device='cpu')
|
|
tags, probabilities = at.inference("audio.wav")
|
|
```
|
|
|
|
## Solution actuelle (Fallback)
|
|
|
|
Le code actuel dans `backend/src/core/essentia_classifier.py` gère gracieusement l'absence d'Essentia :
|
|
|
|
```python
|
|
try:
|
|
from essentia.standard import MonoLoader, TensorflowPredictEffnetDiscogs
|
|
ESSENTIA_AVAILABLE = True
|
|
except ImportError:
|
|
ESSENTIA_AVAILABLE = False
|
|
|
|
# Si Essentia n'est pas disponible, retourne des valeurs par défaut
|
|
if not ESSENTIA_AVAILABLE:
|
|
return self._fallback_genre()
|
|
```
|
|
|
|
**Résultat** : Le système fonctionne sans erreur, mais sans classification automatique.
|
|
|
|
## Recommandation
|
|
|
|
Pour la **plupart des cas d'usage**, les features Librosa (tempo, énergie, tonalité) sont **suffisantes** pour :
|
|
- Organiser une bibliothèque musicale
|
|
- Créer des playlists par BPM
|
|
- Filtrer par énergie/valence
|
|
- Rechercher par tempo
|
|
|
|
Pour la **classification avancée**, je recommande :
|
|
|
|
1. **Court terme** : Utiliser le système actuel (Librosa only)
|
|
2. **Moyen terme** : Implémenter CLAP ou Panns (plus récent, mieux maintenu)
|
|
3. **Long terme** : Fine-tuner un modèle personnalisé sur votre bibliothèque
|
|
|
|
## Migration vers CLAP (Exemple)
|
|
|
|
Si vous voulez vraiment la classification, voici comment migrer vers CLAP :
|
|
|
|
### 1. Modifier requirements-minimal.txt
|
|
|
|
```txt
|
|
# Ajouter
|
|
laion-clap==1.1.4
|
|
torch==2.1.2 # CPU version
|
|
```
|
|
|
|
### 2. Créer clap_classifier.py
|
|
|
|
```python
|
|
"""Classification using CLAP."""
|
|
import laion_clap
|
|
|
|
class CLAPClassifier:
|
|
def __init__(self):
|
|
self.model = laion_clap.CLAP_Module(enable_fusion=False)
|
|
self.model.load_ckpt()
|
|
|
|
self.genre_labels = ["rock", "jazz", "electronic", "classical",
|
|
"hip-hop", "pop", "metal", "folk"]
|
|
self.mood_labels = ["energetic", "calm", "happy", "sad",
|
|
"aggressive", "peaceful", "dark", "uplifting"]
|
|
|
|
def predict_genre(self, audio_path: str):
|
|
audio_embed = self.model.get_audio_embedding_from_filelist([audio_path])
|
|
text_embed = self.model.get_text_embedding(self.genre_labels)
|
|
|
|
similarity = (audio_embed @ text_embed.T)[0]
|
|
top_idx = similarity.argmax()
|
|
|
|
return {
|
|
"primary": self.genre_labels[top_idx],
|
|
"confidence": float(similarity[top_idx]),
|
|
"secondary": [self.genre_labels[i] for i in similarity.argsort()[-3:-1][::-1]]
|
|
}
|
|
```
|
|
|
|
### 3. Intégrer dans analyzer.py
|
|
|
|
```python
|
|
from .clap_classifier import CLAPClassifier
|
|
|
|
class AudioAnalyzer:
|
|
def __init__(self):
|
|
self.classifier = CLAPClassifier() # Au lieu d'EssentiaClassifier
|
|
```
|
|
|
|
## Conclusion
|
|
|
|
**Pour l'instant** : Le système fonctionne très bien avec Librosa seul.
|
|
|
|
**Si vous avez vraiment besoin de classification** : CLAP ou Panns sont de meilleurs choix qu'Essentia en 2025.
|
|
|
|
**Ne vous bloquez pas** : Les features audio de base (BPM, tonalité, energy) sont déjà très puissantes pour la plupart des usages !
|