'''simple docstring'''

import argparse
import random

import joblib
import numpy as np
import torch
from igf.igf import (
    SecondaryLearner,
    collect_objective_set,
    compute_perplexity,
    generate_datasets,
    load_gpta,
    recopy_gpta,
    set_seed,
    train_secondary_learner,
)
from torch.utils.data import DataLoader, RandomSampler

from transformers import GPTaLMHeadModel







def __UpperCamelCase( _A       :					Optional[Any]=32	,      _A       :					List[Any]=10	,      _A       :					Optional[Any]=1_00	,      _A       :					List[str]=10_26	,      _A       :					List[Any]=True	,      _A       :					Union[str, Any]="data/tokenized_stories_train_wikitext103.jbl"	,      _A       :					Union[str, Any]="igf_context_pairs.jbl"	,      ):
   '''simple docstring'''
   set_seed(3     )
   # generate train_data and objective_set
   UpperCAmelCase__					,   UpperCAmelCase__				:					List[str] 					=	generate_datasets(
       _A	,      _A	,      number=_A	,      min_len=10_26	,      trim=_A     )
   # keeps model same across runs
   set_seed(4     )
   # model, lm_optimizer, lm_scheduler = recopy_gpt2(model, device, max_steps) # store original model weights
   # can we train on GPU?
   UpperCAmelCase__				:					int 					=	torch.device('''cuda:0''' if torch.cuda.is_available() else '''cpu'''     )

   # load pretrained model
   UpperCAmelCase__				:					Optional[int] 					=	load_gpta('''gpt2'''     ).to(_A     )
   print('''computing perplexity on objective set'''     )
   UpperCAmelCase__				:					int 					=	compute_perplexity(_A	,      _A	,      _A     ).item()
   print('''perplexity on objective set:'''	,      _A     )

   # collect igf pairs and save to file demo.jbl
   collect_objective_set(_A	,      _A	,      _A	,      _A	,      _A	,      _A	,      _A	,      _A     )

   # clean up, delete model and data we don't need anymore
   del model, train_data, objective_set
   torch.cuda.empty_cache()







def __UpperCamelCase( _A       :					Dict	,      _A       :					Tuple=15	,      _A       :					str=1_28	,      _A       :					Tuple=1_00	,      _A       :					List[Any]="igf_model.pt"	,      ):
   '''simple docstring'''
   set_seed(42     )

   # Load pre-trained model
   UpperCAmelCase__				:					Dict 					=	GPTaLMHeadModel.from_pretrained('''gpt2'''     )

   # Initialize secondary learner to use embedding weights of model
   UpperCAmelCase__				:					str 					=	SecondaryLearner(_A     )

   # Train secondary learner
   UpperCAmelCase__				:					Optional[int] 					=	train_secondary_learner(
       _A	,      _A	,      max_epochs=_A	,      batch_size=_A	,      eval_freq=1_00	,      igf_model_path=_A	,      )

   del model, secondary_learner_train_data
   torch.cuda.empty_cache()

   return secondary_learner







