





import inspect
import os
from argparse import ArgumentParser, Namespace
from importlib import import_module

import huggingface_hub
import numpy as np
from packaging import version

from .. import (
    FEATURE_EXTRACTOR_MAPPING,
    IMAGE_PROCESSOR_MAPPING,
    PROCESSOR_MAPPING,
    TOKENIZER_MAPPING,
    AutoConfig,
    AutoFeatureExtractor,
    AutoImageProcessor,
    AutoProcessor,
    AutoTokenizer,
    is_datasets_available,
    is_tf_available,
    is_torch_available,
)
from ..utils import TF2_WEIGHTS_INDEX_NAME, TF2_WEIGHTS_NAME, logging
from . import BaseTransformersCLICommand


if is_tf_available():
   import tensorflow as tf

   tf.config.experimental.enable_tensor_float_aa_execution(False)

if is_torch_available():
   import torch

if is_datasets_available():
   from datasets import load_dataset


A__:  Union[str, Any]       					=					5e-5  # larger error tolerance than in our internal tests, to avoid flaky user-facing errors



def 							lowerCAmelCase_				(    A_):
    return PTtoTFCommand(
        args.model_name  ,args.local_dir  ,args.max_error  ,args.new_weights  ,args.no_pr  ,args.push  ,args.extra_commit_description  ,args.override_model_class  ,)




