-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsetup_const_files.py
More file actions
executable file
·151 lines (118 loc) · 4.76 KB
/
Copy pathsetup_const_files.py
File metadata and controls
executable file
·151 lines (118 loc) · 4.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#!/usr/bin/env python3
"""Extract individual .const files from packed .fconst for UNet and VAE decoder.
AMD's pre-compiled ONNX models ship .fconst files (packed constants) but the DD
runtime needs individual .const files referenced by the meta.json. This script
extracts them using offset/size info from meta.json.
Run once after downloading a model:
python setup_const_files.py --model-dir models/stable-diffusion-1.5-amdnpu
python setup_const_files.py --model-dir models/segmind-vega-amdnpu
Or, more commonly, called transitively by download_model.py / setup.sh.
"""
import argparse
import json
import os
import sys
# SD 1.5 and SD-Turbo share the same fconst key names.
# SDXL uses `unetconv_inConv` for the UNet entry (not `conv_inConv`);
# its VAE decoder still uses the `post_quant_convConv` naming.
_SD15_COMPONENTS = [
{
"name": "UNet",
"meta": "unet/dd/cache/NhwcConv_0-conv_inConv_meta.json",
"fconst": "unet/dd/dd_metastate_SD15_Unet_NhwcConv_0-conv_inConv.fconst",
"base_dir": "unet/dd",
},
{
"name": "VAE Decoder",
"meta": "vae_decoder/dd/cache/NhwcConv_0-post_quant_convConv_meta.json",
"fconst": "vae_decoder/dd/dd_metastate_Sd15_Decoder_NhwcConv_0-post_quant_convConv.fconst",
"base_dir": "vae_decoder/dd",
},
]
_SDXL_COMPONENTS = [
{
"name": "UNet",
"meta": "unet/dd/cache/NhwcConv_0-unetconv_inConv_meta.json",
"fconst": "unet/dd/dd_metastate_SD15_Unet_NhwcConv_0-unetconv_inConv.fconst",
"base_dir": "unet/dd",
},
{
"name": "VAE Decoder",
"meta": "vae_decoder/dd/cache/NhwcConv_0-post_quant_convConv_meta.json",
"fconst": "vae_decoder/dd/dd_metastate_Sd15_Decoder_NhwcConv_0-post_quant_convConv.fconst",
"base_dir": "vae_decoder/dd",
},
]
def components_for(model_dir):
basename = os.path.basename(os.path.normpath(model_dir))
# Segmind Vega is a distilled SDXL and ships the same fconst key names.
if "sdxl" in basename or "vega" in basename:
return _SDXL_COMPONENTS
return _SD15_COMPONENTS
def extract_consts(component, model_dir):
meta_path = os.path.join(model_dir, component["meta"])
fconst_path = os.path.join(model_dir, component["fconst"])
base_dir = os.path.join(model_dir, component["base_dir"])
if not os.path.exists(meta_path):
print(f" SKIP - meta.json not found: {meta_path}")
return 0
if not os.path.exists(fconst_path):
print(f" SKIP - fconst not found: {fconst_path}")
return 0
with open(meta_path) as f:
meta = json.load(f)
with open(fconst_path, "rb") as f:
fconst_data = f.read()
os.makedirs(os.path.join(base_dir, ".cache"), exist_ok=True)
count = 0
for name, info in meta["tensor_map"].items():
if "file_name" not in info:
continue
offset = info["offset"]
size = info["file_size"]
fname = info["file_name"]
out_path = os.path.join(base_dir, fname)
if os.path.exists(out_path) and os.path.getsize(out_path) == size:
count += 1
continue
os.makedirs(os.path.dirname(out_path), exist_ok=True)
if offset + size <= len(fconst_data):
with open(out_path, "wb") as f:
f.write(fconst_data[offset : offset + size])
else:
# Last entry may extend past fconst; pad with zeros
available = len(fconst_data) - offset
with open(out_path, "wb") as f:
f.write(fconst_data[offset:])
f.write(b"\x00" * (size - available))
count += 1
return count
def extract_all(model_dir):
"""Extract .const files for every component in a model directory.
Returns the total count of const files present (extracted or already-cached).
Raises FileNotFoundError if the model directory itself doesn't exist.
"""
if not os.path.exists(model_dir):
raise FileNotFoundError(f"Model directory not found: {model_dir}")
total = 0
for component in components_for(model_dir):
print(f"Extracting {component['name']} const files...")
count = extract_consts(component, model_dir)
print(f" {count} const files ready")
total += count
return total
def main():
parser = argparse.ArgumentParser(description="Extract .const files from .fconst")
parser.add_argument(
"--model-dir", type=str, required=True,
help="Path to the downloaded model directory (e.g. models/stable-diffusion-1.5-amdnpu)",
)
args = parser.parse_args()
try:
extract_all(args.model_dir)
except FileNotFoundError as e:
print(e, file=sys.stderr)
sys.exit(1)
print(f"\nDone. Model directory: {args.model_dir}")
if __name__ == "__main__":
main()