Spaces:
Sleeping
Sleeping
File size: 13,018 Bytes
3f2b9aa fe5ed62 3f2b9aa 4b6f6a3 4daf054 3f2b9aa 370dfdb 3f2b9aa 370dfdb 3f2b9aa 370dfdb 3f2b9aa 370dfdb 3f2b9aa 370dfdb 3f2b9aa 370dfdb db60512 3f2b9aa 5035131 3f2b9aa 370dfdb 3f2b9aa 5035131 3f2b9aa 370dfdb 3f2b9aa 5035131 3f2b9aa 62795e2 e43362d 3f2b9aa e43362d 3f2b9aa 5035131 3f2b9aa 5b1a214 3f2b9aa 5035131 3f2b9aa a9e161a 3f2b9aa a9e161a 3f2b9aa 7bf4c43 370dfdb 3f2b9aa 7bf4c43 3f2b9aa 7bf4c43 3f2b9aa a9e161a 3f2b9aa a9e161a 3f2b9aa a9e161a 3f2b9aa 4daf054 3f2b9aa 4daf054 3f2b9aa a9e161a 3f2b9aa a9e161a 3f2b9aa 4daf054 3f2b9aa 4daf054 3f2b9aa a9e161a 3f2b9aa a9e161a 3f2b9aa a9e161a 3f2b9aa a9e161a 3f2b9aa a9e161a 3f2b9aa a9e161a 3f2b9aa a9e161a 370dfdb a9e161a 370dfdb a9e161a 3f2b9aa a9e161a 3f2b9aa a9e161a 3f2b9aa 370dfdb 3f2b9aa 5035131 3f2b9aa 12749e6 3f2b9aa 12749e6 3f2b9aa db60512 370dfdb db60512 3f2b9aa 370dfdb 3f2b9aa 4b6f6a3 |
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 |
import gradio as gr
import torch
import pandas as pd
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM, T5Tokenizer, T5ForConditionalGeneration
import numpy as np
import networkx as nx
import nltk
from nltk.corpus import stopwords
from nltk.tokenize import sent_tokenize, word_tokenize
nltk.download('punkt')
nltk.download('stopwords')
nltk.download('punkt_tab')
import string
# Importations spécifiques à Sumy
from sumy.parsers.plaintext import PlaintextParser
from sumy.nlp.tokenizers import Tokenizer
from sumy.summarizers.lsa import LsaSummarizer
from sumy.summarizers.text_rank import TextRankSummarizer
from sumy.nlp.stemmers import Stemmer
from sumy.utils import get_stop_words
# --- Variables globales et chargement des modèles (mis en cache) ---
# Les modèles sont chargés une seule fois lorsque l'application démarre
def load_models():
"""Charge les tokenizers et les modèles T5 et MBart."""
print("Initialisation de l'application et vérification des ressources...")
# Définir le périphérique
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(f"Périphérique utilisé : {device}")
# --- MT5 ---
t5_model_name = 't5-large'
print(f"Chargement du tokenizer T5 ({t5_model_name})...")
t5_tokenizer = AutoTokenizer.from_pretrained(t5_model_name, use_fast=False)
print("Tokenizer T5 chargé.")
print(f"Chargement du modèle T5 ({t5_model_name})...")
t5_model = T5ForConditionalGeneration.from_pretrained(t5_model_name, return_dict=True)
t5_model.to(device)
print("Modèle T5 chargé.")
# --- MBart ---
mbart_model_name = 'facebook/mbart-large-50'
print(f"Chargement du tokenizer MBart ({mbart_model_name})...")
mbart_tokenizer = AutoTokenizer.from_pretrained(mbart_model_name)
print("Tokenizer MBart chargé.")
print(f"Chargement du modèle MBart ({mbart_model_name})...")
mbart_model = AutoModelForSeq2SeqLM.from_pretrained(mbart_model_name, return_dict=True)
mbart_model.to(device)
print("Modèle MBart chargé.")
print("Tous les modèles et ressources sont chargés avec succès ! L'application est prête.")
return t5_tokenizer, t5_model, mbart_tokenizer, mbart_model, device
# Charger les modèles une seule fois au démarrage de l'application
t5_tokenizer, t5_model, mbart_tokenizer, mbart_model, device = load_models()
# --- Fonctions de résumé ---
def summarize_lsa(text, num_sentences=3):
"""Génère un résumé extractif en utilisant LSA de Sumy."""
if not text.strip():
return "Article trop court ou vide pour LSA."
parser = PlaintextParser.from_string(text, Tokenizer("french"))
stemmer = Stemmer("french")
summarizer = LsaSummarizer(stemmer)
summarizer.stop_words = get_stop_words("french")
summary_sentences = summarizer(parser.document, num_sentences)
return " ".join([str(sentence) for sentence in summary_sentences])
def summarize_textrank(text, num_sentences=3):
"""Génère un résumé extractif en utilisant TextRank de Sumy."""
if not text.strip():
return "Article trop court ou vide pour TextRank."
parser = PlaintextParser.from_string(text, Tokenizer("french"))
stemmer = Stemmer("french")
summarizer = TextRankSummarizer(stemmer)
summarizer.stop_words = get_stop_words("french")
summary_sentences = summarizer(parser.document, num_sentences)
return " ".join([str(sentence) for sentence in summary_sentences])
def summarize_t5(text, min_length=200, max_length=350):
"""Génère un résumé abstractif en utilisant T5."""
prefixed_text = f"resumer en francais: {text}"
inputs = t5_tokenizer(
prefixed_text,
return_tensors='pt',
max_length=max_length,
truncation=True,
padding=True
).to(device)
output_sequences = t5_model.generate(
input_ids=inputs['input_ids'],
attention_mask=inputs['attention_mask'],
min_length=min_length,
max_length=max_length
)
return t5_tokenizer.decode(output_sequences[0], skip_special_tokens=True)
def summarize_mbart(text, min_length=200, max_length=350):
"""Génère un résumé abstractif en utilisant mBART."""
#prefixed_text = f"résumer en français: {text}"
inputs = mbart_tokenizer(
text,
return_tensors='pt',
max_length=max_length,
truncation=True,
padding=True
).to(device)
FRENCH_LANGUAGE_TOKEN_ID = mbart_tokenizer.lang_code_to_id["fr_XX"]
output_sequences = mbart_model.generate(
input_ids=inputs['input_ids'],
attention_mask=inputs['attention_mask'],
min_length=min_length,
max_length=max_length,
forced_bos_token_id=FRENCH_LANGUAGE_TOKEN_ID
)
return mbart_tokenizer.decode(output_sequences[0], skip_special_tokens=True)
# --- Fonction principale pour la page de résumé ---
def generate_all_summaries(article_input, num_sentences, min_summary_len, max_summary_len):
"""Génère les résumés pour tous les algorithmes et met à jour la progression."""
if not article_input:
return "Veuillez entrer un article pour générer les résumés.", "", "", ""
# Utilisation de yield pour les mises à jour de progression dans Gradio
# Gradio affichera automatiquement une barre de progression pour les fonctions qui yield
# LSA
yield "Génération du résumé LSA...", "", "", "",""
lsa_summary = summarize_lsa(article_input, num_sentences)
# TextRank
yield "Génération du résumé TextRank...", lsa_summary, "", "",""
textrank_summary = summarize_textrank(article_input, num_sentences)
# T5
yield "Génération du résumé T5...", lsa_summary, textrank_summary, "",""
t5_summary = summarize_t5(article_input, min_summary_len, max_summary_len)
# MBart
yield "Génération du résumé MBart...", lsa_summary, textrank_summary, t5_summary,""
mbart_summary = summarize_mbart(article_input, min_summary_len, max_summary_len)
yield "Résumés terminés !", lsa_summary, textrank_summary, t5_summary, mbart_summary
# --- Contenu de la page d'explications (Markdown) ---
explanations_markdown = """
# Comprendre les Méthodes de Résumé de Texte
---
## Méthodes Extractives vs. Abstractives
Il existe deux grandes catégories de méthodes pour résumer du texte :
### 1. Méthodes Extractives
Ces méthodes fonctionnent en **sélectionnant des phrases ou des passages clés** directement à partir du texte original et en les assemblant pour former le résumé. Elles ne génèrent pas de nouvelles phrases ou de nouveaux mots.
**Avantages :** Les résumés sont garantis d'être grammaticalement corrects et fidèles au texte source.
**Inconvénients :** Ils peuvent manquer de fluidité ou de cohérence, car les phrases sont simplement juxtaposées, et ils peuvent inclure des informations redondantes.
### 2. Méthodes Abstractives
Ces méthodes **génèrent de nouvelles phrases** qui capturent le sens du texte original, de manière similaire à la façon dont un humain écrirait un résumé. Elles peuvent paraphraser, condenser et même introduire des mots qui n'étaient pas présents dans le texte source.
**Avantages :** Les résumés sont plus fluides, plus concis et plus cohérents.
**Inconvénients :** Elles sont plus complexes à développer et peuvent parfois générer des informations incorrectes ou des 'hallucinations' (informations non présentes dans le texte original).
---
## Principes des Algorithmes Spécifiques
### LSA (Latent Semantic Analysis) - Extractif
LSA est une technique qui utilise l'algèbre linéaire pour identifier les relations entre les termes et les documents. Pour le résumé, LSA crée une représentation numérique du texte où les phrases sont des points dans un espace multidimensionnel. Il utilise la **Décomposition en Valeurs Singulières (SVD)** pour réduire la dimensionnalité et identifier les concepts latents (thèmes) dans le texte. Les phrases qui sont les plus représentatives de ces concepts latents sont sélectionnées pour former le résumé.
### TextRank - Extractif
TextRank est un algorithme basé sur le célèbre algorithme PageRank de Google, utilisé pour classer l'importance des pages web. Pour le résumé, TextRank construit un **graphe** où chaque **phrase** du texte est un **nœud**. Les **liens (arêtes)** entre les phrases sont basés sur leur **similarité sémantique** (par exemple, le nombre de mots partagés ou la similarité cosinus des vecteurs de mots). L'algorithme parcourt ensuite ce graphe pour attribuer un score d'importance à chaque phrase. Les phrases avec les scores les plus élevés sont choisies pour le résumé.
### T5 (Text-to-Text Transfer Transformer) - Abstractif
T5 est un modèle de langage développé par Google, dont le principe est de traiter toutes les tâches de traitement du langage naturel (NLP) comme des problèmes de "texte-à-texte". Cela signifie que pour n'importe quelle tâche (résumé, traduction, question-réponse), l'entrée et la sortie du modèle sont toujours du texte. Pour réaliser un résumé, on fournit à T5 le texte original avec un préfixe spécifique, comme 'summarize: '. Le modèle va ensuite générer un nouveau texte qui représente le résumé. Ce résumé n'est pas une simple extraction de phrases existantes, mais une nouvelle formulation des informations clés, ce qui en fait une méthode abstractive.
### MBart (Multilingual BART) - Abstractif
MBart est un modèle de séquence-à-séquence (encoder-decoder) pré-entraîné sur un grand corpus multilingue. Il est particulièrement adapté aux tâches de **traduction** et de **génération de texte multilingues**. Pour le résumé, MBart apprend à reconstruire le texte original tout en le compressant. Pour forcer la génération dans une langue spécifique (comme le français), on utilise un **token de début de séquence (BOS)** spécifique à la langue cible lors de la génération. Cela lui indique de commencer à générer le résumé en français, quelle que soit la langue de l'article d'entrée.
---
*Les modèles abstractifs (T5, MBart) nécessitent généralement plus de ressources de calcul (GPU) que les méthodes extractives (LSA, TextRank).*
"""
# --- Interface Gradio ---
with gr.Blocks(title="Application de Résumé d'Articles") as demo:
gr.Markdown("# Application de Résumé de Texte")
with gr.Tabs() as tabs:
with gr.TabItem("Explications", id="explanations_tab"):
gr.Markdown(explanations_markdown)
with gr.TabItem("Outil de Résumé", id="summarization_tool_tab"):
gr.Markdown("## Outil de Résumé de Texte")
gr.Markdown("---")
article_input = gr.Textbox(
label="Article à résumer",
lines=10,
placeholder="Collez votre article ici. Les modèles abstractifs peuvent résumer des articles multilingues en français."
)
num_sentences_slider = gr.Slider(
minimum=1,
maximum=10,
value=5,
step=1,
label="Nombre de phrases pour les résumés extractifs (LSA, TextRank)"
)
min_summary_len_slider = gr.Slider(
minimum=100,
maximum=300,
value=200,
step=1,
label="Longueur minimale du résumé (tokens) pour les modèles abstractifs"
)
max_summary_len_slider = gr.Slider(
minimum=50,
maximum=600,
value=350,
step=1,
label="Longueur maximale du résumé (tokens) pour les modèles abstractifs"
)
generate_button = gr.Button("Générer les résumés")
status_output = gr.Textbox(label="Statut", interactive=False)
gr.Markdown("---")
gr.Markdown("### Résultats des Résumés")
lsa_output = gr.Textbox(label="Résumé LSA", interactive=False, lines=10)
textrank_output = gr.Textbox(label="Résumé TextRank", interactive=False, lines=10)
t5_output = gr.Textbox(label="Résumé T5", interactive=False, lines=10)
mbart_output = gr.Textbox(label="Résumé MBart", interactive=False, lines=10)
generate_button.click(
fn=generate_all_summaries,
inputs=[
article_input,
num_sentences_slider,
min_summary_len_slider,
max_summary_len_slider
],
outputs=[
status_output,
lsa_output,
textrank_output,
t5_output,
mbart_output
]
)
demo.launch() |