





from manim import *





class 					A_					(   UpperCAmelCase						):







       """simple docstring"""





       def  __UpperCAmelCase			(     self						:						str	)    ->       Union[str, Any]:
         _lowercase						    =			Rectangle(height=0.5    ,width=0.5	)
         _lowercase						    =			Rectangle(height=0.46    ,width=0.46	).set_stroke(width=0	)

         _lowercase						    =			Rectangle(height=0.25    ,width=0.25	)

         _lowercase						    =			[mem.copy() for i in range(6	)]
         _lowercase						    =			[mem.copy() for i in range(6	)]
         _lowercase						    =			VGroup(*__A	).arrange(__A    ,buff=0	)
         _lowercase						    =			VGroup(*__A	).arrange(__A    ,buff=0	)
         _lowercase						    =			VGroup(__A    ,__A	).arrange(__A    ,buff=0	)
         _lowercase						    =			Text('CPU'    ,font_size=24	)
         _lowercase						    =			Group(__A    ,__A	).arrange(__A    ,buff=0.5    ,aligned_edge=__A	)
         cpu.move_to([-2.5, -0.5, 0]	)
         self.add(__A	)

         _lowercase						    =			[mem.copy() for i in range(4	)]
         _lowercase						    =			VGroup(*__A	).arrange(__A    ,buff=0	)
         _lowercase						    =			Text('GPU'    ,font_size=24	)
         _lowercase						    =			Group(__A    ,__A	).arrange(__A    ,buff=0.5    ,aligned_edge=__A	)
         gpu.move_to([-1, -1, 0]	)
         self.add(__A	)

         _lowercase						    =			[mem.copy() for i in range(6	)]
         _lowercase						    =			VGroup(*__A	).arrange(__A    ,buff=0	)

         _lowercase						    =			Text('Model'    ,font_size=24	)
         _lowercase						    =			Group(__A    ,__A	).arrange(__A    ,buff=0.5    ,aligned_edge=__A	)
         model.move_to([3, -1.0, 0]	)
         self.add(__A	)

         _lowercase						    =			[]
         _lowercase						    =			[]

         for i, rect in enumerate(__A	):
           _lowercase						    =			fill.copy().set_fill(__A    ,opacity=0.8	)
           target.move_to(__A	)
           model_arr.append(__A	)

           _lowercase						    =			Rectangle(height=0.46    ,width=0.46	).set_stroke(width=0.0	).set_fill(__A    ,opacity=0.8	)
           cpu_target.move_to(cpu_left_col_base[i]	)
           model_cpu_arr.append(__A	)

         self.add(*__A    ,*__A	)

         _lowercase						    =			[meta_mem.copy() for i in range(6	)]
         _lowercase						    =			[meta_mem.copy() for i in range(6	)]
         _lowercase						    =			VGroup(*__A	).arrange(__A    ,buff=0	)
         _lowercase						    =			VGroup(*__A	).arrange(__A    ,buff=0	)
         _lowercase						    =			VGroup(__A    ,__A	).arrange(__A    ,buff=0	)
         _lowercase						    =			Text('Disk'    ,font_size=24	)
         _lowercase						    =			Group(__A    ,__A	).arrange(__A    ,buff=0.5    ,aligned_edge=__A	)
         disk.move_to([-4, -1.25, 0]	)
         self.add(__A    ,__A	)

         _lowercase						    =			Square(side_length=2.2	)
         key.move_to([-5, 2, 0]	)

         _lowercase						    =			MarkupText(
             F"""<b>Key:</b>\n\n<span fgcolor='{YELLOW}'>●</span> Empty Model"""    ,font_size=18    ,)

         key_text.move_to([-5, 2.4, 0]	)

         self.add(__A    ,__A	)

         _lowercase						    =			MarkupText(
             F"""<span fgcolor='{BLUE}'>●</span> Checkpoint"""    ,font_size=18    ,)

         blue_text.next_to(__A    ,DOWN * 2.4    ,aligned_edge=key_text.get_left()	)
         self.add(__A	)

         _lowercase						    =			MarkupText(
             F"""Now watch as an input is passed through the model\nand how the memory is utilized and handled."""    ,font_size=24    ,)
         step_a.move_to([2, 2, 0]	)

         self.play(Write(__A	)	)

         _lowercase						    =			Square(0.3	)
         input.set_fill(__A    ,opacity=1.0	)
         input.set_stroke(width=0.0	)
         input.next_to(model_base[0]    ,__A    ,buff=0.5	)

         self.play(Write(__A	)	)

         input.generate_target()
         input.target.next_to(model_arr[0]    ,direction=__A    ,buff=0.02	)
         self.play(MoveToTarget(__A	)	)

         self.play(FadeOut(__A	)	)

         _lowercase						    =			Arrow(start=__A    ,end=__A    ,color=__A    ,buff=0.5	)
         a.next_to(model_arr[0].get_left()    ,__A    ,buff=0.2	)

         model_cpu_arr[0].generate_target()
         model_cpu_arr[0].target.move_to(gpu_rect[0]	)

         _lowercase						    =			MarkupText(
             F"""As the input reaches a layer, the hook triggers\nand weights are moved from the CPU\nto the GPU and back."""    ,font_size=24    ,)
         step_a.move_to([2, 2, 0]	)

         self.play(Write(__A    ,run_time=3	)	)

         _lowercase						    =			{'run_time': 1, 'fade_in': True, 'fade_out': True, 'buff': 0.02}

         self.play(
             Write(__A	)    ,Circumscribe(model_arr[0]    ,color=__A    ,**__A	)    ,Circumscribe(model_cpu_arr[0]    ,color=__A    ,**__A	)    ,Circumscribe(gpu_rect[0]    ,color=__A    ,**__A	)    ,)
         self.play(MoveToTarget(model_cpu_arr[0]	)	)

         _lowercase						    =			a.copy()
         for i in range(6	):
           a_c.next_to(model_arr[i].get_right() + 0.02    ,__A    ,buff=0.2	)

           input.generate_target()
           input.target.move_to(model_arr[i].get_right() + 0.02	)

           _lowercase						    =			AnimationGroup(
               FadeOut(__A    ,run_time=0.5	)    ,MoveToTarget(__A    ,run_time=0.5	)    ,FadeIn(__A    ,run_time=0.5	)    ,lag_ratio=0.2	)

           self.play(__A	)

           model_cpu_arr[i].generate_target()
           model_cpu_arr[i].target.move_to(cpu_left_col_base[i]	)

           if i < 5:
             model_cpu_arr[i + 1].generate_target()
             model_cpu_arr[i + 1].target.move_to(gpu_rect[0]	)
             if i >= 1:
               _lowercase						    =			0.7

             self.play(
                 Circumscribe(model_arr[i]    ,**__A	)    ,Circumscribe(cpu_left_col_base[i]    ,**__A	)    ,Circumscribe(cpu_left_col_base[i + 1]    ,color=__A    ,**__A	)    ,Circumscribe(gpu_rect[0]    ,color=__A    ,**__A	)    ,Circumscribe(model_arr[i + 1]    ,color=__A    ,**__A	)    ,)
             if i < 1:
               self.play(
                   MoveToTarget(model_cpu_arr[i]	)    ,MoveToTarget(model_cpu_arr[i + 1]	)    ,)
             else:
               self.play(
                   MoveToTarget(model_cpu_arr[i]    ,run_time=0.7	)    ,MoveToTarget(model_cpu_arr[i + 1]    ,run_time=0.7	)    ,)
           else:
             model_cpu_arr[i].generate_target()
             model_cpu_arr[i].target.move_to(cpu_left_col_base[-1]	)
             input.generate_target()
             input.target.next_to(model_arr[-1].get_right()    ,RIGHT + 0.02    ,buff=0.2	)

             self.play(
                 Circumscribe(model_arr[-1]    ,color=__A    ,**__A	)    ,Circumscribe(cpu_left_col_base[-1]    ,color=__A    ,**__A	)    ,Circumscribe(gpu_rect[0]    ,color=__A    ,**__A	)    ,)

             self.play(MoveToTarget(model_cpu_arr[i]	)	)

           _lowercase						    =			a_c
           _lowercase						    =			a_c.copy()

         input.generate_target()
         input.target.next_to(model_base[-1]    ,RIGHT + 0.02    ,buff=0.5	)
         self.play(
             FadeOut(__A	)    ,FadeOut(__A    ,run_time=0.5	)    ,)

         _lowercase						    =			MarkupText(F"""Inference on a model too large for GPU memory\nis successfully completed."""    ,font_size=24	)
         step_a.move_to([2, 2, 0]	)

         self.play(Write(__A    ,run_time=3	)    ,MoveToTarget(__A	)	)

         self.wait()

