




import argparse
import json
from pathlib import Path

import requests
import torch
from huggingface_hub import cached_download, hf_hub_download, hf_hub_url
from PIL import Image

from transformers import DetaConfig, DetaForObjectDetection, DetaImageProcessor
from transformers.utils import logging


logging.set_verbosity_info()
__A    :				Union[str, Any]    						=	logging.get_logger(__name__)
def        lowerCamelCase_     (     ):
			'''simple docstring'''
			SCREAMING_SNAKE_CASE     =       DetaConfig(
			    num_queries=9_00       ,						encoder_ffn_dim=20_48       ,						decoder_ffn_dim=20_48       ,						num_feature_levels=5       ,						assign_first_stage=__UpperCamelCase       ,						with_box_refine=__UpperCamelCase       ,						two_stage=__UpperCamelCase       ,						)

			# set labels
			SCREAMING_SNAKE_CASE     =       91
			SCREAMING_SNAKE_CASE     =       """huggingface/label-files"""
			SCREAMING_SNAKE_CASE     =       """coco-detection-id2label.json"""
			SCREAMING_SNAKE_CASE     =       json.load(open(cached_download(hf_hub_url(__UpperCamelCase       ,						__UpperCamelCase       ,						repo_type="""dataset""" ) )       ,						"""r""" ) )
			SCREAMING_SNAKE_CASE     =       {int(__UpperCamelCase ): v for k, v in idalabel.items()}
			SCREAMING_SNAKE_CASE     =       idalabel
			SCREAMING_SNAKE_CASE     =       {v: k for k, v in idalabel.items()}

			return config
