Transformers documentation

Génération de texte

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v5.22.1).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Génération de texte

La génération de texte est l’application la plus populaire des grands modèles de langage (LLM). Un LLM est entraîné à générer le mot suivant (jeton) à partir d’un texte initial (invite) ainsi que de ses propres sorties générées, jusqu’à une longueur prédéfinie ou lorsqu’il atteint un jeton de fin de séquence (EOS).

Dans Transformers, l'API generate() gère la génération de texte et est disponible pour tous les modèles dotés de capacités génératives. Ce guide vous présente les bases de la génération de texte avec generate() ainsi que les pièges courants à éviter.

Pour les commandes suivantes, assurez-vous que transformers serve est en cours d'exécution.

transformers chat Qwen/Qwen2.5-0.5B-Instruct

Génération par défaut

Avant de commencer, il est utile d'installer bitsandbytes pour quantifier les très grands modèles afin de réduire leur consommation mémoire.

!pip install -U transformers bitsandbytes

Bitsandbytes prend en charge plusieurs backends en plus des GPU basés sur CUDA. Consultez le guide d’installation multi-backend pour en savoir plus.

Chargez un LLM avec from_pretrained() et ajoutez les deux paramètres suivants pour réduire les besoins en mémoire.

  • device_map="auto" active la fonctionnalité Big Model Inference d’Accelerate, qui initialise automatiquement le squelette du modèle et charge et répartit les poids du modèle sur tous les dispositifs disponibles, en commençant par le dispositif le plus rapide (GPU).
  • quantization_config est un objet de configuration qui définit les paramètres de quantification. Cet exemple utilise bitsandbytes comme backend de quantification (voir la section Quantization pour d'autres backends disponibles) et charge le modèle en 4-bits.
from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig

quantization_config = BitsAndBytesConfig(load_in_4bit=True)
model = AutoModelForCausalLM.from_pretrained("mistralai/Mistral-7B-v0.1", device_map="auto", quantization_config=quantization_config)

Tokenisez votre entrée et définissez le paramètre padding_side() sur "left", car un LLM n'est pas entraîné à poursuivre la génération à partir de jetons de bourrage. Le tokeniseur renvoie les identifiants d'entrée et le masque d'attention.

Traitez plusieurs invites à la fois en passant une liste de chaînes au tokenizer. Regroupez les entrées en lots pour améliorer le débit, au prix d'un léger surcoût en latence et en mémoire.

tokenizer = AutoTokenizer.from_pretrained("mistralai/Mistral-7B-v0.1", padding_side="left")
model_inputs = tokenizer(["A list of colors: red, blue"], return_tensors="pt").to(model.device)

Transmettez les entrées à generate() pour générer des jetons, puis utilisez batch_decode() pour convertir les jetons générés en texte.

generated_ids = model.generate(**model_inputs)
tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
"A list of colors: red, blue, green, yellow, orange, purple, pink,"

Configuration de génération

Tous les paramètres de génération sont contenus dans GenerationConfig. Dans l’exemple ci-dessus, les paramètres de génération sont dérivés du fichier generation_config.json de mistralai/Mistral-7B-v0.1. Une stratégie de décodage par défaut est utilisée lorsqu’aucune configuration n’est enregistrée avec un modèle.

Inspectez la configuration via l'attribut generation_config. N'affiche que les valeurs différentes de la configuration par défaut, en l'occurrence bos_token_id et eos_token_id.

from transformers import AutoModelForCausalLM

model = AutoModelForCausalLM.from_pretrained("mistralai/Mistral-7B-v0.1", device_map="auto")
model.generation_config
GenerationConfig {
  "bos_token_id": 1,
  "eos_token_id": 2
}

Vous pouvez personnaliser generate() en surchargeant les paramètres et les valeurs de GenerationConfig. Consultez cette section ci-dessous pour les paramètres couramment ajustés.

# enable beam search sampling strategy
model.generate(**inputs, num_beams=4, do_sample=True)

generate() peut également être étendu avec des bibliothèques externes ou du code personnalisé :

  1. le paramètre logits_processor accepte des instances personnalisées de LogitsProcessor pour manipuler la distribution de probabilité du jeton suivant ;
  2. le paramètre stopping_criteria prend en charge des StoppingCriteria personnalisés pour arrêter la génération de texte ;
  3. d'autres méthodes de génération personnalisées peuvent être chargées via le drapeau custom_generate (docs).

Consultez le guide Stratégies de génération pour en savoir plus sur les stratégies de recherche, d'échantillonnage et de décodage.

Enregistrement

Créez une instance de GenerationConfig et spécifiez les paramètres de décodage souhaités.

from transformers import AutoModelForCausalLM, GenerationConfig

model = AutoModelForCausalLM.from_pretrained("my_account/my_model")
generation_config = GenerationConfig(
    max_new_tokens=50, do_sample=True, top_k=50, eos_token_id=model.config.eos_token_id
)

Utilisez save_pretrained() pour enregistrer une configuration de génération spécifique et définissez le paramètre push_to_hub sur True pour le téléverser sur le Hub.

generation_config.save_pretrained("my_account/my_model", push_to_hub=True)

Laissez le paramètre config_file_name vide. Ce paramètre doit être utilisé lors du stockage de plusieurs configurations de génération dans un même répertoire. Il vous permet de spécifier quelle configuration de génération charger. Vous pouvez créer différentes configurations pour différentes tâches génératives (génération de texte créatif avec échantillonnage, résumés avec beam search) à utiliser avec un seul modèle.

from transformers import AutoModelForSeq2SeqLM, AutoTokenizer, GenerationConfig

tokenizer = AutoTokenizer.from_pretrained("google-t5/t5-small")
model = AutoModelForSeq2SeqLM.from_pretrained("google-t5/t5-small")

translation_generation_config = GenerationConfig(
    num_beams=4,
    early_stopping=True,
    decoder_start_token_id=0,
    eos_token_id=model.config.eos_token_id,
    pad_token=model.config.pad_token_id,
)

translation_generation_config.save_pretrained("/tmp", config_file_name="translation_generation_config.json", push_to_hub=True)

generation_config = GenerationConfig.from_pretrained("/tmp", config_file_name="translation_generation_config.json")
inputs = tokenizer("translate English to French: Configuration files are easy to use!", return_tensors="pt")
outputs = model.generate(**inputs, generation_config=generation_config)
print(tokenizer.batch_decode(outputs, skip_special_tokens=True))

Options courantes

generate() est un outil puissant qui peut être fortement personnalisé. Cela peut intimider les nouveaux utilisateurs. Cette section contient une liste des options de génération populaires que vous pouvez définir dans la plupart des outils de génération de texte de Transformers : generate(), GenerationConfig, pipelines, le CLI chat, …

Nom de l'optionTypeDescription simplifiée
max_new_tokensintContrôle la longueur maximale de génération. Assurez-vous de le définir, car il est généralement défini par défaut sur une valeur faible.
do_sampleboolDéfinit si la génération échantillonne le jeton suivant (True) ou si elle est au contraire gloutonne (False). La plupart des cas d’utilisation doivent définir ce drapeau sur True. Consultez ce guide pour plus d’informations.
temperaturefloatMesure de l’imprévisibilité du prochain jeton sélectionné. Des valeurs élevées (>0.8) sont adaptées aux tâches créatives, tandis que des valeurs faibles (par ex. <0.4) conviennent aux tâches nécessitant du « raisonnement ». Nécessite do_sample=True.
num_beamsintLorsqu'il est défini sur >1, active l'algorithme de beam search. Le beam search est efficace pour les tâches fondées sur l'entrée. Consultez ce guide pour plus d'informations.
repetition_penaltyfloatDéfinissez-le à une valeur >1.0 si vous constatez que le modèle se répète souvent. Des valeurs plus élevées appliquent une pénalité plus importante.
eos_token_idlist[int]Le(s) jeton(s) qui provoqueront l'arrêt de la génération. La valeur par défaut est généralement bonne, mais vous pouvez spécifier un jeton différent.

Pièges

La section ci-dessous aborde certains problèmes courants que vous pouvez rencontrer lors de la génération de texte et comment les résoudre.

Longueur de la sortie

generate() renvoie par défaut jusqu’à 20 jetons, sauf si une autre valeur est spécifiée dans la GenerationConfig du modèle. Il est fortement recommandé de définir manuellement le nombre de jetons générés à l’aide du paramètre max_new_tokens afin de contrôler la longueur de la sortie. Les modèles Decoder-only renvoient le prompt initial ainsi que les jetons générés.

model_inputs = tokenizer(["A sequence of numbers: 1, 2"], return_tensors="pt").to(model.device)
longueur par défaut
max_new_tokens
generated_ids = model.generate(**model_inputs)
tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
'A sequence of numbers: 1, 2, 3, 4, 5'

Stratégie de décodage

La stratégie de décodage par défaut dans generate() est la recherche gloutonne, qui sélectionne le jeton le plus probable, sauf si une autre stratégie est spécifiée dans la GenerationConfig d’un modèle. Bien que cette stratégie de décodage fonctionne bien pour les tâches ancrées dans l’entrée (transcription, traduction), elle n’est pas optimale pour les cas d’usage plus créatifs (rédaction de récits, applications de chat).

Par exemple, activez une stratégie de multinomial sampling pour générer des sorties plus variées. Consultez le guide Generation strategy pour en savoir plus sur les stratégies de décodage.

model_inputs = tokenizer(["I am a cat."], return_tensors="pt").to(model.device)
recherche gloutonne
échantillonnage multinomial
generated_ids = model.generate(**model_inputs)
tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]

