Aller au contenu principal

Module 8 — Résumé automatique et réponse aux questions

Les modules 6 et 7 classent et étiquettent : ils lisent le texte pour en tirer une décision. Ce module produit du texte : un résumé condensé des avis d'un hôtel, une réponse à une question posée en langage naturel. Deux tâches, deux familles d'approches, un piège commun — le modèle qui a l'air juste et qui invente.

Résumé extractif : sélectionner les meilleures phrases

Un résumé extractif ne produit aucun mot nouveau. Il découpe le texte en phrases, note chaque phrase, et concatène les mieux notées. La sortie est garantie fidèle au texte source, puisqu'elle en est un extrait exact.

La méthode la plus simple, appelée TextRank, applique PageRank au graphe des phrases : chaque phrase est un nœud, deux phrases sont reliées par un poids égal à leur similarité (cosinus des vecteurs TF-IDF ou Sentence-BERT), et le score de chaque phrase est son importance dans le graphe.

from sentence_transformers import SentenceTransformer, util
import networkx as nx

modele = SentenceTransformer("dangvantuan/sentence-camembert-base")

def resumer_extractif(avis: list[str], k: int = 3) -> list[str]:
vecteurs = modele.encode(avis, normalize_embeddings=True)
matrice_sim = util.cos_sim(vecteurs, vecteurs).numpy()
np.fill_diagonal(matrice_sim, 0) # pas de boucle
graphe = nx.from_numpy_array(matrice_sim)
scores = nx.pagerank(graphe)
tri = sorted(range(len(avis)), key=lambda i: scores[i], reverse=True)
return [avis[i] for i in tri[:k]]

# Sur les 200 avis d'un hôtel, on garde les 3 phrases les plus centrales
print(resumer_extractif(tous_les_avis_de_l_hotel, k=3))

Le résultat sur les avis d'un même hôtel donne souvent trois phrases centrales : « L'accueil était très professionnel. », « Chambres propres et confortables. », « Petit-déjeuner correct mais sans plus. ». Aucune n'est inventée, chacune était présente dans le corpus. C'est ce qu'on attend d'un résumé pour un dossier client, une revue de presse, un usage juridique — la fidélité prime sur la fluidité.

Résumé abstractif : reformuler avec ses propres mots

Un résumé abstractif produit du texte nouveau, qui n'apparaît pas verbatim dans la source. Les modèles adaptés (BART, T5, mT5 pour le multilingue, BARThez pour le français) sont des Transformers encodeur-décodeur : l'encodeur lit la source, le décodeur génère le résumé jeton par jeton.

from transformers import pipeline

resumer = pipeline("summarization",
model="moussaKam/barthez-orangesum-abstract",
tokenizer="moussaKam/barthez-orangesum-abstract")

avis_long = "\n".join(tous_les_avis_de_l_hotel[:20])[:3000]
sortie = resumer(avis_long, max_length=80, min_length=30,
num_beams=4, do_sample=False)
print(sortie[0]["summary_text"])

Le résumé abstractif d'un même hôtel peut donner : « L'hôtel propose des chambres confortables et un accueil chaleureux, malgré un petit-déjeuner jugé insuffisant par plusieurs clients. » Le texte est fluide, condensé, agréable à lire, et aucun mot n'est identique à un avis particulier. C'est le format attendu pour une fiche produit, un tableau de bord, un affichage grand public.

ROUGE : la métrique standard, et pourquoi elle trompe

ROUGE (Recall-Oriented Understudy for Gisting Evaluation, 2004) compare le résumé produit à un ou plusieurs résumés de référence, en comptant les recouvrements de n-grammes.

  • ROUGE-1 : recouvrement des unigrammes (mots seuls)
  • ROUGE-2 : recouvrement des bigrammes
  • ROUGE-L : plus longue sous-séquence commune

ROUGE-1rappel=unigrammes communsunigrammes du reˊsumeˊ de reˊfeˊrence\text{ROUGE-1}_{\text{rappel}} = \frac{|\text{unigrammes communs}|}{|\text{unigrammes du résumé de référence}|}

ROUGE est rapide, simple et incontestablement le standard — c'est ce qu'on trouve dans tous les articles. Mais il est aussi profondément trompeur.

Un exemple caricatural :

  • Référence : « L'hôtel est excellent malgré un petit-déjeuner décevant. »
  • Résumé A : « L'hôtel est excellent, le petit-déjeuner est décevant. » — ROUGE-1 très élevé, fidèle.
  • Résumé B : « L'hôtel est décevant malgré un petit-déjeuner excellent. » — ROUGE-1 identique, sens inversé.