def        lowerCamelCase_     (     SCREAMING_SNAKE_CASE ):
			'''simple docstring'''
			SCREAMING_SNAKE_CASE     =       []

			# stem
			# fmt: off
			rename_keys.append(("""backbone.0.body.conv1.weight""", """model.backbone.model.embedder.embedder.convolution.weight""") )
			rename_keys.append(("""backbone.0.body.bn1.weight""", """model.backbone.model.embedder.embedder.normalization.weight""") )
			rename_keys.append(("""backbone.0.body.bn1.bias""", """model.backbone.model.embedder.embedder.normalization.bias""") )
			rename_keys.append(("""backbone.0.body.bn1.running_mean""", """model.backbone.model.embedder.embedder.normalization.running_mean""") )
			rename_keys.append(("""backbone.0.body.bn1.running_var""", """model.backbone.model.embedder.embedder.normalization.running_var""") )
			# stages
			for stage_idx in range(len(config.backbone_config.depths ) ):
						for layer_idx in range(config.backbone_config.depths[stage_idx] ):
									# shortcut
									if layer_idx == 0:
												rename_keys.append(
												    (
												        f"""backbone.0.body.layer{stage_idx + 1}.{layer_idx}.downsample.0.weight""",
												        f"""model.backbone.model.encoder.stages.{stage_idx}.layers.{layer_idx}.shortcut.convolution.weight""",
												    ) )
												rename_keys.append(
												    (
												        f"""backbone.0.body.layer{stage_idx + 1}.{layer_idx}.downsample.1.weight""",
												        f"""model.backbone.model.encoder.stages.{stage_idx}.layers.{layer_idx}.shortcut.normalization.weight""",
												    ) )
												rename_keys.append(
												    (
												        f"""backbone.0.body.layer{stage_idx + 1}.{layer_idx}.downsample.1.bias""",
												        f"""model.backbone.model.encoder.stages.{stage_idx}.layers.{layer_idx}.shortcut.normalization.bias""",
												    ) )
												rename_keys.append(
												    (
												        f"""backbone.0.body.layer{stage_idx + 1}.{layer_idx}.downsample.1.running_mean""",
												        f"""model.backbone.model.encoder.stages.{stage_idx}.layers.{layer_idx}.shortcut.normalization.running_mean""",
												    ) )
												rename_keys.append(
												    (
												        f"""backbone.0.body.layer{stage_idx + 1}.{layer_idx}.downsample.1.running_var""",
												        f"""model.backbone.model.encoder.stages.{stage_idx}.layers.{layer_idx}.shortcut.normalization.running_var""",
												    ) )
									# 3 convs
									for i in range(3 ):
												rename_keys.append(
												    (
												        f"""backbone.0.body.layer{stage_idx + 1}.{layer_idx}.conv{i+1}.weight""",
												        f"""model.backbone.model.encoder.stages.{stage_idx}.layers.{layer_idx}.layer.{i}.convolution.weight""",
												    ) )
												rename_keys.append(
												    (
												        f"""backbone.0.body.layer{stage_idx + 1}.{layer_idx}.bn{i+1}.weight""",
												        f"""model.backbone.model.encoder.stages.{stage_idx}.layers.{layer_idx}.layer.{i}.normalization.weight""",
												    ) )
												rename_keys.append(
												    (
												        f"""backbone.0.body.layer{stage_idx + 1}.{layer_idx}.bn{i+1}.bias""",
												        f"""model.backbone.model.encoder.stages.{stage_idx}.layers.{layer_idx}.layer.{i}.normalization.bias""",
												    ) )
												rename_keys.append(
												    (
												        f"""backbone.0.body.layer{stage_idx + 1}.{layer_idx}.bn{i+1}.running_mean""",
												        f"""model.backbone.model.encoder.stages.{stage_idx}.layers.{layer_idx}.layer.{i}.normalization.running_mean""",
												    ) )
												rename_keys.append(
												    (
												        f"""backbone.0.body.layer{stage_idx + 1}.{layer_idx}.bn{i+1}.running_var""",
												        f"""model.backbone.model.encoder.stages.{stage_idx}.layers.{layer_idx}.layer.{i}.normalization.running_var""",
												    ) )
    # transformer encoder
			for i in range(config.encoder_layers ):
						rename_keys.append((f"""transformer.encoder.layers.{i}.self_attn.sampling_offsets.weight""", f"""model.encoder.layers.{i}.self_attn.sampling_offsets.weight""") )
						rename_keys.append((f"""transformer.encoder.layers.{i}.self_attn.sampling_offsets.bias""", f"""model.encoder.layers.{i}.self_attn.sampling_offsets.bias""") )
						rename_keys.append((f"""transformer.encoder.layers.{i}.self_attn.attention_weights.weight""", f"""model.encoder.layers.{i}.self_attn.attention_weights.weight""") )
						rename_keys.append((f"""transformer.encoder.layers.{i}.self_attn.attention_weights.bias""", f"""model.encoder.layers.{i}.self_attn.attention_weights.bias""") )
						rename_keys.append((f"""transformer.encoder.layers.{i}.self_attn.value_proj.weight""", f"""model.encoder.layers.{i}.self_attn.value_proj.weight""") )
						rename_keys.append((f"""transformer.encoder.layers.{i}.self_attn.value_proj.bias""", f"""model.encoder.layers.{i}.self_attn.value_proj.bias""") )
						rename_keys.append((f"""transformer.encoder.layers.{i}.self_attn.output_proj.weight""", f"""model.encoder.layers.{i}.self_attn.output_proj.weight""") )
						rename_keys.append((f"""transformer.encoder.layers.{i}.self_attn.output_proj.bias""", f"""model.encoder.layers.{i}.self_attn.output_proj.bias""") )
						rename_keys.append((f"""transformer.encoder.layers.{i}.norm1.weight""", f"""model.encoder.layers.{i}.self_attn_layer_norm.weight""") )
						rename_keys.append((f"""transformer.encoder.layers.{i}.norm1.bias""", f"""model.encoder.layers.{i}.self_attn_layer_norm.bias""") )
						rename_keys.append((f"""transformer.encoder.layers.{i}.linear1.weight""", f"""model.encoder.layers.{i}.fc1.weight""") )
						rename_keys.append((f"""transformer.encoder.layers.{i}.linear1.bias""", f"""model.encoder.layers.{i}.fc1.bias""") )
						rename_keys.append((f"""transformer.encoder.layers.{i}.linear2.weight""", f"""model.encoder.layers.{i}.fc2.weight""") )
						rename_keys.append((f"""transformer.encoder.layers.{i}.linear2.bias""", f"""model.encoder.layers.{i}.fc2.bias""") )
						rename_keys.append((f"""transformer.encoder.layers.{i}.norm2.weight""", f"""model.encoder.layers.{i}.final_layer_norm.weight""") )
						rename_keys.append((f"""transformer.encoder.layers.{i}.norm2.bias""", f"""model.encoder.layers.{i}.final_layer_norm.bias""") )

			# transformer decoder
			for i in range(config.decoder_layers ):
						rename_keys.append((f"""transformer.decoder.layers.{i}.cross_attn.sampling_offsets.weight""", f"""model.decoder.layers.{i}.encoder_attn.sampling_offsets.weight""") )
						rename_keys.append((f"""transformer.decoder.layers.{i}.cross_attn.sampling_offsets.bias""", f"""model.decoder.layers.{i}.encoder_attn.sampling_offsets.bias""") )
						rename_keys.append((f"""transformer.decoder.layers.{i}.cross_attn.attention_weights.weight""", f"""model.decoder.layers.{i}.encoder_attn.attention_weights.weight""") )
						rename_keys.append((f"""transformer.decoder.layers.{i}.cross_attn.attention_weights.bias""", f"""model.decoder.layers.{i}.encoder_attn.attention_weights.bias""") )
						rename_keys.append((f"""transformer.decoder.layers.{i}.cross_attn.value_proj.weight""", f"""model.decoder.layers.{i}.encoder_attn.value_proj.weight""") )
						rename_keys.append((f"""transformer.decoder.layers.{i}.cross_attn.value_proj.bias""", f"""model.decoder.layers.{i}.encoder_attn.value_proj.bias""") )
						rename_keys.append((f"""transformer.decoder.layers.{i}.cross_attn.output_proj.weight""", f"""model.decoder.layers.{i}.encoder_attn.output_proj.weight""") )
						rename_keys.append((f"""transformer.decoder.layers.{i}.cross_attn.output_proj.bias""", f"""model.decoder.layers.{i}.encoder_attn.output_proj.bias""") )
						rename_keys.append((f"""transformer.decoder.layers.{i}.norm1.weight""", f"""model.decoder.layers.{i}.encoder_attn_layer_norm.weight""") )
						rename_keys.append((f"""transformer.decoder.layers.{i}.norm1.bias""", f"""model.decoder.layers.{i}.encoder_attn_layer_norm.bias""") )
						rename_keys.append((f"""transformer.decoder.layers.{i}.self_attn.out_proj.weight""", f"""model.decoder.layers.{i}.self_attn.out_proj.weight""") )
						rename_keys.append((f"""transformer.decoder.layers.{i}.self_attn.out_proj.bias""", f"""model.decoder.layers.{i}.self_attn.out_proj.bias""") )
						rename_keys.append((f"""transformer.decoder.layers.{i}.norm2.weight""", f"""model.decoder.layers.{i}.self_attn_layer_norm.weight""") )
						rename_keys.append((f"""transformer.decoder.layers.{i}.norm2.bias""", f"""model.decoder.layers.{i}.self_attn_layer_norm.bias""") )
						rename_keys.append((f"""transformer.decoder.layers.{i}.linear1.weight""", f"""model.decoder.layers.{i}.fc1.weight""") )
						rename_keys.append((f"""transformer.decoder.layers.{i}.linear1.bias""", f"""model.decoder.layers.{i}.fc1.bias""") )
						rename_keys.append((f"""transformer.decoder.layers.{i}.linear2.weight""", f"""model.decoder.layers.{i}.fc2.weight""") )
						rename_keys.append((f"""transformer.decoder.layers.{i}.linear2.bias""", f"""model.decoder.layers.{i}.fc2.bias""") )
						rename_keys.append((f"""transformer.decoder.layers.{i}.norm3.weight""", f"""model.decoder.layers.{i}.final_layer_norm.weight""") )
						rename_keys.append((f"""transformer.decoder.layers.{i}.norm3.bias""", f"""model.decoder.layers.{i}.final_layer_norm.bias""") )

			# fmt: on

			return rename_keys
