# Adicionar componentes de processamento de visão

Adicionar um modelo de visão requer componentes de processamento de imagem ou vídeo além da abordagem [modular](./modular_transformers) padrão. Modelos apenas de imagem precisam de processadores de imagem e modelos de vídeo precisam de um processador de vídeo, ambos acessíveis por meio dos pontos de entrada [AutoImageProcessor](/docs/transformers/main/pt/model_doc/auto#transformers.AutoImageProcessor) e [AutoVideoProcessor](/docs/transformers/main/pt/model_doc/auto#transformers.AutoVideoProcessor).

> [!NOTE]
> Para as etapas de modelagem e configuração, siga primeiro o guia [modular](./modular_transformers).

## Processadores de imagem

Crie processadores de imagem quando o modelo consome imagens. O backend [torchvision](https://docs.pytorch.org/vision/stable/index.html) é o padrão e suporta aceleração por GPU. [PIL](https://pillow.readthedocs.io/en/stable/index.html) é a alternativa quando o torchvision não está disponível.

As duas classes de processador de imagem compartilham a mesma lógica de pré-processamento, mas possuem backends diferentes. As assinaturas dos construtores e os valores padrão devem ser idênticos. [AutoImageProcessor.from_pretrained()](/docs/transformers/main/pt/model_doc/auto#transformers.AutoImageProcessor.from_pretrained) seleciona o backend no momento do carregamento e recorre ao PIL quando o torchvision não está disponível. Assinaturas incompatíveis fazem com que a mesma configuração salva se comporte de maneira diferente em ambientes distintos.

### torchvision

Crie `image_processing_<model_name>.py` com uma classe que herda de [TorchvisionBackend](/docs/transformers/main/pt/main_classes/image_processor#transformers.TorchvisionBackend). Se o seu processador precisar de parâmetros personalizados além dos [ImagesKwargs] padrão, defina uma classe de kwargs.

```py
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]
> Consulte [LlavaOnevisionImageProcessor](/docs/transformers/main/pt/model_doc/llava_onevision#transformers.LlavaOnevisionImageProcessor) para referência.

### PIL

Crie `image_processing_pil_<model_name>.py` com uma classe que herda de [PilBackend](/docs/transformers/main/pt/main_classes/image_processor#transformers.PilBackend). Duplicar a classe de kwargs aqui, em vez de importá-la do arquivo do torchvision, pois ela pode falhar quando o torchvision não está instalado. Adicione um comentário `# Adapted from` para que os dois permaneçam sincronizados. Para processadores sem parâmetros personalizados, use [ImagesKwargs](/docs/transformers/main/pt/main_classes/processors#transformers.ImagesKwargs) diretamente.

```py
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]
> Consulte [LlavaOnevisionImageProcessorPil](/docs/transformers/main/pt/model_doc/llava_onevision#transformers.LlavaOnevisionImageProcessorPil) para referência.

### Adicionar métodos de pós-processamento

Adicione métodos de pós-processamento diretamente à classe do processador. Os métodos de pós-processamento são chamados com as saídas do modelo (`outputs`) e quaisquer argumentos adicionais necessários para o método de pós-processamento específico.

```py
class MyModelImageProcessor(TorchvisionBackend):
    ...

    def post_process_my_task(self, outputs, ...):
        ...
```

Os pós-processadores retornam uma lista de objetos simples (`list[str]` ou `list[torch.Tensor]`) ou uma lista de objetos complexos (`list[MyTaskPostProcessorOutput]` ou `list[dict]`). As saídas dos pós-processadores são definidas em `src/transformers/image_processing_outputs.py` e herdam de [BatchFeature](/docs/transformers/main/pt/main_classes/feature_extractor#transformers.BatchFeature).

```py
class MyTaskPostProcessorOutput(BatchFeature):
    predictions: torch.Tensor
    scores: torch.Tensor
```

## Processador de vídeo

Adicione um processador de vídeo quando o modelo consumir vídeos ou quadros de vídeo amostrados.

Crie `video_processing_<model_name>.py` no diretório do modelo. [BaseVideoProcessor](/docs/transformers/main/pt/main_classes/video_processor#transformers.BaseVideoProcessor) herda de [TorchvisionBackend](/docs/transformers/main/pt/main_classes/image_processor#transformers.TorchvisionBackend) e fornece comportamento compartilhado para decodificação, amostragem de quadros, redimensionamento, reescalonamento, normalização, salvamento e carregamento.

Os atributos da classe são os valores padrão de pré-processamento. Os usuários podem sobrescrevê-los na inicialização ou na chamada. Use os mesmos nomes de [VideosKwargs](/docs/transformers/main/pt/main_classes/processors#transformers.VideosKwargs) sempre que possível, como `size`, `crop_size`, `do_resize`, `do_sample_frames`, `num_frames` e `fps`.

Defina uma classe de kwargs se o seu processador de vídeo precisar de parâmetros personalizados além dos padrões do [VideosKwargs](/docs/transformers/main/pt/main_classes/processors#transformers.VideosKwargs). Defina-a como `valid_kwargs` e use-a para anotar `__init__` para validação em tempo de execução e para a docstring gerada automaticamente.

```py
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)
```

Sobrescreva [sample_frames()](/docs/transformers/main/pt/main_classes/video_processor#transformers.BaseVideoProcessor.sample_frames) apenas quando o modelo exigir uma regra de amostragem que o amostrador uniforme base não consegue expressar. Por exemplo, alguns modelos impõem um número mínimo ou máximo de frames, ou amostram com base em restrições específicas do modelo.

Se o método forward do modelo espera um nome de entrada legado, sobrescreva `preprocess` e renomeie a chave após chamar a implementação base.

```py
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
```

Salve o processador de vídeo junto com o checkpoint instanciando-o no script de conversão e chamando [save_pretrained()](/docs/transformers/main/pt/main_classes/video_processor#transformers.VideoProcessorMixin.save_pretrained). Se um [ProcessorMixin](/docs/transformers/main/pt/main_classes/processors#transformers.ProcessorMixin) encapsular o processador de vídeo, chame [save_pretrained()](/docs/transformers/main/pt/model_doc/wav2vec2#transformers.Wav2Vec2Processor.save_pretrained) em vez disso. Não crie nem edite manualmente os arquivos de configuração de pré-processamento.

> [!TIP]
> Consulte [Qwen3VLVideoProcessor](/docs/transformers/main/pt/model_doc/qwen3_vl#transformers.Qwen3VLVideoProcessor) para referência.

## Registre as classes

Adicione as novas classes a `__all__` no final do arquivo e, em seguida, regenere o `__init__.py` com:

```bash
python utils/check_inits.py --fix_and_overwrite
```

Mapeie as novas classes para a configuração do modelo para que as classes `Auto` possam carregá-las. O arquivo de mapeamento automático gerado possui um aviso no topo. Não o edite manualmente. Adicione ou atualize a configuração do modelo e, em seguida, execute:

```bash
python utils/check_auto.py --fix_and_overwrite
```

Após o mapeamento ser gerado, verifique se o tipo de modelo aparece nos mapeamentos relevantes em `src/transformers/models/auto/auto_mappings.py`.

- `IMAGE_PROCESSOR_MAPPING_NAMES` para [AutoImageProcessor](/docs/transformers/main/pt/model_doc/auto#transformers.AutoImageProcessor)
- `VIDEO_PROCESSOR_MAPPING_NAMES` para [AutoVideoProcessor](/docs/transformers/main/pt/model_doc/auto#transformers.AutoVideoProcessor)

## Testes

Adicione testes para cada componente de processamento de visão no diretório de testes do modelo. Use os mixins de teste compartilhados e forneça os kwargs de inicialização específicos do modelo. Os testes de imagem descobrem automaticamente os backends do processador por meio de um tester compartilhado, enquanto os testes de vídeo configuram explicitamente a classe do processador e os fixtures.

### Testes do processador de imagens

Os testes de processador de imagem estão em `tests/models/<model_name>/test_image_processing_<model_name>.py`. Defina um tester que herda de `ImageProcessingTester` e uma classe de teste que herda de `ImageProcessingTestMixin` e `unittest.TestCase`.

O testador de processamento de imagens define atributos de teste padrão, como os argumentos de inicialização do processador e os parâmetros para criar entradas aleatórias para os testes. Sobrescreva os argumentos apenas se eles devem ser diferentes dos padrões do processador de imagens. Por exemplo, geralmente testamos com tamanhos de imagem menores para manter os testes rápidos. As classes de processador de imagens são inferidas automaticamente a partir de `IMAGE_PROCESSOR_MAPPING_NAMES`.

Defina `image_processor_tester_class` na classe de teste. O mixin cria `self.image_processor_tester` e já cobre a maioria dos métodos de teste necessários.

```py
import unittest

from transformers.testing_utils import require_torch, require_vision
from ...test_image_processing_common import ImageProcessingTestMixin, ImageProcessingTester

class MyModelImageProcessingTester(ImageProcessingTester):
    def __init__(self, **kwargs):
        # Random test inputs kwargs
        kwargs.setdefault("batch_size", 2)          # default: 7     
        kwargs.setdefault("num_channels", 4)        # default: 3
        kwargs.setdefault("min_resolution", 20)     # default: 30
        kwargs.setdefault("max_resolution", 100)    # default: 400

        # Image processor init kwargs
        kwargs.setdefault("size", {"shortest_edge": 20})
        kwargs.setdefault("crop_size", {"height": 18, "width": 18})

        super().__init__(**kwargs)

@require_torch
@require_vision
class MyModelImageProcessingTest(ImageProcessingTestMixin, unittest.TestCase):
    image_processor_tester_class = MyModelImageProcessingTester

    def test_inherits_from_mixin(self):
        # Always iterate over all image processing classes
        for image_processing_class in self.image_processing_classes.values():
            # self.image_processor_dict contains the default processor init kwargs
            # including overrides from the tester.
            image_processor = image_processing_class(**self.image_processor_dict)
            self.assertIsInstance(image_processor, ImageProcessingMixin)
```

Adicione testes focados para comportamentos que o mixin não consegue inferir, como regras de redimensionamento personalizadas ou kwargs específicos do modelo.

Os mixins de teste de pós-processamento estão disponíveis em `tests/test_image_processing_common.py` e são adicionados por cima de `ImageProcessingTestMixin`.

```py
class MyModelImageProcessingTest(ImageProcessingTestMixin, MyTaskPostProcessTestMixin, unittest.TestCase):
    image_processor_tester_class = MyModelImageProcessingTester
```

Os testes verificam automaticamente que os mixins corretos são usados para o seu modelo. Os mixins para novas tarefas devem ser adicionados a `tests/test_image_processing_common.py`.

### Testes do processador de vídeo

Os testes de processador de vídeo geralmente ficam em `tests/models/<model_name>/test_video_processing_<model_name>.py` e herdam de `VideoProcessingTestMixin`. Defina `fast_video_processing_class`, defina `video_processor_dict` e sobrescreva `input_name` se o modelo usar uma chave diferente de `pixel_values_videos`.

```py
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}
```

Adicione testes de vídeo focados em amostragem de quadros, tratamento de metadados, entradas de vídeo decodificadas, entradas em lista de quadros e formas de saída. Se o seu processador renomear `pixel_values_videos`, afirme que a chave renomeada é retornada.

Se o modelo também possui um [ProcessorMixin](/docs/transformers/main/pt/main_classes/processors#transformers.ProcessorMixin) que encapsula o processador de imagem ou vídeo, adicione `tests/models/<model_name>/test_processing_<model_name>.py` e herde de `ProcessorTesterMixin`. Defina `processor_class` e sobrescreva os métodos de classe `_setup_<component>()` para componentes que não podem ser construídos sem argumentos. Use `_setup_test_attributes()` para expor os tokens de substituição usados pelos testes comuns de processador.

```py
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", "")
```

## Próximas etapas

- Leia o guia [Geração automática de docstrings](./auto_docstring) para gerar automaticamente docstrings consistentes com `@auto_docstring`.
- Leia os guias de [Processadores de imagem](./image_processors) e [Processadores de vídeo](./video_processors) para o comportamento de pré-processamento voltado ao usuário.

