Video-text-to-text
비디오-텍스트-투-텍스트, 즉 비디오 언어 모델은 비디오를 처리하고 텍스트를 출력하는 모델입니다. 이러한 모델은 비디오 질의응답부터 비디오 캡셔닝까지 다양한 작업을 수행할 수 있습니다.
이 모델들은 이미지-텍스트-투-텍스트 모델과 거의 동일한 아키텍처를 가지며, 영상 데이터는 기본적으로 시간적 의존성을 가진 이미지 프레임의 집합이므로 영상 데이터를 받아들이기 위해 일부 변경 사항이 적용되었습니다. 일부 이미지-텍스트-투-텍스트 모델은 여러 이미지를 입력으로 받지만, 이것만으로는 모델이 영상을 받아들이기에 충분하지 않습니다.
Moreover, video-text-to-text models are often trained with all vision modalities. Each example might have videos, multiple videos, images and multiple images. Some of these models can also take interleaved inputs. For example, you can refer to a specific video inside a string of text by adding a video token in text like “What is happening in this video? <video>“.
이 모델들은 오디오가 없는 비디오를 처리합니다. 반면 Any-to-any 모델은 오디오가 포함된 비디오를 처리할 수 있습니다.
이 가이드에서는 비디오 LM에 대한 간단한 개요를 제공하고, Transformers를 사용하여 추론을 수행하는 방법을 보여줍니다.
시작하기에 앞서, 비디오 LM에는 여러 유형이 있습니다:
- fine-tuning에 사용되는 base models
- 대화용 fine-tuned 모델
- 지시어 파인튜닝된 모델
이 가이드는 지시 학습(instruction-tuned) 모델, 즉 교차(interleaved) 데이터를 입력으로 받을 수 있는 llava-hf/llava-onevision-qwen2-0.5b-ov-hf를 활용한 추론에 초점을 맞춥니다. 하드웨어 사양상 7B 모델을 실행할 수 없는 경우, llava-interleave-qwen-0.5b-hf를 사용해 보실 수 있습니다.
의존성을 설치하는 것으로 시작해 보겠습니다.
pip install -q transformers accelerate flash_attn torchcodec
모델과 프로세서를 초기화해 보겠습니다.
from transformers import AutoProcessor, LlavaOnevisionForConditionalGeneration
import torch
model_id = "llava-hf/llava-onevision-qwen2-0.5b-ov-hf"
device = torch.accelerator.current_accelerator().type if torch.accelerator.is_available() else "cpu"
processor = AutoProcessor.from_pretrained(model_id, device=device)
model = LlavaForConditionalGeneration.from_pretrained(model_id, device_map="auto", dtype=torch.float16)두 개의 비디오로 추론을 수행합니다. 두 비디오 모두 고양이가 포함되어 있습니다.
영상은 이미지 프레임의 연속입니다. 하드웨어의 제한에 따라 다운샘플링이 필요합니다. 다운샘플링된 프레임의 수가 너무 적으면 예측 품질이 저하됩니다.
Video-text-to-text 모델에는 video processor가 추상화되어 있는 processor가 있습니다. apply_chat_template() 함수에 video 추론 관련 인수를 전달할 수 있습니다.
비디오 프로세서에 대한 자세한 내용은 여기에서 확인하실 수 있습니다.
아래와 같이 URL을 통해 비디오를 전달하여 채팅 히스토리를 정의할 수 있습니다.
messages = [
{
"role": "user",
"content": [
{"type": "video", "video": "https://huggingface.co/spaces/merve/llava-interleave/resolve/main/cats_1.mp4"},
{"type": "text", "text": "Describe what is happening in this video."},
],
}
]메시지를 전달하고 do_sample_frames을 True로 설정한 뒤 num_frames을 전달하여 비디오를 전처리할 수 있습니다. 여기서는 10개의 프레임을 샘플링합니다.
inputs = processor.apply_chat_template(
messages,
tokenize=True,
add_generation_prompt=True,
return_dict=True,
return_tensors="pt",
num_frames=10,
do_sample_frames=True
)
inputs.to(model.device)입력에는 토큰화된 텍스트의 input_ids, 10개 프레임의 pixel_values_videos, 그리고 해당 토큰을 위한 attention_mask가 포함되어 있습니다.
이제 전처리된 입력으로 추론을 수행하고 결과를 디코딩할 수 있습니다.
generated_ids = model.generate(**inputs, max_new_tokens=128)
input_length = len(inputs["input_ids"][0])
output_text = processor.batch_decode(
generated_ids[:, input_length:], skip_special_tokens=True, clean_up_tokenization_spaces=False
)
output_text = processor.batch_decode(
generated_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False
)
print(output_text[0])
#"The video features a fluffy, long-haired cat with a mix of brown and white fur, lying on a beige carpeted floor. The cat's eyes are wide open, and its whiskers are prominently visible. The cat appears to be in a relaxed state, with its head slightly"아래와 같이 채팅 템플릿에서 텍스트와 여러 비디오를 직접 교차 배치할 수도 있습니다.
messages = [
{
"role": "user",
"content": [
{"type": "text", "text": "Here's a video."},
{"type": "video", "video": "https://huggingface.co/spaces/merve/llava-interleave/resolve/main/cats_1.mp4"},
{"type": "text", "text": "Here's another video."},
{"type": "video", "video": "https://huggingface.co/spaces/merve/llava-interleave/resolve/main/cats_2.mp4"},
{"type": "text", "text": "Describe similarities in these videos."},
],
}
]추론은 이전 예제와 동일하게 유지됩니다.
inputs = processor.apply_chat_template(
messages,
tokenize=True,
add_generation_prompt=True,
return_dict=True,
return_tensors="pt",
num_frames=100,
do_sample_frames=True
)
inputs.to(model.device)
generated_ids = model.generate(**inputs, max_new_tokens=50)
input_length = len(inputs["input_ids"][0])
output_text = processor.batch_decode(
generated_ids[:, input_length:], skip_special_tokens=True, clean_up_tokenization_spaces=False
)
print(output_text)
#['Both videos feature a cat with a similar appearance, characterized by a fluffy white coat with black markings, a pink nose, and a pink tongue. The cat\'s eyes are wide open, and it appears to be in a state of alertness or excitement. ']