Deep-Studio-Text / PRESENTATION.md
demeulemeesterxmaxime
Ajout d'un support de plusieurs langues, FR ES GR ETC
f23553c
|
Raw
History Blame Contribute Delete
18.1 kB
# DeepText Studio — Guide de Présentation
> **Projet** : Multi-Task NLP Toolkit · ISEN M1 S8
> **Auteur** : Maxime Demeulemeester
> **Date** : Mars 2026
---
## 1. Présentation Générale
**DeepText Studio** est une application web qui regroupe **5 modules de NLP** (Natural Language Processing) dans une interface unique construite avec **Gradio**.
L'idée est de proposer un **toolkit interactif** où l'on peut explorer différentes tâches du traitement du langage naturel sans écrire de code — tout se fait via une interface web avec des onglets dédiés.
### Les 5 modules
| # | Onglet | Ce que ça fait | Modèle utilisé |
|---|--------|----------------|-----------------|
| 1 | **Tokenization** | Compare 4 méthodes de découpage de texte en tokens | NLTK punkt, SpaCy, BERT WordPiece, GPT-2 BPE |
| 2 | **Sentiment Analysis** | Détecte le sentiment (positif/négatif) + les émotions | DistilBERT SST-2 + DistilRoBERTa emotions |
| 3 | **Semantic Similarity** | Mesure la distance sémantique entre 2 textes | sentence-transformers/all-MiniLM-L6-v2 |
| 4 | **Zero-Shot Classification** | Classe un texte dans des catégories libres (sans entraînement) | facebook/bart-large-mnli |
| 5 | **NER (Innovation)** | Extrait les entités nommées (personnes, lieux, organisations) | dslim/bert-base-NER |
**+ un onglet Settings** pour configurer une clé API Gemini qui permet de générer du texte aléatoire dans chaque module.
---
## 2. Stack Technique
| Composant | Technologie | Rôle |
|-----------|-------------|------|
| Framework UI | **Gradio 4.x** | Interface web multi-onglets |
| Backend | **Python 3.10+** | Logique NLP |
| Modèles NLP | **HuggingFace Transformers** | Pipelines pré-entraînés |
| Embeddings | **sentence-transformers** | Encodage sémantique des phrases |
| Tokeniseurs classiques | **NLTK** + **SpaCy** | Tokenisation word-level |
| Deep Learning | **PyTorch** | Backend des modèles Transformers |
| API externe | **Google Gemini** | Génération de texte aléatoire |
| Déploiement | **FastAPI** + **Vercel** (via `api/index.py`) | Serverless |
---
## 3. Architecture du Projet
```
DeepText Studio/
├── app.py ← Point d'entrée (lance l'app Gradio)
├── requirements.txt ← Dépendances Python
├── api/
│ └── index.py ← Entry point Vercel (FastAPI + Gradio monté)
├── core/ ← Logique métier pure (pas de Gradio ici)
│ ├── tokenizer.py ← 4 méthodes de tokenisation
│ ├── sentiment.py ← Pipeline sentiment + émotions
│ ├── similarity.py ← Cosine similarity sur embeddings
│ ├── zero_shot.py ← Classification zero-shot BART
│ ├── innovation.py ← NER avec BERT-base-NER
│ └── settings.py ← Gestion clé API Gemini + génération de texte
├── ui/ ← Interface Gradio (composants visuels)
│ ├── theme.py ← Thème dark futuriste + CSS custom
│ ├── tab_tokenizer.py ← UI onglet tokenisation
│ ├── tab_sentiment.py ← UI onglet sentiment
│ ├── tab_similarity.py ← UI onglet similarité
│ ├── tab_zero_shot.py ← UI onglet zero-shot
│ ├── tab_innovation.py ← UI onglet NER
│ └── tab_settings.py ← UI onglet paramètres
└── build/ ← Fichiers de planification et suivi
├── plan.md ← Plan de développement par phases
├── agent.md ← Contexte IA inter-phases
└── claude.md ← Instructions pour les agents IA
```
### Principe de séparation `core/` vs `ui/`
Le projet suit un pattern **MVC simplifié** :
- **`core/`** contient toute la logique métier (appels aux modèles, calculs). Aucune dépendance à Gradio.
- **`ui/`** contient uniquement les composants d'interface. Chaque fichier `tab_*.py` importe les fonctions depuis `core/` et les branche sur des boutons Gradio.
Cela permet de :
- Tester la logique indépendamment de l'UI
- Réutiliser le core dans un autre contexte (API, CLI, etc.)
- Garder le code lisible et maintenable
---
## 4. Méthodologie de Développement
### 4.1 Planification par Phases
Le développement a été structuré en **8 phases séquentielles**, chacune correspondant à une branche Git :
| Phase | Branche | Contenu | Tags |
|-------|---------|---------|------|
| **P0** | `setup/init` | Scaffold du projet, structure de dossiers, requirements | `v0.1-scaffold` |
| **P1** | `feature/tokenization` | Module tokenisation (4 méthodes) | `v0.2-tokenization` |
| **P2** | `feature/sentiment` | Module sentiment + émotions | `v0.3-sentiment` |
| **P3** | `feature/similarity` | Module similarité sémantique | `v0.4-similarity` |
| **P4** | `feature/zero-shot` | Module classification zero-shot | `v0.5-zero-shot` |
| **P5** | `feature/innovation` | Module NER (feature innovante) | `v0.6-innovation` |
| **P6** | `ui/theme-polish` | Thème dark futuriste, CSS, polish | `v0.7-themed` |
| **P7** | `release/v1.0` | Tests, nettoyage, documentation | `v1.0-release` |
### 4.2 Convention de commits
Format : `<type>(<scope>): <description>`
- Types : `init`, `feat`, `fix`, `style`, `docs`, `test`, `chore`, `release`
- Scopes : `token`, `sentiment`, `sim`, `zs`, `ner`, `ui`, `app`
### 4.3 Fichiers de suivi IA
Le projet utilise trois fichiers de pilotage pour les agents IA :
- **`build/plan.md`** : Le plan de développement complet avec chaque étape détaillée
- **`build/agent.md`** : L'état du projet (version, phase active, décisions prises, problèmes)
- **`build/claude.md`** : Les règles de code, style UI, et conventions à respecter
Ces fichiers permettent de maintenir la cohérence du projet quand on utilise un LLM pour coder.
---
## 5. Détail Technique par Module
### 5.1 Tokenization (Tab 1)
**Objectif** : Montrer la différence entre tokenisation word-level et subword.
**4 méthodes comparées :**
1. **NLTK (punkt)** — Word-level classique, découpe sur les espaces et la ponctuation
2. **SpaCy** — Word-level plus intelligent (gère les contractions, abbréviations)
3. **BERT WordPiece** — Subword : découpe les mots rares en sous-parties (préfixe `##`)
4. **GPT-2 BPE** — Byte Pair Encoding : subword basé sur la fréquence des paires d'octets (préfixe `Ġ`)
**Point intéressant à expliquer en démo** : Pour le mot "unprecedented", NLTK et SpaCy gardent le mot entier, mais BERT le découpe en `un`, `##pre`, `##ce`, `##dent`, `##ed` — ça montre comment les Transformers gèrent les mots hors vocabulaire.
**Lazy loading** : Les modèles ne sont chargés qu'au premier clic (pas au démarrage de l'app).
### 5.2 Sentiment Analysis (Tab 2)
**Objectif** : Analyser la tonalité d'un texte.
**Deux analyses combinées :**
1. **Sentiment** (DistilBERT SST-2) → Positif / Négatif avec score de confiance
2. **Émotions** (DistilRoBERTa j-hartmann) → 7 émotions : joy, anger, fear, sadness, surprise, disgust, neutral — classées par score décroissant
**Point intéressant** : On utilise `top_k=None` pour obtenir TOUTES les émotions avec leur score, pas juste la dominante. Ça permet d'afficher un tableau complet avec barres de progression.
### 5.3 Semantic Similarity (Tab 3)
**Objectif** : Mesurer à quel point deux textes disent "la même chose".
**Comment ça marche :**
1. Les deux textes sont encodés en **vecteurs d'embedding** (384 dimensions) via `all-MiniLM-L6-v2`
2. On calcule la **similarité cosinus** entre les deux vecteurs (1 = identique, 0 = aucun rapport)
3. Le résultat est affiché avec une **interprétation** (Very Similar / Moderately / Slightly / Not Similar)
**Point intéressant** : "The cat is sitting on the mat" vs "A kitten is resting on the rug" → score élevé car le modèle comprend que chat ≈ chaton, tapis ≈ natte, assis ≈ se repose.
### 5.4 Zero-Shot Classification (Tab 4)
**Objectif** : Classer un texte dans des catégories arbitraires sans ré-entraîner le modèle.
**Comment ça marche :**
- Le modèle **BART-large-MNLI** est entraîné sur le Natural Language Inference (NLI)
- Pour chaque catégorie, il évalue l'hypothèse "This text is about {category}" et donne un score
- L'utilisateur peut entrer n'importe quelles catégories séparées par des virgules
**Point intéressant** : Le modèle fait ~1.6 GB — c'est le plus gros du projet. Il est capable de classifier dans des catégories jamais vues grâce au transfer learning.
### 5.5 NER - Innovation (Tab 5)
**Objectif** : Extraire les entités nommées d'un texte.
**4 types d'entités détectées :**
- **PER** (Person) : Elon Musk, Barack Obama
- **ORG** (Organization) : NASA, Tesla, SpaceX
- **LOC** (Location) : Washington, Tokyo, Paris
- **MISC** (Miscellaneous) : European, FIFA World Cup
**Choix de l'innovation** : La NER est complémentaire aux autres modules — elle montre une compréhension structurelle du texte (qui, où, quelle organisation) plutôt que sémantique (sentiment, similarité).
**Modèle** : `dslim/bert-base-NER` avec `aggregation_strategy="simple"` pour fusionner les sous-tokens en entités complètes.
### 5.6 Settings (Tab 6)
**Objectif** : Permettre la configuration d'une clé API Gemini.
**Fonctionnalités :**
- Sauvegarde sécurisée de la clé API (champ password)
- Test de connexion automatique à l'API
- Une fois configurée, un bouton "Generate with Gemini" apparaît dans chaque onglet pour générer du texte aléatoire adapté au module (texte simple, paires de phrases, texte riche en entités, catégories...)
---
## 6. Choix de Design (UI/UX)
### Thème Dark Futuriste
- **Fond** : Noir profond `#0a0a0f` → Bleu nuit `#0d1117`
- **Accents** : Cyan néon `#00f0ff` + Violet électrique `#a855f7`
- **Texte** : Blanc `#e6edf3`
- **Police** : Inter (UI) + JetBrains Mono (code/tokens)
- **Effets** : Bordures subtiles, glow cyan au focus, animation fadeIn sur les onglets.
### Principes UX appliqués
1. **Textes pré-remplis** : Chaque onglet a un texte d'exemple par défaut → pas de champ vide
2. **Feedback immédiat** : Un clic sur le bouton = résultat visible sans scroll
3. **Tabs autonomes** : Chaque onglet est indépendant, on peut démontrer un seul module
4. **Responsive** : CSS adaptatif pour tablette et mobile
---
## 7. Difficultés Rencontrées & Solutions
### 7.1 Taille des modèles
**Problème** : Les modèles Transformers sont volumineux (BART-large-MNLI = ~1.6 GB). Le premier chargement est lent et consomme beaucoup de RAM.
**Solution** : **Lazy loading** — chaque modèle est stocké dans une variable globale `_pipeline = None` et n'est chargé qu'au premier appel de la fonction. Ça évite de charger les 5 modèles au démarrage.
```python
_sentiment_pipeline = None
def _get_sentiment_pipeline():
global _sentiment_pipeline
if _sentiment_pipeline is None:
_sentiment_pipeline = pipeline("sentiment-analysis", model="...")
return _sentiment_pipeline
```
### 7.2 Tokenisation SpaCy — modèle manquant
**Problème** : SpaCy nécessite un modèle de langue téléchargé séparément (`fr_core_news_sm` ou `en_core_web_sm`). Sans ça, l'app crash.
**Solution** : Fallback automatique — on essaie d'abord le modèle français, puis l'anglais, et si aucun n'est trouvé, on télécharge automatiquement :
```python
for model in ("fr_core_news_sm", "en_core_web_sm"):
try:
_spacy_nlp = spacy.load(model)
return _spacy_nlp
except OSError:
continue
# Auto-download si aucun trouvé
subprocess.run(["python", "-m", "spacy", "download", "fr_core_news_sm"])
```
### 7.3 NLTK punkt — téléchargement silencieux
**Problème** : NLTK a besoin du tokenizer `punkt_tab` mais ne le télécharge pas tout seul.
**Solution** : Vérification + téléchargement automatique au chargement du module :
```python
try:
nltk.data.find("tokenizers/punkt_tab")
except LookupError:
nltk.download("punkt_tab", quiet=True)
```
### 7.4 Warnings des modèles Transformers
**Problème** : Les modèles HuggingFace affichent des warnings "UNEXPECTED keys" dans la console, ce qui peut être confus.
**Solution** : Suppression des warnings dans `app.py` :
```python
import warnings, logging
warnings.filterwarnings("ignore", message=".*UNEXPECTED.*")
logging.getLogger("transformers.modeling_utils").setLevel(logging.ERROR)
```
### 7.5 SSR (Server-Side Rendering) de Gradio
**Problème** : Le mode SSR de Gradio posait des problèmes de compatibilité lors du déploiement.
**Solution** : Désactivation explicite du SSR dans `app.py` :
```python
app.launch(ssr_mode=False)
```
### 7.6 Déploiement Vercel (Serverless)
**Problème** : Gradio est conçu pour tourner en tant que serveur persistant, pas en serverless.
**Solution** : Création de `api/index.py` qui monte l'app Gradio sur **FastAPI**, compatible avec le runtime serverless de Vercel :
```python
app = FastAPI()
app = gr.mount_gradio_app(app, demo, path="/")
```
### 7.7 NER — Tokens fragmentés
**Problème** : Le modèle NER retourne des entités fragmentées en sous-tokens (ex: "Elon" et "Musk" séparés).
**Solution** : Utilisation de `aggregation_strategy="simple"` dans le pipeline pour fusionner automatiquement les sous-tokens en entités complètes.
### 7.8 Émotions — Format de retour variable
**Problème** : Le pipeline d'émotions avec `top_k=None` retourne tantôt une liste simple, tantôt une liste de listes selon la version de Transformers.
**Solution** : Double vérification du format :
```python
if emo_result and isinstance(emo_result[0], list):
emo_raw = emo_result[0]
else:
emo_raw = emo_result
```
---
## 8. Ce qu'on peut montrer en Démo
### Scénario de démo recommandé (5-10 min)
1. **Settings** → Entrer la clé Gemini (optionnel, les textes par défaut suffisent)
2. **Tokenization** → Montrer le texte par défaut, cliquer "Tokenize"
- Comparer NLTK vs BERT → expliquer word-level vs subword
- Montrer que GPT-2 BPE gère différemment de BERT WordPiece
3. **Sentiment** → Tester avec une phrase positive puis une négative
- Montrer les 7 émotions détectées
- Changer le texte et relancer pour voir la différence
4. **Similarity** → Garder l'exemple par défaut (cat/kitten)
- Montrer le score élevé (~0.8+)
- Changer un texte pour quelque chose sans rapport → score bas
5. **Zero-Shot** → Le texte SpaceX par défaut
- Montrer que "Technology" et "Science" scorent le plus haut
- Changer les catégories pour des choses farfelues → le modèle s'adapte
6. **NER** → Le texte avec Elon Musk, NASA, Washington
- Montrer l'extraction des entités avec leur type
- Expliquer PER / ORG / LOC / MISC
### Questions potentielles du jury et réponses
| Question | Réponse |
|----------|---------|
| Pourquoi Gradio et pas Flask/Streamlit ? | Gradio est imposé par le sujet, mais il est idéal pour les démos ML : composants pré-construits, multi-tabs, déploiement facile |
| Pourquoi ces modèles spécifiques ? | Bon compromis taille/performance. DistilBERT est léger (~260 MB), MiniLM est ultra-compact (~90 MB). Seul BART est gros (~1.6 GB) mais c'est le standard pour le zero-shot |
| Comment gérez-vous la performance ? | Lazy loading des modèles + cache HuggingFace local. Premier appel lent, ensuite instantané |
| Pourquoi NER comme innovation ? | Complémentaire aux autres modules (analyse structurelle vs sémantique), bonne démo visuelle, modèle performant et léger |
| Le projet tourne-t-il sur GPU ? | Auto-détection CPU/GPU. En démo locale, CPU suffit car les modèles sont optimisés (DistilBERT, MiniLM) |
| Comment fonctionne le zero-shot ? | BART est entraîné sur le NLI (textual entailment). Pour chaque catégorie, il teste l'hypothèse "This text is about {category}" |
| Quel est le rôle de Gemini ? | Uniquement pour la génération de texte aléatoire (bouton "Generate"). Les analyses NLP sont 100% locales avec les modèles HuggingFace |
---
## 9. Résumé des Technologies et Concepts Clés
### Concepts NLP à connaître
- **Tokenisation** : Découpage du texte en unités (tokens). Word-level = mots entiers, Subword = sous-parties de mots
- **WordPiece** (BERT) : Algorithme qui découpe les mots rares en sous-tokens fréquents (préfixe `##`)
- **BPE** (GPT-2) : Byte Pair Encoding — fusionne itérativement les paires de caractères les plus fréquentes
- **Sentiment Analysis** : Classification binaire (positif/négatif) ou multi-classes (émotions)
- **Embeddings** : Représentation vectorielle dense d'un texte (ici 384 dimensions)
- **Cosine Similarity** : Mesure de l'angle entre deux vecteurs (1 = même direction = même sens)
- **Zero-Shot** : Capacité d'un modèle à classifier dans des catégories jamais vues pendant l'entraînement
- **NLI (Natural Language Inference)** : Tâche consistant à déterminer si une hypothèse est impliquée par une prémisse
- **NER (Named Entity Recognition)** : Identification et classification des entités nommées dans un texte
- **Transfer Learning** : Réutilisation d'un modèle pré-entraîné pour une tâche différente
- **Lazy Loading** : Chargement différé d'une ressource au moment où elle est réellement nécessaire
### Bibliothèques utilisées
| Bibliothèque | Version | Usage |
|---------------|---------|-------|
| `gradio` | ≥ 4.0 | Interface web |
| `transformers` | latest | Pipelines NLP (sentiment, NER, zero-shot) |
| `torch` | latest | Backend PyTorch pour les modèles |
| `sentence-transformers` | latest | Embeddings de phrases |
| `spacy` | latest | Tokenisation word-level |
| `nltk` | latest | Tokenisation word-level (punkt) |
| `scipy` | latest | Calcul de distance cosinus |
| `google-genai` | latest | API Gemini pour génération de texte |
| `fastapi` | latest | Montage Gradio pour Vercel |
| `uvicorn` | latest | Serveur ASGI |
---
> _Bonne présentation !_