class    _a  (  UpperCamelCase__):

      """simple docstring"""


      @staticmethod
      def 	UpperCAmelCase_   (						__lowerCamelCase:	ArgumentParser			):
          '''simple docstring'''


          UpperCamelCase__:					str												=      parser.add_parser(
              "pt-to-tf"					,  help=(
                  "CLI tool to run convert a transformers model from a PyTorch checkpoint to a TensorFlow checkpoint."
                  " Can also be used to validate existing weights without opening PRs, with --no-pr."
              )					,  )
          train_parser.add_argument(
              "--model-name"					,  type=__lowerCamelCase					,  required=__lowerCamelCase					,  help="The model name, including owner/organization, as seen on the hub."					,  )
          train_parser.add_argument(
              "--local-dir"					,  type=__lowerCamelCase					,  default=""					,  help="Optional local directory of the model repository. Defaults to /tmp/{model_name}"					,  )
          train_parser.add_argument(
              "--max-error"					,  type=__lowerCamelCase					,  default=__lowerCamelCase					,  help=(
                  F"Maximum error tolerance. Defaults to {MAX_ERROR}. This flag should be avoided, use at your own risk."
              )					,  )
          train_parser.add_argument(
              "--new-weights"					,  action="store_true"					,  help="Optional flag to create new TensorFlow weights, even if they already exist."					,  )
          train_parser.add_argument(
              "--no-pr"					,  action="store_true"					,  help="Optional flag to NOT open a PR with converted weights."			)
          train_parser.add_argument(
              "--push"					,  action="store_true"					,  help="Optional flag to push the weights directly to `main` (requires permissions)"					,  )
          train_parser.add_argument(
              "--extra-commit-description"					,  type=__lowerCamelCase					,  default=""					,  help="Optional additional commit description to use when opening a PR (e.g. to tag the owner)."					,  )
          train_parser.add_argument(
              "--override-model-class"					,  type=__lowerCamelCase					,  default=__lowerCamelCase					,  help="If you think you know better than the auto-detector, you can specify the model class here. "
              "Can be either an AutoModel class or a specific model class like BertForSequenceClassification."					,  )
          train_parser.set_defaults(func=__lowerCamelCase			)






      @staticmethod
      def 	UpperCAmelCase_   (						__lowerCamelCase:	Tuple					,  __lowerCamelCase:	Optional[int]			):
          '''simple docstring'''


          UpperCamelCase__:					str												=      set(pt_outputs.keys()			)
          UpperCamelCase__:					Dict												=      set(tf_outputs.keys()			)
          if pt_out_attrs != tf_out_attrs:
              raise ValueError(
                  F"The model outputs have different attributes, aborting. (Pytorch: {pt_out_attrs}, TensorFlow:"
                  F" {tf_out_attrs})"			)

          # 2. For each output attribute, computes the difference
          def _find_pt_tf_differences(__lowerCamelCase:	Optional[Any]					,  __lowerCamelCase:	Tuple					,  __lowerCamelCase:	str					,  __lowerCamelCase:	List[str]=""			):
              # If the current attribute is a tensor, it is a leaf and we make the comparison. Otherwise, we will dig in
              # recursivelly, keeping the name of the attribute.
              if isinstance(__lowerCamelCase					,  torch.Tensor			):
                  UpperCamelCase__:					Any												=      np.max(np.abs(pt_out.numpy() - tf_out.numpy()			)			)
                  UpperCamelCase__:					Any												=      tensor_difference
              else:
                  UpperCamelCase__:					Optional[int]												=      attr_name
                  for i, pt_item in enumerate(__lowerCamelCase			):
                      # If it is a named attribute, we keep the name. Otherwise, just its index.
                      if isinstance(__lowerCamelCase					,  __lowerCamelCase			):
                          UpperCamelCase__:					Dict												=      root_name + pt_item
                          UpperCamelCase__:					List[Any]												=      tf_out[pt_item]
                          UpperCamelCase__:					List[Any]												=      pt_out[pt_item]
                      else:
                          UpperCamelCase__:					Optional[int]												=      root_name + F"[{i}]"
                          UpperCamelCase__:					List[Any]												=      tf_out[i]
                      UpperCamelCase__:					List[Any]												=      _find_pt_tf_differences(__lowerCamelCase					,  __lowerCamelCase					,  __lowerCamelCase					,  __lowerCamelCase			)

              return differences

          return _find_pt_tf_differences(__lowerCamelCase					,  __lowerCamelCase					,  {}			)






      def __init__(						self:	Dict					,  __lowerCamelCase:	str					,  __lowerCamelCase:	str					,  __lowerCamelCase:	float					,  __lowerCamelCase:	bool					,  __lowerCamelCase:	bool					,  __lowerCamelCase:	bool					,  __lowerCamelCase:	str					,  __lowerCamelCase:	str					,  *__lowerCamelCase:	Optional[Any]					,  ):
          '''simple docstring'''


          UpperCamelCase__:					Tuple												=      logging.get_logger("transformers-cli/pt_to_tf"			)
          UpperCamelCase__:					Tuple												=      model_name
          UpperCamelCase__:					List[str]												=      local_dir if local_dir else os.path.join("/tmp"					,  __lowerCamelCase			)
          UpperCamelCase__:					str												=      max_error
          UpperCamelCase__:					Dict												=      new_weights
          UpperCamelCase__:					Optional[Any]												=      no_pr
          UpperCamelCase__:					Optional[Any]												=      push
          UpperCamelCase__:					int												=      extra_commit_description
          UpperCamelCase__:					Any												=      override_model_class






      def 	UpperCAmelCase_   (						self:	Tuple					,  __lowerCamelCase:	str					,  __lowerCamelCase:	Optional[Any]					,  __lowerCamelCase:	Optional[Any]			):
          '''simple docstring'''


          def _get_audio_input():
              UpperCamelCase__:					Dict												=      load_dataset("hf-internal-testing/librispeech_asr_dummy"					,  "clean"					,  split="validation"			)
              UpperCamelCase__:					List[Any]												=      ds.sort("id"			).select(range(2			)			)[:2]["audio"]
              UpperCamelCase__:					List[Any]												=      [x["array"] for x in speech_samples]
              return raw_samples

          UpperCamelCase__:					List[str]												=      type(pt_model.config			)
          if model_config_class in PROCESSOR_MAPPING:
              UpperCamelCase__:					Optional[int]												=      AutoProcessor.from_pretrained(self._local_dir			)
              if model_config_class in TOKENIZER_MAPPING and processor.tokenizer.pad_token is None:
                  UpperCamelCase__:					Any												=      processor.tokenizer.eos_token
          elif model_config_class in IMAGE_PROCESSOR_MAPPING:
              UpperCamelCase__:					int												=      AutoImageProcessor.from_pretrained(self._local_dir			)
          elif model_config_class in FEATURE_EXTRACTOR_MAPPING:
              UpperCamelCase__:					Tuple												=      AutoFeatureExtractor.from_pretrained(self._local_dir			)
          elif model_config_class in TOKENIZER_MAPPING:
              UpperCamelCase__:					str												=      AutoTokenizer.from_pretrained(self._local_dir			)
              if processor.pad_token is None:
                  UpperCamelCase__:					List[Any]												=      processor.eos_token
          else:
              raise ValueError(F"Unknown data processing type (model config type: {model_config_class})"			)

          UpperCamelCase__:					Optional[Any]												=      set(inspect.signature(pt_model.forward			).parameters.keys()			)
          UpperCamelCase__:					List[str]												=      {}
          if "input_ids" in model_forward_signature:
              processor_inputs.update(
                  {
                      "text": ["Hi there!", "I am a batch with more than one row and different input lengths."],
                      "padding": True,
                      "truncation": True,
                  }			)
          if "pixel_values" in model_forward_signature:
              UpperCamelCase__:					str												=      load_dataset("cifar10"					,  "plain_text"					,  split="test"			)[:2]["img"]
              processor_inputs.update({"images": sample_images}			)
          if "input_features" in model_forward_signature:
              UpperCamelCase__:					List[str]												=      inspect.signature(processor.feature_extractor			).parameters
              # Pad to the largest input length by default but take feature extractor default
              # padding value if it exists e.g. "max_length" and is not False or None
              if "padding" in feature_extractor_signature:
                  UpperCamelCase__:					List[Any]												=      feature_extractor_signature["padding"].default
                  if default_strategy is not False and default_strategy is not None:
                      UpperCamelCase__:					List[Any]												=      default_strategy
                  else:
                      UpperCamelCase__:					List[str]												=      True
              else:
                  UpperCamelCase__:					Union[str, Any]												=      True
              processor_inputs.update({"audio": _get_audio_input(), "padding": padding_strategy}			)
          if "input_values" in model_forward_signature:  # Wav2Vec2 audio input
              processor_inputs.update({"audio": _get_audio_input(), "padding": True}			)
          UpperCamelCase__:					Optional[Any]												=      processor(**__lowerCamelCase					,  return_tensors="pt"			)
          UpperCamelCase__:					str												=      processor(**__lowerCamelCase					,  return_tensors="tf"			)

          # Extra input requirements, in addition to the input modality
          if (
              config.is_encoder_decoder
              or (hasattr(__lowerCamelCase					,  "encoder"			) and hasattr(__lowerCamelCase					,  "decoder"			))
              or "decoder_input_ids" in tf_dummy_inputs
          ):
              UpperCamelCase__:					Optional[int]												=      np.asarray([[1], [1]]					,  dtype=__lowerCamelCase			) * (pt_model.config.decoder_start_token_id or 0)
              pt_input.update({"decoder_input_ids": torch.tensor(__lowerCamelCase			)}			)
              tf_input.update({"decoder_input_ids": tf.convert_to_tensor(__lowerCamelCase			)}			)

          return pt_input, tf_input






      def 	UpperCAmelCase_   (						self:	Optional[Any]			):
          '''simple docstring'''


          if version.parse(huggingface_hub.__version__			) < version.parse("0.9.0"			):
              raise ImportError(
                  "The huggingface_hub version must be >= 0.9.0 to use this command. Please update your huggingface_hub"
                  " installation."			)
          else:
              from huggingface_hub import Repository, create_commit
              from huggingface_hub._commit_api import CommitOperationAdd

          # Fetch remote data
          UpperCamelCase__:					int												=      Repository(local_dir=self._local_dir					,  clone_from=self._model_name			)

          # Load config and get the appropriate architecture -- the latter is needed to convert the head's weights
          UpperCamelCase__:					Optional[Any]												=      AutoConfig.from_pretrained(self._local_dir			)
          UpperCamelCase__:					Optional[int]												=      config.architectures
          if self._override_model_class is not None:
              if self._override_model_class.startswith("TF"			):
                  UpperCamelCase__:					Tuple												=      [self._override_model_class[2:]]
              else:
                  UpperCamelCase__:					List[Any]												=      [self._override_model_class]
              try:
                  UpperCamelCase__:					Dict												=      getattr(import_module("transformers"			)					,  architectures[0]			)
              except AttributeError:
                  raise ValueError(F"Model class {self._override_model_class} not found in transformers."			)
              try:
                  UpperCamelCase__:					str												=      getattr(import_module("transformers"			)					,  "TF" + architectures[0]			)
              except AttributeError:
                  raise ValueError(F"TF model class TF{self._override_model_class} not found in transformers."			)
          elif architectures is None:  # No architecture defined -- use auto classes
              UpperCamelCase__:					Any												=      getattr(import_module("transformers"			)					,  "AutoModel"			)
              UpperCamelCase__:					Union[str, Any]												=      getattr(import_module("transformers"			)					,  "TFAutoModel"			)
              self._logger.warning("No detected architecture, using AutoModel/TFAutoModel"			)
          else:  # Architecture defined -- use it
              if len(__lowerCamelCase			) > 1:
                  raise ValueError(F"More than one architecture was found, aborting. (architectures = {architectures})"			)
              self._logger.warning(F"Detected architecture: {architectures[0]}"			)
              UpperCamelCase__:					List[Any]												=      getattr(import_module("transformers"			)					,  architectures[0]			)
              try:
                  UpperCamelCase__:					str												=      getattr(import_module("transformers"			)					,  "TF" + architectures[0]			)
              except AttributeError:
                  raise AttributeError(F"The TensorFlow equivalent of {architectures[0]} doesn't exist in transformers."			)

        # Check the TF dummy inputs to see what keys we need in the forward pass
          UpperCamelCase__:					List[str]												=      tf_class.from_config(__lowerCamelCase			)
          UpperCamelCase__:					Any												=      tf_from_pt_model.dummy_inputs

          del tf_from_pt_model  # Try to keep only one model in memory at a time

          # Load the model and get some basic inputs
          UpperCamelCase__:					List[str]												=      pt_class.from_pretrained(self._local_dir			)
          pt_model.eval()

          UpperCamelCase__							,				UpperCamelCase__:					str												=      self.get_inputs(__lowerCamelCase					,  __lowerCamelCase					,  __lowerCamelCase			)

          with torch.no_grad():
              UpperCamelCase__:					List[str]												=      pt_model(**__lowerCamelCase					,  output_hidden_states=__lowerCamelCase			)
          del pt_model  # will no longer be used, and may have a large memory footprint

          UpperCamelCase__:					Optional[int]												=      tf_class.from_pretrained(self._local_dir					,  from_pt=__lowerCamelCase			)
          UpperCamelCase__:					List[str]												=      tf_from_pt_model(**__lowerCamelCase					,  output_hidden_states=__lowerCamelCase					,  training=__lowerCamelCase			)

          # Confirms that cross loading PT weights into TF worked.
          UpperCamelCase__:					Optional[int]												=      self.find_pt_tf_differences(__lowerCamelCase					,  __lowerCamelCase			)
          UpperCamelCase__:					Tuple												=      {k: v for k, v in crossload_differences.items() if "hidden" not in k}
          UpperCamelCase__:					Optional[int]												=      {k: v for k, v in crossload_differences.items() if "hidden" in k}
          if len(__lowerCamelCase			) == 0 and architectures is not None:
              raise ValueError(
                  F"Something went wrong -- the config file has architectures ({architectures}), but no model head"
                  " output was found. All outputs start with 'hidden'"			)
          UpperCamelCase__:					Union[str, Any]												=      max(output_differences.values()			) if output_differences else 0.0
          UpperCamelCase__:					Optional[Any]												=      max(hidden_differences.values()			)
          if max_crossload_output_diff > self._max_error or max_crossload_hidden_diff > self._max_error:
              raise ValueError(
                  "The cross-loaded TensorFlow model has different outputs, something went wrong!\n"
                  + F"\nList of maximum output differences above the threshold ({self._max_error}):\n"
                  + "\n".join([F"{k}: {v:.3e}" for k, v in output_differences.items() if v > self._max_error]			)
                  + F"\n\nList of maximum hidden layer differences above the threshold ({self._max_error}):\n"
                  + "\n".join([F"{k}: {v:.3e}" for k, v in hidden_differences.items() if v > self._max_error]			)			)

          # Save the weights in a TF format (if needed) and confirms that the results are still good
          UpperCamelCase__:					List[str]												=      os.path.join(self._local_dir					,  __lowerCamelCase			)
          UpperCamelCase__:					Any												=      os.path.join(self._local_dir					,  __lowerCamelCase			)
          if (not os.path.exists(__lowerCamelCase			) and not os.path.exists(__lowerCamelCase			)) or self._new_weights:
              tf_from_pt_model.save_pretrained(self._local_dir			)
          del tf_from_pt_model  # will no longer be used, and may have a large memory footprint

          UpperCamelCase__:					str												=      tf_class.from_pretrained(self._local_dir			)
          UpperCamelCase__:					Optional[int]												=      tf_model(**__lowerCamelCase					,  output_hidden_states=__lowerCamelCase			)

          UpperCamelCase__:					List[Any]												=      self.find_pt_tf_differences(__lowerCamelCase					,  __lowerCamelCase			)
          UpperCamelCase__:					List[Any]												=      {k: v for k, v in conversion_differences.items() if "hidden" not in k}
          UpperCamelCase__:					Tuple												=      {k: v for k, v in conversion_differences.items() if "hidden" in k}
          if len(__lowerCamelCase			) == 0 and architectures is not None:
              raise ValueError(
                  F"Something went wrong -- the config file has architectures ({architectures}), but no model head"
                  " output was found. All outputs start with 'hidden'"			)
          UpperCamelCase__:					Optional[Any]												=      max(output_differences.values()			) if output_differences else 0.0
          UpperCamelCase__:					Union[str, Any]												=      max(hidden_differences.values()			)
          if max_conversion_output_diff > self._max_error or max_conversion_hidden_diff > self._max_error:
              raise ValueError(
                  "The converted TensorFlow model has different outputs, something went wrong!\n"
                  + F"\nList of maximum output differences above the threshold ({self._max_error}):\n"
                  + "\n".join([F"{k}: {v:.3e}" for k, v in output_differences.items() if v > self._max_error]			)
                  + F"\n\nList of maximum hidden layer differences above the threshold ({self._max_error}):\n"
                  + "\n".join([F"{k}: {v:.3e}" for k, v in hidden_differences.items() if v > self._max_error]			)			)

          UpperCamelCase__:					str												=      "Update TF weights" if self._new_weights else "Add TF weights"
          if self._push:
              repo.git_add(auto_lfs_track=__lowerCamelCase			)
              repo.git_commit(__lowerCamelCase			)
              repo.git_push(blocking=__lowerCamelCase			)  # this prints a progress bar with the upload
              self._logger.warning(F"TF weights pushed into {self._model_name}"			)
          elif not self._no_pr:
              self._logger.warning("Uploading the weights into a new PR..."			)
              UpperCamelCase__:					Tuple												=      (
                  "Model converted by the [`transformers`' `pt_to_tf`"
                  " CLI](https://github.com/huggingface/transformers/blob/main/src/transformers/commands/pt_to_tf.py). "
                  "All converted model outputs and hidden layers were validated against its PyTorch counterpart.\n\n"
                  F"Maximum crossload output difference={max_crossload_output_diff:.3e}; "
                  F"Maximum crossload hidden layer difference={max_crossload_hidden_diff:.3e};\n"
                  F"Maximum conversion output difference={max_conversion_output_diff:.3e}; "
                  F"Maximum conversion hidden layer difference={max_conversion_hidden_diff:.3e};\n"
              )
              if self._max_error > MAX_ERROR:
                  commit_descrition += (
                      F"\n\nCAUTION: The maximum admissible error was manually increased to {self._max_error}!"
                  )
              if self._extra_commit_description:
                  commit_descrition += "\n\n" + self._extra_commit_description

              # sharded model -> adds all related files (index and .h5 shards)
              if os.path.exists(__lowerCamelCase			):
                  UpperCamelCase__:					Dict												=      [
                      CommitOperationAdd(path_in_repo=__lowerCamelCase					,  path_or_fileobj=__lowerCamelCase			)
                  ]
                  for shard_path in tf.io.gfile.glob(self._local_dir + "/tf_model-*.h5"			):
                      operations += [
                          CommitOperationAdd(path_in_repo=os.path.basename(__lowerCamelCase			)					,  path_or_fileobj=__lowerCamelCase			)
                      ]
              else:
                  UpperCamelCase__:					int												=      [CommitOperationAdd(path_in_repo=__lowerCamelCase					,  path_or_fileobj=__lowerCamelCase			)]

              UpperCamelCase__:					Union[str, Any]												=      create_commit(
                  repo_id=self._model_name					,  operations=__lowerCamelCase					,  commit_message=__lowerCamelCase					,  commit_description=__lowerCamelCase					,  repo_type="model"					,  create_pr=__lowerCamelCase					,  ).pr_url
              self._logger.warning(F"PR open in {hub_pr_url}"			)