def __UpperCamelCase( _A       :					List[Any]	,      _A       :					str	,      _A       :					Union[str, Any]	,      _A       :					Optional[int]=32	,      _A       :					Any=10_00	,      _A       :					Tuple=16	,      _A       :					Tuple=1.0	,      _A       :					List[str]=recopy_gpta	,      _A       :					int=None	,      _A       :					Optional[int]=10	,      _A       :					Tuple="gpt2_finetuned.pt"	,      ):
   '''simple docstring'''
   UpperCAmelCase__				:					Dict 					=	torch.device('''cuda:0''' if torch.cuda.is_available() else '''cpu'''     )
   UpperCAmelCase__				:					Union[str, Any] 					=	RandomSampler(_A     )
   UpperCAmelCase__				:					str 					=	DataLoader(_A	,      sampler=_A     )

   UpperCAmelCase__				:					str 					=	max_steps // (len(_A     )) + 1
   UpperCAmelCase__				:					List[Any] 					=	0
   UpperCAmelCase__				:					Tuple 					=	torch.zeros((1, context_len)	,      dtype=torch.long	,      device=_A     )
   UpperCAmelCase__					,   UpperCAmelCase__					,   UpperCAmelCase__				:					Dict 					=	recopy_model(_A	,      _A	,      _A     )

   model.train()
   if secondary_learner is not None:
      secondary_learner.to(_A     )
      secondary_learner.eval()
   UpperCAmelCase__				:					List[str] 					=	[]
   UpperCAmelCase__				:					Tuple 					=	0

   UpperCAmelCase__				:					Union[str, Any] 					=	[]
   UpperCAmelCase__				:					Dict 					=	[]

   # Compute the performance of the transformer model at the beginning
   UpperCAmelCase__				:					Any 					=	compute_perplexity(_A	,      _A	,      _A     )
   test_perps.append(_A     )
   print('''Test perplexity, step'''	,      _A	,      ''':'''	,      _A     )
   for epoch in range(int(_A     )     ):
      for step, example in enumerate(_A     ):
         torch.cuda.empty_cache()
         UpperCAmelCase__				:					Dict 					=	random.randint(0	,      example.size(2     ) - context_len - 1     )
         UpperCAmelCase__				:					Union[str, Any] 					=	example[0, 0, start : start + context_len]
         lm_optimizer.zero_grad()
         UpperCAmelCase__				:					Union[str, Any] 					=	model(_A	,      labels=_A     )
         UpperCAmelCase__				:					Dict 					=	True

         if secondary_learner is not None:
            UpperCAmelCase__				:					Tuple 					=	secondary_learner.forward(
                torch.tensor(_A	,      dtype=torch.long	,      device=_A     ).unsqueeze(0     )     )[0].item()
            observed_qs.append(float(_A     )     )

            # Here we implement the simple non-constant threshold for the predicted IG(X) value
            # We will decay the selectivity of our secondary learner filter from
            # 1 standard deviation above average to 1 below average after 10 batches.

            if global_step == 10:
               UpperCAmelCase__				:					Tuple 					=	-1
            if predicted_q < threshold:
               UpperCAmelCase__				:					Optional[int] 					=	False

            # If we passed the filter, add the context to the batch!
         if do_backprop:
            contexts.append(np.array(context.cpu()     )     )
            UpperCAmelCase__				:					Tuple 					=	outputs[0]
            lm_loss.backward()
            examples += 1

         del outputs

         # Once the batch is filled with enough contexts, backprop on the batch.
         if examples == batch_size:
            torch.cuda.empty_cache()
            UpperCAmelCase__				:					Optional[Any] 					=	0
            # Do LM backprop
            torch.nn.utils.clip_grad_norm_(model.parameters()	,      3.0     )
            lm_optimizer.step()
            lm_scheduler.step()  # Update learning rate schedule
            global_step += 1
            # Compute the performance of the transformer model at this batch
            if global_step % eval_interval == 0:
               UpperCAmelCase__				:					str 					=	compute_perplexity(_A	,      _A	,      _A     )
               test_perps.append(_A     )

               print('''Test perplexity, step'''	,      _A	,      ''':'''	,      _A     )
            # Break out of the loop after 60 batches
         if max_steps > 0 and global_step > 60:
            break
      if max_steps > 0 and global_step > 60:
         break

    # save finetuned transformer model
   torch.save(model.state_dict()	,      _A     )
   torch.cuda.empty_cache()
   # Do some cleaning up so we can reinitialize for the next run of this function
   del lm_optimizer
   del lm_scheduler
   return model