Côté de bourrage

Les entrées doivent être remplies (padding) si elles n’ont pas la même longueur. Mais les LLM ne sont pas entraînés à poursuivre la génération à partir de jetons de remplissage, ce qui signifie que le paramètre padding_side() doit être défini à gauche de l’entrée. Le remplissage à droite est plus défavorable pour les modèles à espace d’état et hybrides, car leur état récurrent continue de se mettre à jour sur les jetons de remplissage de fin, si bien que le cache ne correspond plus à la fin du prompt.

remplissage à droite
left pad
model_inputs = tokenizer(
    ["1, 2, 3", "A, B, C, D, E"], padding=True, return_tensors="pt"
).to(model.device)
generated_ids = model.generate(**model_inputs)
tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
'1, 2, 33333333333'

Format du prompt

Certains modèles et tâches attendent un format de prompt d’entrée spécifique, et si le format est incorrect, le modèle renvoie une sortie sous-optimale. Vous pouvez en savoir plus sur le prompting dans le guide prompt engineering.

Par exemple, un modèle de chat s’attend à recevoir l’entrée sous forme de chat template. Votre invite doit inclure un role et un content pour indiquer qui participe à la conversation. Si vous essayez de passer votre invite sous forme d’une seule chaîne de caractères, le modèle ne renvoie pas toujours la sortie attendue.

