Transformers documentation

Generación de texto

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

Generación de texto

La generación de texto es la aplicación más popular de los modelos de lenguaje grandes (LLM). Un LLM se entrena para generar la siguiente palabra (token) a partir de un texto inicial (prompt) junto con sus propias salidas generadas hasta una longitud predefinida o cuando alcanza un token de fin de secuencia (EOS).

En Transformers, la API generate() gestiona la generación de texto y está disponible para todos los modelos con capacidades generativas. Esta guía te mostrará las bases de la generación de texto con generate() y algunos errores comunes a evitar.

Para los siguientes comandos, asegúrese de que transformers serve esté en ejecución.

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

Generación predeterminada

Antes de comenzar, es útil instalar bitsandbytes para cuantizar modelos muy grandes y reducir su uso de memoria.

!pip install -U transformers bitsandbytes

Bitsandbytes admite varios backends además de las GPU basadas en CUDA. Consulte la guía de instalación multi-backend para obtener más información.

Carga un LLM con from_pretrained() y añade los siguientes dos parámetros para reducir los requisitos de memoria.

  • device_map="auto" habilita la función Big Model Inference de Accelerate para iniciar automáticamente el esqueleto del modelo y cargar y distribuir los pesos del modelo en todos los dispositivos disponibles, comenzando por el dispositivo más rápido (GPU).
  • quantization_config es un objeto de configuración que define los ajustes de cuantización. Este ejemplo utiliza bitsandbytes como backend de cuantización (consulte la sección Cuantización para ver más backends disponibles) y carga el modelo 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)

Tokeniza tu entrada y establece el parámetro padding_side() en "left" porque un LLM no está entrenado para continuar la generación desde tokens de relleno. El tokenizador devuelve los ids de entrada y la máscara de atención.

Procesar más de un prompt a la vez pasando una lista de cadenas al tokenizer. Agrupar las entradas en lotes para mejorar el rendimiento a un pequeño costo en latencia y memoria.

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)

Pasa las entradas a generate() para generar tokens y usa batch_decode() para convertir los tokens generados de nuevo en texto.

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,"

Configuración de generación

Todos los ajustes de generación están contenidos en GenerationConfig. En el ejemplo anterior, los ajustes de generación se derivan del archivo generation_config.json de mistralai/Mistral-7B-v0.1. Se utiliza una estrategia de decodificación predeterminada cuando no se guarda ninguna configuración con un modelo.

Inspeccione la configuración a través del atributo generation_config. Solo muestra los valores que difieren de la configuración predeterminada, en este caso, bos_token_id y 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
}

Puedes personalizar generate() sobrescribiendo los parámetros y valores en GenerationConfig. Consulta esta sección más abajo para ver los parámetros que se ajustan con mayor frecuencia.

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

generate() también se puede extender con bibliotecas externas o código personalizado:

  1. el parámetro logits_processor acepta instancias personalizadas de LogitsProcessor para manipular la distribución de probabilidad del siguiente token;
  2. El parámetro stopping_criteria admite StoppingCriteria personalizados para detener la generación de texto;
  3. otros métodos de generación personalizados se pueden cargar a través de la bandera custom_generate (documentación).

Consulte la guía de Estrategias de generación para obtener más información sobre las estrategias de búsqueda, muestreo y decodificación.

Guardado

Cree una instancia de GenerationConfig y especifique los parámetros de decodificación que desee.

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
)

Use save_pretrained() para guardar una configuración de generación específica y establezca el parámetro push_to_hub en True para subirlo al Hub.

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

Deja el parámetro config_file_name vacío. Este parámetro debe usarse cuando se almacenan varias configuraciones de generación en un solo directorio. Te permite especificar qué configuración de generación cargar. Puedes crear configuraciones diferentes para tareas generativas distintas (generación de texto creativo con muestreo, resumen con búsqueda de haces) para usarlas con un solo modelo.

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))

Opciones comunes

generate() es una herramienta potente que se puede personalizar en gran medida. Esto puede resultar abrumador para los usuarios nuevos. Esta sección contiene una lista de opciones de generación populares que puedes definir en la mayoría de las herramientas de generación de texto de Transformers: generate(), GenerationConfig, pipelines, la CLI chat, …

