Spaces:
Sleeping
Sleeping
File size: 18,087 Bytes
f23553c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 | # 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 !_
|