


"""simple docstring"""
import os
import time
from dataclasses import dataclass, field
from enum import Enum
from typing import Dict, List, Optional, Union

import torch
from filelock import FileLock
from torch.utils.data import Dataset

from ...models.auto.modeling_auto import MODEL_FOR_QUESTION_ANSWERING_MAPPING
from ...tokenization_utils import PreTrainedTokenizer
from ...utils import logging
from ..processors.squad import SquadFeatures, SquadVaProcessor, SquadVaProcessor, squad_convert_examples_to_features


SCREAMING_SNAKE_CASE :    Optional[Any]									=				logging.get_logger(__name__)

SCREAMING_SNAKE_CASE :    Optional[Any]									=				list(MODEL_FOR_QUESTION_ANSWERING_MAPPING.keys())
SCREAMING_SNAKE_CASE :    List[Any]									=				tuple(conf.model_type for conf in MODEL_CONFIG_CLASSES)



@dataclass
class 			_UpperCAmelCase :






		'''simple docstring'''

		lowerCamelCase__				=field(
		    default=__snake_case,				metadata={'help': 'Model type selected in the list: ' + ', '.join(__snake_case				)}				)
		lowerCamelCase__				=field(
		    default=__snake_case,				metadata={'help': 'The input data dir. Should contain the .json files for the SQuAD task.'}				)
		lowerCamelCase__				=field(
		    default=128,				metadata={
		        'help': (
		            'The maximum total input sequence length after tokenization. Sequences longer '
		            'than this will be truncated, sequences shorter will be padded.'
		        )
		    },				)
		lowerCamelCase__				=field(
		    default=128,				metadata={'help': 'When splitting up a long document into chunks, how much stride to take between chunks.'},				)
		lowerCamelCase__				=field(
		    default=64,				metadata={
		        'help': (
		            'The maximum number of tokens for the question. Questions longer than this will '
		            'be truncated to this length.'
		        )
		    },				)
		lowerCamelCase__				=field(
		    default=30,				metadata={
		        'help': (
		            'The maximum length of an answer that can be generated. This is needed because the start '
		            'and end predictions are not conditioned on one another.'
		        )
		    },				)
		lowerCamelCase__				=field(
		    default=__snake_case,				metadata={'help': 'Overwrite the cached training and evaluation sets'}				)
		lowerCamelCase__				=field(
		    default=__snake_case,				metadata={'help': 'If true, the SQuAD examples contain some that do not have an answer.'}				)
		lowerCamelCase__				=field(
		    default=0.0,				metadata={'help': 'If null_score - best_non_null is greater than the threshold predict null.'}				)
		lowerCamelCase__				=field(
		    default=20,				metadata={'help': 'If null_score - best_non_null is greater than the threshold predict null.'}				)
		lowerCamelCase__				=field(
		    default=0,				metadata={
		        'help': (
		            'language id of input for language-specific xlm models (see'
		            ' tokenization_xlm.PRETRAINED_INIT_CONFIGURATION)'
		        )
		    },				)
		lowerCamelCase__				=field(default=1,				metadata={'help': 'multiple threads for converting example to features'}				)



class 			_UpperCAmelCase (							__snake_case				):






		'''simple docstring'''

		lowerCamelCase__				='train'
		lowerCamelCase__				='dev'



