Spaces:
Runtime error
Runtime error
| title: Sentiment d'appels vocaux francais | |
| emoji: "🎙️" | |
| colorFrom: blue | |
| colorTo: purple | |
| sdk: gradio | |
| sdk_version: 5.50.0 | |
| python_version: 3.11 | |
| app_file: app.py | |
| suggested_hardware: cpu-basic | |
| preload_from_hub: | |
| - jonatasgrosman/wav2vec2-large-xlsr-53-french | |
| - cardiffnlp/twitter-xlm-roberta-base-sentiment | |
| # Détection de sentiment dans des appels vocaux français | |
| Projet individuel de **Deep Learning 2** : un pipeline de bout en bout qui reçoit un fichier audio, le transcrit en français, puis classe le sentiment en `positif`, `négatif` ou `neutre` avec un score de confiance. | |
| ## Architecture | |
| ```text | |
| WAV / MP3 | |
| -> validation + mono + 16 kHz + normalisation | |
| -> Wav2Vec 2.0 (ASR) | |
| -> transcription française | |
| -> XLM-RoBERTa fine-tuné (sentiment) | |
| -> positif / négatif / neutre + confiance | |
| ``` | |
| La même classe `SentimentCallPipeline` est utilisée par l'interface Gradio et l'API FastAPI. Cela évite que les deux interfaces divergent et garantit que le même prétraitement est appliqué partout. | |
| ## Choix des modèles et justification | |
| | Étape | Modèle | Justification | | |
| |---------------|-------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | |
| | Transcription | [`jonatasgrosman/wav2vec2-large-xlsr-53-french`](https://huggingface.co/jonatasgrosman/wav2vec2-large-xlsr-53-french) | Wav2Vec 2.0 XLSR est spécifiquement fine-tuné pour le français et correspond au modèle proposé par l'énoncé. Il prend un signal mono de 16 kHz, d'où le prétraitement imposé. | | |
| | Sentiment | [`cardiffnlp/twitter-xlm-roberta-base-sentiment`](https://huggingface.co/cardiffnlp/twitter-xlm-roberta-base-sentiment) | XLM-RoBERTa est une variante de la famille BERT. Son fine-tuning fournit directement trois classes (négatif, neutre, positif) et prend en charge le français. | | |
| Les poids ne sont pas stockés dans Git : ils sont téléchargés une seule fois au premier appel via Hugging Face, puis mis en cache localement. Sur une machine avec GPU CUDA, PyTorch l'utilise automatiquement ; sinon l'inférence fonctionne sur CPU, plus lentement. | |
| Le décodage de la transcription est un décodage CTC glouton (`argmax`) réalisé dans le code. Il ne nécessite pas `pyctcdecode` : cette dépendance est réservée au décodage avec language model externe, qui n'est pas indispensable ici. | |
| `sentencepiece` et `protobuf` font partie des dépendances obligatoires : elles permettent de charger le tokenizer du modèle XLM-RoBERTa de sentiment. Le message Hugging Face concernant `hf_xet` est seulement une optimisation de téléchargement ; sans ce paquet, le téléchargement HTTP standard fonctionne normalement. | |
| ## Installation et reproduction | |
| Prérequis : Python 3.9 ou supérieur. Pour les fichiers MP3, installez aussi `ffmpeg` et rendez-le disponible dans le `PATH`. | |
| ```bash | |
| git clone <URL_DU_DEPOT> | |
| cd DL_FINAL_EXAMEN | |
| python -m venv .venv | |
| ``` | |
| Sous Windows : | |
| ```powershell | |
| .venv\Scripts\Activate.ps1 | |
| pip install -r requirements.txt | |
| ``` | |
| Sous Linux/macOS : | |
| ```bash | |
| source .venv/bin/activate | |
| pip install -r requirements.txt | |
| ``` | |
| Vérifier les validations audio sans charger les modèles : | |
| ```bash | |
| pytest -q | |
| ``` | |
| ## Interface Gradio | |
| ```bash | |
| python app.py | |
| ``` | |
| Ouvrez l'URL affichée par Gradio dans un navigateur. L'utilisateur peut importer ou enregistrer un WAV/MP3. L'écran affiche volontairement la **transcription intermédiaire**, le sentiment final et la confiance, comme demandé dans l'énoncé. | |
| ## API REST | |
| Démarrer le serveur : | |
| ```bash | |
| uvicorn api:app --reload | |
| ``` | |
| Vérifier qu'il répond : | |
| ```bash | |
| curl http://127.0.0.1:8000/health | |
| ``` | |
| Prédire à partir d'un audio : | |
| ```bash | |
| curl -X POST "http://127.0.0.1:8000/predict" -F "file=@samples/positif.wav" | |
| ``` | |
| Réponse attendue : | |
| ```json | |
| { | |
| "transcription": "je suis très satisfait du service","sentiment": "positif","confidence": 0.9273 | |
| } | |
| ``` | |
| `POST /predict` renvoie `400` pour un format non supporté, un fichier vide, un audio silencieux ou un audio de plus de cinq minutes. Un échec de téléchargement/chargement du modèle est renvoyé en `503` plutôt que masqué par une erreur interne. | |
| ## Démonstration | |
| Le dossier [`samples/`](samples/) contient trois audios de démonstration, un par classe. Les phrases attendues sont documentées dans [`samples/README.md`](samples/README.md). Sous PowerShell, exécutez les trois commandes suivantes : | |
| ```bash | |
| curl -X POST "http://127.0.0.1:8000/predict" -F "file=@samples/positif.wav" | |
| curl -X POST "http://127.0.0.1:8000/predict" -F "file=@samples/negatif.wav" | |
| curl -X POST "http://127.0.0.1:8000/predict" -F "file=@samples/neutre.wav" | |
| ``` | |
| Les scores peuvent varier légèrement selon la version des bibliothèques et la qualité de l'enregistrement. La classe attendue est celle indiquée dans `samples/README.md`. | |
| ### Origine des audios de test | |
| Les fichiers `samples/positif.wav`, `samples/negatif.wav` et `samples/neutre.wav` **ne proviennent pas d'un site externe** : ils ont été créés localement par synthèse vocale Windows avec la voix française `Microsoft Hortense Desktop`. Ce choix rend la démonstration réutilisable, évite les problèmes de droit d'auteur et garantit qu'aucune donnée vocale de client n'est incluse dans le dépôt. | |
| Le script complet et commenté est disponible dans [`scripts/generate_demo_audios.ps1`](scripts/generate_demo_audios.ps1). Pour régénérer exactement les fichiers sous Windows, depuis la racine du projet : | |
| ```powershell | |
| powershell -ExecutionPolicy Bypass -File .\scripts\generate_demo_audios.ps1 | |
| ``` | |
| Si la voix `Microsoft Hortense Desktop` n'est pas disponible, il faut l'ajouter dans les paramètres Windows (voix française), ou enregistrer les trois phrases indiquées dans `samples/README.md` avec un téléphone puis les exporter en WAV/MP3. | |
| ## Limites connues | |
| - La qualité de l'ASR diminue avec le bruit, les chevauchements de voix, les accents peu représentés dans les données d'entraînement et les appels téléphoniques fortement compressés. | |
| - Le classifieur a été fine-tuné sur des textes courts de type réseaux sociaux : une transcription erronée, l'ironie ou le contexte conversationnel peuvent conduire à une classe incorrecte. | |
| - Le score est la probabilité du modèle, pas une garantie de justesse ni une mesure de satisfaction métier calibrée. | |
| - Les fichiers longs sont refusés à cinq minutes pour protéger la mémoire et le temps de réponse. Pour un centre d'appels réel, il faut découper les conversations et ajouter l'identification des locuteurs. | |
| ## Bonus : Docker | |
| Le conteneur lance l'API FastAPI sur le port `8000`. Il installe aussi `ffmpeg`, nécessaire pour que les fichiers MP3 soient réellement pris en charge dans le conteneur. | |
| ```bash | |
| docker compose up --build | |
| ``` | |
| L'API sera accessible sur `http://127.0.0.1:8000`. Au premier appel de prédiction, le conteneur doit avoir accès à Internet pour télécharger les modèles. | |
| ## Bonus : déploiement public de la démo | |
| Le fichier `README.md` contient déjà la configuration d'un **Hugging Face Space Gradio** : `app.py` est l'interface publique, et les deux modèles sont préchargés lors du build pour éviter un premier clic très lent. | |
| 1. Créer un nouveau Space public sur Hugging Face et choisir le SDK **Gradio**. | |
| 2. Pousser tout ce dépôt dans le Space ; ne pas envoyer `.venv/` grâce au `.gitignore`. | |
| 3. Attendre la fin du build, puis ouvrir l'URL publique `https://<utilisateur>-<nom-du-space>.hf.space`. | |
| 4. Tester un import WAV et un enregistrement microphone dans la démo publique. | |
| ## Structure du dépôt | |
| ```text | |
| . | |
| ├── app.py # interface Gradio | |
| ├── api.py # endpoint POST /predict | |
| ├── src/audio.py # validation et prétraitement 16 kHz/mono | |
| ├── src/pipeline.py # Wav2Vec2 -> XLM-RoBERTa | |
| ├── tests/ # tests unitaires de la couche audio | |
| ├── samples/ # trois audios et deux vidéos de démonstration | |
| ├── scripts/ # outil reproductible de génération des audios | |
| ├── requirements.txt | |
| └── Dockerfile | |
| ``` | |