Transformers Pipeline : Exécuter des Modèles NLP en Quelques Lignes

1. Vue d’ensemble

Hugging Face Transformers fournit une API pipeline() qui vous permet d’exécuter un modèle NLP/vision/audio préentraîné avec seulement quelques lignes de code, sans avoir besoin de charger manuellement le tokenizer, la config ou de traiter les tensors vous-même. Cet article vous aide à comprendre comment fonctionne pipeline(), comment l’utiliser pour les tâches courantes (sentiment analysis, NER, summarization, zero-shot classification), et quand vous devriez « descendre d’un niveau » pour un contrôle plus granulaire.

Une fois que vous aurez lu cet article, vous pourrez exécuter vous-même l’inférence avec des modèles Hugging Face dans votre application Python, écrire des tests pour vérifier les résultats, et connaître les limites du pipeline avant de le mettre en production.

2. Installation

Vous avez besoin de la bibliothèque transformers et d’un backend (PyTorch ou TensorFlow). Par exemple, avec PyTorch :

pip install transformers torch

Les versions recommandées au moment de la rédaction : transformers>=4.40, torch>=2.2.

Note : À la première exécution, pipeline() téléchargera le modèle depuis Hugging Face Hub et le mettra en cache dans ~/.cache/huggingface. Le modèle peut faire plusieurs centaines de MB, donc si vous exécutez cela dans un conteneur CI, vous devez prévoir du temps/bande passante pour cette étape ou inclure le cache à l’avance dans votre image.

3. Pipeline de Base : Sentiment Analysis

from transformers import pipeline

classifier = pipeline("sentiment-analysis")
result = classifier("I really love this product, it works great!")
print(result)
  • Ligne 1 : importer la fonction pipeline.
  • Ligne 3 : créer un pipeline pour la tâche sentiment-analysis. Quand vous ne spécifiez pas de modèle, Hugging Face choisit automatiquement un modèle par défaut (généralement distilbert-base-uncased-finetuned-sst-2-english).
  • Ligne 4 : appeler le pipeline comme une fonction, en passant la phrase de texte.

Résultat :

[{'label': 'POSITIVE', 'score': 0.9998}]

pipeline retourne une liste car il prend en charge le traitement par batch (vous pouvez aussi passer une liste de chaînes).

4. Spécifier un Modèle et un Tokenizer Particulier

Ne dépendez pas du modèle par défaut dans le code de production, car Hugging Face peut changer le défaut entre les versions. Spécifiez-le clairement :

from transformers import pipeline

classifier = pipeline(
    task="sentiment-analysis",
    model="distilbert-base-uncased-finetuned-sst-2-english",
    device=-1  # -1 = CPU, 0 = GPU index 0
)

results = classifier([
    "This movie was a complete waste of time.",
    "Absolutely fantastic service!"
])
for r in results:
    print(r)
  • model : spécifiez clairement le checkpoint pour éviter de dépendre d’une valeur par défaut qui pourrait changer.
  • device : -1 s’exécute sur CPU, 0 s’exécute sur le GPU index 0. Si votre machine n’a pas de CUDA mais que vous réglez device=0, le pipeline lèvera une erreur.
  • Passez une liste de phrases au classifier pour traiter par batch, c’est plus efficace que d’appeler la fonction une phrase à la fois.

Résultat :

{'label': 'NEGATIVE', 'score': 0.9995}
{'label': 'POSITIVE', 'score': 0.9997}

5. Reconnaissance d’Entités Nommées (NER)

from transformers import pipeline

