
from typing import List, Optional, Union

import torch
from transformers import (
    XLMRobertaTokenizer,
)

from ...models import UNetaDConditionModel, VQModel
from ...pipelines import DiffusionPipeline
from ...pipelines.pipeline_utils import ImagePipelineOutput
from ...schedulers import DDIMScheduler, DDPMScheduler
from ...utils import (
    is_accelerate_available,
    is_accelerate_version,
    logging,
    randn_tensor,
    replace_example_docstring,
)
from .text_encoder import MultilingualCLIP


lowercase   =	logging.get_logger(__name__)  # pylint: disable=invalid-name

lowercase   =	'''
    Examples:
        ```py
        >>> from diffusers import KandinskyPipeline, KandinskyPriorPipeline
        >>> import torch

        >>> pipe_prior = KandinskyPriorPipeline.from_pretrained("kandinsky-community/Kandinsky-2-1-prior")
        >>> pipe_prior.to("cuda")

        >>> prompt = "red cat, 4k photo"
        >>> out = pipe_prior(prompt)
        >>> image_emb = out.image_embeds
        >>> negative_image_emb = out.negative_image_embeds

        >>> pipe = KandinskyPipeline.from_pretrained("kandinsky-community/kandinsky-2-1")
        >>> pipe.to("cuda")

        >>> image = pipe(
        ...     prompt,
        ...     image_embeds=image_emb,
        ...     negative_image_embeds=negative_image_emb,
        ...     height=768,
        ...     width=768,
        ...     num_inference_steps=100,
        ... ).images

        >>> image[0].save("cat.png")
        ```
'''



def   __lowerCAmelCase    (				UpperCAmelCase__					:   Dict      ,					UpperCAmelCase__					:   int      ,					UpperCAmelCase__					:   Dict=8							)	->     int:
							lowerCamelCase_					=       h // scale_factor**2
							if h % scale_factor**2 != 0:
														new_h += 1
							lowerCamelCase_					=       w // scale_factor**2
							if w % scale_factor**2 != 0:
														new_w += 1
							return new_h * scale_factor, new_w * scale_factor





