Transformers documentation

Plantillas de chat multimodales

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

and get access to the augmented documentation experience

to get started

Plantillas de chat multimodales

Los modelos de chat multimodales aceptan entradas como imágenes, audio o video, además de texto. La clave content en un historial de chat multimodal es una lista que contiene varios elementos de diferentes tipos. Esto difiere de los modelos de chat solo de texto, cuya clave content es una sola cadena.

De la misma manera que la clase Tokenizer gestiona las plantillas de chat y la tokenización para modelos solo de texto, la clase Processor gestiona el preprocesamiento, la tokenización y las plantillas de chat para modelos multimodales. Sus métodos apply_chat_template() son casi idénticos.

Esta guía le mostrará cómo chatear con modelos multimodales a alto nivel con ImageTextToTextPipeline y a un nivel más bajo utilizando los métodos apply_chat_template() y generate().

ImageTextToTextPipeline

ImageTextToTextPipeline es una clase de alto nivel para la generación de imágenes y texto con un “modo de chat”. El modo de chat se activa cuando se detecta un modelo conversacional y el prompt de chat está correctamente formateado.

Agregue bloques de imagen y texto a la clave content en el historial de chat.

messages = [
    {
        "role": "system",
        "content": [{"type": "text", "text": "You are a friendly chatbot who always responds in the style of a pirate"}],
    },
    {
      "role": "user",
      "content": [
            {"type": "image", "url": "http://images.cocodataset.org/val2017/000000039769.jpg"},
            {"type": "text", "text": "What are these?"},
        ],
    },
]

Crea un ImageTextToTextPipeline y pásale el chat. Para modelos grandes, establecer device_map=“auto” ayuda a cargar el modelo más rápido y lo coloca automáticamente en el dispositivo más rápido disponible. Establecer el tipo de datos en auto también ayuda a ahorrar memoria y mejorar la velocidad.

import torch
from transformers import pipeline

pipe = pipeline("image-text-to-text", model="Qwen/Qwen2.5-VL-3B-Instruct", device_map="auto", dtype="auto")
out = pipe(text=messages, max_new_tokens=128)
print(out[0]['generated_text'][-1]['content'])
Ahoy, me hearty! These be two feline friends, likely some tabby cats, taking a siesta on a cozy pink blanket. They're resting near remote controls, perhaps after watching some TV or just enjoying some quiet time together. Cats sure know how to find comfort and relaxation, don't they?

Además del descenso gradual del lenguaje pirata al inglés americano moderno (al fin y al cabo, es solo un modelo de 3B), ¡esto es correcto!

Usando apply_chat_template

Al igual que con los modelos solo de texto, utiliza el método apply_chat_template() para preparar los mensajes de chat para los modelos multimodales. Este método se encarga de la tokenización y el formato de los mensajes de chat, incluidas las imágenes y otros tipos de medios. Las entradas resultantes se pasan al modelo para la generación.

from transformers import AutoProcessor, AutoModelForImageTextToText

model = AutoModelForImageTextToText.from_pretrained("Qwen/Qwen2.5-VL-3B-Instruct", device_map="auto", torch_dtype="auto")
processor = AutoProcessor.from_pretrained("Qwen/Qwen2.5-VL-3B-Instruct")

messages = [
    {
      "role": "system",
      "content": [{"type": "text", "text": "You are a friendly chatbot who always responds in the style of a pirate"}],
    },
    {
      "role": "user",
      "content": [
            {"type": "image", "url": "http://images.cocodataset.org/val2017/000000039769.jpg"},
            {"type": "text", "text": "What are these?"},
        ],
    },
]

Pasa messages a apply_chat_template() para tokenizar el contenido de entrada. A diferencia de los modelos de texto, la salida de apply_chat_template contiene una clave pixel_values con los datos de imagen preprocesados, además del texto tokenizado.

