비디오 프로세서
비디오 프로세서 (Video Processor)
**비디오 프로세서(Video Processor)**는 비디오 모델용 입력 특징을 준비하고 출력의 후처리를 담당하는 유틸리티예요. 리사이즈, 정규화, PyTorch로의 변환 같은 변환을 제공해요.
출처: 문서
본문
비디오 프로세서는 이미지와 다른 인자 집합으로 모델이 비디오를 처리할 수 있게 함으로써 이미지 프로세서의 기능을 확장해요. 이것은 원시 비디오 데이터와 모델 사이의 다리 역할을 하며, 입력 특징이 VLM에 최적화되도록 보장해요.
from_pretrained()을 사용해 Hugging Face Hub 또는 로컬 디렉토리의 비디오 모델에서 비디오 프로세서 구성(이미지 크기, 정규화 및 리스케일 여부 등)을 로드해요. 각 사전 훈련된 모델의 구성은 [video_preprocessor_config.json] 파일에 저장해야 하지만, 이전 모델은 구성을 preprocessor_config.json 파일에 저장했을 수 있어요. 후자는 덜 선호되며 앞으로 제거될 것이라는 점에 유의하세요.
사용 예시 (Usage Example)
llava-hf/llava-onevision-qwen2-0.5b-ov-hf 모델로 비디오 프로세서를 로드하는 예시는 다음과 같아요:
from transformers import AutoVideoProcessor
processor = AutoVideoProcessor.from_pretrained("llava-hf/llava-onevision-qwen2-0.5b-ov-hf")
현재 비디오에 기본 이미지 프로세서를 사용하면 각 프레임을 개별 이미지로 취급하고 프레임별로 변환을 적용해 비디오 데이터를 처리해요. 작동은 하지만 이 방식은 효율적이지 않아요. AutoVideoProcessor를 사용하면 torchvision 라이브러리를 활용하는 **빠른 비디오 프로세서(fast video processors)**의 이점을 얻을 수 있어요. 빠른 프로세서는 각 비디오나 프레임을 반복하지 않고 비디오 배치 전체를 한 번에 처리해요. 이러한 업데이트는 GPU 가속을 도입하고, 높은 처리량이 필요한 작업에서 특히 처리 속도를 크게 향상시켜요.
빠른 비디오 프로세서는 모든 모델에서 사용할 수 있고, AutoVideoProcessor를 초기화할 때 기본으로 로드돼요. 빠른 비디오 프로세서를 사용할 때는 device 인자를 설정해서 처리를 수행할 장치를 지정할 수도 있어요. 기본적으로 입력이 텐서이면 입력과 같은 장치에서, 그렇지 않으면 CPU에서 처리가 수행돼요. 더 큰 속도 향상을 위해 가속기를 장치로 사용할 때 프로세서를 컴파일할 수도 있어요.
import torch
from transformers.video_utils import load_video
from transformers import AutoVideoProcessor
device = torch.accelerator.current_accelerator().type if torch.accelerator.is_available() else "cpu"
video = load_video("video.mp4")
processor = AutoVideoProcessor.from_pretrained("llava-hf/llava-onevision-qwen2-0.5b-ov-hf", device=device)
processor = torch.compile(processor)
processed_video = processor(video, return_tensors="pt")
프레임 샘플링 (Frame sampling)
비디오 프로세서는 비디오를 디코딩하고 모델이 실제로 보는 프레임을 선택해요. do_sample_frames=True로 설정해서 샘플링을 켠 다음, 두 가지 방법 중 하나로 프레임을 선택해요.
num_frames는 비디오 전체에 균일하게 분포된 고정 개수를 요청해요.fps는 초당 프레임 수의 비율을 요청해요.
경로나 URL을 전달하면 프로세서가 기본 디코더인 torchcodec로 비디오를 디코딩해 줘요. torchcodec를 사용할 수 없고 이전 torchvision 버전을 사용 중이라면 디코딩은 torchvision으로 폴백해요.
return_metadata=True를 추가하면 샘플링된 프레임 인덱스, 원본 차원, 지속 시간, fps를 돌려받아요.
from transformers import AutoVideoProcessor
processor = AutoVideoProcessor.from_pretrained("Qwen/Qwen3-VL-4B-Instruct")
inputs = processor(videos=["video.mp4"], do_sample_frames=True, fps=1, return_metadata=True, return_tensors="pt")
print(inputs.pixel_values_videos.shape, inputs.video_grid_thw)
print(inputs["video_metadata"][0].total_num_frames)
샘플링 기본값은 모델마다 다르고, num_frames나 fps에 대한 요청은 보장이 아니라 시작점이에요. Qwen3-VL은 fps=2로 샘플링하고 결과를 min_frames=4와 max_frames=768 사이로 제한하므로, 1초 클립도 4개 프레임을 산출하고 긴 녹화물은 실제 프레임 수보다 훨씬 아래로 상한이 정해져요.
temporal_patch_size가 있는 모델은 시간 축을 따라 프레임들을 그 개수만큼의 패치로 묶고, 개수가 균등하게 나누어질 때까지 마지막 프레임을 반복하는 두 번째 제약이 추가돼요.
이미 디코딩된 비디오 배열을 전달하면서도 모델별 샘플링을 원한다면 video_metadata도 함께 제공해요. 그렇게 하지 않으면 샘플러가 원본 지속 시간이나 fps를 알지 못하며, fps로 샘플링할 때 경고하고 비디오가 24fps로 녹화됐다고 가정해요.
import torch
from transformers import AutoVideoProcessor
from transformers.video_utils import VideoMetadata
processor = AutoVideoProcessor.from_pretrained("Qwen/Qwen3-VL-4B-Instruct")
video = torch.randint(0, 255, size=(100, 3, 1280, 1280)) # short video of 100 frames
video_metadata = VideoMetadata(total_num_frames=100, fps=24, duration=4.1)
inputs = processor(
videos=[video], video_metadata=[video_metadata], do_sample_frames=True, num_frames=16, return_tensors="pt"
)