






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()
__UpperCamelCase      :      Optional[int]     						=						logging.get_logger(__name__)





def 				snake_case  (     lowerCamelCase				,  lowerCamelCase=False					):




	'''simple docstring'''







	__lowercase             =  []
	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"
		__lowercase             =  [(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 				snake_case  (     lowerCamelCase				,  lowerCamelCase				,  lowerCamelCase=False					):




	'''simple docstring'''







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





def 				snake_case  (     lowerCamelCase					):




	'''simple docstring'''







	__lowercase             =  ["""head.weight""", """head.bias"""]
	for k in ignore_keys:
		state_dict.pop(lowerCamelCase				,  lowerCamelCase					)





def 				snake_case  (     lowerCamelCase				,  lowerCamelCase				,  lowerCamelCase					):




	'''simple docstring'''







	__lowercase             =  dct.pop(lowerCamelCase					)
	__lowercase             =  val





def 				snake_case  (     ):




	'''simple docstring'''







	__lowercase             =  """http://images.cocodataset.org/val2017/000000039769.jpg"""
	__lowercase             =  Image.open(requests.get(lowerCamelCase				,  stream=lowerCamelCase					).raw					)
	return im





@torch.no_grad()
def 				snake_case  (     lowerCamelCase				,  lowerCamelCase				,  lowerCamelCase=True					):




	'''simple docstring'''







	__lowercase             =  ViTConfig()
	# patch_size
	if model_name[-1] == "8":
		__lowercase             =  8
	# set labels if required
	if not base_model:
		__lowercase             =  1_000
		__lowercase             =  """huggingface/label-files"""
		__lowercase             =  """imagenet-1k-id2label.json"""
		__lowercase             =  json.load(open(hf_hub_download(lowerCamelCase				,  lowerCamelCase				,  repo_type="""dataset"""					)				,  """r"""					)					)
		__lowercase             =  {int(lowerCamelCase					): v for k, v in idalabel.items()}
		__lowercase             =  idalabel
		__lowercase             =  {v: k for k, v in idalabel.items()}
	# size of the architecture
	if model_name in ["dino_vits8", "dino_vits16"]:
		__lowercase             =  384
		__lowercase             =  1_536
		__lowercase             =  12
		__lowercase             =  6

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

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

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

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

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

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


if __name__ == "__main__":
						__UpperCamelCase      :      Optional[Any]     						=						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)
						__UpperCamelCase      :      Tuple     						=						parser.parse_args()
						convert_vit_checkpoint(args.model_name, args.pytorch_dump_folder_path, args.base_model)









import gc
import unittest

from diffusers import FlaxDPMSolverMultistepScheduler, FlaxStableDiffusionPipeline
from diffusers.utils import is_flax_available, slow
from diffusers.utils.testing_utils import require_flax


if is_flax_available():
						import jax
						import jax.numpy as jnp
						from flax.jax_utils import replicate
						from flax.training.common_utils import shard


@slow
@require_flax
class        __UpperCamelCase    (     unittest.TestCase   ):







	def  _a   (  self      :							Union[str, Any]			)		-> Any:
		"""simple docstring"""







		super().tearDown()
		gc.collect()







	def  _a   (  self      :							List[str]			)		-> int:
		"""simple docstring"""







		__lowercase       ,						__lowercase             =  FlaxStableDiffusionPipeline.from_pretrained(
		    """stabilityai/stable-diffusion-2"""       ,				revision="""bf16"""       ,				dtype=jnp.bfloataa       ,				)

		__lowercase             =  """A painting of a squirrel eating a burger"""
		__lowercase             =  jax.device_count()
		__lowercase             =  num_samples * [prompt]
		__lowercase             =  sd_pipe.prepare_inputs(_lowerCAmelCase			)

		__lowercase             =  replicate(_lowerCAmelCase			)
		__lowercase             =  shard(_lowerCAmelCase			)

		__lowercase             =  jax.random.PRNGKey(0			)
		__lowercase             =  jax.random.split(_lowerCAmelCase       ,				jax.device_count()			)

		__lowercase             =  sd_pipe(_lowerCAmelCase       ,				_lowerCAmelCase       ,				_lowerCAmelCase       ,				num_inference_steps=25       ,				jit=_lowerCAmelCase			)[0]
		assert images.shape == (jax.device_count(), 1, 768, 768, 3)

		__lowercase             =  images.reshape((images.shape[0] * images.shape[1],) + images.shape[-3:]			)
		__lowercase             =  images[0, 253:256, 253:256, -1]

		__lowercase             =  jnp.asarray(jax.device_get(image_slice.flatten()			)			)
		__lowercase             =  jnp.array([0.4_238, 0.4_414, 0.4_395, 0.4_453, 0.4_629, 0.4_590, 0.4_531, 0.45_508, 0.4_512]			)
		print(F'output_slice: {output_slice}'			)
		assert jnp.abs(output_slice - expected_slice			).max() < 1e-2







	def  _a   (  self      :							str			)		-> List[Any]:
		"""simple docstring"""







		__lowercase             =  """stabilityai/stable-diffusion-2"""
		__lowercase       ,						__lowercase             =  FlaxDPMSolverMultistepScheduler.from_pretrained(_lowerCAmelCase       ,				subfolder="""scheduler"""			)
		__lowercase       ,						__lowercase             =  FlaxStableDiffusionPipeline.from_pretrained(
		    _lowerCAmelCase       ,				scheduler=_lowerCAmelCase       ,				revision="""bf16"""       ,				dtype=jnp.bfloataa       ,				)
		__lowercase             =  scheduler_params

		__lowercase             =  """A painting of a squirrel eating a burger"""
		__lowercase             =  jax.device_count()
		__lowercase             =  num_samples * [prompt]
		__lowercase             =  sd_pipe.prepare_inputs(_lowerCAmelCase			)

		__lowercase             =  replicate(_lowerCAmelCase			)
		__lowercase             =  shard(_lowerCAmelCase			)

		__lowercase             =  jax.random.PRNGKey(0			)
		__lowercase             =  jax.random.split(_lowerCAmelCase       ,				jax.device_count()			)

		__lowercase             =  sd_pipe(_lowerCAmelCase       ,				_lowerCAmelCase       ,				_lowerCAmelCase       ,				num_inference_steps=25       ,				jit=_lowerCAmelCase			)[0]
		assert images.shape == (jax.device_count(), 1, 768, 768, 3)

		__lowercase             =  images.reshape((images.shape[0] * images.shape[1],) + images.shape[-3:]			)
		__lowercase             =  images[0, 253:256, 253:256, -1]

		__lowercase             =  jnp.asarray(jax.device_get(image_slice.flatten()			)			)
		__lowercase             =  jnp.array([0.4_336, 0.42_969, 0.4_453, 0.4_199, 0.4_297, 0.4_531, 0.4_434, 0.4_434, 0.4_297]			)
		print(F'output_slice: {output_slice}'			)
		assert jnp.abs(output_slice - expected_slice			).max() < 1e-2