class    __A(					UpperCAmelCase							):

					def __init__(						self       :  List[str] ,       __UpperCamelCase       :  MultilingualCLIP ,       __UpperCamelCase       :  XLMRobertaTokenizer ,       __UpperCamelCase       :  UNetaDConditionModel ,       __UpperCamelCase       :  Union[DDIMScheduler, DDPMScheduler] ,       __UpperCamelCase       :  VQModel ,       ):
												super().__init__()

												self.register_modules(
												    text_encoder=__UpperCamelCase ,       tokenizer=__UpperCamelCase ,       unet=__UpperCamelCase ,       scheduler=__UpperCamelCase ,       movq=__UpperCamelCase ,       )
												lowerCamelCase_					=       2 ** (len(self.movq.config.block_out_channels ) - 1)

					def  lowercase__   (						self       :  Dict ,       __UpperCamelCase       :  List[Any] ,       __UpperCamelCase       :  Tuple ,       __UpperCamelCase       :  Any ,       __UpperCamelCase       :  Union[str, Any] ,       __UpperCamelCase       :  List[Any] ,       __UpperCamelCase       :  List[Any] ):
												if latents is None:
																			lowerCamelCase_					=       randn_tensor(__UpperCamelCase ,       generator=__UpperCamelCase ,       device=__UpperCamelCase ,       dtype=__UpperCamelCase )
												else:
																			if latents.shape != shape:
																										raise ValueError(F'''Unexpected latents shape, got {latents.shape}, expected {shape}''' )
																			lowerCamelCase_					=       latents.to(__UpperCamelCase )

												lowerCamelCase_					=       latents * scheduler.init_noise_sigma
												return latents

					def  lowercase__   (						self       :  List[Any] ,       __UpperCamelCase       :  Union[str, Any] ,       __UpperCamelCase       :  Union[str, Any] ,       __UpperCamelCase       :  Any ,       __UpperCamelCase       :  Union[str, Any] ,       __UpperCamelCase       :  List[Any]=None ,       ):
												lowerCamelCase_					=       len(__UpperCamelCase ) if isinstance(__UpperCamelCase ,       __UpperCamelCase ) else 1
												# get prompt text embeddings
												lowerCamelCase_					=       self.tokenizer(
												    __UpperCamelCase ,       padding="""max_length""" ,       truncation=__UpperCamelCase ,       max_length=7_7 ,       return_attention_mask=__UpperCamelCase ,       add_special_tokens=__UpperCamelCase ,       return_tensors="""pt""" ,       )

												lowerCamelCase_					=       text_inputs.input_ids
												lowerCamelCase_					=       self.tokenizer(__UpperCamelCase ,       padding="""longest""" ,       return_tensors="""pt""" ).input_ids

												if untruncated_ids.shape[-1] >= text_input_ids.shape[-1] and not torch.equal(__UpperCamelCase ,       __UpperCamelCase ):
																			lowerCamelCase_					=       self.tokenizer.batch_decode(untruncated_ids[:, self.tokenizer.model_max_length - 1 : -1] )
																			logger.warning(
																			    """The following part of your input was truncated because CLIP can only handle sequences up to"""
																			    F''' {self.tokenizer.model_max_length} tokens: {removed_text}''' )

												lowerCamelCase_					=       text_input_ids.to(__UpperCamelCase )
												lowerCamelCase_					=       text_inputs.attention_mask.to(__UpperCamelCase )

												lowerCamelCase_	, lowerCamelCase_					=       self.text_encoder(
												    input_ids=__UpperCamelCase ,       attention_mask=__UpperCamelCase )

												lowerCamelCase_					=       prompt_embeds.repeat_interleave(__UpperCamelCase ,       dim=0 )
												lowerCamelCase_					=       text_encoder_hidden_states.repeat_interleave(__UpperCamelCase ,       dim=0 )
												lowerCamelCase_					=       text_mask.repeat_interleave(__UpperCamelCase ,       dim=0 )

												if do_classifier_free_guidance:
																			lowerCamelCase_					=       42
																			if negative_prompt is None:
																										lowerCamelCase_					=       [""""""] * batch_size
																			elif type(__UpperCamelCase ) is not type(__UpperCamelCase ):
																										raise TypeError(
																										    F'''`negative_prompt` should be the same type to `prompt`, but got {type(__UpperCamelCase )} !='''
																										    F''' {type(__UpperCamelCase )}.''' )
																			elif isinstance(__UpperCamelCase ,       __UpperCamelCase ):
																										lowerCamelCase_					=       [negative_prompt]
																			elif batch_size != len(__UpperCamelCase ):
																										raise ValueError(
																										    F'''`negative_prompt`: {negative_prompt} has batch size {len(__UpperCamelCase )}, but `prompt`:'''
																										    F''' {prompt} has batch size {batch_size}. Please make sure that passed `negative_prompt` matches'''
																										    """ the batch size of `prompt`.""" )
																			else:
																										lowerCamelCase_					=       negative_prompt

																			lowerCamelCase_					=       self.tokenizer(
																			    __UpperCamelCase ,       padding="""max_length""" ,       max_length=7_7 ,       truncation=__UpperCamelCase ,       return_attention_mask=__UpperCamelCase ,       add_special_tokens=__UpperCamelCase ,       return_tensors="""pt""" ,       )
																			lowerCamelCase_					=       uncond_input.input_ids.to(__UpperCamelCase )
																			lowerCamelCase_					=       uncond_input.attention_mask.to(__UpperCamelCase )

																			lowerCamelCase_	, lowerCamelCase_					=       self.text_encoder(
																			    input_ids=__UpperCamelCase ,       attention_mask=__UpperCamelCase )

																			# duplicate unconditional embeddings for each generation per prompt, using mps friendly method

																			lowerCamelCase_					=       negative_prompt_embeds.shape[1]
																			lowerCamelCase_					=       negative_prompt_embeds.repeat(1 ,       __UpperCamelCase )
																			lowerCamelCase_					=       negative_prompt_embeds.view(batch_size * num_images_per_prompt ,       __UpperCamelCase )

																			lowerCamelCase_					=       uncond_text_encoder_hidden_states.shape[1]
																			lowerCamelCase_					=       uncond_text_encoder_hidden_states.repeat(1 ,       __UpperCamelCase ,       1 )
																			lowerCamelCase_					=       uncond_text_encoder_hidden_states.view(
																			    batch_size * num_images_per_prompt ,       __UpperCamelCase ,       -1 )
																			lowerCamelCase_					=       uncond_text_mask.repeat_interleave(__UpperCamelCase ,       dim=0 )

																			# done duplicates

																			# For classifier free guidance, we need to do two forward passes.
																			# Here we concatenate the unconditional and text embeddings into a single batch
																			# to avoid doing two forward passes
																			lowerCamelCase_					=       torch.cat([negative_prompt_embeds, prompt_embeds] )
																			lowerCamelCase_					=       torch.cat([uncond_text_encoder_hidden_states, text_encoder_hidden_states] )

																			lowerCamelCase_					=       torch.cat([uncond_text_mask, text_mask] )

												return prompt_embeds, text_encoder_hidden_states, text_mask

					def  lowercase__   (						self       :  Any ,       __UpperCamelCase       :  Any=0 ):
												if is_accelerate_available():
																			from accelerate import cpu_offload
												else:
																			raise ImportError("""Please install accelerate via `pip install accelerate`""" )

												lowerCamelCase_					=       torch.device(F'''cuda:{gpu_id}''' )

												lowerCamelCase_					=       [
												    self.unet,
												    self.text_encoder,
												    self.movq,
												]
												for cpu_offloaded_model in models:
																			if cpu_offloaded_model is not None:
																										cpu_offload(__UpperCamelCase ,       __UpperCamelCase )

					def  lowercase__   (						self       :  List[str] ,       __UpperCamelCase       :  Union[str, Any]=0 ):
												if is_accelerate_available() and is_accelerate_version(""">=""" ,       """0.17.0.dev0""" ):
																			from accelerate import cpu_offload_with_hook
												else:
																			raise ImportError("""`enable_model_cpu_offload` requires `accelerate v0.17.0` or higher.""" )

												lowerCamelCase_					=       torch.device(F'''cuda:{gpu_id}''' )

												if self.device.type != "cpu":
																			self.to("""cpu""" ,       silence_dtype_warnings=__UpperCamelCase )
																			torch.cuda.empty_cache()  # otherwise we don't see the memory savings (but they probably exist)

												lowerCamelCase_					=       None
												for cpu_offloaded_model in [self.text_encoder, self.unet, self.movq]:
																			lowerCamelCase_	, lowerCamelCase_					=       cpu_offload_with_hook(__UpperCamelCase ,       __UpperCamelCase ,       prev_module_hook=__UpperCamelCase )

												if self.safety_checker is not None:
																			lowerCamelCase_	, lowerCamelCase_					=       cpu_offload_with_hook(self.safety_checker ,       __UpperCamelCase ,       prev_module_hook=__UpperCamelCase )

												# We'll offload the last model manually.
												lowerCamelCase_					=       hook

					@property
					# Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.StableDiffusionPipeline._execution_device
					def  lowercase__   (						self       :  Optional[Any] ):
												if not hasattr(self.unet ,       """_hf_hook""" ):
																			return self.device
												for module in self.unet.modules():
																			if (
																			    hasattr(__UpperCamelCase ,       """_hf_hook""" )
																			    and hasattr(module._hf_hook ,       """execution_device""" )
																			    and module._hf_hook.execution_device is not None
																			):
																										return torch.device(module._hf_hook.execution_device )
												return self.device



					@torch.no_grad()
					@replace_example_docstring(__UpperCamelCase )
					def __call__(						self       :  Optional[Any] ,       __UpperCamelCase       :  Union[str, List[str]] ,       __UpperCamelCase       :  Union[torch.FloatTensor, List[torch.FloatTensor]] ,       __UpperCamelCase       :  Union[torch.FloatTensor, List[torch.FloatTensor]] ,       __UpperCamelCase       :  Optional[Union[str, List[str]]] = None ,       __UpperCamelCase       :  int = 5_1_2 ,       __UpperCamelCase       :  int = 5_1_2 ,       __UpperCamelCase       :  int = 1_0_0 ,       __UpperCamelCase       :  float = 4.0 ,       __UpperCamelCase       :  int = 1 ,       __UpperCamelCase       :  Optional[Union[torch.Generator, List[torch.Generator]]] = None ,       __UpperCamelCase       :  Optional[torch.FloatTensor] = None ,       __UpperCamelCase       :  Optional[str] = "pil" ,       __UpperCamelCase       :  bool = True ,       ):

												if isinstance(__UpperCamelCase ,       __UpperCamelCase ):
																			lowerCamelCase_					=       1
												elif isinstance(__UpperCamelCase ,       __UpperCamelCase ):
																			lowerCamelCase_					=       len(__UpperCamelCase )
												else:
																			raise ValueError(F'''`prompt` has to be of type `str` or `list` but is {type(__UpperCamelCase )}''' )

												lowerCamelCase_					=       self._execution_device

												lowerCamelCase_					=       batch_size * num_images_per_prompt
												lowerCamelCase_					=       guidance_scale > 1.0

												lowerCamelCase_	, lowerCamelCase_	, lowerCamelCase_					=       self._encode_prompt(
												    __UpperCamelCase ,       __UpperCamelCase ,       __UpperCamelCase ,       __UpperCamelCase ,       __UpperCamelCase )

												if isinstance(__UpperCamelCase ,       __UpperCamelCase ):
																			lowerCamelCase_					=       torch.cat(__UpperCamelCase ,       dim=0 )
												if isinstance(__UpperCamelCase ,       __UpperCamelCase ):
																			lowerCamelCase_					=       torch.cat(__UpperCamelCase ,       dim=0 )

												if do_classifier_free_guidance:
																			lowerCamelCase_					=       image_embeds.repeat_interleave(__UpperCamelCase ,       dim=0 )
																			lowerCamelCase_					=       negative_image_embeds.repeat_interleave(__UpperCamelCase ,       dim=0 )

												lowerCamelCase_					=       torch.cat([negative_image_embeds, image_embeds] ,       dim=0 ).to(
												    dtype=prompt_embeds.dtype ,       device=__UpperCamelCase )

												self.scheduler.set_timesteps(__UpperCamelCase ,       device=__UpperCamelCase )
												lowerCamelCase_					=       self.scheduler.timesteps

												lowerCamelCase_					=       self.unet.config.in_channels

												lowerCamelCase_	, lowerCamelCase_					=       get_new_h_w(__UpperCamelCase ,       __UpperCamelCase ,       self.movq_scale_factor )

												# create initial latent
												lowerCamelCase_					=       self.prepare_latents(
												    (batch_size, num_channels_latents, height, width) ,       text_encoder_hidden_states.dtype ,       __UpperCamelCase ,       __UpperCamelCase ,       __UpperCamelCase ,       self.scheduler ,       )

												for i, t in enumerate(self.progress_bar(__UpperCamelCase ) ):
																			# expand the latents if we are doing classifier free guidance
																			lowerCamelCase_					=       torch.cat([latents] * 2 ) if do_classifier_free_guidance else latents

																			lowerCamelCase_					=       {"""text_embeds""": prompt_embeds, """image_embeds""": image_embeds}
																			lowerCamelCase_					=       self.unet(
																			    sample=__UpperCamelCase ,       timestep=__UpperCamelCase ,       encoder_hidden_states=__UpperCamelCase ,       added_cond_kwargs=__UpperCamelCase ,       return_dict=__UpperCamelCase ,       )[0]

																			if do_classifier_free_guidance:
																										lowerCamelCase_	, lowerCamelCase_					=       noise_pred.split(latents.shape[1] ,       dim=1 )
																										lowerCamelCase_	, lowerCamelCase_					=       noise_pred.chunk(2 )
																										lowerCamelCase_	, lowerCamelCase_					=       variance_pred.chunk(2 )
																										lowerCamelCase_					=       noise_pred_uncond + guidance_scale * (noise_pred_text - noise_pred_uncond)
																										lowerCamelCase_					=       torch.cat([noise_pred, variance_pred_text] ,       dim=1 )

																			if not (
																			    hasattr(self.scheduler.config ,       """variance_type""" )
																			    and self.scheduler.config.variance_type in ["learned", "learned_range"]
																			):
																										lowerCamelCase_	, lowerCamelCase_					=       noise_pred.split(latents.shape[1] ,       dim=1 )

																			# compute the previous noisy sample x_t -> x_t-1
																			lowerCamelCase_					=       self.scheduler.step(
																			    __UpperCamelCase ,       __UpperCamelCase ,       __UpperCamelCase ,       generator=__UpperCamelCase ,       ).prev_sample
												# post-processing
												lowerCamelCase_					=       self.movq.decode(__UpperCamelCase ,       force_not_quantize=__UpperCamelCase )["""sample"""]

												if output_type not in ["pt", "np", "pil"]:
																			raise ValueError(F'''Only the output types `pt`, `pil` and `np` are supported not output_type={output_type}''' )

												if output_type in ["np", "pil"]:
																			lowerCamelCase_					=       image * 0.5 + 0.5
																			lowerCamelCase_					=       image.clamp(0 ,       1 )
																			lowerCamelCase_					=       image.cpu().permute(0 ,       2 ,       3 ,       1 ).float().numpy()

												if output_type == "pil":
																			lowerCamelCase_					=       self.numpy_to_pil(__UpperCamelCase )

												if not return_dict:
																			return (image,)

												return ImagePipelineOutput(images=__UpperCamelCase )