Le score ROUGE est aveugle à la structure, à la négation et au sens. Un résumé qui recopie fidèlement les mots de la référence en changeant leur ordre obtient la même note qu'un résumé fidèle.

ROUGE n'évalue pas la fidélité factuelle

Les articles récents sur le résumé abstractif utilisent en complément une évaluation humaine ou une métrique appelée entailment (le résumé est-il logiquement impliqué par la source ?). Sur un système en production, ROUGE seul est insuffisant. Un pilote avec dix évaluateurs humains sur cent résumés vaut mille scores ROUGE.

L'hallucination, le défaut structurel du résumé abstractif

Un modèle abstractif peut inventer. Il ne le fait pas au hasard : il produit ce qui, statistiquement, ressemble à ce qu'on écrit dans ce genre de contexte, même si ce n'est pas dans la source. Sur nos avis, un modèle peut :

  • Ajouter une note qui n'existe pas (« l'hôtel obtient 4,5 étoiles en moyenne » alors que la source ne contient aucune note).
  • Généraliser à tort (« tous les clients ont apprécié la piscine » à partir d'un seul avis positif).
  • Inverser une critique (« le personnel était très aimable » alors que trois avis sur cinq se plaignent d'un accueil froid).

Ces erreurs sont d'autant plus dangereuses qu'elles sont plausibles. Un lecteur n'a aucun moyen de les repérer sans revenir à la source, ce qui annule l'intérêt du résumé. Pour un usage à faible enjeu (article de blog), c'est acceptable ; pour un usage à fort enjeu (santé, juridique), c'est disqualifiant. Le résumé extractif reste le choix par défaut dans ces domaines.

Question-réponse extractive : trouver le passage qui répond

La QA extractive prend une question et un contexte, et prédit les deux positions dans le contexte qui délimitent la réponse. C'est presque un problème d'étiquetage, sauf que les étiquettes sont deux entiers — début et fin — au lieu d'une étiquette par jeton.

from transformers import pipeline

qa = pipeline("question-answering",
model="etalab-ia/camembert-base-squadFR-fquad-piaf",
tokenizer="etalab-ia/camembert-base-squadFR-fquad-piaf")

contexte = " ".join(tous_les_avis_de_l_hotel[:50])
sortie = qa(question="Le petit-déjeuner est-il inclus ?",
context=contexte)
print(sortie)
# {'score': 0.62, 'start': 1734, 'end': 1789,
# 'answer': "petit-déjeuner en supplément à 12 € par personne"}

Le modèle rend le fragment exact du contexte qui répond, avec un score de confiance. Deux propriétés essentielles :

  1. Il ne peut pas inventer. La réponse est toujours un sous-texte du contexte. Pas d'hallucination possible.
  2. Il peut refuser. Sur SQuAD 2.0, le modèle est entraîné à répondre « pas de réponse » quand aucun passage ne correspond, ce qui est indispensable en production.

Pour construire un service de QA sur l'ensemble du corpus, on combine cette QA extractive avec la recherche sémantique du module 5 : la requête sélectionne les cinq avis les plus pertinents, la QA extrait la réponse dans la concaténation. C'est le squelette de la génération augmentée par récupération (RAG) que le cours 22 traite en détail.

Extractif pour la fidélité, abstractif pour la fluidité

La règle qui structure toutes les décisions de ce module : fidélité impose extractif, fluidité impose abstractif. Un système qui a besoin des deux les combine — extractif pour trouver le passage source, abstractif pour reformuler à la demande. Séparer les deux étapes rend chaque erreur imputable et corrigeable.

En résumé

  • Le résumé extractif sélectionne des phrases du texte source, avec TextRank sur un graphe de similarité ; la fidélité est garantie, la fluidité est faible.
  • Le résumé abstractif avec BART, T5 ou BARThez produit un texte reformulé, fluide, mais peut halluciner — inventer une note, généraliser à tort, inverser une critique.
  • La métrique ROUGE compte les recouvrements de n-grammes ; elle est aveugle au sens et à la négation, un résumé faux peut avoir un ROUGE parfait.
  • La QA extractive ne peut pas inventer : elle rend un sous-texte exact du contexte et peut refuser de répondre ; c'est le socle des systèmes RAG à faible risque.

Module suivant : la bibliothèque transformers en pratique — comment choisir un modèle sur le Hub selon la langue, la taille et la licence, et comment tout enchaîner avec pipeline ou Trainer.