비전 처리 컴포넌트 추가하기
비전 처리 컴포넌트 추가하기 (Add vision processing components)
비전 모델을 추가하려면 표준 modular 방식 위에 이미지나 비디오 처리 컴포넌트를 얹어야 해요. 이미지만 쓰는 모델은 image processor를, 비디오 모델은 video processor를 필요로 하는데, 둘 다 각각 AutoImageProcessor와 AutoVideoProcessor 진입점 뒤에서 접근할 수 있어요. 이 페이지에서는 이 컴포넌트들을 만들고 등록하고 테스트하는 방법을 살펴볼게요.
출처: 문서
본문
[!NOTE] 모델링과 설정 단계는 먼저 modular 가이드를 따라 진행해 주세요.
Image processors (이미지 프로세서)
모델이 이미지를 사용할 때는 image processor를 만들어요. 기본 백엔드는 torchvision이고 GPU 가속을 지원해요. torchvision이 없으면 PIL이 대체(fallback)로 쓰여요.
두 image processor 클래스는 전처리 로직을 공유하지만 백엔드가 달라요. 따라서 생성자 시그니처와 기본값은 반드시 동일해야 해요. AutoImageProcessor.from_pretrained()는 로드할 때 백엔드를 선택하고, torchvision이 없으면 PIL로 폴백해요. 시그니처가 어긋나면 같은 저장된 config가 환경마다 다르게 동작할 수 있어요.
torchvision
TorchvisionBackend를 상속받는 클래스로 image_processing_<model_name>.py를 만들어요. 표준 [ImagesKwargs] 외에 커스텀 파라미터가 필요하다면 kwargs 클래스를 정의해요.
from ...image_processing_backends import TorchvisionBackend
from ...image_utils import OPENAI_CLIP_MEAN, OPENAI_CLIP_STD, PILImageResampling
from ...processing_utils import ImagesKwargs, Unpack
from ...utils import auto_docstring
class MyModelImageProcessorKwargs(ImagesKwargs, total=False):
tile_size: int # any model-specific kwargs
@auto_docstring
class MyModelImageProcessor(TorchvisionBackend):
resample = PILImageResampling.BICUBIC
image_mean = OPENAI_CLIP_MEAN
image_std = OPENAI_CLIP_STD
size = {"shortest_edge": 224}
do_resize = True
do_rescale = True
do_normalize = True
do_convert_rgb = True
def __init__(self, **kwargs: Unpack[MyModelImageProcessorKwargs]):
super().__init__(**kwargs)
[!TIP] 참고로 LlavaOnevisionImageProcessor를 확인해 보세요.
PIL
PilBackend를 상속받는 클래스로 image_processing_pil_<model_name>.py를 만들어요. kwargs 클래스는 torchvision 파일에서 import 하지 말고 여기서 복제해요. torchvision이 설치되지 않은 환경에서 import가 실패할 수 있기 때문이에요. 두 파일이 동기화되도록 # Adapted from 주석을 추가해요. 커스텀 파라미터가 없는 processor는 ImagesKwargs를 직접 사용해요.
from ...image_processing_backends import PilBackend
from ...image_utils import OPENAI_CLIP_MEAN, OPENAI_CLIP_STD, PILImageResampling
from ...processing_utils import ImagesKwargs, Unpack
from ...utils import auto_docstring
# Adapted from transformers.models.my_model.image_processing_my_model.MyModelImageProcessorKwargs
class MyModelImageProcessorKwargs(ImagesKwargs, total=False):
tile_size: int # any model-specific kwargs
@auto_docstring
class MyModelImageProcessorPil(PilBackend):
resample = PILImageResampling.BICUBIC
image_mean = OPENAI_CLIP_MEAN
image_std = OPENAI_CLIP_STD
size = {"shortest_edge": 224}
do_resize = True
do_rescale = True
do_normalize = True
do_convert_rgb = True
def __init__(self, **kwargs: Unpack[MyModelImageProcessorKwargs]):
super().__init__(**kwargs)
[!TIP] 참고로 LlavaOnevisionImageProcessorPil을 확인해 보세요.
후처리(post-processing) 메서드 추가하기
후처리 메서드는 processor 클래스에 직접 추가해요. 후처리 메서드는 모델 출력(outputs)과 특정 후처리 메서드에 필요한 추가 인자들을 받아 호출돼요.
class MyModelImageProcessor(TorchvisionBackend):
...
def post_process_my_task(self, outputs, ...):
...
후처리기는 단순 객체 목록(list[str] 또는 list[torch.Tensor])이나 복잡한 객체 목록(list[MyTaskPostProcessorOutput] 또는 list[dict])을 반환해요. 후처리기 출력은 src/transformers/image_processing_outputs.py에 정의되며 BatchFeature를 상속받아요.
class MyTaskPostProcessorOutput(BatchFeature):
predictions: torch.Tensor
scores: torch.Tensor
Video processor (비디오 프로세서)
모델이 비디오나 샘플링된 비디오 프레임을 사용할 때는 video processor를 추가해요.
모델 디렉터리에 video_processing_<model_name>.py를 만들어요. BaseVideoProcessor는 TorchvisionBackend를 상속받아 디코딩, 프레임 샘플링, 리사이즈(resizing), 리스케일(rescaling), 정규화, 저장, 로딩 동작을 공유해요.
클래스 속성은 기본 전처리 값이에요. 사용자는 초기화 시점이나 호출 시점에 이 값을 오버라이드할 수 있어요. 가능하면 VideosKwargs와 같은 이름을 사용해요. 예를 들어 size, crop_size, do_resize, do_sample_frames, num_frames, fps 같은 이름 말이지요.
표준 VideosKwargs 외에 커스텀 파라미터가 필요하면 kwargs 클래스를 정의해요. valid_kwargs로 설정하고, __init__ 주석에 사용해서 런타임 검증과 자동 생성 docstring 양쪽에 반영해요.
from ...processing_utils import Unpack, VideosKwargs
from ...utils import auto_docstring
from ...video_processing_utils import BaseVideoProcessor
class MyModelVideoProcessorKwargs(VideosKwargs, total=False):
min_frames: int
max_frames: int
@auto_docstring
class MyModelVideoProcessor(BaseVideoProcessor):
size = {"shortest_edge": 224}
crop_size = {"height": 224, "width": 224}
do_resize = True
do_center_crop = True
do_normalize = True
do_sample_frames = True
num_frames = 16
model_input_names = ["pixel_values_videos"]
valid_kwargs = MyModelVideoProcessorKwargs
def __init__(self, **kwargs: Unpack[MyModelVideoProcessorKwargs]):
super().__init__(**kwargs)
기본 균등 표본 추출기(uniform sampler)로 표현할 수 없는 샘플링 규칙이 모델에 필요한 경우에만 sample_frames()를 오버라이드해요. 예를 들어 어떤 모델은 최소/최대 프레임 수를 강제하거나 모델 고유 제약에 따라 샘플링하기도 해요.
모델의 forward 메서드가 레거시(legacy) 입력 이름을 기대한다면 preprocess를 오버라이드하고 기본 구현을 호출한 뒤 키 이름을 바꿔요.
class MyModelVideoProcessor(BaseVideoProcessor):
model_input_names = ["pixel_values"]
def preprocess(self, videos, **kwargs):
batch = super().preprocess(videos, **kwargs)
batch["pixel_values"] = batch.pop("pixel_values_videos")
return batch
video processor를 변환 스크립트에서 인스턴스화하고 save_pretrained()를 호출해서 checkpoint와 함께 저장해요. ProcessorMixin이 video processor를 감싸고 있다면 대신 save_pretrained()을 호출해요. 전처리 설정 파일을 직접 만들거나 편집하지 마세요.
[!TIP] 참고로 Qwen3VLVideoProcessor를 확인해 보세요.
클래스 등록하기 (Register the classes)
모델 패키지 __init__.py에서 처리 클래스를 노출해요. 주변 모델들이 사용하는 lazy import 패턴을 따르고, 각 백엔드가 요구하는 선택적 의존성과 동일한 의존성으로 import를 가드해 주세요.
새 클래스를 모델 config에 매핑해서 Auto 클래스들이 로드할 수 있게 해요. 생성된 auto 매핑 파일 맨 위에는 경고가 있어요. 손으로 편집하지 말고, 모델 config를 추가·수정한 뒤 다음을 실행해요:
python utils/check_auto.py --fix_and_overwrite
매핑이 생성된 후에는 src/transformers/models/auto/auto_mappings.py의 관련 매핑에 모델 타입이 나타나는지 확인해 주세요.
- AutoImageProcessor용
IMAGE_PROCESSOR_MAPPING_NAMES - AutoVideoProcessor용
VIDEO_PROCESSOR_MAPPING_NAMES
테스트 (Testing)
모델 테스트 디렉터리에 각 비전 처리 컴포넌트에 대한 테스트를 추가해요. 이미지와 비디오 processor 테스트는 같은 패턴을 따라요. 공유 mixin을 상속받고, 자동 탐지가 부족할 때 fast·slow 처리 클래스를 명시하며, 모델별 init kwargs를 제공하고, 모델이 기본이 아닌 출력 키를 쓸 때 입력 이름을 오버라이드해요.
Image processor 테스트
Image processor 테스트는 보통 tests/models/<model_name>/test_image_processing_<model_name>.py에 있고 ImageProcessingTestMixin을 상속받아요.
이미지 처리 mixin은 IMAGE_PROCESSOR_MAPPING_NAMES에서 image processor 클래스를 찾아요. 모델별 기본값은 image_processor_dict로 노출해요. 재사용 가능한 더미 입력이나 집중 테스트용 헬퍼 메서드가 필요할 때만 tester 객체를 추가해요.
from transformers.testing_utils import require_torch, require_vision
from ...test_image_processing_common import ImageProcessingTestMixin
@require_torch
@require_vision
class MyModelImageProcessingTest(ImageProcessingTestMixin, unittest.TestCase):
@property
def image_processor_dict(self):
return {"size": {"shortest_edge": 224}, "do_resize": True}
mixin이 추론할 수 없는 동작(예: 커스텀 리사이즈 규칙이나 모델별 kwargs)에 대한 집중 테스트를 추가해요.
후처리 테스트 mixin은 tests/test_image_processing_common.py에 있고 ImageProcessingTestMixin 위에 추가해요.
class MyModelImageProcessingTest(ImageProcessingTestMixin, MyTaskPostProcessTestMixin, unittest.TestCase):
테스트는 여러분 모델에 올바른 mixin이 사용되는지 자동으로 확인해요. 새 태스크용 mixin은 tests/test_image_processing_common.py에 추가해야 해요.
Video processor 테스트
Video processor 테스트는 보통 tests/models/<model_name>/test_video_processing_<model_name>.py에 있고 VideoProcessingTestMixin을 상속받아요. fast_video_processing_class를 설정하고, video_processor_dict를 정의하며, 모델이 pixel_values_videos가 아닌 키를 쓴다면 input_name을 오버라이드해요.
from transformers.testing_utils import require_torch, require_vision
from transformers.utils import is_torchvision_available
from ...test_video_processing_common import VideoProcessingTestMixin
@require_torch
@require_vision
class MyModelVideoProcessingTest(VideoProcessingTestMixin, unittest.TestCase):
fast_video_processing_class = MyModelVideoProcessor if is_torchvision_available() else None
input_name = "pixel_values_videos"
@property
def video_processor_dict(self):
return {"size": {"shortest_edge": 224}, "num_frames": 16}
프레임 샘플링, 메타데이터 처리, 디코딩된 비디오 입력, 프레임 목록(list-of-frame) 입력, 출력 shape에 대한 집중 비디오 테스트를 추가해요. processor가 pixel_values_videos 이름을 바꾼다면 이름이 바뀐 키가 반환되는지 단언(assert)해요.
모델에 이미지나 비디오 processor를 감싸는 ProcessorMixin도 있다면 tests/models/<model_name>/test_processing_<model_name>.py를 추가하고 ProcessorTesterMixin을 상속받아요. processor_class를 설정하고, 인자 없이는 생성할 수 없는 컴포넌트는 _setup_<component>() 클래스 메서드를 오버라이드해요. _setup_test_attributes()를 사용해서 공통 processor 테스트가 쓰는 placeholder 토큰을 노출해요.
from ...test_processing_common import ProcessorTesterMixin
class MyModelProcessorTest(ProcessorTesterMixin, unittest.TestCase):
processor_class = MyModelProcessor
@classmethod
def _setup_image_processor(cls):
return cls._get_component_class_from_processor("image_processor")(size={"shortest_edge": 224})
@classmethod
def _setup_video_processor(cls):
return cls._get_component_class_from_processor("video_processor")(num_frames=2)
@classmethod
def _setup_test_attributes(cls, processor):
cls.image_token = getattr(processor, "image_token", "")
cls.video_token = getattr(processor, "video_token", "")
다음 단계 (Next steps)
- 일관된 docstring을
@auto_docstring으로 자동 생성하는 방법은 Auto-generating docstrings 가이드를 읽어주세요. - 사용자 대상 전처리 동작은 Image processors와 Video processors 가이드를 읽어주세요.