def        lowerCamelCase_     (     SCREAMING_SNAKE_CASE       ,						SCREAMING_SNAKE_CASE       ,						SCREAMING_SNAKE_CASE ):
			'''simple docstring'''
			SCREAMING_SNAKE_CASE     =       dct.pop(__UpperCamelCase )
			SCREAMING_SNAKE_CASE     =       val
def        lowerCamelCase_     (     SCREAMING_SNAKE_CASE       ,						SCREAMING_SNAKE_CASE ):
			'''simple docstring'''
			# transformer decoder self-attention layers
			SCREAMING_SNAKE_CASE     =       config.d_model
			for i in range(config.decoder_layers ):
						# read in weights + bias of input projection layer of self-attention
						SCREAMING_SNAKE_CASE     =       state_dict.pop(f"""transformer.decoder.layers.{i}.self_attn.in_proj_weight""" )
						SCREAMING_SNAKE_CASE     =       state_dict.pop(f"""transformer.decoder.layers.{i}.self_attn.in_proj_bias""" )
						# next, add query, keys and values (in that order) to the state dict
						SCREAMING_SNAKE_CASE     =       in_proj_weight[:hidden_size, :]
						SCREAMING_SNAKE_CASE     =       in_proj_bias[:hidden_size]
						SCREAMING_SNAKE_CASE     =       in_proj_weight[
						    hidden_size : hidden_size * 2, :
						]
						SCREAMING_SNAKE_CASE     =       in_proj_bias[hidden_size : hidden_size * 2]
						SCREAMING_SNAKE_CASE     =       in_proj_weight[-hidden_size:, :]
						SCREAMING_SNAKE_CASE     =       in_proj_bias[-hidden_size:]