Nombre de la opciónTipoDescripción simplificada
max_new_tokensintControla la longitud máxima de generación. Asegúrate de definirla, ya que por defecto suele tener un valor pequeño.
do_sampleboolDefine si la generación muestreará el siguiente token (True) o si, en su lugar, será codiciosa (False). La mayoría de los casos de uso deben establecer esta bandera en True. Consulte esta guía para obtener más información.
temperaturefloatQué tan impredecible será el siguiente token seleccionado. Los valores altos (>0.8) son adecuados para tareas creativas, mientras que los valores bajos (p. ej. <0.4) son para tareas que requieren “razonamiento”. Requiere do_sample=True.
num_beamsintCuando se establece en >1, activa el algoritmo de búsqueda por haz (beam search). La búsqueda por haz es adecuada para tareas basadas en la entrada. Consulta esta guía para obtener más información.
repetition_penaltyfloatEstablécelo en >1.0 si ves que el modelo se repite con frecuencia. Los valores más grandes aplican una penalización mayor.
eos_token_idlist[int]El o los tokens que harán que la generación se detenga. El valor predeterminado suele ser adecuado, pero puedes especificar un token diferente.

Errores comunes

La sección siguiente aborda algunos problemas comunes que puede encontrar durante la generación de texto y cómo resolverlos.

Longitud de la salida

generate() devuelve hasta 20 tokens de forma predeterminada, a menos que se especifique lo contrario en la GenerationConfig de un modelo. Se recomienda encarecidamente establecer manualmente el número de tokens generados con el parámetro max_new_tokens para controlar la longitud de la salida. Los modelos Decoder-only devuelven el prompt inicial junto con los tokens generados.

model_inputs = tokenizer(["A sequence of numbers: 1, 2"], return_tensors="pt").to(model.device)
longitud predeterminada
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'

Estrategia de decodificación

La estrategia de decodificación predeterminada en generate() es greedy search, que selecciona el siguiente token más probable, a menos que se especifique lo contrario en la GenerationConfig de un modelo. Aunque esta estrategia de decodificación funciona bien para tareas basadas en la entrada (transcripción, traducción), no es óptima para casos de uso más creativos (escritura de historias, aplicaciones de chat).

Por ejemplo, active una estrategia de muestreo multinomial para generar salidas más diversas. Consulte la guía de Estrategia de generación para conocer más estrategias de decodificación.

model_inputs = tokenizer(["I am a cat."], return_tensors="pt").to(model.device)
búsqueda voraz
muestreo multinomial
generated_ids = model.generate(**model_inputs)
tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]

Lado de relleno

Las entradas deben rellenarse si no tienen la misma longitud. Sin embargo, los LLM no se entrenan para continuar la generación desde tokens de relleno, lo que significa que el parámetro padding_side() debe establecerse a la izquierda de la entrada. El relleno a la derecha es peor para los modelos de espacio de estado e híbridos, ya que su estado recurrente sigue actualizándose sobre los tokens de relleno finales, por lo que la caché ya no coincide con el final del prompt.

relleno a la derecha
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'

Formato del prompt

Algunos modelos y tareas esperan un formato de entrada específico, y si el formato es incorrecto, el modelo devuelve una salida subóptima. Puede obtener más información sobre el prompting en la guía de ingeniería de prompts.

Por ejemplo, un modelo de chat espera la entrada como una plantilla de chat. Tu indicación debe incluir un role y un content para indicar quién participa en la conversación. Si intentas pasar tu indicación como una sola cadena de texto, el modelo no siempre devuelve la salida esperada.

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)
)
sin formato
plantilla de chat
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"

Recursos

A continuación, echa un vistazo a algunas bibliotecas de generación de texto más específicas y especializadas.

  • Optimum: una extensión de Transformers centrada en optimizar el entrenamiento y la inferencia en dispositivos de hardware específicos
  • Outlines: una biblioteca para la generación de texto restringida (por ejemplo, generar archivos JSON).
  • SynCode: una biblioteca para la generación guiada por gramáticas libres de contexto (JSON, SQL, Python).
  • Text Generation Inference: un servidor listo para producción para LLMs.
  • Text generation web UI: una interfaz web de Gradio para la generación de texto.
  • logits-processor-zoo: procesadores de logits adicionales para controlar la generación de texto.
Update on GitHub