class 			_UpperCAmelCase (							__snake_case				):






		'''simple docstring'''

		lowerCamelCase__				=42
		lowerCamelCase__				=42
		lowerCamelCase__				=42
		lowerCamelCase__				=42



		def __init__(self				,       a_				,       a_				,       a_ = None				,       a_ = Split.train				,       a_ = False				,       a_ = None				,       a_ = "pt"				,       ):





			'''simple docstring'''

			__snake_case	:						Optional[Any]						=				args
			__snake_case	:						Optional[Any]						=				is_language_sensitive
			__snake_case	:						Dict						=				SquadVaProcessor() if args.version_2_with_negative else SquadVaProcessor()
			if isinstance(a_				,       a_					):
				try:
					__snake_case	:						Any						=				Split[mode]
				except KeyError:
					raise KeyError('''mode is not a valid split name'''					)
			__snake_case	:						Optional[int]						=				mode
			# Load data features from cache or dataset file
			__snake_case	:						Tuple						=				'''v2''' if args.version_2_with_negative else '''v1'''
			__snake_case	:						Any						=				os.path.join(
			    cache_dir if cache_dir is not None else args.data_dir				,       f"""cached_{mode.value}_{tokenizer.__class__.__name__}_{args.max_seq_length}_{version_tag}"""				,       )

			# Make sure only the first process in distributed training processes the dataset,
			# and the others will use the cache.
			__snake_case	:						Any						=				cached_features_file + '''.lock'''
			with FileLock(a_					):
				if os.path.exists(a_					) and not args.overwrite_cache:
					__snake_case	:						int						=				time.time()
					__snake_case	:						Optional[Any]						=				torch.load(a_					)

					# Legacy cache files have only features, while new cache files
					# will have dataset and examples also.
					__snake_case	:						Tuple						=				self.old_features['''features''']
					__snake_case	:						Union[str, Any]						=				self.old_features.get('''dataset'''				,       a_					)
					__snake_case	:						Optional[Any]						=				self.old_features.get('''examples'''				,       a_					)
					logger.info(
					    f"""Loading features from cached file {cached_features_file} [took %.3f s]"""				,       time.time() - start					)

					if self.dataset is None or self.examples is None:
						logger.warning(
						    f"""Deleting cached file {cached_features_file} will allow dataset and examples to be cached in"""
						    ''' future run'''					)
				else:
					if mode == Split.dev:
						__snake_case	:						str						=				self.processor.get_dev_examples(args.data_dir					)
					else:
						__snake_case	:						int						=				self.processor.get_train_examples(args.data_dir					)

					__snake_case	,							__snake_case	:						int						=				squad_convert_examples_to_features(
					    examples=self.examples				,       tokenizer=a_				,       max_seq_length=args.max_seq_length				,       doc_stride=args.doc_stride				,       max_query_length=args.max_query_length				,       is_training=mode == Split.train				,       threads=args.threads				,       return_dataset=a_				,       )

					__snake_case	:						Union[str, Any]						=				time.time()
					torch.save(
					    {'''features''': self.features, '''dataset''': self.dataset, '''examples''': self.examples}				,       a_				,       )
					# ^ This seems to take a lot of time so I want to investigate why and how we can improve.
					logger.info(
					    f"""Saving features into cached file {cached_features_file} [took {time.time() - start:.3f} s]"""					)



		def __len__(self					):





			'''simple docstring'''

			return len(self.features					)



		def __getitem__(self				,       a_					):





			'''simple docstring'''

			__snake_case	:						Tuple						=				self.features[i]

			__snake_case	:						Any						=				torch.tensor(feature.input_ids				,       dtype=torch.long					)
			__snake_case	:						Optional[Any]						=				torch.tensor(feature.attention_mask				,       dtype=torch.long					)
			__snake_case	:						str						=				torch.tensor(feature.token_type_ids				,       dtype=torch.long					)
			__snake_case	:						Optional[Any]						=				torch.tensor(feature.cls_index				,       dtype=torch.long					)
			__snake_case	:						Optional[Any]						=				torch.tensor(feature.p_mask				,       dtype=torch.float					)
			__snake_case	:						str						=				torch.tensor(feature.is_impossible				,       dtype=torch.float					)

			__snake_case	:						List[str]						=				{
			    '''input_ids''': input_ids,
			    '''attention_mask''': attention_mask,
			    '''token_type_ids''': token_type_ids,
			}

			if self.args.model_type in ["xlm", "roberta", "distilbert", "camembert"]:
				del inputs["token_type_ids"]

			if self.args.model_type in ["xlnet", "xlm"]:
				inputs.update({'''cls_index''': cls_index, '''p_mask''': p_mask}					)
				if self.args.version_2_with_negative:
					inputs.update({'''is_impossible''': is_impossible}					)
				if self.is_language_sensitive:
					inputs.update({'''langs''': (torch.ones(input_ids.shape				,       dtype=torch.intaa					) * self.args.lang_id)}					)

			if self.mode == Split.train:
				__snake_case	:						Dict						=				torch.tensor(feature.start_position				,       dtype=torch.long					)
				__snake_case	:						str						=				torch.tensor(feature.end_position				,       dtype=torch.long					)
				inputs.update({'''start_positions''': start_positions, '''end_positions''': end_positions}					)

			return inputs









