stzhao/rice-range / tmp /video-velocity-model /data_processing /flux2_ae /convert_diffusers_checkpoint.py
stzhao's picture
download
raw
4.36 kB
from __future__ import annotations
import argparse
import re
from pathlib import Path
from safetensors.torch import load_file, save_file
ATTN_WEIGHT_SUFFIXES = (
".attn_1.q.weight",
".attn_1.k.weight",
".attn_1.v.weight",
".attn_1.proj_out.weight",
)
def convert_key(key: str) -> str:
if key == "quant_conv.weight":
return "encoder.quant_conv.weight"
if key == "quant_conv.bias":
return "encoder.quant_conv.bias"
if key == "post_quant_conv.weight":
return "decoder.post_quant_conv.weight"
if key == "post_quant_conv.bias":
return "decoder.post_quant_conv.bias"
if key.startswith("encoder.mid_block.resnets.0."):
return key.replace("encoder.mid_block.resnets.0.", "encoder.mid.block_1.")
if key.startswith("encoder.mid_block.resnets.1."):
return key.replace("encoder.mid_block.resnets.1.", "encoder.mid.block_2.")
if key.startswith("encoder.mid_block.attentions.0."):
key = key.replace("encoder.mid_block.attentions.0.group_norm.", "encoder.mid.attn_1.norm.")
key = key.replace("encoder.mid_block.attentions.0.to_q.", "encoder.mid.attn_1.q.")
key = key.replace("encoder.mid_block.attentions.0.to_k.", "encoder.mid.attn_1.k.")
key = key.replace("encoder.mid_block.attentions.0.to_v.", "encoder.mid.attn_1.v.")
return key.replace("encoder.mid_block.attentions.0.to_out.0.", "encoder.mid.attn_1.proj_out.")
if key.startswith("encoder."):
key = key.replace("encoder.down_blocks.", "encoder.down.")
key = key.replace(".resnets.", ".block.")
key = key.replace(".downsamplers.0.", ".downsample.")
key = key.replace(".conv_shortcut.", ".nin_shortcut.")
return key.replace("encoder.conv_norm_out.", "encoder.norm_out.")
if key.startswith("decoder.mid_block.resnets.0."):
return key.replace("decoder.mid_block.resnets.0.", "decoder.mid.block_1.")
if key.startswith("decoder.mid_block.resnets.1."):
return key.replace("decoder.mid_block.resnets.1.", "decoder.mid.block_2.")
if key.startswith("decoder.mid_block.attentions.0."):
key = key.replace("decoder.mid_block.attentions.0.group_norm.", "decoder.mid.attn_1.norm.")
key = key.replace("decoder.mid_block.attentions.0.to_q.", "decoder.mid.attn_1.q.")
key = key.replace("decoder.mid_block.attentions.0.to_k.", "decoder.mid.attn_1.k.")
key = key.replace("decoder.mid_block.attentions.0.to_v.", "decoder.mid.attn_1.v.")
return key.replace("decoder.mid_block.attentions.0.to_out.0.", "decoder.mid.attn_1.proj_out.")
if key.startswith("decoder.up_blocks."):
match = re.match(r"decoder\.up_blocks\.(\d+)\.(.*)", key)
if match is None:
return key
# Diffusers stores decoder up blocks low->high, while the local FLUX.2 module indexes high->low.
key = f"decoder.up.{3 - int(match.group(1))}.{match.group(2)}"
key = key.replace(".resnets.", ".block.")
key = key.replace(".upsamplers.0.", ".upsample.")
return key.replace(".conv_shortcut.", ".nin_shortcut.")
if key.startswith("decoder."):
return key.replace("decoder.conv_norm_out.", "decoder.norm_out.")
return key
def convert_checkpoint(input_path: Path, output_path: Path) -> None:
source = load_file(str(input_path), device="cpu")
converted = {}
for key, value in source.items():
new_key = convert_key(key)
if any(suffix in new_key for suffix in ATTN_WEIGHT_SUFFIXES) and value.ndim == 2:
value = value[:, :, None, None]
converted[new_key] = value
output_path.parent.mkdir(parents=True, exist_ok=True)
save_file(converted, str(output_path))
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description="Convert a diffusers FLUX.2 VAE checkpoint for the local FLUX.2 AE module.")
parser.add_argument("input", type=Path, help="Input diffusers diffusion_pytorch_model.safetensors path.")
parser.add_argument("output", type=Path, help="Output converted ae.safetensors path.")
return parser.parse_args()
def main() -> None:
args = parse_args()
convert_checkpoint(args.input.expanduser(), args.output.expanduser())
print(f"Saved converted FLUX.2 AE checkpoint to {args.output.expanduser()}")
if __name__ == "__main__":
main()

Xet Storage Details

Size:
4.36 kB
·
Xet hash:
48fd5d5fd7b1b6fc12d27d811668eea5960e8f06be5ce1baef67d46c033f4a97

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.