comdoleger commited on
Commit
31709d8
·
verified ·
1 Parent(s): 0954cca

Upload scripts/convert_cog.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. scripts/convert_cog.py +128 -0
scripts/convert_cog.py ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ from collections import OrderedDict
3
+ import os
4
+ import torch
5
+ from safetensors import safe_open
6
+ from safetensors.torch import save_file
7
+
8
+ device = torch.device('cpu')
9
+
10
+ # [diffusers] -> kohya
11
+ embedding_mapping = {
12
+ 'text_encoders_0': 'clip_l',
13
+ 'text_encoders_1': 'clip_g'
14
+ }
15
+
16
+ PROJECT_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
17
+ KEYMAP_ROOT = os.path.join(PROJECT_ROOT, 'toolkit', 'keymaps')
18
+ sdxl_keymap_path = os.path.join(KEYMAP_ROOT, 'stable_diffusion_locon_sdxl.json')
19
+
20
+ # load keymap
21
+ with open(sdxl_keymap_path, 'r') as f:
22
+ ldm_diffusers_keymap = json.load(f)['ldm_diffusers_keymap']
23
+
24
+ # invert the item / key pairs
25
+ diffusers_ldm_keymap = {v: k for k, v in ldm_diffusers_keymap.items()}
26
+
27
+
28
+ def get_ldm_key(diffuser_key):
29
+ diffuser_key = f"lora_unet_{diffuser_key.replace('.', '_')}"
30
+ diffuser_key = diffuser_key.replace('_lora_down_weight', '.lora_down.weight')
31
+ diffuser_key = diffuser_key.replace('_lora_up_weight', '.lora_up.weight')
32
+ diffuser_key = diffuser_key.replace('_alpha', '.alpha')
33
+ diffuser_key = diffuser_key.replace('_processor_to_', '_to_')
34
+ diffuser_key = diffuser_key.replace('_to_out.', '_to_out_0.')
35
+ if diffuser_key in diffusers_ldm_keymap:
36
+ return diffusers_ldm_keymap[diffuser_key]
37
+ else:
38
+ raise KeyError(f"Key {diffuser_key} not found in keymap")
39
+
40
+
41
+ def convert_cog(lora_path, embedding_path):
42
+ embedding_state_dict = OrderedDict()
43
+ lora_state_dict = OrderedDict()
44
+
45
+ # # normal dict
46
+ # normal_dict = OrderedDict()
47
+ # example_path = "/mnt/Models/stable-diffusion/models/LoRA/sdxl/LogoRedmond_LogoRedAF.safetensors"
48
+ # with safe_open(example_path, framework="pt", device='cpu') as f:
49
+ # keys = list(f.keys())
50
+ # for key in keys:
51
+ # normal_dict[key] = f.get_tensor(key)
52
+
53
+ with safe_open(embedding_path, framework="pt", device='cpu') as f:
54
+ keys = list(f.keys())
55
+ for key in keys:
56
+ new_key = embedding_mapping[key]
57
+ embedding_state_dict[new_key] = f.get_tensor(key)
58
+
59
+ with safe_open(lora_path, framework="pt", device='cpu') as f:
60
+ keys = list(f.keys())
61
+ lora_rank = None
62
+
63
+ # get the lora dim first. Check first 3 linear layers just to be safe
64
+ for key in keys:
65
+ new_key = get_ldm_key(key)
66
+ tensor = f.get_tensor(key)
67
+ num_checked = 0
68
+ if len(tensor.shape) == 2:
69
+ this_dim = min(tensor.shape)
70
+ if lora_rank is None:
71
+ lora_rank = this_dim
72
+ elif lora_rank != this_dim:
73
+ raise ValueError(f"lora rank is not consistent, got {tensor.shape}")
74
+ else:
75
+ num_checked += 1
76
+ if num_checked >= 3:
77
+ break
78
+
79
+ for key in keys:
80
+ new_key = get_ldm_key(key)
81
+ tensor = f.get_tensor(key)
82
+ if new_key.endswith('.lora_down.weight'):
83
+ alpha_key = new_key.replace('.lora_down.weight', '.alpha')
84
+ # diffusers does not have alpha, they usa an alpha multiplier of 1 which is a tensor weight of the dims
85
+ # assume first smallest dim is the lora rank if shape is 2
86
+ lora_state_dict[alpha_key] = torch.ones(1).to(tensor.device, tensor.dtype) * lora_rank
87
+
88
+ lora_state_dict[new_key] = tensor
89
+
90
+ return lora_state_dict, embedding_state_dict
91
+
92
+
93
+ if __name__ == "__main__":
94
+ import argparse
95
+
96
+ parser = argparse.ArgumentParser()
97
+ parser.add_argument(
98
+ 'lora_path',
99
+ type=str,
100
+ help='Path to lora file'
101
+ )
102
+ parser.add_argument(
103
+ 'embedding_path',
104
+ type=str,
105
+ help='Path to embedding file'
106
+ )
107
+
108
+ parser.add_argument(
109
+ '--lora_output',
110
+ type=str,
111
+ default="lora_output",
112
+ )
113
+
114
+ parser.add_argument(
115
+ '--embedding_output',
116
+ type=str,
117
+ default="embedding_output",
118
+ )
119
+
120
+ args = parser.parse_args()
121
+
122
+ lora_state_dict, embedding_state_dict = convert_cog(args.lora_path, args.embedding_path)
123
+
124
+ # save them
125
+ save_file(lora_state_dict, args.lora_output)
126
+ save_file(embedding_state_dict, args.embedding_output)
127
+ print(f"Saved lora to {args.lora_output}")
128
+ print(f"Saved embedding to {args.embedding_output}")