import argparse
import json
from pathlib import Path

import requests
import torch
from huggingface_hub import hf_hub_download
from PIL import Image

from transformers import ViTConfig, ViTForImageClassification, ViTImageProcessor, ViTModel
from transformers.utils import logging


logging.set_verbosity_info()
lowercase   =	logging.get_logger(__name__)



def   __lowerCAmelCase    (				UpperCAmelCase__					:   int      ,					UpperCAmelCase__					:   Tuple=False							)	->     Optional[Any]:
							lowerCamelCase_					=       []
							for i in range(config.num_hidden_layers							):
														# encoder layers: output projection, 2 feedforward neural networks and 2 layernorms
														rename_keys.append((F'''blocks.{i}.norm1.weight''', F'''vit.encoder.layer.{i}.layernorm_before.weight''')							)
														rename_keys.append((F'''blocks.{i}.norm1.bias''', F'''vit.encoder.layer.{i}.layernorm_before.bias''')							)
														rename_keys.append((F'''blocks.{i}.attn.proj.weight''', F'''vit.encoder.layer.{i}.attention.output.dense.weight''')							)
														rename_keys.append((F'''blocks.{i}.attn.proj.bias''', F'''vit.encoder.layer.{i}.attention.output.dense.bias''')							)
														rename_keys.append((F'''blocks.{i}.norm2.weight''', F'''vit.encoder.layer.{i}.layernorm_after.weight''')							)
														rename_keys.append((F'''blocks.{i}.norm2.bias''', F'''vit.encoder.layer.{i}.layernorm_after.bias''')							)
														rename_keys.append((F'''blocks.{i}.mlp.fc1.weight''', F'''vit.encoder.layer.{i}.intermediate.dense.weight''')							)
														rename_keys.append((F'''blocks.{i}.mlp.fc1.bias''', F'''vit.encoder.layer.{i}.intermediate.dense.bias''')							)
														rename_keys.append((F'''blocks.{i}.mlp.fc2.weight''', F'''vit.encoder.layer.{i}.output.dense.weight''')							)
														rename_keys.append((F'''blocks.{i}.mlp.fc2.bias''', F'''vit.encoder.layer.{i}.output.dense.bias''')							)

							# projection layer + position embeddings
							rename_keys.extend(
							    [
							        ("""cls_token""", """vit.embeddings.cls_token"""),
							        ("""patch_embed.proj.weight""", """vit.embeddings.patch_embeddings.projection.weight"""),
							        ("""patch_embed.proj.bias""", """vit.embeddings.patch_embeddings.projection.bias"""),
							        ("""pos_embed""", """vit.embeddings.position_embeddings"""),
							    ]							)

							if base_model:
														# layernorm + pooler
														rename_keys.extend(
														    [
														        ("""norm.weight""", """layernorm.weight"""),
														        ("""norm.bias""", """layernorm.bias"""),
														    ]							)

														# if just the base model, we should remove "vit" from all keys that start with "vit"
														lowerCamelCase_					=       [(pair[0], pair[1][4:]) if pair[1].startswith("""vit"""							) else pair for pair in rename_keys]
							else:
														# layernorm + classification head
														rename_keys.extend(
														    [
														        ("""norm.weight""", """vit.layernorm.weight"""),
														        ("""norm.bias""", """vit.layernorm.bias"""),
														        ("""head.weight""", """classifier.weight"""),
														        ("""head.bias""", """classifier.bias"""),
														    ]							)

							return rename_keys