def __UpperCamelCase( ):
   '''simple docstring'''
   UpperCAmelCase__				:					Union[str, Any] 					=	argparse.ArgumentParser(description='''Fine-tune a transformer model with IGF on a language modeling task'''     )

   # Required parameters
   parser.add_argument(
       '''--data_dir'''	,      default=_A	,      type=_A	,      required=_A	,      help='''The input data dir. Should contain data files for WikiText.'''	,      )
   parser.add_argument(
       '''--model_name_or_path'''	,      default=_A	,      type=_A	,      required=_A	,      help='''Path to pretrained model or model identifier from huggingface.co/models'''	,      )
   parser.add_argument(
       '''--data_file'''	,      type=_A	,      default=_A	,      help=(
           '''A jbl file containing tokenized data which can be split as objective dataset, '''
           '''train_dataset and test_dataset.'''
       )	,      )

   parser.add_argument(
       '''--igf_data_file'''	,      type=_A	,      default=_A	,      help='''A jbl file containing the context and information gain pairs to train secondary learner.'''	,      )

   parser.add_argument(
       '''--output_dir'''	,      default=_A	,      type=_A	,      required=_A	,      help='''The output directory where the final fine-tuned model is stored.'''	,      )

   parser.add_argument(
       '''--tokenizer_name'''	,      default=_A	,      type=_A	,      help='''Pretrained tokenizer name or path if not the same as model_name'''	,      )
   parser.add_argument('''--seed'''	,      type=_A	,      default=_A	,      help='''A seed for reproducible training.'''     )

   parser.add_argument(
       '''--context_len'''	,      default=32	,      type=_A	,      help=(
           '''The maximum total input sequence length after tokenization. Sequences longer '''
           '''than this will be truncated, sequences shorter will be padded.'''
       )	,      )

   parser.add_argument(
       '''--size_objective_set'''	,      default=1_00	,      type=_A	,      help='''number of articles that are long enough to be used as our objective set'''	,      )
   parser.add_argument(
       '''--eval_freq'''	,      default=1_00	,      type=_A	,      help='''secondary model evaluation is triggered at eval_freq'''     )

   parser.add_argument('''--max_steps'''	,      default=10_00	,      type=_A	,      help='''To calculate training epochs'''     )

   parser.add_argument(
       '''--secondary_learner_batch_size'''	,      default=1_28	,      type=_A	,      help='''batch size of training data for secondary learner'''	,      )

   parser.add_argument(
       '''--batch_size'''	,      default=16	,      type=_A	,      help='''batch size of training data of language model(gpt2) '''     )

   parser.add_argument(
       '''--eval_interval'''	,      default=10	,      type=_A	,      help=(
           '''decay the selectivity of our secondary learner filter from'''
           '''1 standard deviation above average to 1 below average after 10 batches'''
       )	,      )

   parser.add_argument(
       '''--number'''	,      default=1_00	,      type=_A	,      help='''The number of examples split to be used as objective_set/test_data'''     )

   parser.add_argument(
       '''--min_len'''	,      default=10_26	,      type=_A	,      help='''The minimum length of the article to be used as objective set'''     )

   parser.add_argument(
       '''--secondary_learner_max_epochs'''	,      default=15	,      type=_A	,      help='''number of epochs to train secondary learner'''     )

   parser.add_argument('''--trim'''	,      default=_A	,      type=_A	,      help='''truncate the example if it exceeds context length'''     )

   parser.add_argument(
       '''--threshold'''	,      default=1.0	,      type=_A	,      help=(
           '''The threshold value used by secondary learner to filter the train_data and allow only'''
           ''' informative data as input to the model'''
       )	,      )

   parser.add_argument('''--finetuned_model_name'''	,      default='''gpt2_finetuned.pt'''	,      type=_A	,      help='''finetuned_model_name'''     )

   parser.add_argument(
       '''--recopy_model'''	,      default=_A	,      type=_A	,      help='''Reset the model to the original pretrained GPT-2 weights after each iteration'''	,      )

   # function calls
   # Collecting *n* pairs of context and information gain(X, IG(X)) for training the secondary learner
   generate_n_pairs(
       context_len=32	,      max_steps=10	,      size_objective_set=1_00	,      min_len=10_26	,      trim=_A	,      data_file='''data/tokenized_stories_train_wikitext103.jbl'''	,      igf_data_file='''igf_context_pairs.jbl'''	,      )

   # Load train data for secondary learner
   UpperCAmelCase__				:					Any 					=	joblib.load('''data/IGF_values.jbl'''     )

   # Train secondary learner
   UpperCAmelCase__				:					List[str] 					=	training_secondary_learner(
       _A	,      secondary_learner_max_epochs=15	,      secondary_learner_batch_size=1_28	,      eval_freq=1_00	,      igf_model_path='''igf_model.pt'''	,      )

   # load pretrained gpt2 model
   UpperCAmelCase__				:					Union[str, Any] 					=	GPTaLMHeadModel.from_pretrained('''gpt2'''     )
   set_seed(42     )

   # Generate train and test data to train and evaluate gpt2 model
   UpperCAmelCase__					,   UpperCAmelCase__				:					Any 					=	generate_datasets(
       context_len=32	,      file='''data/tokenized_stories_train_wikitext103.jbl'''	,      number=1_00	,      min_len=10_26	,      trim=_A     )

   # fine-tuning of the gpt2 model using igf (Information Gain Filtration)
   finetune(
       _A	,      _A	,      _A	,      context_len=32	,      max_steps=10_00	,      batch_size=16	,      threshold=1.0	,      recopy_model=_A	,      secondary_learner=_A	,      eval_interval=10	,      finetuned_model_name='''gpt2_finetuned.pt'''	,      )


