Build OK
This commit is contained in:
203
ESSENTIA.md
Normal file
203
ESSENTIA.md
Normal file
@@ -0,0 +1,203 @@
|
||||
# 🎼 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 !
|
||||
Reference in New Issue
Block a user