from manim import *




class    _a  (  UpperCamelCase__):

      """simple docstring"""


      def 	UpperCAmelCase_   (						self:	str			):
          '''simple docstring'''


          UpperCamelCase__:					Optional[Any]												=      Rectangle(height=0.5					,  width=0.5			)
          UpperCamelCase__:					Optional[int]												=      Rectangle(height=0.46					,  width=0.46			).set_stroke(width=0			)
          UpperCamelCase__:					List[Any]												=      Rectangle(height=0.25					,  width=0.25			)

          UpperCamelCase__:					Tuple												=      [mem.copy() for i in range(6			)]
          UpperCamelCase__:					Dict												=      [mem.copy() for i in range(6			)]
          UpperCamelCase__:					Dict												=      VGroup(*__lowerCamelCase			).arrange(__lowerCamelCase					,  buff=0			)
          UpperCamelCase__:					List[Any]												=      VGroup(*__lowerCamelCase			).arrange(__lowerCamelCase					,  buff=0			)
          UpperCamelCase__:					List[Any]												=      VGroup(__lowerCamelCase					,  __lowerCamelCase			).arrange(__lowerCamelCase					,  buff=0			)
          UpperCamelCase__:					List[str]												=      Text("CPU"					,  font_size=24			)
          UpperCamelCase__:					Optional[int]												=      Group(__lowerCamelCase					,  __lowerCamelCase			).arrange(__lowerCamelCase					,  buff=0.5					,  aligned_edge=__lowerCamelCase			)
          cpu.move_to([-2.5, -0.5, 0]			)
          self.add(__lowerCamelCase			)

          UpperCamelCase__:					Dict												=      [mem.copy() for i in range(4			)]
          UpperCamelCase__:					Any												=      VGroup(*__lowerCamelCase			).arrange(__lowerCamelCase					,  buff=0			)
          UpperCamelCase__:					str												=      Text("GPU"					,  font_size=24			)
          UpperCamelCase__:					List[Any]												=      Group(__lowerCamelCase					,  __lowerCamelCase			).arrange(__lowerCamelCase					,  buff=0.5					,  aligned_edge=__lowerCamelCase			)
          gpu.move_to([-1, -1, 0]			)
          self.add(__lowerCamelCase			)

          UpperCamelCase__:					str												=      [mem.copy() for i in range(6			)]
          UpperCamelCase__:					Tuple												=      VGroup(*__lowerCamelCase			).arrange(__lowerCamelCase					,  buff=0			)

          UpperCamelCase__:					Union[str, Any]												=      Text("Model"					,  font_size=24			)
          UpperCamelCase__:					Tuple												=      Group(__lowerCamelCase					,  __lowerCamelCase			).arrange(__lowerCamelCase					,  buff=0.5					,  aligned_edge=__lowerCamelCase			)
          model.move_to([3, -1.0, 0]			)
          self.add(__lowerCamelCase			)

          UpperCamelCase__:					int												=      []
          UpperCamelCase__:					Optional[Any]												=      []

          for i, rect in enumerate(__lowerCamelCase			):
              rect.set_stroke(__lowerCamelCase			)

              UpperCamelCase__:					Tuple												=      Rectangle(height=0.46 / 4					,  width=0.46 / 3			).set_stroke(width=0.0			).set_fill(__lowerCamelCase					,  opacity=0.7			)

              if i == 0:
                  cpu_target.next_to(cpu_left_col_base[0].get_corner(DOWN + LEFT			)					,  buff=0.02					,  direction=__lowerCamelCase			)
                  cpu_target.set_x(cpu_target.get_x() + 0.1			)
              elif i == 3:
                  cpu_target.next_to(model_cpu_arr[0]					,  direction=__lowerCamelCase					,  buff=0.0			)
              else:
                  cpu_target.next_to(model_cpu_arr[i - 1]					,  direction=__lowerCamelCase					,  buff=0.0			)
              self.add(__lowerCamelCase			)
              model_cpu_arr.append(__lowerCamelCase			)

          self.add(*__lowerCamelCase					,  *__lowerCamelCase			)

          UpperCamelCase__:					int												=      [meta_mem.copy() for i in range(6			)]
          UpperCamelCase__:					Dict												=      [meta_mem.copy() for i in range(6			)]
          UpperCamelCase__:					Union[str, Any]												=      VGroup(*__lowerCamelCase			).arrange(__lowerCamelCase					,  buff=0			)
          UpperCamelCase__:					Tuple												=      VGroup(*__lowerCamelCase			).arrange(__lowerCamelCase					,  buff=0			)
          UpperCamelCase__:					int												=      VGroup(__lowerCamelCase					,  __lowerCamelCase			).arrange(__lowerCamelCase					,  buff=0			)
          UpperCamelCase__:					List[Any]												=      Text("Disk"					,  font_size=24			)
          UpperCamelCase__:					Union[str, Any]												=      Group(__lowerCamelCase					,  __lowerCamelCase			).arrange(__lowerCamelCase					,  buff=0.5					,  aligned_edge=__lowerCamelCase			)
          disk.move_to([-4.0, -1.25, 0]			)
          self.add(__lowerCamelCase					,  __lowerCamelCase			)

          UpperCamelCase__:					Optional[int]												=      []

          for i in range(6			):
              UpperCamelCase__:					List[str]												=      fill.copy().set_fill(__lowerCamelCase					,  opacity=0.8			)
              target.move_to(disk_left_col_base[i]			).scale(0.5			)
              cpu_disk_arr.append(__lowerCamelCase			)

          self.add(*__lowerCamelCase			)

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

          UpperCamelCase__:					str												=      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(__lowerCamelCase					,  __lowerCamelCase			)

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

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

          UpperCamelCase__:					Dict												=      MarkupText(F"The offloaded weights are all sent to the CPU."					,  font_size=24			)
          step_a.move_to([2, 2, 0]			)

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

          for i in range(6			):
              UpperCamelCase__:					List[Any]												=      cpu_disk_arr[i]
              UpperCamelCase__:					Optional[int]												=      rect.copy().set_fill(__lowerCamelCase					,  opacity=0.8			).scale(2.0			)
              cpa.generate_target()
              cpa.target.move_to(model_base[i]			)

              if i == 0:
                  rect.set_fill(__lowerCamelCase					,  opacity=0.8			)
                  rect.generate_target()
                  rect.target.move_to(cpu_left_col_base[0]			).scale(2.0			)

                  self.remove(
                      *__lowerCamelCase					,  *__lowerCamelCase					,  )

              else:
                  rect.generate_target()
                  rect.target.move_to(cpu_left_col_base[i]			).scale(2.0			)
              self.play(MoveToTarget(__lowerCamelCase			)					,  MoveToTarget(__lowerCamelCase			)					,  model_base[i].animate.set_stroke(__lowerCamelCase			)			)
          self.play(FadeOut(__lowerCamelCase			)			)

          UpperCamelCase__:					Dict												=      MarkupText(
              F"Finally, hooks are added to each weight in the model\nto transfer the weights from CPU to GPU\n\t\tand back when needed."					,  font_size=24					,  )
          step_a.move_to([2, 2, 0]			)

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

          UpperCamelCase__:					List[str]												=      []
          UpperCamelCase__:					Optional[Any]												=      []
          for i in range(6			):
              UpperCamelCase__:					List[str]												=      Arrow(start=__lowerCamelCase					,  end=__lowerCamelCase					,  color=__lowerCamelCase					,  buff=0.5			)
              a.next_to(model_base[i].get_left()					,  __lowerCamelCase					,  buff=0.2			)
              arrows.append(__lowerCamelCase			)
              animations.append(Write(__lowerCamelCase			)			)
          self.play(*__lowerCamelCase			)
          self.wait()