if __name__ == "__main__":
  main()





'''simple docstring'''

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


UpperCamelCase__  :						Union[str, Any]					=      logging.get_logger(__name__)  # pylint: disable=invalid-name

UpperCamelCase__  :						int					=      '\n    Examples:\n        ```py\n        >>> from diffusers import KandinskyPipeline, KandinskyPriorPipeline\n        >>> import torch\n\n        >>> pipe_prior = KandinskyPriorPipeline.from_pretrained("kandinsky-community/Kandinsky-2-1-prior")\n        >>> pipe_prior.to("cuda")\n\n        >>> prompt = "red cat, 4k photo"\n        >>> out = pipe_prior(prompt)\n        >>> image_emb = out.image_embeds\n        >>> negative_image_emb = out.negative_image_embeds\n\n        >>> pipe = KandinskyPipeline.from_pretrained("kandinsky-community/kandinsky-2-1")\n        >>> pipe.to("cuda")\n\n        >>> image = pipe(\n        ...     prompt,\n        ...     image_embeds=image_emb,\n        ...     negative_image_embeds=negative_image_emb,\n        ...     height=768,\n        ...     width=768,\n        ...     num_inference_steps=100,\n        ... ).images\n\n        >>> image[0].save("cat.png")\n        ```\n'







def __UpperCamelCase( _A       :					List[str]	,      _A       :					Optional[int]	,      _A       :					Dict=8     ):
   '''simple docstring'''
   UpperCAmelCase__				:					Union[str, Any] 					=	h // scale_factor**2
   if h % scale_factor**2 != 0:
      new_h += 1
   UpperCAmelCase__				:					Tuple 					=	w // scale_factor**2
   if w % scale_factor**2 != 0:
      new_w += 1
   return new_h * scale_factor, new_w * scale_factor