processed_chat = processor.apply_chat_template(messages, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt")
print(list(processed_chat.keys()))
['input_ids', 'attention_mask', 'pixel_values', 'image_grid_thw']

Pase estas entradas a generate().

out = model.generate(**processed_chat.to(model.device), max_new_tokens=128)
print(processor.decode(out[0]))

La salida decodificada contiene la conversación completa hasta el momento, incluido el mensaje del usuario y los tokens de marcador de posición que contienen la información de la imagen. Es posible que debas recortar la conversación anterior de la salida antes de mostrarla al usuario.

Entradas de video

Algunos modelos de visión también admiten entradas de video. El formato de mensaje es muy similar al formato para entradas de imagen descrito en la sección anterior.

  • El contenido "type" debe ser "video" para indicar que el contenido es un video.
  • Para los vídeos, puede ser un enlace al vídeo ("url") o una ruta de archivo ("path"). Los vídeos se decodifican con torchcodec. Si torchcodec no está disponible y se utiliza una versión anterior de torchvision, la decodificación se realiza con torchvision.
  • Además de cargar videos desde una URL o ruta de archivo, también puede pasar directamente los datos de video decodificados. Esto es útil si ya ha preprocesado o decodificado los fotogramas del video en otro lugar de la memoria. No necesita guardarlos en archivos ni almacenarlos en una URL.

PyAV y Decord están disponibles, pero solo si decodificas el video tú mismo y solicitas el backend explícitamente con load_video(backend=...).

from transformers import AutoProcessor, LlavaOnevisionForConditionalGeneration

model_id = "llava-hf/llava-onevision-qwen2-0.5b-ov-hf"
model = LlavaOnevisionForConditionalGeneration.from_pretrained(model_id)
processor = AutoProcessor.from_pretrained(model_id)

messages = [
    {
      "role": "system",
      "content": [{"type": "text", "text": "You are a friendly chatbot who always responds in the style of a pirate"}],
    },
    {
      "role": "user",
      "content": [
            {"type": "video", "url": "https://test-videos.co.uk/vids/bigbuckbunny/mp4/h264/720/Big_Buck_Bunny_720_10s_10MB.mp4"},
            {"type": "text", "text": "What do you see in this video?"},
        ],
    },
]

Ejemplo: Pasar objetos de video decodificados

import numpy as np

video_object1 = np.random.randint(0, 255, size=(16, 224, 224, 3), dtype=np.uint8),

messages = [
    {
        "role": "system",
        "content": [{"type": "text", "text": "You are a friendly chatbot who always responds in the style of a pirate"}],
    },
    {
        "role": "user",
        "content": [
            {"type": "video", "video": video_object1},
            {"type": "text", "text": "What do you see in this video?"}
        ],
    },
]

También puede usar la función existente ("load_video()") para cargar un video, editarlo en memoria y pasarlo en los mensajes.


# Make sure a video backend library (torchcodec, pyav, or decord) is available.
from transformers.video_utils import load_video

# load a video file in memory for testing
video_object2, _ = load_video(
    "https://test-videos.co.uk/vids/bigbuckbunny/mp4/h264/720/Big_Buck_Bunny_720_10s_10MB.mp4"
)

messages = [
    {
        "role": "system",
        "content": [{"type": "text", "text": "You are a friendly chatbot who always responds in the style of a pirate"}],
    },
    {
        "role": "user",
        "content": [
            {"type": "video", "video": video_object2},
            {"type": "text", "text": "What do you see in this video?"}
        ],
    },
]

Pase messages a apply_chat_template() para tokenizar el contenido de entrada. Hay algunos parámetros adicionales para incluir en apply_chat_template() que controlan el proceso de muestreo.

número fijo de fotogramas
fps
lista de fotogramas de imagen

El parámetro num_frames controla cuántos fotogramas se muestrean uniformemente del video. Cada punto de control tiene un número máximo de fotogramas con el que se preentrenó y superar este recuento puede reducir significativamente la calidad de la generación. Es importante elegir un recuento de fotogramas que se ajuste tanto a la capacidad del modelo como a los recursos de hardware. Si no se especifica num_frames, se carga el video completo sin ningún muestreo de fotogramas.

processed_chat = processor.apply_chat_template(
    messages,
    add_generation_prompt=True,
    tokenize=True,
    return_dict=True,
    return_tensors="pt",
    num_frames=32,
)
print(processed_chat.keys())

Estas entradas ya están listas para usarse en generate().

Update on GitHub