comdoleger commited on
Commit
36ccbe3
·
verified ·
1 Parent(s): 0f7310d

Upload testing/merge_in_text_encoder_adapter.py with huggingface_hub

Browse files
testing/merge_in_text_encoder_adapter.py ADDED
@@ -0,0 +1,180 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+
3
+ import torch
4
+ from transformers import T5EncoderModel, T5Tokenizer
5
+ from diffusers import StableDiffusionPipeline, UNet2DConditionModel, PixArtSigmaPipeline, Transformer2DModel, PixArtTransformer2DModel
6
+ from safetensors.torch import load_file, save_file
7
+ from collections import OrderedDict
8
+ import json
9
+
10
+ # model_path = "/home/jaret/Dev/models/hf/kl-f16-d42_sd15_v01_000527000"
11
+ # te_path = "google/flan-t5-xl"
12
+ # te_aug_path = "/mnt/Train/out/ip_adapter/t5xx_sd15_v1/t5xx_sd15_v1_000032000.safetensors"
13
+ # output_path = "/home/jaret/Dev/models/hf/kl-f16-d42_sd15_t5xl_raw"
14
+ model_path = "/home/jaret/Dev/models/hf/objective-reality-16ch"
15
+ te_path = "google/flan-t5-xl"
16
+ te_aug_path = "/mnt/Train2/out/ip_adapter/t5xl-sd15-16ch_v1/t5xl-sd15-16ch_v1_000115000.safetensors"
17
+ output_path = "/home/jaret/Dev/models/hf/t5xl-sd15-16ch_sd15_v1"
18
+
19
+
20
+ print("Loading te adapter")
21
+ te_aug_sd = load_file(te_aug_path)
22
+
23
+ print("Loading model")
24
+ is_diffusers = (not os.path.exists(model_path)) or os.path.isdir(model_path)
25
+
26
+ # if "pixart" in model_path.lower():
27
+ is_pixart = "pixart" in model_path.lower()
28
+
29
+ pipeline_class = StableDiffusionPipeline
30
+
31
+ # transformer = PixArtTransformer2DModel.from_pretrained('PixArt-alpha/PixArt-Sigma-XL-2-512-MS', subfolder='transformer', torch_dtype=torch.float16)
32
+
33
+ if is_pixart:
34
+ pipeline_class = PixArtSigmaPipeline
35
+
36
+ if is_diffusers:
37
+ sd = pipeline_class.from_pretrained(model_path, torch_dtype=torch.float16)
38
+ else:
39
+ sd = pipeline_class.from_single_file(model_path, torch_dtype=torch.float16)
40
+
41
+ print("Loading Text Encoder")
42
+ # Load the text encoder
43
+ te = T5EncoderModel.from_pretrained(te_path, torch_dtype=torch.float16)
44
+
45
+ # patch it
46
+ sd.text_encoder = te
47
+ sd.tokenizer = T5Tokenizer.from_pretrained(te_path)
48
+
49
+ if is_pixart:
50
+ unet = sd.transformer
51
+ unet_sd = sd.transformer.state_dict()
52
+ else:
53
+ unet = sd.unet
54
+ unet_sd = sd.unet.state_dict()
55
+
56
+
57
+ if is_pixart:
58
+ weight_idx = 0
59
+ else:
60
+ weight_idx = 1
61
+
62
+ new_cross_attn_dim = None
63
+
64
+ # count the num of params in state dict
65
+ start_params = sum([v.numel() for v in unet_sd.values()])
66
+
67
+ print("Building")
68
+ attn_processor_keys = []
69
+ if is_pixart:
70
+ transformer: Transformer2DModel = unet
71
+ for i, module in transformer.transformer_blocks.named_children():
72
+ attn_processor_keys.append(f"transformer_blocks.{i}.attn1")
73
+ # cross attention
74
+ attn_processor_keys.append(f"transformer_blocks.{i}.attn2")
75
+ else:
76
+ attn_processor_keys = list(unet.attn_processors.keys())
77
+
78
+ for name in attn_processor_keys:
79
+ cross_attention_dim = None if name.endswith("attn1.processor") or name.endswith("attn.1") or name.endswith(
80
+ "attn1") else \
81
+ unet.config['cross_attention_dim']
82
+ if name.startswith("mid_block"):
83
+ hidden_size = unet.config['block_out_channels'][-1]
84
+ elif name.startswith("up_blocks"):
85
+ block_id = int(name[len("up_blocks.")])
86
+ hidden_size = list(reversed(unet.config['block_out_channels']))[block_id]
87
+ elif name.startswith("down_blocks"):
88
+ block_id = int(name[len("down_blocks.")])
89
+ hidden_size = unet.config['block_out_channels'][block_id]
90
+ elif name.startswith("transformer"):
91
+ hidden_size = unet.config['cross_attention_dim']
92
+ else:
93
+ # they didnt have this, but would lead to undefined below
94
+ raise ValueError(f"unknown attn processor name: {name}")
95
+ if cross_attention_dim is None:
96
+ pass
97
+ else:
98
+ layer_name = name.split(".processor")[0]
99
+ to_k_adapter = unet_sd[layer_name + ".to_k.weight"]
100
+ to_v_adapter = unet_sd[layer_name + ".to_v.weight"]
101
+
102
+ te_aug_name = None
103
+ while True:
104
+ if is_pixart:
105
+ te_aug_name = f"te_adapter.adapter_modules.{weight_idx}.to_k_adapter"
106
+ else:
107
+ te_aug_name = f"te_adapter.adapter_modules.{weight_idx}.to_k_adapter"
108
+ if f"{te_aug_name}.weight" in te_aug_sd:
109
+ # increment so we dont redo it next time
110
+ weight_idx += 1
111
+ break
112
+ else:
113
+ weight_idx += 1
114
+
115
+ if weight_idx > 1000:
116
+ raise ValueError("Could not find the next weight")
117
+
118
+ orig_weight_shape_k = list(unet_sd[layer_name + ".to_k.weight"].shape)
119
+ new_weight_shape_k = list(te_aug_sd[te_aug_name + ".weight"].shape)
120
+ orig_weight_shape_v = list(unet_sd[layer_name + ".to_v.weight"].shape)
121
+ new_weight_shape_v = list(te_aug_sd[te_aug_name.replace('to_k', 'to_v') + ".weight"].shape)
122
+
123
+ unet_sd[layer_name + ".to_k.weight"] = te_aug_sd[te_aug_name + ".weight"]
124
+ unet_sd[layer_name + ".to_v.weight"] = te_aug_sd[te_aug_name.replace('to_k', 'to_v') + ".weight"]
125
+
126
+ if new_cross_attn_dim is None:
127
+ new_cross_attn_dim = unet_sd[layer_name + ".to_k.weight"].shape[1]
128
+
129
+
130
+
131
+ if is_pixart:
132
+ # copy the caption_projection weight
133
+ del unet_sd['caption_projection.linear_1.bias']
134
+ del unet_sd['caption_projection.linear_1.weight']
135
+ del unet_sd['caption_projection.linear_2.bias']
136
+ del unet_sd['caption_projection.linear_2.weight']
137
+
138
+ print("Saving unmodified model")
139
+ sd = sd.to("cpu", torch.float16)
140
+ sd.save_pretrained(
141
+ output_path,
142
+ safe_serialization=True,
143
+ )
144
+
145
+ # overwrite the unet
146
+ if is_pixart:
147
+ unet_folder = os.path.join(output_path, "transformer")
148
+ else:
149
+ unet_folder = os.path.join(output_path, "unet")
150
+
151
+ # move state_dict to cpu
152
+ unet_sd = {k: v.clone().cpu().to(torch.float16) for k, v in unet_sd.items()}
153
+
154
+ meta = OrderedDict()
155
+ meta["format"] = "pt"
156
+
157
+ print("Patching")
158
+
159
+ save_file(unet_sd, os.path.join(unet_folder, "diffusion_pytorch_model.safetensors"), meta)
160
+
161
+ # load the json file
162
+ with open(os.path.join(unet_folder, "config.json"), 'r') as f:
163
+ config = json.load(f)
164
+
165
+ config['cross_attention_dim'] = new_cross_attn_dim
166
+
167
+ if is_pixart:
168
+ config['caption_channels'] = None
169
+
170
+ # save it
171
+ with open(os.path.join(unet_folder, "config.json"), 'w') as f:
172
+ json.dump(config, f, indent=2)
173
+
174
+ print("Done")
175
+
176
+ new_params = sum([v.numel() for v in unet_sd.values()])
177
+
178
+ # print new and old params with , formatted
179
+ print(f"Old params: {start_params:,}")
180
+ print(f"New params: {new_params:,}")