ner = pipeline("ner", model="dslim/bert-base-NER", aggregation_strategy="simple")
text = "Satya Nadella is the CEO of Microsoft, based in Redmond."
for entity in ner(text):
    print(entity["word"], "->", entity["entity_group"], f"{entity['score']:.2f}")
  • aggregation_strategy="simple" : groupe les sous-tokens (par exemple Sat, ##ya) en une entité complète au lieu de retourner des tokens fragmentés distincts.
  • entity_group : l’étiquette du type d’entité (PER, ORG, LOC…).

Résultat :

Satya Nadella -> PER 0.99
Microsoft -> ORG 0.99
Redmond -> LOC 0.98

Note : Si vous omettez aggregation_strategy, vous recevrez des tokens fragmentés au format BIO-tagging (B-PER, I-PER…), et vous devrez les regrouper vous-même — c’est facile de créer des bugs si vous ne gérez pas cela correctement.

6. Classification Zero-Shot

La classification zero-shot vous permet de classer du texte dans des catégories arbitraires sans que le modèle n’ait été spécifiquement entraîné pour ces catégories.

from transformers import pipeline

classifier = pipeline("zero-shot-classification", model="facebook/bart-large-mnli")

result = classifier(
    "This new phone has an amazing camera and battery life.",
    candidate_labels=["technology", "sports", "politics", "finance"]
)
print(result["labels"][0], result["scores"][0])
  • candidate_labels : une liste d’étiquettes que vous définissez vous-même, sans avoir besoin d’affiner le modèle.
  • Le modèle utilise la technique Natural Language Inference pour calculer la probabilité que le texte « implique » chaque étiquette.

Résultat :

technology 0.93

Zero-shot est très pratique pour les prototypes rapides, mais c’est plus lent et moins précis qu’un modèle affiné directement pour votre tâche.

7. Résumé de Texte

from transformers import pipeline

summarizer = pipeline("summarization", model="facebook/bart-large-cnn")

article = """
The Transformers library by Hugging Face provides thousands of pretrained
models to perform tasks on texts such as classification, information
extraction, question answering, summarization, translation, and more.
It bridges research and production by exposing a simple pipeline API
on top of complex model architectures.
"""

summary = summarizer(article, max_length=40, min_length=10, do_sample=False)
print(summary[0]["summary_text"])
  • max_length/min_length : limite la longueur des tokens du résumé, pas le nombre de mots.
  • do_sample=False : utilise le décodage greedy/beam au lieu d’un échantillonnage aléatoire, pour des résultats cohérents entre les exécutions.

Résultat (résumé) :

Transformers library provides pretrained models for classification,
extraction, question answering, and summarization.

8. Que se Passe-t-il à l’Intérieur d’un Pipeline ?

pipeline() combine en réalité 3 composants : le tokenizer, le modèle et la logique de post-traitement pour chaque tâche. Vous pouvez les assembler vous-même pour un contrôle plus granulaire :

from transformers import AutoTokenizer, AutoModelForSequenceClassification
import torch

model_name = "distilbert-base-uncased-finetuned-sst-2-english"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForSequenceClassification.from_pretrained(model_name)

inputs = tokenizer("Great product!", return_tensors="pt")
with torch.no_grad():
    logits = model(**inputs).logits

probs = torch.softmax(logits, dim=-1)
label_id = probs.argmax().item()
print(model.config.id2label[label_id], probs[0][label_id].item())
  • AutoTokenizer/AutoModelForSequenceClassification : identifient automatiquement l’architecture correcte en fonction du nom du modèle.
  • tokenizer(..., return_tensors="pt") : retourne un tenseur PyTorch au lieu d’une liste de nombres ordinaires.
  • torch.no_grad() : désactive le calcul des gradients car ceci est une inférence, pas un entraînement — cela économise la mémoire et est plus rapide.
  • model.config.id2label : mappe l’indice de classe au nom de l’étiquette (LABEL_0/LABEL_1 ou POSITIVE/NEGATIVE selon le modèle).

Comprendre cette couche vous aide à déboguer quand le pipeline donne des résultats inattendus, ou quand vous avez besoin d’une logique personnalisée (par exemple appliquer votre propre seuil au lieu de prendre l’argmax).

9. Écrire des Tests pour le Pipeline

Parce que le résultat du modèle peut légèrement varier entre les versions, les tests doivent vérifier le « comportement » plutôt que de faire correspondre les décimales absolues.

import pytest
from transformers import pipeline

@pytest.fixture(scope="module")
def sentiment_classifier():
    return pipeline(
        "sentiment-analysis",
        model="distilbert-base-uncased-finetuned-sst-2-english",
    )

def test_classifies_positive_sentence(sentiment_classifier):
    result = sentiment_classifier("I absolutely love this!")[0]

    assert result["label"] == "POSITIVE"
    assert result["score"] > 0.9

def test_classifies_negative_sentence(sentiment_classifier):
    result = sentiment_classifier("This is the worst experience ever.")[0]

    assert result["label"] == "NEGATIVE"
    assert result["score"] > 0.9
  • scope="module" : la fixture charge le modèle une seule fois pour tout le fichier de test, évitant de recharger le modèle à chaque cas de test — le chargement du modèle peut prendre plusieurs secondes à plusieurs dizaines de secondes.
  • Assert basé sur label et un seuil score, ne codez pas en dur la valeur exacte du score car elle peut légèrement varier entre les versions de la bibliothèque.

Note : L’exécution de ce type de test nécessite de charger le modèle réel, donc ce n’est pas approprié pour les tests unitaires qui s’exécutent rapidement dans une boucle CI. Séparez-les en tests d’intégration ou mock le pipeline lors des tests de la logique métier environnante.

10. Quand Ne Pas Utiliser Pipeline

Pipeline est excellent pour les prototypes et les tâches standard, mais il a des limites :

  • Gros batch, haute performance : pipeline n’optimise pas aussi bien que la gestion manuelle du batching, du padding et du dynamic batching.
  • Besoin de logique personnalisée complexe : par exemple appliquer plusieurs conditions de post-traitement, combiner plusieurs modèles, ou accéder aux états cachés — utilisez directement AutoModel + tokenizer comme dans la section 8.
  • Serveur de production à grande échelle : envisagez des outils spécialisés comme Text Generation Inference ou ONNX Runtime/TensorRT pour optimiser la latence, au lieu d’appeler pipeline() directement dans un gestionnaire de requête.
  • Modèle trop volumineux pour le CPU : les modèles comme bart-large-mnli ou les LLM avec des milliards de paramètres s’exécuteront très lentement sur le CPU ; vous avez besoin d’un GPU ou d’une quantification.

11. Conclusion

pipeline() de Hugging Face Transformers est le moyen le plus rapide d’exécuter l’inférence avec des modèles NLP préentraînés — il faut seulement quelques lignes de code pour sentiment analysis, NER, summarization ou zero-shot classification. Quand vous avez besoin d’un contrôle plus granulaire sur la performance ou la logique de traitement, vous pouvez « décomposer » le pipeline en tokenizer et modèle séparés pour les gérer vous-même. Spécifiez toujours explicitement le modèle au lieu d’utiliser la valeur par défaut, et écrivez des tests basés sur le comportement (label, seuil de score) plutôt que sur les valeurs absolues pour éviter les tests flaky quand la bibliothèque se met à jour.

huggingfacetransformersnlppythonmachine-learning