Transformers documentation

Modèles de discussion multimodaux

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

Modèles de discussion multimodaux

Les modèles de chat multimodaux acceptent des entrées telles que des images, de l'audio ou de la vidéo, en plus du texte. La clé content dans un historique de chat multimodal est une liste contenant plusieurs éléments de types différents. Cela diffère des modèles de chat texte uniquement, dont la clé content est une simple chaîne de caractères.

De la même manière que la classe Tokenizer gère les modèles de chat et la tokenisation pour les modèles textuels, la classe Processor gère la prétraitement, la tokenisation et les modèles de chat pour les modèles multimodaux. Leurs méthodes apply_chat_template() sont presque identiques.

Ce guide vous montre comment discuter avec des modèles multimodaux à l’aide du pipeline de haut niveau ImageTextToTextPipeline et, à un niveau plus bas, en utilisant les méthodes apply_chat_template() et generate().

ImageTextToTextPipeline

ImageTextToTextPipeline est une classe de haut niveau pour la génération d’images et de texte avec un « mode conversation ». Le mode conversation est activé lorsqu’un modèle conversationnel est détecté et que le prompt de conversation est correctement formaté.

Ajoutez des blocs d’image et de texte à la clé content dans l’historique de la conversation.

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?"},
        ],
    },
]

Créez un ImageTextToTextPipeline et passez-lui la conversation. Pour les grands modèles, définir device_map=“auto” aide à charger le modèle plus rapidement et le place automatiquement sur le périphérique le plus rapide disponible. Définir le type de données sur auto aide également à économiser de la mémoire et à améliorer la vitesse.

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?

En dehors de la transition progressive du jargon des pirates vers l’anglais américain moderne (c’est un modèle de 3B, après tout), c’est correct !

Utilisation de apply_chat_template

Comme pour les modèles de texte uniquement, utilisez la méthode apply_chat_template() pour préparer les messages de chat destinés aux modèles multimodaux. Cette méthode gère la tokenisation et le formatage des messages de chat, y compris les images et les autres types de médias. Les entrées résultantes sont transmises au modèle pour la génération.

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?"},
        ],
    },
]

Passez messages à apply_chat_template() pour tokeniser le contenu d'entrée. Contrairement aux modèles de texte, la sortie de apply_chat_template contient une clé pixel_values avec les données d'image prétraitées, en plus du texte tokenisé.

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']

Passez ces entrées à generate().

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

La sortie décodée contient la conversation complète jusqu’à présent, y compris le message de l’utilisateur et les jetons de substitution qui contiennent les informations de l’image. Il est peut-être nécessaire de retirer la conversation précédente de la sortie avant de l’afficher à l’utilisateur.

Entrées vidéo

Certains modèles de vision prennent également en charge les entrées vidéo. Le format des messages est très similaire au format des entrées d’images décrit dans la section précédente.

  • Le contenu "type" doit être "video" pour indiquer que le contenu est une vidéo.
  • Pour les vidéos, il peut s’agir d’un lien vers la vidéo ("url") ou d’un chemin de fichier ("path"). Les vidéos sont décodées avec torchcodec. Si torchcodec n’est pas disponible et que vous utilisez une ancienne version de torchvision, le décodage bascule sur torchvision.
  • En plus de charger des vidéos à partir d’une URL ou d’un chemin de fichier, vous pouvez également transmettre directement des données vidéo décodées. Cela est utile si vous avez déjà prétraité ou décodé les images vidéo ailleurs en mémoire. Vous n’avez pas besoin de les enregistrer dans des fichiers ni de les stocker dans une URL.

PyAV et Decord sont disponibles, mais uniquement si vous décodez la vidéo vous-même et que vous demandez explicitement le backend avec 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?"},
        ],
    },
]

Exemple : Passer des objets vidéo décodés

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?"}
        ],
    },
]

Vous pouvez également utiliser la fonction existante ("load_video()") pour charger une vidéo, la modifier en mémoire et la transmettre dans les messages.


# 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?"}
        ],
    },
]

Passez messages à apply_chat_template() pour tokeniser le contenu d’entrée. Il y a quelques paramètres supplémentaires à inclure dans apply_chat_template() qui contrôlent le processus d’échantillonnage.

nombre fixe d'images
fps
liste de trames d'image

Le paramètre num_frames contrôle le nombre de frames à échantillonner uniformément dans la vidéo. Chaque checkpoint a un nombre maximal de frames avec lequel il a été pré-entraîné, et dépasser ce nombre peut réduire considérablement la qualité de la génération. Il est important de choisir un nombre de frames adapté à la capacité du modèle et à vos ressources matérielles. Si num_frames n’est pas spécifié, la vidéo entière est chargée sans aucun échantillonnage de frames.

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

Ces entrées sont désormais prêtes à être utilisées dans generate().

Update on GitHub