'''simple docstring'''
import argparse
from pathlib import Path

import torch
from packaging import version
from torch.onnx import export

from diffusers import AutoencoderKL


lowercase__											=version.parse(version.parse(torch.__version__).base_version) < version.parse('1.11')






def      UpperCamelCase_				(      A__  ,      A__  ,      A__  ,      A__  ,      A__  ,      A__  ,      A__  ,      A__=False  ,      ):
	output_path.parent.mkdir(parents=A__  ,      exist_ok=A__						)
	# PyTorch deprecated the `enable_onnx_checker` and `use_external_data_format` arguments in v1.11,
	# so we check the torch version for backwards compatibility
	if is_torch_less_than_1_11:
		export(
		    A__  ,      A__  ,      f=output_path.as_posix()  ,      input_names=A__  ,      output_names=A__  ,      dynamic_axes=A__  ,      do_constant_folding=A__  ,      use_external_data_format=A__  ,      enable_onnx_checker=A__  ,      opset_version=A__  ,      )
	else:
		export(
		    A__  ,      A__  ,      f=output_path.as_posix()  ,      input_names=A__  ,      output_names=A__  ,      dynamic_axes=A__  ,      do_constant_folding=A__  ,      opset_version=A__  ,      )






@torch.no_grad()
def      UpperCamelCase_				(      A__  ,      A__  ,      A__  ,      A__ = False						):
	a_      				=						torch.floataa if fpaa else torch.floataa
	if fpaa and torch.cuda.is_available():
		a_      				=						"""cuda"""
	elif fpaa and not torch.cuda.is_available():
		raise ValueError("""`float16` model export is only supported on GPUs with CUDA"""						)
	else:
		a_      				=						"""cpu"""
	a_      				=						Path(A__						)

	# VAE DECODER
	a_      				=						AutoencoderKL.from_pretrained(model_path + """/vae"""						)
	a_      				=						vae_decoder.config.latent_channels
	# forward only through the decoder part
	a_      				=						vae_decoder.decode
	onnx_export(
	    A__  ,      model_args=(
	        torch.randn(1  ,      A__  ,      25  ,      25						).to(device=A__  ,      dtype=A__						),
	        False,
	    )  ,      output_path=output_path / """vae_decoder""" / """model.onnx"""  ,      ordered_input_names=["""latent_sample""", """return_dict"""]  ,      output_names=["""sample"""]  ,      dynamic_axes={
	        """latent_sample""": {0: """batch""", 1: """channels""", 2: """height""", 3: """width"""},
	    }  ,      opset=A__  ,      )
	del vae_decoder


if __name__ == "__main__":
		lowercase__											=argparse.ArgumentParser()

		parser.add_argument(
		    '--model_path',
		    type=str,
		    required=True,
		    help='Path to the `diffusers` checkpoint to convert (either a local directory or on the Hub).',
		)

		parser.add_argument('--output_path', type=str, required=True, help='Path to the output model.')
		parser.add_argument(
		    '--opset',
		    default=14,
		    type=int,
		    help='The version of the ONNX operator set to use.',
		)
		parser.add_argument('--fp16', action='store_true', default=False, help='Export the models in `float16` mode')

		lowercase__											=parser.parse_args()
		print(args.output_path)
		convert_models(args.model_path, args.output_path, args.opset, args.fpaa)
		print('SD: Done: ONNX')