def        lowerCamelCase_     (     ):
			'''simple docstring'''
			SCREAMING_SNAKE_CASE     =       """http://images.cocodataset.org/val2017/000000039769.jpg"""
			SCREAMING_SNAKE_CASE     =       Image.open(requests.get(__UpperCamelCase       ,						stream=__UpperCamelCase ).raw )

			return im
@torch.no_grad()
def        lowerCamelCase_     (     SCREAMING_SNAKE_CASE       ,						SCREAMING_SNAKE_CASE       ,						SCREAMING_SNAKE_CASE ):
			'''simple docstring'''
			SCREAMING_SNAKE_CASE     =       get_deta_config()

			# load original state dict
			if model_name == "deta-resnet-50":
						SCREAMING_SNAKE_CASE     =       """adet_checkpoint0011.pth"""
			elif model_name == "deta-resnet-50-24-epochs":
						SCREAMING_SNAKE_CASE     =       """adet_2x_checkpoint0023.pth"""
			else:
						raise ValueError(f"""Model name {model_name} not supported""" )
			SCREAMING_SNAKE_CASE     =       hf_hub_download(repo_id="""nielsr/deta-checkpoints"""       ,						filename=__UpperCamelCase )
			SCREAMING_SNAKE_CASE     =       torch.load(__UpperCamelCase       ,						map_location="""cpu""" )["""model"""]

			# rename keys
			SCREAMING_SNAKE_CASE     =       create_rename_keys(__UpperCamelCase )
			for src, dest in rename_keys:
						rename_key(__UpperCamelCase       ,						__UpperCamelCase       ,						__UpperCamelCase )
			read_in_decoder_q_k_v(__UpperCamelCase       ,						__UpperCamelCase )

			# fix some prefixes
			for key in state_dict.copy().keys():
						if "transformer.decoder.class_embed" in key or "transformer.decoder.bbox_embed" in key:
									SCREAMING_SNAKE_CASE     =       state_dict.pop(__UpperCamelCase )
									SCREAMING_SNAKE_CASE     =       val
						if "input_proj" in key:
									SCREAMING_SNAKE_CASE     =       state_dict.pop(__UpperCamelCase )
									SCREAMING_SNAKE_CASE     =       val
						if "level_embed" in key or "pos_trans" in key or "pix_trans" in key or "enc_output" in key:
									SCREAMING_SNAKE_CASE     =       state_dict.pop(__UpperCamelCase )
									SCREAMING_SNAKE_CASE     =       val

    # finally, create HuggingFace model and load state dict
			SCREAMING_SNAKE_CASE     =       DetaForObjectDetection(__UpperCamelCase )
			model.load_state_dict(__UpperCamelCase )
			model.eval()

			SCREAMING_SNAKE_CASE     =       """cuda""" if torch.cuda.is_available() else """cpu"""
			model.to(__UpperCamelCase )

			# load image processor
			SCREAMING_SNAKE_CASE     =       DetaImageProcessor(format="""coco_detection""" )

			# verify our conversion on image
			SCREAMING_SNAKE_CASE     =       prepare_img()
			SCREAMING_SNAKE_CASE     =       processor(images=__UpperCamelCase       ,						return_tensors="""pt""" )
			SCREAMING_SNAKE_CASE     =       encoding["""pixel_values"""]
			SCREAMING_SNAKE_CASE     =       model(pixel_values.to(__UpperCamelCase ) )

			# verify logits
			if model_name == "deta-resnet-50":
						SCREAMING_SNAKE_CASE     =       torch.tensor(
						    [[-7.3_978, -2.5_406, -4.1_668], [-8.2_684, -3.9_933, -3.8_096], [-7.0_515, -3.7_973, -5.8_516]] )
						SCREAMING_SNAKE_CASE     =       torch.tensor([[0.5_043, 0.4_973, 0.9_998], [0.2_542, 0.5_489, 0.4_748], [0.5_490, 0.2_765, 0.0_570]] )
			elif model_name == "deta-resnet-50-24-epochs":
						SCREAMING_SNAKE_CASE     =       torch.tensor(
						    [[-7.1_688, -2.4_857, -4.8_669], [-7.8_630, -3.8_154, -4.2_674], [-7.2_730, -4.1_865, -5.5_323]] )
						SCREAMING_SNAKE_CASE     =       torch.tensor([[0.5_021, 0.4_971, 0.9_994], [0.2_546, 0.5_486, 0.4_731], [0.1_686, 0.1_986, 0.2_142]] )

			assert torch.allclose(outputs.logits[0, :3, :3]       ,						expected_logits.to(__UpperCamelCase )       ,						atol=1E-4 )
			assert torch.allclose(outputs.pred_boxes[0, :3, :3]       ,						expected_boxes.to(__UpperCamelCase )       ,						atol=1E-4 )
			print("""Everything ok!""" )

			if pytorch_dump_folder_path:
						# Save model and processor
						logger.info(f"""Saving PyTorch model and processor to {pytorch_dump_folder_path}...""" )
						Path(__UpperCamelCase ).mkdir(exist_ok=__UpperCamelCase )
						model.save_pretrained(__UpperCamelCase )
						processor.save_pretrained(__UpperCamelCase )

			# Push to hub
			if push_to_hub:
						print("""Pushing model and processor to hub...""" )
						model.push_to_hub(f"""jozhang97/{model_name}""" )
						processor.push_to_hub(f"""jozhang97/{model_name}""" )