def   __lowerCAmelCase    (				UpperCAmelCase__					:   List[str]      ,					UpperCAmelCase__					:   Optional[Any]      ,					UpperCAmelCase__					:   Any=False							)	->     int:
							for i in range(config.num_hidden_layers							):
														if base_model:
																					lowerCamelCase_					=       """"""
														else:
																					lowerCamelCase_					=       """vit."""
														# read in weights + bias of input projection layer (in timm, this is a single matrix + bias)
														lowerCamelCase_					=       state_dict.pop(F'''blocks.{i}.attn.qkv.weight'''							)
														lowerCamelCase_					=       state_dict.pop(F'''blocks.{i}.attn.qkv.bias'''							)
														# next, add query, keys and values (in that order) to the state dict
														lowerCamelCase_					=       in_proj_weight[
														    : config.hidden_size, :
														]
														lowerCamelCase_					=       in_proj_bias[: config.hidden_size]
														lowerCamelCase_					=       in_proj_weight[
														    config.hidden_size : config.hidden_size * 2, :
														]
														lowerCamelCase_					=       in_proj_bias[
														    config.hidden_size : config.hidden_size * 2
														]
														lowerCamelCase_					=       in_proj_weight[
														    -config.hidden_size :, :
														]
														lowerCamelCase_					=       in_proj_bias[-config.hidden_size :]



