Transformers documentation
비전 인코더 디코더 모델
이 모델은 2021-09-21에 HF papers에 게시되었으며, 2021-10-13에 Hugging Face Transformers에 기여되었습니다.
비전 인코더 디코더 모델
개요
VisionEncoderDecoderModel은 사전 학습된 Transformer 기반 비전 모델을 인코더(예: ViT, BEiT, DeiT, Swin)로, 사전 학습된 언어 모델을 디코더(예: RoBERTa, GPT2, BERT, DistilBERT)로 사용하여 이미지-텍스트 모델을 초기화하는 데 사용할 수 있습니다.
예를 들어, Minghao Li, Tengchao Lv, Lei Cui, Yijuan Lu, Dinei Florencio, Cha Zhang, Zhoujun Li, Furu Wei의 TrOCR: Transformer-based Optical Character Recognition with Pre-trained Models에서 사전 학습된 체크포인트로 이미지-텍스트 시퀀스 모델을 초기화하는 것이 효과적임이 입증되었습니다.
이러한 VisionEncoderDecoderModel이 학습/파인튜닝된 후에는 다른 모델과 동일한 방식으로 저장/로드할 수 있습니다(자세한 내용은 아래 예시를 참조하세요).
예를 들어 이미지 캡셔닝이 있습니다. 이 작업에서는 인코더를 사용하여 이미지를 인코딩한 다음, 자기회귀 언어 모델이 캡션을 생성합니다. 또 다른 예로는 광학 문자 인식(OCR)이 있습니다. VisionEncoderDecoderModel의 한 인스턴스인 TrOCR를 참고하세요.
model configurations에서 VisionEncoderDecoderModel을 무작위로 초기화
VisionEncoderDecoderModel은 인코더와 디코더의 config를 기반으로 무작위로 초기화할 수 있습니다. 다음 예시에서는 인코더에 ViTModel의 기본 구성, 디코더에 BertForCausalLM의 기본 구성을 사용하여 이를 수행하는 방법을 보여 줍니다.
from transformers import BertConfig, VisionEncoderDecoderConfig, VisionEncoderDecoderModel, ViTConfig
config_encoder = ViTConfig()
config_decoder = BertConfig()
config = VisionEncoderDecoderConfig.from_encoder_decoder_configs(config_encoder, config_decoder)
model = VisionEncoderDecoderModel(config=config)pretrained encoder와 pretrained decoder에서 VisionEncoderDecoderModel을 초기화
VisionEncoderDecoderModel은 사전 학습된 인코더 체크포인트와 사전 학습된 디코더 체크포인트로부터 초기화할 수 있습니다. 사전 학습된 Transformer 기반 비전 모델, 예를 들어 Swin는 인코더로 사용할 수 있으며, 사전 학습된 오토인코딩 모델, 예를 들어 BERT, 사전 학습된 인과 언어 모델, 예를 들어 GPT2, 그리고 시퀀스-투-시퀀스 모델의 사전 학습된 디코더 부분, 예를 들어 BART의 디코더는 모두 디코더로 사용할 수 있습니다.
디코더로 선택하는 아키텍처에 따라 크로스 어텐션 레이어가 무작위로 초기화될 수 있습니다.
사전 학습된 인코더와 디코더 체크포인트로부터 VisionEncoderDecoderModel을 초기화하려면 Warm-starting-encoder-decoder 블로그 게시물에서 보여준 바와 같이 다운스트림 작업으로 모델이 파인튜닝되어야 합니다.
이를 위해 VisionEncoderDecoderModel 클래스는 VisionEncoderDecoderModel.from_encoder_decoder_pretrained() 메서드를 제공합니다.
from transformers import VisionEncoderDecoderModel
model = VisionEncoderDecoderModel.from_encoder_decoder_pretrained(
"microsoft/swin-base-patch4-window7-224-in22k", "google-bert/bert-base-uncased"
)…
VisionEncoderDecoderModel 클래스의 fine-tuned 체크포인트를 로드하려면, VisionEncoderDecoderModel은 Transformers의 다른 모델 아키텍처와 마찬가지로 from_pretrained(...) 메서드를 제공합니다.
추론을 수행하려면 generate 메서드를 사용합니다. 이 메서드는 텍스트를 자기회귀적으로 생성할 수 있으며, greedy, beam search, multinomial sampling 등 다양한 디코딩 방식을 지원합니다.
import requests
from PIL import Image
from transformers import GPT2TokenizerFast, ViTImageProcessor, VisionEncoderDecoderModel
# load a fine-tuned image captioning model and corresponding tokenizer and image processor
model = VisionEncoderDecoderModel.from_pretrained("nlpconnect/vit-gpt2-image-captioning", device_map="auto")
tokenizer = GPT2TokenizerFast.from_pretrained("nlpconnect/vit-gpt2-image-captioning")
image_processor = ViTImageProcessor.from_pretrained("nlpconnect/vit-gpt2-image-captioning")
# let's perform inference on an image
url = "http://images.cocodataset.org/val2017/000000039769.jpg"
image = Image.open(requests.get(url, stream=True).raw)
pixel_values = image_processor(image, return_tensors="pt").to(model.device).pixel_values
# autoregressively generate caption (uses greedy decoding by default)
generated_ids = model.generate(pixel_values)
generated_text = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
print(generated_text)
a cat laying on a blanket next to a cat laying on a bed학습
모델이 생성되면, (이미지, 텍스트) 쌍으로 구성된 데이터셋에서 BART, T5 또는 기타 인코더-디코더 모델과 유사하게 파인튜닝할 수 있습니다.
확인할 수 있듯이, 손실을 계산하기 위해 모델에는 두 개의 입력만 필요합니다: pixel_values(이미지)와 labels(인코딩된 대상 시퀀스의 input_ids).
from datasets import load_dataset
from transformers import BertTokenizer, VisionEncoderDecoderModel, ViTImageProcessor
image_processor = ViTImageProcessor.from_pretrained("google/vit-base-patch16-224-in21k")
tokenizer = BertTokenizer.from_pretrained("google-bert/bert-base-uncased")
model = VisionEncoderDecoderModel.from_encoder_decoder_pretrained(
"google/vit-base-patch16-224-in21k", "google-bert/bert-base-uncased"
)
model.config.decoder_start_token_id = tokenizer.cls_token_id
model.config.pad_token_id = tokenizer.pad_token_id
dataset = load_dataset("huggingface/cats-image")
image = dataset["test"]["image"][0]
pixel_values = image_processor(image, return_tensors="pt").to(model.device).pixel_values
labels = tokenizer(
"an image of two cats chilling on a couch",
return_tensors="pt",
).input_ids
# the forward function automatically creates the correct decoder_input_ids
loss = model(pixel_values=pixel_values, labels=labels).loss이 모델은 nielsr에 의해 기여되었습니다.
VisionEncoderDecoderConfig
클래스 transformers.VisionEncoderDecoderConfig
< source >( transformers_version: str | None = Nonearchitectures: list[str] | None = Noneoutput_hidden_states: bool | None = Falsereturn_dict: bool | None = Truedtype: str | torch.dtype | None = Nonechunk_size_feed_forward: int = 0id2label: dict[int, str] | dict[str, str] | None = Nonelabel2id: dict[str, int] | dict[str, str] | None = Noneproblem_type: Literal['regression', 'single_label_classification', 'multi_label_classification'] | None = Noneis_encoder_decoder: bool = Trueencoder: transformers.configuration_utils.PreTrainedConfig | dict | None = Nonedecoder: transformers.configuration_utils.PreTrainedConfig | dict | None = None )
이것은 Vision Encoder DecoderModel의 설정을 저장하기 위한 설정 클래스입니다. 지정된 인수를 기반으로 Vision Encoder Decoder 모델을 인스턴스화하여 모델 아키텍처를 정의하는 데 사용됩니다. 기본값으로 설정을 인스턴스화하면 None과 유사한 설정이 생성됩니다.
Configuration 객체는 PreTrainedConfig를 상속하며 모델 출력을 제어하는 데 사용할 수 있습니다. 자세한 내용은 PreTrainedConfig의 문서를 참고하세요.
예:
>>> from transformers import BertConfig, ViTConfig, VisionEncoderDecoderConfig, VisionEncoderDecoderModel
>>> # Initializing a ViT & BERT style configuration
>>> config_encoder = ViTConfig()
>>> config_decoder = BertConfig()
>>> config = VisionEncoderDecoderConfig(encoder=config_encoder, decoder=config_decoder)
>>> # Initializing a ViTBert model (with random weights) from a ViT & google-bert/bert-base-uncased style configurations
>>> model = VisionEncoderDecoderModel(config=config)
>>> # Accessing the model configuration
>>> config_encoder = model.config.encoder
>>> config_decoder = model.config.decoder
>>> # set decoder config to causal lm
>>> config_decoder.is_decoder = True
>>> config_decoder.add_cross_attention = True
>>> # Saving the model, including its configuration
>>> model.save_pretrained("my-model")
>>> # loading model and config from pretrained folder
>>> encoder_decoder_config = VisionEncoderDecoderConfig.from_pretrained("my-model")
>>> model = VisionEncoderDecoderModel.from_pretrained("my-model", config=encoder_decoder_config)from_encoder_decoder_configs
< source >( encoder_config: PreTrainedConfigdecoder_config: PreTrainedConfig**kwargs ) → VisionEncoderDecoderConfig
설정 객체의 인스턴스
사전 학습된 인코더 모델 구성과 디코더 모델 구성에서 VisionEncoderDecoderConfig(또는 파생 클래스)를 초기화합니다.
VisionEncoderDecoderModel
클래스 transformers.VisionEncoderDecoderModel
< source >( config: transformers.configuration_utils.PreTrainedConfig | None = Noneencoder: transformers.modeling_utils.PreTrainedModel | None = Nonedecoder: transformers.modeling_utils.PreTrainedModel | None = None )
매개변수
- config (PreTrainedConfig, 선택) — 모델의 모든 매개변수를 포함하는 모델 구성 클래스입니다. 구성 파일로 초기화하면 모델에 연결된 가중치는 로드되지 않으며 구성만 로드됩니다. 모델 가중치를 로드하려면 from_pretrained() 메서드를 확인하세요.
- encoder (
PreTrainedModel, 선택 사항) — 사용할 인코더 모델입니다. - decoder (
PreTrainedModel, 선택 사항) — 사용할 decoder 모델입니다.
특정 헤드가 위에 없는 상태에서 원시 hidden-states를 출력하는 기본 Vision Encoder Decoder Model입니다.
이 모델은 PreTrainedModel에서 상속됩니다. 라이브러리가 모든 모델에 대해 구현하는 일반적 메서드(다운로드 또는 저장, 입력 임베딩 크기 조정, 헤드 프루닝 등)에 대한 세부 사항은 상위 클래스 문서를 확인하세요.
이 모델은 또한 PyTorch torch.nn.Module의 하위 클래스입니다. 일반적인 PyTorch Module처럼 사용하며, 일반적인 사용법 및 동작과 관련된 모든 사항은 PyTorch 문서를 참조하세요.
forward
< source >( pixel_values: typing.Optional[torch.Tensor] = Nonedecoder_input_ids: typing.Optional[torch.LongTensor] = Nonedecoder_attention_mask: typing.Optional[torch.BoolTensor] = Noneencoder_outputs: tuple[torch.Tensor] | None = Nonepast_key_values: transformers.cache_utils.Cache | None = Nonedecoder_inputs_embeds: typing.Optional[torch.Tensor] = Nonelabels: typing.Optional[torch.LongTensor] = Noneuse_cache: bool | None = Noneoutput_attentions: bool | None = Noneoutput_hidden_states: bool | None = Nonereturn_dict: bool | None = None**kwargs ) → Seq2SeqLMOutput or tuple(torch.Tensor)
매개변수
- pixel_values (
torch.Tensor, shape(batch_size, num_channels, image_size, image_size), 선택 사항) — 입력 이미지에 해당하는 텐서입니다. 픽셀 값은image_processor_class를 사용하여 얻을 수 있습니다. 자세한 내용은image_processor_class.__call__를 참조하세요 (processor_class는 이미지 처리에image_processor_class를 사용합니다). - decoder_input_ids (
torch.LongTensor형상(batch_size, target_sequence_length), 선택 사항) — 어휘(decoder input sequence) 토큰의 인덱스입니다. 인덱스는 PreTrainedTokenizer를 사용하여 얻을 수 있습니다. 자세한 내용은 PreTrainedTokenizer.encode() 및 PreTrainedTokenizer.call()를 참조하세요. input ID란 무엇인가요? past_key_values를 사용하는 경우, 선택적으로 마지막 decoder_input_ids만 입력하면 됩니다(past_key_values 참조). 학습 시에는 decoder_input_ids가 모델에 의해 자동으로 생성되며, labels를 오른쪽으로 이동시키고 -100을 pad_token_id로 대체한 뒤, 앞에 decoder_start_token_id를 붙여 생성됩니다.PreTrainedTokenizer를 사용하여 인덱스를 얻을 수 있습니다. 자세한 내용은 PreTrainedTokenizer.encode() 및 PreTrainedTokenizer.call()를 참고하세요.
past_key_values를 사용하는 경우, 선택적으로 마지막decoder_input_ids만 입력하면 됩니다(past_key_values참조).학습 시
decoder_input_ids는 모델이labels을 오른쪽으로 이동시키고, -100을pad_token_id로 대체한 뒤decoder_start_token_id를 앞에 붙여 자동으로 생성합니다. - decoder_attention_mask (
torch.BoolTensor, shape(batch_size, target_sequence_length), 선택) — 기본 동작:decoder_input_ids의 pad 토큰을 무시하는 텐서를 생성합니다. 기본적으로 causal mask도 사용됩니다. - encoder_outputs (
tuple[torch.Tensor], 선택 사항) — (last_hidden_state, 선택 사항:hidden_states, 선택 사항:attentions)으로 구성된 튜플입니다.last_hidden_state의 모양은(batch_size, sequence_length, hidden_size), 선택 사항)이며, 인코더의 마지막 레이어 출력에서 생성된 hidden-states의 시퀀스입니다. 디코더의 cross-attention에 사용됩니다. - past_key_values (
~cache_utils.Cache, 선택 사항) — 순차적 디코딩을 가속화할 수 있는 사전 계산된 hidden-states(self-attention 블록과 cross-attention 블록의 key 및 value). 일반적으로 이는past_key_values디코딩의 이전 단계에서 모델이 반환한use_cache=True또는config.use_cache=True.입력으로 Cache 인스턴스만 허용되며, kv cache 가이드를 참고하세요.
past_key_values가 전달되지 않으면 기본적으로 DynamicCache가 초기화됩니다.모델은 입력으로 제공된 것과 동일한 캐시 형식을 출력합니다.
past_key_values를 사용하는 경우, 이 모델에 과거 키 값 상태가 제공되지 않은input_ids만 입력해야 하며, 이때의 shape은(batch_size, unprocessed_length)입니다. shape이(batch_size, sequence_length)인 전체input_ids를 입력하지 않습니다. - decoder_inputs_embeds (
torch.Tensor, shape(batch_size, target_sequence_length, hidden_size), 선택 사항) —decoder_input_ids를 전달하는 대신 임베딩 표현을 직접 전달할 수 있습니다. 이는 모델 내부 임베딩 조회 행렬보다decoder_input_ids인덱스를 관련 벡터로 변환하는 방식에 대한 더 세밀한 제어가 필요한 경우 유용합니다. - labels (
torch.LongTensor, shape(batch_size, sequence_length), 선택 사항) — 디코더의 masked language modeling loss를 계산하는 데 사용되는 라벨입니다. 인덱스는[-100, 0, ..., config.vocab_size]범위여야 합니다(input_idsdocstring 참조). 인덱스가-100으로 설정된 토큰은 무시(마스크)되며, loss는 라벨이[0, ..., config.vocab_size]범위에 있는 토큰에 대해서만 계산됩니다. - use_cache (
bool, 선택 사항) —True로 설정하면past_key_values키 값 상태가 반환되며, 디코딩 속도를 높이는 데 사용할 수 있습니다(past_key_values참조). - output_attentions (
bool, 선택 사항) — 모든 attention 레이어의 attentions 텐서를 반환할지 여부. 자세한 내용은 반환 텐서 섹션의attentions항목을 참조하세요. - output_hidden_states (
bool, 선택 사항) — 모든 레이어의 hidden states를 반환할지 여부입니다. 자세한 내용은 반환되는 텐서 중hidden_states항목을 참고하세요. - return_dict (
bool, 선택) — 일반 튜플 대신 ModelOutput를 반환할지 여부.
반환값
Seq2SeqLMOutput 또는 tuple(torch.Tensor)
torch.Tensor의 튜플 또는 Seq2SeqLMOutput입니다. return_dict=False가 전달되었거나 config.return_dict=False인 경우, 구성(VisionEncoderDecoderConfig)과 입력에 따라 다양한 요소를 포함합니다.
VisionEncoderDecoderModel의 forward 메서드는 __call__ 특수 메서드를 오버라이드합니다.
이 함수 내에서 forward pass의 레시피를 정의해야 하지만, 이후에는 이 함수 대신
Module인스턴스를 호출해야 합니다. 전자는 전처리 및 후처리 단계를 실행하는 것을 처리하는 반면, 후자는 이를 조용히 무시하기 때문입니다.
loss (
torch.Tensor, shape(1,), 선택 사항,labels이 제공될 때 반환됨) — 언어 모델링 손실.logits (
torch.Tensor, shape(batch_size, sequence_length, config.vocab_size)) — 언어 모델링 헤드에서 생성된 예측 점수(SoftMax 적용 전 각 어휘 토큰에 대한 점수).past_key_values (
EncoderDecoderCache, 선택 사항,use_cache=True가 전달되었거나config.use_cache=True인 경우 반환됨) — EncoderDecoderCache 인스턴스입니다. 자세한 내용은 kv 캐시 가이드를 참고하세요.순차적 디코딩을 가속화하는 데 사용할 수 있는 사전 계산된 hidden-states(셀프 어텐션 블록과 크로스 어텐션 블록의 key 및 value)를 포함합니다(입력
past_key_values참조).decoder_hidden_states (
tuple(torch.Tensor), 선택 사항,output_hidden_states=True가 전달되거나config.output_hidden_states=True인 경우 반환됨) —torch.Tensor의 튜플(모델에 임베딩 레이어가 있는 경우 임베딩의 출력에 대한 것 1개 + 각 레이어의 출력에 대한 것 1개)로, 모양은(batch_size, sequence_length, hidden_size)입니다.각 레이어의 출력에서 디코더의 Hidden-states와 초기 임베딩 출력을 더한 값.
decoder_attentions (
tuple(torch.Tensor), 선택 사항,output_attentions=True가 전달되거나config.output_attentions=True인 경우 반환됨) — 각 레이어마다 하나씩 포함된torch.Tensor의 튜플로, 모양은(batch_size, num_heads, sequence_length, sequence_length)입니다.self-attention 헤드에서 가중 평균을 계산하는 데 사용되는, attention softmax 이후의 decoder의 attention 가중치입니다.
cross_attentions (
tuple(torch.Tensor), 선택 사항,output_attentions=True가 전달되었거나config.output_attentions=True인 경우 반환됨) — 각 레이어마다 하나씩 포함된torch.Tensor의 튜플로, 모양은(batch_size, num_heads, sequence_length, sequence_length)입니다.decoder의 cross-attention 레이어에서 attention softmax를 적용한 후, cross-attention 헤드에서 가중 평균을 계산하는 데 사용되는 attention 가중치입니다.
encoder_last_hidden_state (
torch.Tensor, shape(batch_size, sequence_length, hidden_size), 선택 사항) — 모델 인코더의 마지막 레이어 출력에서 생성된 hidden-state 시퀀스입니다.encoder_hidden_states (
tuple(torch.Tensor), 선택 사항,output_hidden_states=True가 전달되었거나config.output_hidden_states=True인 경우 반환됨) —torch.Tensor의 튜플(모델에 임베딩 레이어가 있는 경우 임베딩의 출력에 대한 것 1개 + 각 레이어의 출력에 대한 것 1개)로, 모양은(batch_size, sequence_length, hidden_size)입니다.각 레이어의 출력에서 인코더의 Hidden-states와 초기 임베딩 출력을 더한 값.
encoder_attentions (
tuple(torch.Tensor), 선택 사항,output_attentions=True가 전달되거나config.output_attentions=True인 경우 반환됨) — 각 레이어마다 하나씩 포함된torch.Tensor의 튜플로, 모양은(batch_size, num_heads, sequence_length, sequence_length)입니다.self-attention 헤드에서 가중 평균을 계산하는 데 사용되는, attention softmax 이후의 인코더 attention 가중치입니다.
예:
>>> from transformers import AutoProcessor, VisionEncoderDecoderModel
>>> from huggingface_hub.utils import httpx
>>> from io import BytesIO
>>> from PIL import Image
>>> import torch
>>> processor = AutoProcessor.from_pretrained("microsoft/trocr-base-handwritten")
>>> model = VisionEncoderDecoderModel.from_pretrained("microsoft/trocr-base-handwritten")
>>> # load image from the IAM dataset
>>> url = "https://fki.tic.heia-fr.ch/static/img/a01-122-02.jpg"
>>> with httpx.stream("GET", url) as response:
... image = Image.open(BytesIO(response.read())).convert("RGB")
>>> # training
>>> model.config.decoder_start_token_id = processor.tokenizer.eos_token_id
>>> model.config.pad_token_id = processor.tokenizer.pad_token_id
>>> model.config.vocab_size = model.config.decoder.vocab_size
>>> pixel_values = processor(image, return_tensors="pt").pixel_values
>>> text = "hello world"
>>> labels = processor.tokenizer(text, return_tensors="pt").input_ids
>>> outputs = model(pixel_values=pixel_values, labels=labels)
>>> loss = outputs.loss
>>> # inference (generation)
>>> generated_ids = model.generate(pixel_values)
>>> generated_text = processor.batch_decode(generated_ids, skip_special_tokens=True)[0]from_encoder_decoder_pretrained
< source >( encoder_pretrained_model_name_or_path: str | None = Nonedecoder_pretrained_model_name_or_path: str | None = None*model_args**kwargs )
매개변수
- encoder_pretrained_model_name_or_path (
str, 선택 사항) — 이미지 인코더를 초기화하는 데 필요한 정보. 다음 중 하나일 수 있습니다:- huggingface.co의 모델 저장소에 호스팅된 사전 학습 모델의 model id를 나타내는 문자열입니다. 예시로
google/vit-base-patch16-224-in21k가 있습니다. - save_pretrained()를 사용하여 저장된 모델 가중치가 포함된 디렉터리의 경로입니다. 예:
./my_model_directory/.
- huggingface.co의 모델 저장소에 호스팅된 사전 학습 모델의 model id를 나타내는 문자열입니다. 예시로
- decoder_pretrained_model_name_or_path (
str, 선택 사항, 기본값은None) — 텍스트 디코더를 초기화하는 데 필요한 정보입니다. 다음 중 하나일 수 있습니다:- huggingface.co의 모델 저장소에 호스팅된 사전 학습 모델의 model id를 나타내는 문자열입니다.
- save_pretrained()를 사용하여 저장된 모델 가중치가 포함된 디렉터리의 경로입니다. 예:
./my_model_directory/.
- model_args (나머지 위치 인자, 선택 사항) —
나머지 위치 인자는 모두 기본 모델의
__init__메서드에 전달됩니다. - kwargs (나머지 키워드 인자 사전, 선택 사항) —
설정 객체를 업데이트(로드된 후)하고 모델을 초기화하는 데 사용할 수 있습니다(예:
output_attentions=True).- 인코더 구성을 업데이트하려면 각 구성 매개변수에 접두사 encoder_를 사용하세요.
- 디코더 구성을 업데이트하려면 각 구성 매개변수에 접두사 decoder_를 사용하세요.
- parent 모델의 구성을 업데이트하려면 각 구성 매개변수에 접두사를 사용하지 마세요.
config이 제공되었는지 자동으로 로드되었는지에 따라 동작이 달라집니다.
library의 하나 또는 두 개의 베이스 클래스에서 사전 학습된 모델 체크포인트를 사용하여 인코더와 디코더를 초기화합니다.
model.eval()을 사용하여 기본적으로 모델이 평가 모드로 설정됩니다(Dropout 모듈은 비활성화됨). 모델을 학습하려면 먼저 model.train()을 사용하여 모델을 학습 모드로 되돌려야 합니다.
예:
>>> from transformers import VisionEncoderDecoderModel
>>> # initialize a vit-bert from a pretrained ViT and a pretrained BERT model. Note that the cross-attention layers will be randomly initialized
>>> model = VisionEncoderDecoderModel.from_encoder_decoder_pretrained(
... "google/vit-base-patch16-224-in21k", "google-bert/bert-base-uncased"
... )
>>> # saving model after fine-tuning
>>> model.save_pretrained("./vit-bert")
>>> # load fine-tuned model
>>> model = VisionEncoderDecoderModel.from_pretrained("./vit-bert")