def build_pipeline(
        cls,
        base_cfg,
        base_model: str,
        unet_path: str,
        dreambooth_path: Optional[str] = None,
        lora_path: Optional[str] = None,
        lora_alpha: float = 0,
        vae_path: Optional[str] = None,
        ip_adapter_path: Optional[str] = None,
        ip_adapter_scale: float = 0.0,
        only_load_vae_decoder: bool = False,
        only_load_vae_encoder: bool = False,
    ) -> "I2VPipeline":
        """Method to build pipeline in a faster way~
        Args:
            base_cfg: The config to build model
            base_mode: The model id to initialize StableDiffusion
            unet_path: Path for i2v unet

            dreambooth_path: path for dreambooth model
            lora_path: path for lora model
            lora_alpha: value for lora scale

            only_load_vae_decoder: Only load VAE decoder from dreambooth / VAE ckpt
                and maintain encoder as original.

        """
        # build unet
        unet = UNet3DConditionModel.from_pretrained_2d(
            base_model,
            subfolder="unet",
            unet_additional_kwargs=OmegaConf.to_container(base_cfg.unet_additional_kwargs),
        )

        old_weights = unet.conv_in.weight
        old_bias = unet.conv_in.bias
        new_conv1 = InflatedConv3d(
            9,
            old_weights.shape[0],
            kernel_size=unet.conv_in.kernel_size,
            stride=unet.conv_in.stride,
            padding=unet.conv_in.padding,
            bias=True if old_bias is not None else False,
        )
        param = torch.zeros((320, 5, 3, 3), requires_grad=True)
        new_conv1.weight = torch.nn.Parameter(torch.cat((old_weights, param), dim=1))
        if old_bias is not None:
            new_conv1.bias = old_bias
        unet.conv_in = new_conv1
        unet.config["in_channels"] = 9

        unet_ckpt = torch.load(unet_path, map_location="cpu")
        unet.load_state_dict(unet_ckpt, strict=False)
        # NOTE: only load temporal layers and condition module
        # for key, value in unet_ckpt.items():
        #     if 'motion' in key or 'conv_in' in key:
        #         unet.state_dict()[key].copy_(value)

        # load vae, tokenizer, text encoder
        vae = AutoencoderKL.from_pretrained(base_model, subfolder="vae")
        tokenizer = CLIPTokenizer.from_pretrained(base_model, subfolder="tokenizer")
        text_encoder = CLIPTextModel.from_pretrained(base_model, subfolder="text_encoder")
        noise_scheduler = DDIMScheduler(**OmegaConf.to_container(base_cfg.noise_scheduler_kwargs))

        if dreambooth_path:
            print(" >>> Begin loading DreamBooth >>>")
            base_model_state_dict = {}
            with safe_open(dreambooth_path, framework="pt", device="cpu") as f:
                for key in f.keys():
                    base_model_state_dict[key] = f.get_tensor(key)

            # load unet
            converted_unet_checkpoint = convert_ldm_unet_checkpoint(base_model_state_dict, unet.config)

            old_value = converted_unet_checkpoint["conv_in.weight"]
            new_param = unet_ckpt["conv_in.weight"][:, 4:, :, :].clone().cpu()
            new_value = torch.nn.Parameter(torch.cat((old_value, new_param), dim=1))
            converted_unet_checkpoint["conv_in.weight"] = new_value
            unet.load_state_dict(converted_unet_checkpoint, strict=False)

            # load vae
            converted_vae_checkpoint = convert_ldm_vae_checkpoint(
                base_model_state_dict,
                vae.config,
                only_decoder=only_load_vae_decoder,
                only_encoder=only_load_vae_encoder,
            )
            need_strict = not (only_load_vae_decoder or only_load_vae_encoder)
            vae.load_state_dict(converted_vae_checkpoint, strict=need_strict)
            print("Prefix in loaded VAE checkpoint: ")
            print({k.split(".")[0] for k in converted_vae_checkpoint.keys()})

            # load text encoder
            text_encoder_checkpoint = convert_ldm_clip_checkpoint(base_model_state_dict)
            if text_encoder_checkpoint:
                text_encoder.load_state_dict(text_encoder_checkpoint, strict=False)

            print(" <<< Loaded DreamBooth        <<<")

        if vae_path:
            print(" >>> Begin loading VAE >>>")
            vae_state_dict = {}
            if vae_path.endswith("safetensors"):
                with safe_open(vae_path, framework="pt", device="cpu") as f:
                    for key in f.keys():
                        vae_state_dict[key] = f.get_tensor(key)
            elif vae_path.endswith("ckpt") or vae_path.endswith("pt"):
                vae_state_dict = torch.load(vae_path, map_location="cpu")
            if "state_dict" in vae_state_dict:
                vae_state_dict = vae_state_dict["state_dict"]

            vae_state_dict = {f"first_stage_model.{k}": v for k, v in vae_state_dict.items()}

            converted_vae_checkpoint = convert_ldm_vae_checkpoint(
                vae_state_dict,
                vae.config,
                only_decoder=only_load_vae_decoder,
                only_encoder=only_load_vae_encoder,
            )
            print("Prefix in loaded VAE checkpoint: ")
            print({k.split(".")[0] for k in converted_vae_checkpoint.keys()})
            need_strict = not (only_load_vae_decoder or only_load_vae_encoder)
            vae.load_state_dict(converted_vae_checkpoint, strict=need_strict)
            print(" <<< Loaded VAE        <<<")

        if lora_path:
            print(" >>> Begin loading LoRA >>>")

            lora_dict = {}
            with safe_open(lora_path, framework="pt", device="cpu") as file:
                for k in file.keys():
                    lora_dict[k] = file.get_tensor(k)
            unet, text_encoder = convert_lora_model_level(lora_dict, unet, text_encoder, alpha=lora_alpha)

            print(" <<< Loaded LoRA        <<<")

        # move model to device
        device = torch.device("cuda")
        unet_dtype = torch.float16
        tenc_dtype = torch.float16
        vae_dtype = torch.bfloat16 if torch.cuda.is_bf16_supported() else torch.float32

        unet = unet.to(device=device, dtype=unet_dtype)
        text_encoder = text_encoder.to(device=device, dtype=tenc_dtype)
        vae = vae.to(device=device, dtype=vae_dtype)
        print(f"Set Unet to {unet_dtype}")
        print(f"Set text encoder to {tenc_dtype}")
        print(f"Set vae to {vae_dtype}")

        if is_xformers_available():
            unet.enable_xformers_memory_efficient_attention()

        pipeline = cls(unet=unet, vae=vae, tokenizer=tokenizer, text_encoder=text_encoder, scheduler=noise_scheduler)

        # ip_adapter_path = 'h94/IP-Adapter'
        if ip_adapter_path and ip_adapter_scale > 0:
            ip_adapter_name = "ip-adapter_sd15.bin"
            # only online repo need subfolder
            if not osp.isdir(ip_adapter_path):
                subfolder = "models"
            else:
                subfolder = ""
            pipeline.load_ip_adapter(ip_adapter_path, subfolder, ip_adapter_name)
            pipeline.set_ip_adapter_scale(ip_adapter_scale)
            pipeline.use_ip_adapter = True
            print(f"Load IP-Adapter, scale: {ip_adapter_scale}")

        # text_inversion_path = './models/TextualInversion/easynegative.safetensors'
        # if text_inversion_path:
        #     pipeline.load_textual_inversion(text_inversion_path, 'easynegative')

        return pipeline
Method to build pipeline in a faster way~
        Args:
            base_cfg: The config to build model
            base_mode: The model id to initialize StableDiffusion
            unet_path: Path for i2v unet

            dreambooth_path: path for dreambooth model
            lora_path: path for lora model
            lora_alpha: value for lora scale

            only_load_vae_decoder: Only load VAE decoder from dreambooth / VAE ckpt
                and maintain encoder as original.

        
animatediff/pipelines/i2v_pipeline.py