def   __lowerCAmelCase    (				UpperCAmelCase__					:   str							)	->     str:
							lowerCamelCase_					=       ["""head.weight""", """head.bias"""]
							for k in ignore_keys:
														state_dict.pop(UpperCAmelCase__      ,					UpperCAmelCase__							)



def   __lowerCAmelCase    (				UpperCAmelCase__					:   Dict      ,					UpperCAmelCase__					:   int      ,					UpperCAmelCase__					:   int							)	->     Tuple:
							lowerCamelCase_					=       dct.pop(UpperCAmelCase__							)
							lowerCamelCase_					=       val



def   __lowerCAmelCase    (				)	->     Any:
							lowerCamelCase_					=       """http://images.cocodataset.org/val2017/000000039769.jpg"""
							lowerCamelCase_					=       Image.open(requests.get(UpperCAmelCase__      ,					stream=UpperCAmelCase__							).raw							)
							return im



@torch.no_grad()
def   __lowerCAmelCase    (				UpperCAmelCase__					:   str      ,					UpperCAmelCase__					:   Optional[int]      ,					UpperCAmelCase__					:   Tuple=True							)	->     Dict:
							lowerCamelCase_					=       ViTConfig()
							# patch_size
							if model_name[-1] == "8":
														lowerCamelCase_					=       8
							# set labels if required
							if not base_model:
														lowerCamelCase_					=       1_0_0_0
														lowerCamelCase_					=       """huggingface/label-files"""
														lowerCamelCase_					=       """imagenet-1k-id2label.json"""
														lowerCamelCase_					=       json.load(open(hf_hub_download(UpperCAmelCase__      ,					UpperCAmelCase__      ,					repo_type="""dataset"""							)      ,					"""r"""							)							)
														lowerCamelCase_					=       {int(UpperCAmelCase__							): v for k, v in idalabel.items()}
														lowerCamelCase_					=       idalabel
														lowerCamelCase_					=       {v: k for k, v in idalabel.items()}
							# size of the architecture
							if model_name in ["dino_vits8", "dino_vits16"]:
														lowerCamelCase_					=       3_8_4
														lowerCamelCase_					=       1_5_3_6
														lowerCamelCase_					=       1_2
														lowerCamelCase_					=       6

							# load original model from torch hub
							lowerCamelCase_					=       torch.hub.load("""facebookresearch/dino:main"""      ,					UpperCAmelCase__							)
							original_model.eval()

							# load state_dict of original model, remove and rename some keys
							lowerCamelCase_					=       original_model.state_dict()
							if base_model:
														remove_classification_head_(UpperCAmelCase__							)
							lowerCamelCase_					=       create_rename_keys(UpperCAmelCase__      ,					base_model=UpperCAmelCase__							)
							for src, dest in rename_keys:
														rename_key(UpperCAmelCase__      ,					UpperCAmelCase__      ,					UpperCAmelCase__							)
							read_in_q_k_v(UpperCAmelCase__      ,					UpperCAmelCase__      ,					UpperCAmelCase__							)

							# load HuggingFace model
							if base_model:
														lowerCamelCase_					=       ViTModel(UpperCAmelCase__      ,					add_pooling_layer=UpperCAmelCase__							).eval()
							else:
														lowerCamelCase_					=       ViTForImageClassification(UpperCAmelCase__							).eval()
							model.load_state_dict(UpperCAmelCase__							)

							# Check outputs on an image, prepared by ViTImageProcessor
							lowerCamelCase_					=       ViTImageProcessor()
							lowerCamelCase_					=       image_processor(images=prepare_img()      ,					return_tensors="""pt"""							)
							lowerCamelCase_					=       encoding["""pixel_values"""]
							lowerCamelCase_					=       model(UpperCAmelCase__							)

							if base_model:
														lowerCamelCase_					=       original_model(UpperCAmelCase__							)
														assert torch.allclose(UpperCAmelCase__      ,					outputs.last_hidden_state[:, 0, :]      ,					atol=1e-1							)
							else:
														lowerCamelCase_					=       original_model(UpperCAmelCase__							)
														assert logits.shape == outputs.logits.shape
														assert torch.allclose(UpperCAmelCase__      ,					outputs.logits      ,					atol=1e-3							)

							Path(UpperCAmelCase__							).mkdir(exist_ok=UpperCAmelCase__							)
							print(F'''Saving model {model_name} to {pytorch_dump_folder_path}'''							)
							model.save_pretrained(UpperCAmelCase__							)
							print(F'''Saving image processor to {pytorch_dump_folder_path}'''							)
							image_processor.save_pretrained(UpperCAmelCase__							)


if __name__ == "__main__":
		lowercase   =	argparse.ArgumentParser()
		# Required parameters
		parser.add_argument(
		    '''--model_name''',
		    default='''dino_vitb16''',
		    type=str,
		    help='''Name of the model trained with DINO you\'d like to convert.''',
		)
		parser.add_argument(
		    '''--pytorch_dump_folder_path''', default=None, type=str, help='''Path to the output PyTorch model directory.'''
		)
		parser.add_argument(
		    '''--base_model''',
		    action='''store_true''',
		    help='''Whether to only convert the base model (no projection head weights).''',
		)

		parser.set_defaults(base_model=True)
		lowercase   =	parser.parse_args()
		convert_vit_checkpoint(args.model_name, args.pytorch_dump_folder_path, args.base_model)





