Transformers documentation
Template obrolan multimodal
Template obrolan multimodal
Model chat multimodal menerima input seperti gambar, audio, atau video, di samping teks. Kunci content dalam riwayat chat multimodal adalah daftar yang berisi beberapa item dengan tipe yang berbeda. Hal ini berbeda dari model chat yang hanya teks, di mana kunci content berupa satu string.
Dengan cara yang sama kelas Tokenizer menangani template chat dan tokenisasi untuk model teks saja, kelas Processor menangani pra-pemrosesan, tokenisasi, dan template chat untuk model multimodal. Metode apply_chat_template() mereka hampir identik.
Panduan ini akan menunjukkan cara Anda berinteraksi dengan model multimodal menggunakan ImageTextToTextPipeline tingkat tinggi dan pada tingkat yang lebih rendah menggunakan metode apply_chat_template() dan generate().
ImageTextToTextPipeline
ImageTextToTextPipeline adalah kelas generasi gambar dan teks tingkat tinggi dengan “mode chat”. Mode chat diaktifkan ketika model percakapan terdeteksi dan prompt chat terformat dengan benar.
Tambahkan blok gambar dan teks ke kunci content dalam riwayat 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?"},
],
},
]Buat ImageTextToTextPipeline dan lemparkan chat ke dalamnya. Untuk model besar, mengatur device_map=“auto” membantu memuat model lebih cepat dan secara otomatis menempatnya pada perangkat tercepat yang tersedia. Mengatur tipe data menjadi auto juga membantu menghemat memori dan meningkatkan kecepatan.
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?
Selain penurunan bertahap dari bahasa bajak laut ke bahasa Inggris Amerika modern (lagi pula, ini hanya model 3B), ini benar!
Menggunakan apply_chat_template
Seperti pada model teks saja, gunakan metode apply_chat_template() untuk menyiapkan pesan chat untuk model multimodal. Metode ini menangani tokenisasi dan pemformatan pesan chat, termasuk gambar dan jenis media lainnya. Input yang dihasilkan kemudian diteruskan ke model untuk generasi.
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?"},
],
},
]Lewatkan messages ke apply_chat_template() untuk menokenisasi konten input. Berbeda dengan model teks, output dari apply_chat_template berisi kunci pixel_values dengan data gambar yang telah dipreprocess, di samping teks yang ditokenisasi.
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']
Lewatkan input-inp ini ke generate().
out = model.generate(**processed_chat.to(model.device), max_new_tokens=128)
print(processor.decode(out[0]))Output yang didekodekan berisi percakapan lengkap sejauh ini, termasuk pesan pengguna dan token placeholder yang berisi informasi gambar. Anda mungkin perlu memangkas percakapan sebelumnya dari output sebelum menampilkannya kepada pengguna.
Input video
Beberapa model visi juga mendukung input video. Format pesannya sangat mirip dengan format untuk input gambar yang dijelaskan di bagian sebelumnya.
- Konten
"type"harus berupa"video"untuk menunjukkan bahwa kontennya adalah video. - Untuk video, ini bisa berupa tautan ke video (
"url") atau jalur file ("path"). Video didekode dengan torchcodec. Jika torchcodec tidak tersedia dan Anda menggunakan versi torchvision yang lebih lama, proses dekoding akan kembali ke torchvision. - Selain memuat video dari URL atau jalur file, Anda juga dapat meneruskan data video yang sudah didekode secara langsung. Hal ini berguna jika Anda sudah memproses pra atau mendekode bingkai video di tempat lain dalam memori. Anda tidak perlu menyimpannya ke file atau menyimpannya di URL.
PyAV dan Decord tersedia, tetapi hanya jika Anda mendekode video sendiri dan meminta backend secara eksplisit dengan
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?"},
],
},
]Contoh: Menyalurkan objek video yang telah didekode
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?"}
],
},
]Anda juga dapat menggunakan fungsi yang sudah ada ("load_video()") untuk memuat video, mengedit video di memori, dan meneruskannya ke dalam pesan.
# 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?"}
],
},
]Lewatkan messages ke apply_chat_template() untuk menokenisasi konten input. Ada beberapa parameter tambahan yang perlu disertakan di apply_chat_template() untuk mengontrol proses sampling.
Parameter num_frames mengontrol berapa banyak frame yang akan disampel secara seragam dari video. Setiap checkpoint memiliki jumlah frame maksimum yang digunakan saat prapelatihan, dan melampaui jumlah ini dapat menurunkan kualitas generasi secara signifikan. Penting untuk memilih jumlah frame yang sesuai dengan kapasitas model dan sumber daya perangkat keras Anda. Jika num_frames tidak ditentukan, seluruh video dimuat tanpa pengambilan sampel frame.
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())Input ini sekarang siap digunakan di generate().
Untuk video yang lebih panjang, mungkin lebih baik untuk mengambil sampel lebih banyak frame agar representasinya lebih baik dengan parameter fps. Parameter ini menentukan berapa banyak frame per detik yang akan diekstrak. Sebagai contoh, jika sebuah video berdurasi 10 detik dan fps=2, maka model akan mengambil sampel 20 frame. Dengan kata lain, 2 frame diambil secara seragam setiap 10 detik.
processed_chat = processor.apply_chat_template(
messages,
add_generation_prompt=True,
tokenize=True,
return_dict=True,
fps=16,
)
print(processed_chat.keys())Video juga dapat hadir sebagai kumpulan frame yang disampelkan dan disimpan sebagai gambar, bukan sebagai file video lengkap.
Dalam kasus ini, berikan daftar jalur file gambar dan prosesor akan secara otomatis menggabungkannya menjadi video. Pastikan semua gambar memiliki ukuran yang sama karena diasumsikan berasal dari video yang sama.
frames_paths = ["/path/to/frame0.png", "/path/to/frame5.png", "/path/to/frame10.png"]
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", "path": frames_paths},
{"type": "text", "text": "What do you see in this video?"},
],
},
]
processed_chat = processor.apply_chat_template(
messages,
add_generation_prompt=True,
tokenize=True,
return_dict=True,
)
print(processed_chat.keys())