Spaces:
Sleeping
Sleeping
| # 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 !_ | |