멀티모달 프로세서
멀티모달 프로세서
프로세서(processor)는 토크나이저와 하나 이상의 모달리티 프로세서(이미지 프로세서, 비디오 프로세서, 또는 피처 추출기)를 결합합니다. 단일 __call__ 메서드를 노출하여 각 입력을 올바른 구성 요소로 라우팅하고 출력을 하나의 딕셔너리로 병합합니다.
출처: 문서
본문
프로세서는 토크나이저와 하나 이상의 모달리티 프로세서(이미지 프로세서, 비디오 프로세서, 또는 피처 추출기)를 결합합니다. 단일 __call__ 메서드를 노출하여 각 입력을 올바른 구성 요소로 라우팅하고 출력을 하나의 딕셔너리로 병합합니다.
일부 멀티모달 모델은 텍스트와 이미지, 비디오, 오디오를 혼합합니다. 이러한 모델의 경우 ProcessorMixin이 <image>, <video>, <audio> 같은 플레이스홀더 토큰을 모델이 기대하는 토큰 패턴으로 대체할 수 있습니다.
새 프로세서 추가
src/transformers/models/<model>/processing_<my_model_name>.py를 만들고 ProcessorMixin을 서브클래스로 하여 프로세서 클래스를 정의합니다. 기본값을 가진 TypedDict 객체를 정의하고 이를 cls.valid_processor_kwargs로 할당해야 합니다.
from ...processing_utils import ProcessorMixin, ProcessingKwargs, Unpack
class MyModelProcessorKwargs(ProcessingKwargs, total=False):
images_kwargs: MyModelImageProcessorKwargs
_defaults = {
"text_kwargs": {"padding": True},
"images_kwargs": {"do_convert_rgb": True},
}
class MyModelProcessor(ProcessorMixin):
valid_processor_kwargs = MyModelProcessorKwargs
def __init__(self, image_processor, tokenizer, chat_template=None, **kwargs):
self.image_token = tokenizer.image_token
self.image_token_id = tokenizer.image_token_id
super().__init__(
image_processor=image_processor,
tokenizer=tokenizer,
chat_template=chat_template,
**kwargs,
)
필요하면 replace_<modality>_token을 구현합니다. 이 메서드는 서브프로세서의 전체 출력 딕셔너리와 현재 입력의 인덱스를 받아, 해당 입력에 대한 확장된 대체 문자열을 반환합니다. 대체 문자열은 모델이 입력 시퀀스에서 기대하는 것이 무엇이든 그대로입니다.
모델이 플레이스홀더 반복을 전혀 사용하지 않는다면(image_token이 정의되지 않음) 이 메서드를 재정의할 필요가 없습니다. self.image_token을 설정하지 않으면 베이스 클래스가 대체를 완전히 건너뜁니다.
def replace_image_token(self, image_inputs: dict, image_idx: int) -> str:
num_crops = image_inputs["num_crops"][image_idx]
return f"{self.boi_token}{self.image_token * self.num_image_tokens * num_crops}{self.eoi_token}"
선택적으로 prepare_inputs_layout와 validate_inputs 메서드를 재정의할 수 있습니다. 모델이 처리 시작 전에 특정 입력 구조(예: 이미지를 중첩 리스트로 재정렬)를 요구하거나, 공통 검사 외에 모델별 검증이 필요한 경우입니다.
def prepare_inputs_layout(self, images=None, text=None, videos=None, audio=None, **kwargs):
# 공통 준비 단계를 먼저 적용하려면 `super()` 호출
images, text, videos, audio = super().prepare_inputs_layout(images, text, videos, audio)
if images is not None:
images = make_nested_list_of_images(images)
return images, text, videos, audio
def validate_inputs(self, images=None, text=None, videos=None, audio=None, **kwargs):
super().validate_inputs(images=images, text=text, **kwargs)
if text is not None and images is not None:
n_tokens = [s.count(self.image_token) for s in text]
n_images = [len(img_list) for img_list in images]
if n_tokens != n_images:
raise ValueError(
f"Number of {self.image_token} tokens in text {n_tokens} does not match "
f"number of images {n_images}."
)
[!TIP] 참고 자료는 Gemma4Processor와 Qwen2VLProcessor를 참조하세요.
테스트
모든 멀티모달 프로세서는 ProcessorTesterMixin을 상속하는 테스트 클래스를 가져야 합니다. 이 믹스인은 토크나이제이션, 이미지 처리, 배치, 왕복 인코딩을 다루는 표준 테스트 모음을 제공합니다.
# tests/models/my_model_name/test_processor_<my_model_name>.py
from transformers.testing_utils import require_vision
from transformers.utils import is_vision_available
from ...test_processing_common import ProcessorTesterMixin
if is_vision_available():
from transformers import MyModelProcessor
@require_vision
class MyModelProcessorTest(ProcessorTesterMixin, unittest.TestCase):
processor_class = MyModelProcessor
def get_processor(self):
return MyModelProcessor.from_pretrained("hf-internal-testing/my-model-test")