"""simple docstring"""
import inspect
from typing import Callable, List, Optional, Union

import torch
from transformers import CLIPImageProcessor, CLIPTextModel, CLIPTokenizer

from diffusers import DiffusionPipeline
from diffusers.models import AutoencoderKL, UNetaDConditionModel
from diffusers.pipelines.stable_diffusion import StableDiffusionPipelineOutput
from diffusers.pipelines.stable_diffusion.safety_checker import StableDiffusionSafetyChecker
from diffusers.schedulers import DDIMScheduler, LMSDiscreteScheduler, PNDMScheduler
from diffusers.utils import logging


SCREAMING_SNAKE_CASE :    List[str]									=				logging.get_logger(__name__)  # pylint: disable=invalid-name



class 			_UpperCAmelCase (							__snake_case				):






		'''simple docstring'''

		def __init__(self				,       a_				,       a_				,       a_				,       a_				,       a_				,       a_				,       a_				,       ):





			'''simple docstring'''

			super().__init__()
			self.register_modules(
			    vae=a_				,       text_encoder=a_				,       tokenizer=a_				,       unet=a_				,       scheduler=a_				,       safety_checker=a_				,       feature_extractor=a_				,       )



		def 				SCREAMING_SNAKE_CASE  (self				,       a_ = "auto"					):





			'''simple docstring'''

			if slice_size == "auto":
				# half the attention head size is usually a good trade-off between
				# speed and memory
				__snake_case	:						Optional[int]						=				self.unet.config.attention_head_dim // 2
			self.unet.set_attention_slice(a_					)



		def 				SCREAMING_SNAKE_CASE  (self					):





			'''simple docstring'''

			self.enable_attention_slicing(a_					)



		@torch.no_grad()
		def __call__(self				,       a_				,       a_ = 5_12				,       a_ = 5_12				,       a_ = 50				,       a_ = 7.5				,       a_ = None				,       a_ = 1				,       a_ = 0.0				,       a_ = None				,       a_ = None				,       a_ = "pil"				,       a_ = True				,       a_ = None				,       a_ = 1				,       a_ = None				,       **a_				,       ):





			'''simple docstring'''

			if isinstance(a_				,       a_					):
				__snake_case	:						Any						=				1
			elif isinstance(a_				,       a_					):
				__snake_case	:						Any						=				len(a_					)
			else:
				raise ValueError(f"""`prompt` has to be of type `str` or `list` but is {type(a_					)}"""					)

			if height % 8 != 0 or width % 8 != 0:
				raise ValueError(f"""`height` and `width` have to be divisible by 8 but are {height} and {width}."""					)

			if (callback_steps is None) or (
			    callback_steps is not None and (not isinstance(a_				,       a_					) or callback_steps <= 0)
			):
				raise ValueError(
				    f"""`callback_steps` has to be a positive integer but is {callback_steps} of type"""
				    f""" {type(a_					)}."""					)

			# get prompt text embeddings
			__snake_case	:						int						=				self.tokenizer(
			    a_				,       padding='''max_length'''				,       max_length=self.tokenizer.model_max_length				,       return_tensors='''pt'''				,       )
			__snake_case	:						int						=				text_inputs.input_ids

			if text_input_ids.shape[-1] > self.tokenizer.model_max_length:
				__snake_case	:						List[Any]						=				self.tokenizer.batch_decode(text_input_ids[:, self.tokenizer.model_max_length :]					)
				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}"""					)
				__snake_case	:						Optional[int]						=				text_input_ids[:, : self.tokenizer.model_max_length]

			if text_embeddings is None:
				__snake_case	:						Optional[int]						=				self.text_encoder(text_input_ids.to(self.device					)					)[0]

			# duplicate text embeddings for each generation per prompt, using mps friendly method
			__snake_case	,							__snake_case	,							__snake_case	:						Union[str, Any]						=				text_embeddings.shape
			__snake_case	:						Optional[int]						=				text_embeddings.repeat(1				,       a_				,       1					)
			__snake_case	:						Dict						=				text_embeddings.view(bs_embed * num_images_per_prompt				,       a_				,       -1					)

			# here `guidance_scale` is defined analog to the guidance weight `w` of equation (2)
			# of the Imagen paper: https://arxiv.org/pdf/2205.11487.pdf . `guidance_scale = 1`
			# corresponds to doing no classifier free guidance.
			__snake_case	:						Dict						=				guidance_scale > 1.0
			# get unconditional embeddings for classifier free guidance
			if do_classifier_free_guidance:
				__snake_case	:						List[str]
				if negative_prompt is None:
					__snake_case	:						List[Any]						=				['''''']
				elif type(a_					) is not type(a_					):
					raise TypeError(
					    f"""`negative_prompt` should be the same type to `prompt`, but got {type(a_					)} !="""
					    f""" {type(a_					)}."""					)
				elif isinstance(a_				,       a_					):
					__snake_case	:						List[str]						=				[negative_prompt]
				elif batch_size != len(a_					):
					raise ValueError(
					    f"""`negative_prompt`: {negative_prompt} has batch size {len(a_					)}, but `prompt`:"""
					    f""" {prompt} has batch size {batch_size}. Please make sure that passed `negative_prompt` matches"""
					    ''' the batch size of `prompt`.'''					)
				else:
					__snake_case	:						Optional[int]						=				negative_prompt

				__snake_case	:						Optional[int]						=				text_input_ids.shape[-1]
				__snake_case	:						List[Any]						=				self.tokenizer(
				    a_				,       padding='''max_length'''				,       max_length=a_				,       truncation=a_				,       return_tensors='''pt'''				,       )
				__snake_case	:						str						=				self.text_encoder(uncond_input.input_ids.to(self.device					)					)[0]

				# duplicate unconditional embeddings for each generation per prompt, using mps friendly method
				__snake_case	:						str						=				uncond_embeddings.shape[1]
				__snake_case	:						int						=				uncond_embeddings.repeat(a_				,       a_				,       1					)
				__snake_case	:						int						=				uncond_embeddings.view(batch_size * num_images_per_prompt				,       a_				,       -1					)

				# 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
				__snake_case	:						Any						=				torch.cat([uncond_embeddings, text_embeddings]					)

			# get the initial random noise unless the user supplied it

			# Unlike in other pipelines, latents need to be generated in the target device
			# for 1-to-1 results reproducibility with the CompVis implementation.
			# However this currently doesn't work in `mps`.
			__snake_case	:						Any						=				(batch_size * num_images_per_prompt, self.unet.config.in_channels, height // 8, width // 8)
			__snake_case	:						Dict						=				(batch_size * num_images_per_prompt, self.unet.config.in_channels, 64, 64)
			__snake_case	:						Dict						=				text_embeddings.dtype
			if latents is None:
				if self.device.type == "mps":
					# randn does not exist on mps
					__snake_case	:						Union[str, Any]						=				torch.randn(
					    a_				,       generator=a_				,       device='''cpu'''				,       dtype=a_					).to(self.device					)
					__snake_case	:						Tuple						=				torch.randn(a_				,       generator=a_				,       device='''cpu'''				,       dtype=a_					).to(
					    self.device					)
				else:
					__snake_case	:						Dict						=				torch.randn(
					    a_				,       generator=a_				,       device=self.device				,       dtype=a_					)
					__snake_case	:						Dict						=				torch.randn(a_				,       generator=a_				,       device=self.device				,       dtype=a_					)
			else:
				if latents_reference.shape != latents_shape:
					raise ValueError(f"""Unexpected latents shape, got {latents.shape}, expected {latents_shape}"""					)
				__snake_case	:						Union[str, Any]						=				latents_reference.to(self.device					)
				__snake_case	:						Dict						=				latents.to(self.device					)

			# This is the key part of the pipeline where we
			# try to ensure that the generated images w/ the same seed
			# but different sizes actually result in similar images
			__snake_case	:						int						=				(latents_shape[3] - latents_shape_reference[3]) // 2
			__snake_case	:						Tuple						=				(latents_shape[2] - latents_shape_reference[2]) // 2
			__snake_case	:						Optional[int]						=				latents_shape_reference[3] if dx >= 0 else latents_shape_reference[3] + 2 * dx
			__snake_case	:						Union[str, Any]						=				latents_shape_reference[2] if dy >= 0 else latents_shape_reference[2] + 2 * dy
			__snake_case	:						int						=				0 if dx < 0 else dx
			__snake_case	:						Union[str, Any]						=				0 if dy < 0 else dy
			__snake_case	:						str						=				max(-dx				,       0					)
			__snake_case	:						Tuple						=				max(-dy				,       0					)
			# import pdb
			# pdb.set_trace()
			__snake_case	:						Any						=				latents_reference[:, :, dy : dy + h, dx : dx + w]

			# set timesteps
			self.scheduler.set_timesteps(a_					)

			# Some schedulers like PNDM have timesteps as arrays
			# It's more optimized to move all timesteps to correct device beforehand
			__snake_case	:						Optional[Any]						=				self.scheduler.timesteps.to(self.device					)

			# scale the initial noise by the standard deviation required by the scheduler
			__snake_case	:						List[Any]						=				latents * self.scheduler.init_noise_sigma

			# prepare extra kwargs for the scheduler step, since not all schedulers have the same signature
			# eta (η) is only used with the DDIMScheduler, it will be ignored for other schedulers.
			# eta corresponds to η in DDIM paper: https://arxiv.org/abs/2010.02502
			# and should be between [0, 1]
			__snake_case	:						Any						=				'''eta''' in set(inspect.signature(self.scheduler.step					).parameters.keys()					)
			__snake_case	:						Tuple						=				{}
			if accepts_eta:
				__snake_case	:						List[str]						=				eta

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

				# predict the noise residual
				__snake_case	:						int						=				self.unet(a_				,       a_				,       encoder_hidden_states=a_					).sample

				# perform guidance
				if do_classifier_free_guidance:
					__snake_case	,							__snake_case	:						Tuple						=				noise_pred.chunk(2					)
					__snake_case	:						str						=				noise_pred_uncond + guidance_scale * (noise_pred_text - noise_pred_uncond)

				# compute the previous noisy sample x_t -> x_t-1
				__snake_case	:						Optional[Any]						=				self.scheduler.step(a_				,       a_				,       a_				,       **a_					).prev_sample

				# call the callback, if provided
				if callback is not None and i % callback_steps == 0:
					callback(a_				,       a_				,       a_					)

			__snake_case	:						Union[str, Any]						=				1 / 0.1_8215 * latents
			__snake_case	:						Optional[Any]						=				self.vae.decode(a_					).sample

			__snake_case	:						Union[str, Any]						=				(image / 2 + 0.5).clamp(0				,       1					)

			# we always cast to float32 as this does not cause significant overhead and is compatible with bfloat16
			__snake_case	:						Union[str, Any]						=				image.cpu().permute(0				,       2				,       3				,       1					).float().numpy()

			if self.safety_checker is not None:
				__snake_case	:						Optional[int]						=				self.feature_extractor(self.numpy_to_pil(a_					)				,       return_tensors='''pt'''					).to(
				    self.device					)
				__snake_case	,							__snake_case	:						List[Any]						=				self.safety_checker(
				    images=a_				,       clip_input=safety_checker_input.pixel_values.to(text_embeddings.dtype					)					)
			else:
				__snake_case	:						Union[str, Any]						=				None

			if output_type == "pil":
				__snake_case	:						Union[str, Any]						=				self.numpy_to_pil(a_					)

			if not return_dict:
				return (image, has_nsfw_concept)

			return StableDiffusionPipelineOutput(images=a_				,       nsfw_content_detected=a_					)