class 					_lowercase						(   lowerCAmelCase ):
      '''simple docstring'''


      def __init__(					self       ,lowerCamelCase_       ,lowerCamelCase_       ,lowerCamelCase_       ,lowerCamelCase_       ,lowerCamelCase_       ,)      ->      Optional[Any]:



         '''simple docstring'''



         super().__init__()

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




      def 		lowerCAmelCase__       (					self       ,lowerCamelCase_       ,lowerCamelCase_       ,lowerCamelCase_       ,lowerCamelCase_       ,lowerCamelCase_       ,lowerCamelCase_				)      ->      Any:



         '''simple docstring'''



         if latents is None:
            UpperCAmelCase__				:					Dict 					=	randn_tensor(lowerCamelCase_       ,generator=lowerCamelCase_       ,device=lowerCamelCase_       ,dtype=lowerCamelCase_				)
         else:
            if latents.shape != shape:
               raise ValueError(f'''Unexpected latents shape, got {latents.shape}, expected {shape}'''				)
            UpperCAmelCase__				:					Optional[Any] 					=	latents.to(lowerCamelCase_				)

         UpperCAmelCase__				:					Dict 					=	latents * scheduler.init_noise_sigma
         return latents




      def 		lowerCAmelCase__       (					self       ,lowerCamelCase_       ,lowerCamelCase_       ,lowerCamelCase_       ,lowerCamelCase_       ,lowerCamelCase_=None       ,)      ->      List[Any]:



         '''simple docstring'''



         UpperCAmelCase__				:					int 					=	len(lowerCamelCase_				) if isinstance(lowerCamelCase_       ,lowerCamelCase_				) else 1
         # get prompt text embeddings
         UpperCAmelCase__				:					Tuple 					=	self.tokenizer(
             lowerCamelCase_       ,padding='''max_length'''       ,truncation=lowerCamelCase_       ,max_length=77       ,return_attention_mask=lowerCamelCase_       ,add_special_tokens=lowerCamelCase_       ,return_tensors='''pt'''       ,)

         UpperCAmelCase__				:					List[Any] 					=	text_inputs.input_ids
         UpperCAmelCase__				:					List[str] 					=	self.tokenizer(lowerCamelCase_       ,padding='''longest'''       ,return_tensors='''pt'''				).input_ids

         if untruncated_ids.shape[-1] >= text_input_ids.shape[-1] and not torch.equal(lowerCamelCase_       ,lowerCamelCase_				):
            UpperCAmelCase__				:					str 					=	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}'''				)

         UpperCAmelCase__				:					Tuple 					=	text_input_ids.to(lowerCamelCase_				)
         UpperCAmelCase__				:					Union[str, Any] 					=	text_inputs.attention_mask.to(lowerCamelCase_				)

         UpperCAmelCase__					,   UpperCAmelCase__				:					Optional[Any] 					=	self.text_encoder(
             input_ids=lowerCamelCase_       ,attention_mask=lowerCamelCase_				)

         UpperCAmelCase__				:					Tuple 					=	prompt_embeds.repeat_interleave(lowerCamelCase_       ,dim=0				)
         UpperCAmelCase__				:					List[str] 					=	text_encoder_hidden_states.repeat_interleave(lowerCamelCase_       ,dim=0				)
         UpperCAmelCase__				:					str 					=	text_mask.repeat_interleave(lowerCamelCase_       ,dim=0				)

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

            UpperCAmelCase__				:					Union[str, Any] 					=	self.tokenizer(
                lowerCamelCase_       ,padding='''max_length'''       ,max_length=77       ,truncation=lowerCamelCase_       ,return_attention_mask=lowerCamelCase_       ,add_special_tokens=lowerCamelCase_       ,return_tensors='''pt'''       ,)
            UpperCAmelCase__				:					Optional[Any] 					=	uncond_input.input_ids.to(lowerCamelCase_				)
            UpperCAmelCase__				:					List[str] 					=	uncond_input.attention_mask.to(lowerCamelCase_				)

            UpperCAmelCase__					,   UpperCAmelCase__				:					Any 					=	self.text_encoder(
                input_ids=lowerCamelCase_       ,attention_mask=lowerCamelCase_				)

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

            UpperCAmelCase__				:					Optional[int] 					=	negative_prompt_embeds.shape[1]
            UpperCAmelCase__				:					List[Any] 					=	negative_prompt_embeds.repeat(1       ,lowerCamelCase_				)
            UpperCAmelCase__				:					List[Any] 					=	negative_prompt_embeds.view(batch_size * num_images_per_prompt       ,lowerCamelCase_				)

            UpperCAmelCase__				:					int 					=	uncond_text_encoder_hidden_states.shape[1]
            UpperCAmelCase__				:					int 					=	uncond_text_encoder_hidden_states.repeat(1       ,lowerCamelCase_       ,1				)
            UpperCAmelCase__				:					List[str] 					=	uncond_text_encoder_hidden_states.view(
                batch_size * num_images_per_prompt       ,lowerCamelCase_       ,-1				)
            UpperCAmelCase__				:					Union[str, Any] 					=	uncond_text_mask.repeat_interleave(lowerCamelCase_       ,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
            UpperCAmelCase__				:					str 					=	torch.cat([negative_prompt_embeds, prompt_embeds]				)
            UpperCAmelCase__				:					str 					=	torch.cat([uncond_text_encoder_hidden_states, text_encoder_hidden_states]				)

            UpperCAmelCase__				:					List[str] 					=	torch.cat([uncond_text_mask, text_mask]				)

         return prompt_embeds, text_encoder_hidden_states, text_mask




      def 		lowerCAmelCase__       (					self       ,lowerCamelCase_=0				)      ->      List[str]:



         '''simple docstring'''



         if is_accelerate_available():
            from accelerate import cpu_offload
         else:
            raise ImportError('''Please install accelerate via `pip install accelerate`'''				)

         UpperCAmelCase__				:					Dict 					=	torch.device(f'''cuda:{gpu_id}'''				)

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




      def 		lowerCAmelCase__       (					self       ,lowerCamelCase_=0				)      ->      Union[str, Any]:



         '''simple docstring'''



         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.'''				)

         UpperCAmelCase__				:					str 					=	torch.device(f'''cuda:{gpu_id}'''				)

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

         UpperCAmelCase__				:					Optional[Any] 					=	None
         for cpu_offloaded_model in [self.text_encoder, self.unet, self.movq]:
            UpperCAmelCase__					,   UpperCAmelCase__				:					Dict 					=	cpu_offload_with_hook(lowerCamelCase_       ,lowerCamelCase_       ,prev_module_hook=lowerCamelCase_				)

         if self.safety_checker is not None:
            UpperCAmelCase__					,   UpperCAmelCase__				:					Optional[int] 					=	cpu_offload_with_hook(self.safety_checker       ,lowerCamelCase_       ,prev_module_hook=lowerCamelCase_				)

         # We'll offload the last model manually.
         UpperCAmelCase__				:					str 					=	hook




      @property
      # Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.StableDiffusionPipeline._execution_device
      def 		lowerCAmelCase__       (					self				)      ->      Optional[Any]:



         '''simple docstring'''



         if not hasattr(self.unet       ,'''_hf_hook'''				):
            return self.device
         for module in self.unet.modules():
            if (
                hasattr(lowerCamelCase_       ,'''_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(lowerCamelCase_				)
      def __call__(					self       ,lowerCamelCase_       ,lowerCamelCase_       ,lowerCamelCase_       ,lowerCamelCase_ = None       ,lowerCamelCase_ = 512       ,lowerCamelCase_ = 512       ,lowerCamelCase_ = 100       ,lowerCamelCase_ = 4.0       ,lowerCamelCase_ = 1       ,lowerCamelCase_ = None       ,lowerCamelCase_ = None       ,lowerCamelCase_ = "pil"       ,lowerCamelCase_ = True       ,)      ->      Optional[Any]:



         '''simple docstring'''



         if isinstance(lowerCamelCase_       ,lowerCamelCase_				):
            UpperCAmelCase__				:					List[Any] 					=	1
         elif isinstance(lowerCamelCase_       ,lowerCamelCase_				):
            UpperCAmelCase__				:					Union[str, Any] 					=	len(lowerCamelCase_				)
         else:
            raise ValueError(f'''`prompt` has to be of type `str` or `list` but is {type(lowerCamelCase_				)}'''				)

         UpperCAmelCase__				:					Union[str, Any] 					=	self._execution_device

         UpperCAmelCase__				:					Optional[int] 					=	batch_size * num_images_per_prompt
         UpperCAmelCase__				:					Dict 					=	guidance_scale > 1.0

         UpperCAmelCase__					,   UpperCAmelCase__					,   UpperCAmelCase__				:					Optional[int] 					=	self._encode_prompt(
             lowerCamelCase_       ,lowerCamelCase_       ,lowerCamelCase_       ,lowerCamelCase_       ,lowerCamelCase_				)

         if isinstance(lowerCamelCase_       ,lowerCamelCase_				):
            UpperCAmelCase__				:					List[str] 					=	torch.cat(lowerCamelCase_       ,dim=0				)
         if isinstance(lowerCamelCase_       ,lowerCamelCase_				):
            UpperCAmelCase__				:					int 					=	torch.cat(lowerCamelCase_       ,dim=0				)

         if do_classifier_free_guidance:
            UpperCAmelCase__				:					Optional[Any] 					=	image_embeds.repeat_interleave(lowerCamelCase_       ,dim=0				)
            UpperCAmelCase__				:					Optional[Any] 					=	negative_image_embeds.repeat_interleave(lowerCamelCase_       ,dim=0				)

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

         self.scheduler.set_timesteps(lowerCamelCase_       ,device=lowerCamelCase_				)
         UpperCAmelCase__				:					Union[str, Any] 					=	self.scheduler.timesteps

         UpperCAmelCase__				:					List[Any] 					=	self.unet.config.in_channels

         UpperCAmelCase__					,   UpperCAmelCase__				:					Tuple 					=	get_new_h_w(lowerCamelCase_       ,lowerCamelCase_       ,self.movq_scale_factor				)

         # create initial latent
         UpperCAmelCase__				:					Optional[Any] 					=	self.prepare_latents(
             (batch_size, num_channels_latents, height, width)       ,text_encoder_hidden_states.dtype       ,lowerCamelCase_       ,lowerCamelCase_       ,lowerCamelCase_       ,self.scheduler       ,)

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

            UpperCAmelCase__				:					Tuple 					=	{'''text_embeds''': prompt_embeds, '''image_embeds''': image_embeds}
            UpperCAmelCase__				:					int 					=	self.unet(
                sample=lowerCamelCase_       ,timestep=lowerCamelCase_       ,encoder_hidden_states=lowerCamelCase_       ,added_cond_kwargs=lowerCamelCase_       ,return_dict=lowerCamelCase_       ,)[0]

            if do_classifier_free_guidance:
               UpperCAmelCase__					,   UpperCAmelCase__				:					Optional[int] 					=	noise_pred.split(latents.shape[1]       ,dim=1				)
               UpperCAmelCase__					,   UpperCAmelCase__				:					Any 					=	noise_pred.chunk(2				)
               UpperCAmelCase__					,   UpperCAmelCase__				:					Union[str, Any] 					=	variance_pred.chunk(2				)
               UpperCAmelCase__				:					Tuple 					=	noise_pred_uncond + guidance_scale * (noise_pred_text - noise_pred_uncond)
               UpperCAmelCase__				:					List[str] 					=	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"]
            ):
               UpperCAmelCase__					,   UpperCAmelCase__				:					Union[str, Any] 					=	noise_pred.split(latents.shape[1]       ,dim=1				)

            # compute the previous noisy sample x_t -> x_t-1
            UpperCAmelCase__				:					Tuple 					=	self.scheduler.step(
                lowerCamelCase_       ,lowerCamelCase_       ,lowerCamelCase_       ,generator=lowerCamelCase_       ,).prev_sample
         # post-processing
         UpperCAmelCase__				:					Optional[int] 					=	self.movq.decode(lowerCamelCase_       ,force_not_quantize=lowerCamelCase_				)['''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"]:
            UpperCAmelCase__				:					Optional[Any] 					=	image * 0.5 + 0.5
            UpperCAmelCase__				:					Any 					=	image.clamp(0       ,1				)
            UpperCAmelCase__				:					str 					=	image.cpu().permute(0       ,2       ,3       ,1				).float().numpy()

         if output_type == "pil":
            UpperCAmelCase__				:					List[Any] 					=	self.numpy_to_pil(lowerCamelCase_				)

         if not return_dict:
            return (image,)

         return ImagePipelineOutput(images=lowerCamelCase_				)




