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

A newer version of the Gradio SDK is available: 6.22.0

Upgrade

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.

_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 :

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 :

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 :

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 :

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 :

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 :

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 !