if __name__ == "__main__":
		__A    :				Optional[int]    						=	argparse.ArgumentParser()

		parser.add_argument(
		    """--model_name""",
		    type=str,
		    default="""deta-resnet-50""",
		    choices=["""deta-resnet-50""", """deta-resnet-50-24-epochs"""],
		    help="""Name of the model you\'d like to convert.""",
		)
		parser.add_argument(
		    """--pytorch_dump_folder_path""",
		    default=None,
		    type=str,
		    help="""Path to the folder to output PyTorch model.""",
		)
		parser.add_argument(
		    """--push_to_hub""", action="""store_true""", help="""Whether or not to push the converted model to the 🤗 hub."""
		)
		__A    :				str    						=	parser.parse_args()
		convert_deta_checkpoint(args.model_name, args.pytorch_dump_folder_path, args.push_to_hub)









"""simple docstring"""






from manim import *
class 	_lowerCAmelCase    (      __snake_case       ):

							def 					_lowerCAmelCase  ( self       :    Dict    )   ->    Tuple:

									"""simple docstring"""
									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    ):
											rect.set_stroke(a    )

											lowercase										=							Rectangle(height=0.46 / 4 ,		width=0.46 / 3    ).set_stroke(width=0.0    ).set_fill(a ,		opacity=0.7    )

											if i == 0:
													cpu_target.next_to(cpu_left_col_base[0].get_corner(DOWN + LEFT    ) ,		buff=0.02 ,		direction=a    )
													cpu_target.set_x(cpu_target.get_x() + 0.1    )
											elif i == 3:
													cpu_target.next_to(model_cpu_arr[0] ,		direction=a ,		buff=0.0    )
											else:
													cpu_target.next_to(model_cpu_arr[i - 1] ,		direction=a ,		buff=0.0    )
											self.add(a    )
											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.0, -1.25, 0]    )
									self.add(a ,		a    )

									lowercase										=							[]

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

									self.add(*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"""The offloaded weights are all sent to the CPU.""" ,		font_size=24    )
									step_a.move_to([2, 2, 0]    )

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

									for i in range(6    ):
											lowercase										=							cpu_disk_arr[i]
											lowercase										=							rect.copy().set_fill(a ,		opacity=0.8    ).scale(2.0    )
											cpa.generate_target()
											cpa.target.move_to(model_base[i]    )

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

													self.remove(
													    *a ,		*a ,		)

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

									lowercase										=							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(a ,		run_time=3    )    )

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