비디오-텍스트-투-텍스트
비디오-텍스트-투-텍스트 (Video-text-to-text)
비디오-텍스트-투-텍스트(video-text-to-text)는 비디오 언어 모델(video language model)이라고도 하며, 비디오를 처리하고 텍스트를 출력할 수 있는 모델이에요. 이런 모델은 비디오 질문 답변(video question answering)부터 비디오 캡셔닝(video captioning)까지 다양한 작업을 처리할 수 있어요.
출처: 문서
본문
이런 모델은 이미지-텍스트-투-텍스트 모델과 거의 같은 아키텍처를 갖지만, 비디오 데이터가 본질적으로 시간적 의존성(temporal dependency)을 가진 이미지 프레임이기 때문에 비디오 데이터를 받아들이도록 몇 가지 변경 사항이 있어요. 일부 이미지-텍스트-투-텍스트 모델은 여러 이미지를 입력으로 받지만, 그것만으로는 모델이 비디오를 받아들이기에 충분하지 않아요.
또한 비디오-텍스트-투-텍스트 모델은 흔히 모든 비전 모달리티를 사용해 훈련돼요. 각 예시에는 비디오, 여러 비디오, 이미지, 여러 이미지가 있을 수 있어요. 일부 모델은 인터리브된(interleaved) 입력도 받을 수 있어요. 예를 들어 텍스트 안에 비디오 토큰을 넣어서 "이 비디오에서 무슨 일이 일어나고 있어? <video>"처럼 텍스트 열 안의 특정 비디오를 참조할 수 있어요.
이런 모델들은 오디오가 없는 비디오를 처리한다는 점에 유의하세요. 반면 Any-to-any 모델은 오디오가 포함된 비디오를 처리할 수 있어요.
이 가이드에서는 비디오 LM(video LM)에 대한 간단한 개요를 제공하고, Transformers에서 추론에 사용하는 방법을 보여줄게요.
먼저 비디오 LM에는 여러 유형이 있어요:
- 파인튜닝에 사용되는 기본 모델(base model)
- 대화용으로 파인튜닝된 채팅 모델(chat fine-tuned model)
- 명령어 파인튜닝된 모델(instruction fine-tuned model)
이 가이드는 인터리브된 데이터를 받을 수 있는 명령어 튜닝 모델인 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)
두 개의 비디오로 추론할 거예요. 둘 다 고양이가 나와요.
비디오는 이미지 프레임의 연속이에요. 하드웨어 제약에 따라 다운샘플링(downsampling)이 필요해요. 다운샘플링된 프레임 수가 너무 적으면 예측 품질이 낮아져요.
비디오-텍스트-투-텍스트 모델에는 비디오 프로세서가 추상화된 프로세서가 있어요. 비디오 추론 관련 인자를 apply_chat_template() 함수에 전달할 수 있어요.
[!WARNING] 비디오 프로세서에 대해 더 자세히 알고 싶다면 여기를 참고하세요.
아래처럼 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. ']