MCPcopy Create free account
hub / github.com/TencentARC/BrushNet / convert_vae_to_diffusers

Function convert_vae_to_diffusers

scripts/convert_unidiffuser_to_diffusers.py:348–493  ·  view source on GitHub ↗

Converts a UniDiffuser autoencoder_kl.pth checkpoint to a diffusers AutoencoderKL.

(ckpt, diffusers_model, num_head_channels=1)

Source from the content-addressed store, hash-verified

346
347# Based on diffusers.pipelines.stable_diffusion.convert_from_ckpt.convert_ldm_vae_checkpoint
348def convert_vae_to_diffusers(ckpt, diffusers_model, num_head_channels=1):
349 """
350 Converts a UniDiffuser autoencoder_kl.pth checkpoint to a diffusers AutoencoderKL.
351 """
352 # autoencoder_kl.pth ckpt is a torch state dict
353 vae_state_dict = torch.load(ckpt, map_location="cpu")
354
355 new_checkpoint = {}
356
357 new_checkpoint["encoder.conv_in.weight"] = vae_state_dict["encoder.conv_in.weight"]
358 new_checkpoint["encoder.conv_in.bias"] = vae_state_dict["encoder.conv_in.bias"]
359 new_checkpoint["encoder.conv_out.weight"] = vae_state_dict["encoder.conv_out.weight"]
360 new_checkpoint["encoder.conv_out.bias"] = vae_state_dict["encoder.conv_out.bias"]
361 new_checkpoint["encoder.conv_norm_out.weight"] = vae_state_dict["encoder.norm_out.weight"]
362 new_checkpoint["encoder.conv_norm_out.bias"] = vae_state_dict["encoder.norm_out.bias"]
363
364 new_checkpoint["decoder.conv_in.weight"] = vae_state_dict["decoder.conv_in.weight"]
365 new_checkpoint["decoder.conv_in.bias"] = vae_state_dict["decoder.conv_in.bias"]
366 new_checkpoint["decoder.conv_out.weight"] = vae_state_dict["decoder.conv_out.weight"]
367 new_checkpoint["decoder.conv_out.bias"] = vae_state_dict["decoder.conv_out.bias"]
368 new_checkpoint["decoder.conv_norm_out.weight"] = vae_state_dict["decoder.norm_out.weight"]
369 new_checkpoint["decoder.conv_norm_out.bias"] = vae_state_dict["decoder.norm_out.bias"]
370
371 new_checkpoint["quant_conv.weight"] = vae_state_dict["quant_conv.weight"]
372 new_checkpoint["quant_conv.bias"] = vae_state_dict["quant_conv.bias"]
373 new_checkpoint["post_quant_conv.weight"] = vae_state_dict["post_quant_conv.weight"]
374 new_checkpoint["post_quant_conv.bias"] = vae_state_dict["post_quant_conv.bias"]
375
376 # Retrieves the keys for the encoder down blocks only
377 num_down_blocks = len({".".join(layer.split(".")[:3]) for layer in vae_state_dict if "encoder.down" in layer})
378 down_blocks = {
379 layer_id: [key for key in vae_state_dict if f"down.{layer_id}" in key] for layer_id in range(num_down_blocks)
380 }
381
382 # Retrieves the keys for the decoder up blocks only
383 num_up_blocks = len({".".join(layer.split(".")[:3]) for layer in vae_state_dict if "decoder.up" in layer})
384 up_blocks = {
385 layer_id: [key for key in vae_state_dict if f"up.{layer_id}" in key] for layer_id in range(num_up_blocks)
386 }
387
388 for i in range(num_down_blocks):
389 resnets = [key for key in down_blocks[i] if f"down.{i}" in key and f"down.{i}.downsample" not in key]
390
391 if f"encoder.down.{i}.downsample.conv.weight" in vae_state_dict:
392 new_checkpoint[f"encoder.down_blocks.{i}.downsamplers.0.conv.weight"] = vae_state_dict.pop(
393 f"encoder.down.{i}.downsample.conv.weight"
394 )
395 new_checkpoint[f"encoder.down_blocks.{i}.downsamplers.0.conv.bias"] = vae_state_dict.pop(
396 f"encoder.down.{i}.downsample.conv.bias"
397 )
398
399 paths = renew_vae_resnet_paths(resnets)
400 meta_path = {"old": f"down.{i}.block", "new": f"down_blocks.{i}.resnets"}
401 assign_to_checkpoint(
402 paths,
403 new_checkpoint,
404 vae_state_dict,
405 additional_replacements=[meta_path],

Calls 7

load_state_dictMethod · 0.80
renew_vae_resnet_pathsFunction · 0.70
assign_to_checkpointFunction · 0.70
conv_attn_to_linearFunction · 0.70
loadMethod · 0.45
popMethod · 0.45

Tested by

no test coverage detected