from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig

tokenizer = AutoTokenizer.from_pretrained("HuggingFaceH4/zephyr-7b-alpha")
model = AutoModelForCausalLM.from_pretrained(
    "HuggingFaceH4/zephyr-7b-alpha", device_map="auto", quantization_config=BitsAndBytesConfig(load_in_4bit=True)
)
aucun format
chat template
prompt = """How many cats does it take to change a light bulb? Reply as a pirate."""
model_inputs = tokenizer([prompt], return_tensors="pt").to(model.device)
input_length = model_inputs.input_ids.shape[1]
generated_ids = model.generate(**model_inputs, max_new_tokens=50)
print(tokenizer.batch_decode(generated_ids[:, input_length:], skip_special_tokens=True)[0])
"Aye, matey! 'Tis a simple task for a cat with a keen eye and nimble paws. First, the cat will climb up the ladder, carefully avoiding the rickety rungs. Then, with"

Ressources

Consultez ci-dessous quelques bibliothèques de génération de texte plus spécifiques et spécialisées.

  • Optimum : une extension de Transformers axée sur l’optimisation de l’entraînement et de l’inférence sur des dispositifs matériels spécifiques
  • Outlines : une bibliothèque pour la génération de texte contrainte (générer des fichiers JSON, par exemple).
  • SynCode : une bibliothèque pour la génération guidée par grammaires sans contexte (JSON, SQL, Python).
  • Text Generation Inference : un serveur prêt pour la production destiné aux LLM.
  • Text generation web UI : une interface web Gradio pour la génération de texte.
  • logits-processor-zoo : processeurs de logits supplémentaires pour contrôler la génération de texte.
Update on GitHub