BiliSakura commited on
Commit
f43f486
·
verified ·
1 Parent(s): ee21cfe

Upload W-Flow-diffusers checkpoints

Browse files
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ demo.png filter=lfs diff=lfs merge=lfs -text
.gitignore ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ __pycache__/
2
+ *.py[cod]
3
+ .DS_Store
README.md ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: apache-2.0
3
+ library_name: diffusers
4
+ pipeline_tag: unconditional-image-generation
5
+ tags:
6
+ - diffusers
7
+ - w-flow
8
+ - image-generation
9
+ - class-conditional
10
+ - one-step
11
+ - imagenet
12
+ widget:
13
+ - text: golden retriever
14
+ output:
15
+ url: demo.png
16
+ language:
17
+ - en
18
+ ---
19
+
20
+ # W-Flow-diffusers
21
+
22
+ Native [diffusers](https://github.com/huggingface/diffusers) checkpoints for **W-Flow** ([One-Step Generative Modeling via Wasserstein Gradient Flows](https://arxiv.org/abs/2605.11755)). Code: [hanjq17/W-Flow](https://github.com/hanjq17/W-Flow). Each variant folder is self-contained:
23
+
24
+ - `pipeline.py` — `WFlowPipeline`
25
+ - `scheduler/scheduling_wflow.py` — `WFlowScheduler` (one evaluation; the transformer predicts the clean latent)
26
+ - `transformer/transformer_wflow.py` — `WFlowTransformer2DModel`
27
+ - `vae/` — `stabilityai/sd-vae-ft-mse` (`AutoencoderKL`, scaling factor 0.18215)
28
+
29
+ Load with PyPI `diffusers` and `trust_remote_code=True`. No extra W-Flow package is required. Sampling is one forward pass at 256×256. `guidance_scale` is the official CFG value, which the paper writes as \(w+1\). Weights are the released EMA. The paper reports ImageNet-256 FID 1.52 for W-Flow-B, 1.35 for W-Flow-L, and 1.29 for W-Flow-XL.
30
+
31
+ ## Available checkpoints
32
+
33
+ | Checkpoint | Path | Resolution | Steps | Guidance |
34
+ | --- | --- | --- | ---: | ---: |
35
+ | W-Flow-B | [`W-Flow-B/`](W-Flow-B/) | 256×256 | 1 | 1.19 |
36
+ | W-Flow-L | [`W-Flow-L/`](W-Flow-L/) | 256×256 | 1 | 1.14 |
37
+ | W-Flow-XL | [`W-Flow-XL/`](W-Flow-XL/) | 256×256 | 1 | 1.09 |
38
+
39
+ ## Demo
40
+
41
+ ![W-Flow-B demo](demo.png)
42
+
43
+ Class: *golden retriever* (ImageNet 207) — 256×256, 1 step, `guidance_scale=1.19`, `torch_dtype=bfloat16`, seed 1.
44
+
45
+ ## ImageNet class labels
46
+
47
+ Each variant keeps an English `id2label` map in `model_index.json`.
48
+
49
+ - `pipe.id2label` — id → English label
50
+ - `pipe.labels` — synonym → id
51
+ - `pipe.get_label_ids("golden retriever")`
52
+ - `pipe(class_labels="golden retriever", ...)` — string labels resolve automatically
53
+
54
+ `height` and `width` default to 256. The patch embedding is fixed to a 32×32 latent, so other sizes are rejected. On CUDA the generator autocasts to bfloat16.
55
+
56
+ ## Inference
57
+
58
+ ```python
59
+ import torch
60
+ from diffusers import DiffusionPipeline
61
+
62
+ pipe = DiffusionPipeline.from_pretrained(
63
+ "BiliSakura/W-Flow-diffusers",
64
+ subfolder="W-Flow-B",
65
+ custom_pipeline="pipeline.py",
66
+ trust_remote_code=True,
67
+ torch_dtype=torch.bfloat16,
68
+ ).to("cuda")
69
+
70
+ print(pipe.id2label[207])
71
+ image = pipe(
72
+ class_labels="golden retriever",
73
+ num_inference_steps=1,
74
+ guidance_scale=1.19,
75
+ generator=torch.Generator(device="cuda").manual_seed(1),
76
+ ).images[0]
77
+ image.save("demo.png")
78
+ ```
79
+
80
+ Local checkout:
81
+
82
+ ```python
83
+ from pathlib import Path
84
+ import torch
85
+ from diffusers import DiffusionPipeline
86
+
87
+ model_dir = Path("W-Flow-diffusers/W-Flow-B")
88
+ pipe = DiffusionPipeline.from_pretrained(
89
+ str(model_dir),
90
+ local_files_only=True,
91
+ custom_pipeline=str(model_dir / "pipeline.py"),
92
+ trust_remote_code=True,
93
+ torch_dtype=torch.bfloat16,
94
+ ).to("cuda")
95
+ ```
96
+
97
+ ## Citation
98
+
99
+ ```bibtex
100
+ @article{han2026one,
101
+ title = {One-Step Generative Modeling via Wasserstein Gradient Flows},
102
+ author = {Han, Jiaqi and Li, Puheng and Guo, Qiushan and Xu, Renyuan and Ermon, Stefano and Cand{\`e}s, Emmanuel J.},
103
+ journal = {arXiv preprint arXiv:2605.11755},
104
+ year = {2026},
105
+ url = {https://arxiv.org/abs/2605.11755}
106
+ }
107
+ ```
W-Flow-B/model_index.json ADDED
@@ -0,0 +1,1021 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_class_name": [
3
+ "pipeline",
4
+ "WFlowPipeline"
5
+ ],
6
+ "_diffusers_version": "0.39.0",
7
+ "scheduler": [
8
+ "scheduling_wflow",
9
+ "WFlowScheduler"
10
+ ],
11
+ "transformer": [
12
+ "transformer_wflow",
13
+ "WFlowTransformer2DModel"
14
+ ],
15
+ "vae": [
16
+ "diffusers",
17
+ "AutoencoderKL"
18
+ ],
19
+ "id2label": {
20
+ "0": "tench, Tinca tinca",
21
+ "1": "goldfish, Carassius auratus",
22
+ "2": "great white shark, white shark, man-eater, man-eating shark, Carcharodon carcharias",
23
+ "3": "tiger shark, Galeocerdo cuvieri",
24
+ "4": "hammerhead, hammerhead shark",
25
+ "5": "electric ray, crampfish, numbfish, torpedo",
26
+ "6": "stingray",
27
+ "7": "cock",
28
+ "8": "hen",
29
+ "9": "ostrich, Struthio camelus",
30
+ "10": "brambling, Fringilla montifringilla",
31
+ "11": "goldfinch, Carduelis carduelis",
32
+ "12": "house finch, linnet, Carpodacus mexicanus",
33
+ "13": "junco, snowbird",
34
+ "14": "indigo bunting, indigo finch, indigo bird, Passerina cyanea",
35
+ "15": "robin, American robin, Turdus migratorius",
36
+ "16": "bulbul",
37
+ "17": "jay",
38
+ "18": "magpie",
39
+ "19": "chickadee",
40
+ "20": "water ouzel, dipper",
41
+ "21": "kite",
42
+ "22": "bald eagle, American eagle, Haliaeetus leucocephalus",
43
+ "23": "vulture",
44
+ "24": "great grey owl, great gray owl, Strix nebulosa",
45
+ "25": "European fire salamander, Salamandra salamandra",
46
+ "26": "common newt, Triturus vulgaris",
47
+ "27": "eft",
48
+ "28": "spotted salamander, Ambystoma maculatum",
49
+ "29": "axolotl, mud puppy, Ambystoma mexicanum",
50
+ "30": "bullfrog, Rana catesbeiana",
51
+ "31": "tree frog, tree-frog",
52
+ "32": "tailed frog, bell toad, ribbed toad, tailed toad, Ascaphus trui",
53
+ "33": "loggerhead, loggerhead turtle, Caretta caretta",
54
+ "34": "leatherback turtle, leatherback, leathery turtle, Dermochelys coriacea",
55
+ "35": "mud turtle",
56
+ "36": "terrapin",
57
+ "37": "box turtle, box tortoise",
58
+ "38": "banded gecko",
59
+ "39": "common iguana, iguana, Iguana iguana",
60
+ "40": "American chameleon, anole, Anolis carolinensis",
61
+ "41": "whiptail, whiptail lizard",
62
+ "42": "agama",
63
+ "43": "frilled lizard, Chlamydosaurus kingi",
64
+ "44": "alligator lizard",
65
+ "45": "Gila monster, Heloderma suspectum",
66
+ "46": "green lizard, Lacerta viridis",
67
+ "47": "African chameleon, Chamaeleo chamaeleon",
68
+ "48": "Komodo dragon, Komodo lizard, dragon lizard, giant lizard, Varanus komodoensis",
69
+ "49": "African crocodile, Nile crocodile, Crocodylus niloticus",
70
+ "50": "American alligator, Alligator mississipiensis",
71
+ "51": "triceratops",
72
+ "52": "thunder snake, worm snake, Carphophis amoenus",
73
+ "53": "ringneck snake, ring-necked snake, ring snake",
74
+ "54": "hognose snake, puff adder, sand viper",
75
+ "55": "green snake, grass snake",
76
+ "56": "king snake, kingsnake",
77
+ "57": "garter snake, grass snake",
78
+ "58": "water snake",
79
+ "59": "vine snake",
80
+ "60": "night snake, Hypsiglena torquata",
81
+ "61": "boa constrictor, Constrictor constrictor",
82
+ "62": "rock python, rock snake, Python sebae",
83
+ "63": "Indian cobra, Naja naja",
84
+ "64": "green mamba",
85
+ "65": "sea snake",
86
+ "66": "horned viper, cerastes, sand viper, horned asp, Cerastes cornutus",
87
+ "67": "diamondback, diamondback rattlesnake, Crotalus adamanteus",
88
+ "68": "sidewinder, horned rattlesnake, Crotalus cerastes",
89
+ "69": "trilobite",
90
+ "70": "harvestman, daddy longlegs, Phalangium opilio",
91
+ "71": "scorpion",
92
+ "72": "black and gold garden spider, Argiope aurantia",
93
+ "73": "barn spider, Araneus cavaticus",
94
+ "74": "garden spider, Aranea diademata",
95
+ "75": "black widow, Latrodectus mactans",
96
+ "76": "tarantula",
97
+ "77": "wolf spider, hunting spider",
98
+ "78": "tick",
99
+ "79": "centipede",
100
+ "80": "black grouse",
101
+ "81": "ptarmigan",
102
+ "82": "ruffed grouse, partridge, Bonasa umbellus",
103
+ "83": "prairie chicken, prairie grouse, prairie fowl",
104
+ "84": "peacock",
105
+ "85": "quail",
106
+ "86": "partridge",
107
+ "87": "African grey, African gray, Psittacus erithacus",
108
+ "88": "macaw",
109
+ "89": "sulphur-crested cockatoo, Kakatoe galerita, Cacatua galerita",
110
+ "90": "lorikeet",
111
+ "91": "coucal",
112
+ "92": "bee eater",
113
+ "93": "hornbill",
114
+ "94": "hummingbird",
115
+ "95": "jacamar",
116
+ "96": "toucan",
117
+ "97": "drake",
118
+ "98": "red-breasted merganser, Mergus serrator",
119
+ "99": "goose",
120
+ "100": "black swan, Cygnus atratus",
121
+ "101": "tusker",
122
+ "102": "echidna, spiny anteater, anteater",
123
+ "103": "platypus, duckbill, duckbilled platypus, duck-billed platypus, Ornithorhynchus anatinus",
124
+ "104": "wallaby, brush kangaroo",
125
+ "105": "koala, koala bear, kangaroo bear, native bear, Phascolarctos cinereus",
126
+ "106": "wombat",
127
+ "107": "jellyfish",
128
+ "108": "sea anemone, anemone",
129
+ "109": "brain coral",
130
+ "110": "flatworm, platyhelminth",
131
+ "111": "nematode, nematode worm, roundworm",
132
+ "112": "conch",
133
+ "113": "snail",
134
+ "114": "slug",
135
+ "115": "sea slug, nudibranch",
136
+ "116": "chiton, coat-of-mail shell, sea cradle, polyplacophore",
137
+ "117": "chambered nautilus, pearly nautilus, nautilus",
138
+ "118": "Dungeness crab, Cancer magister",
139
+ "119": "rock crab, Cancer irroratus",
140
+ "120": "fiddler crab",
141
+ "121": "king crab, Alaska crab, Alaskan king crab, Alaska king crab, Paralithodes camtschatica",
142
+ "122": "American lobster, Northern lobster, Maine lobster, Homarus americanus",
143
+ "123": "spiny lobster, langouste, rock lobster, crawfish, crayfish, sea crawfish",
144
+ "124": "crayfish, crawfish, crawdad, crawdaddy",
145
+ "125": "hermit crab",
146
+ "126": "isopod",
147
+ "127": "white stork, Ciconia ciconia",
148
+ "128": "black stork, Ciconia nigra",
149
+ "129": "spoonbill",
150
+ "130": "flamingo",
151
+ "131": "little blue heron, Egretta caerulea",
152
+ "132": "American egret, great white heron, Egretta albus",
153
+ "133": "bittern",
154
+ "134": "crane",
155
+ "135": "limpkin, Aramus pictus",
156
+ "136": "European gallinule, Porphyrio porphyrio",
157
+ "137": "American coot, marsh hen, mud hen, water hen, Fulica americana",
158
+ "138": "bustard",
159
+ "139": "ruddy turnstone, Arenaria interpres",
160
+ "140": "red-backed sandpiper, dunlin, Erolia alpina",
161
+ "141": "redshank, Tringa totanus",
162
+ "142": "dowitcher",
163
+ "143": "oystercatcher, oyster catcher",
164
+ "144": "pelican",
165
+ "145": "king penguin, Aptenodytes patagonica",
166
+ "146": "albatross, mollymawk",
167
+ "147": "grey whale, gray whale, devilfish, Eschrichtius gibbosus, Eschrichtius robustus",
168
+ "148": "killer whale, killer, orca, grampus, sea wolf, Orcinus orca",
169
+ "149": "dugong, Dugong dugon",
170
+ "150": "sea lion",
171
+ "151": "Chihuahua",
172
+ "152": "Japanese spaniel",
173
+ "153": "Maltese dog, Maltese terrier, Maltese",
174
+ "154": "Pekinese, Pekingese, Peke",
175
+ "155": "Shih-Tzu",
176
+ "156": "Blenheim spaniel",
177
+ "157": "papillon",
178
+ "158": "toy terrier",
179
+ "159": "Rhodesian ridgeback",
180
+ "160": "Afghan hound, Afghan",
181
+ "161": "basset, basset hound",
182
+ "162": "beagle",
183
+ "163": "bloodhound, sleuthhound",
184
+ "164": "bluetick",
185
+ "165": "black-and-tan coonhound",
186
+ "166": "Walker hound, Walker foxhound",
187
+ "167": "English foxhound",
188
+ "168": "redbone",
189
+ "169": "borzoi, Russian wolfhound",
190
+ "170": "Irish wolfhound",
191
+ "171": "Italian greyhound",
192
+ "172": "whippet",
193
+ "173": "Ibizan hound, Ibizan Podenco",
194
+ "174": "Norwegian elkhound, elkhound",
195
+ "175": "otterhound, otter hound",
196
+ "176": "Saluki, gazelle hound",
197
+ "177": "Scottish deerhound, deerhound",
198
+ "178": "Weimaraner",
199
+ "179": "Staffordshire bullterrier, Staffordshire bull terrier",
200
+ "180": "American Staffordshire terrier, Staffordshire terrier, American pit bull terrier, pit bull terrier",
201
+ "181": "Bedlington terrier",
202
+ "182": "Border terrier",
203
+ "183": "Kerry blue terrier",
204
+ "184": "Irish terrier",
205
+ "185": "Norfolk terrier",
206
+ "186": "Norwich terrier",
207
+ "187": "Yorkshire terrier",
208
+ "188": "wire-haired fox terrier",
209
+ "189": "Lakeland terrier",
210
+ "190": "Sealyham terrier, Sealyham",
211
+ "191": "Airedale, Airedale terrier",
212
+ "192": "cairn, cairn terrier",
213
+ "193": "Australian terrier",
214
+ "194": "Dandie Dinmont, Dandie Dinmont terrier",
215
+ "195": "Boston bull, Boston terrier",
216
+ "196": "miniature schnauzer",
217
+ "197": "giant schnauzer",
218
+ "198": "standard schnauzer",
219
+ "199": "Scotch terrier, Scottish terrier, Scottie",
220
+ "200": "Tibetan terrier, chrysanthemum dog",
221
+ "201": "silky terrier, Sydney silky",
222
+ "202": "soft-coated wheaten terrier",
223
+ "203": "West Highland white terrier",
224
+ "204": "Lhasa, Lhasa apso",
225
+ "205": "flat-coated retriever",
226
+ "206": "curly-coated retriever",
227
+ "207": "golden retriever",
228
+ "208": "Labrador retriever",
229
+ "209": "Chesapeake Bay retriever",
230
+ "210": "German short-haired pointer",
231
+ "211": "vizsla, Hungarian pointer",
232
+ "212": "English setter",
233
+ "213": "Irish setter, red setter",
234
+ "214": "Gordon setter",
235
+ "215": "Brittany spaniel",
236
+ "216": "clumber, clumber spaniel",
237
+ "217": "English springer, English springer spaniel",
238
+ "218": "Welsh springer spaniel",
239
+ "219": "cocker spaniel, English cocker spaniel, cocker",
240
+ "220": "Sussex spaniel",
241
+ "221": "Irish water spaniel",
242
+ "222": "kuvasz",
243
+ "223": "schipperke",
244
+ "224": "groenendael",
245
+ "225": "malinois",
246
+ "226": "briard",
247
+ "227": "kelpie",
248
+ "228": "komondor",
249
+ "229": "Old English sheepdog, bobtail",
250
+ "230": "Shetland sheepdog, Shetland sheep dog, Shetland",
251
+ "231": "collie",
252
+ "232": "Border collie",
253
+ "233": "Bouvier des Flandres, Bouviers des Flandres",
254
+ "234": "Rottweiler",
255
+ "235": "German shepherd, German shepherd dog, German police dog, alsatian",
256
+ "236": "Doberman, Doberman pinscher",
257
+ "237": "miniature pinscher",
258
+ "238": "Greater Swiss Mountain dog",
259
+ "239": "Bernese mountain dog",
260
+ "240": "Appenzeller",
261
+ "241": "EntleBucher",
262
+ "242": "boxer",
263
+ "243": "bull mastiff",
264
+ "244": "Tibetan mastiff",
265
+ "245": "French bulldog",
266
+ "246": "Great Dane",
267
+ "247": "Saint Bernard, St Bernard",
268
+ "248": "Eskimo dog, husky",
269
+ "249": "malamute, malemute, Alaskan malamute",
270
+ "250": "Siberian husky",
271
+ "251": "dalmatian, coach dog, carriage dog",
272
+ "252": "affenpinscher, monkey pinscher, monkey dog",
273
+ "253": "basenji",
274
+ "254": "pug, pug-dog",
275
+ "255": "Leonberg",
276
+ "256": "Newfoundland, Newfoundland dog",
277
+ "257": "Great Pyrenees",
278
+ "258": "Samoyed, Samoyede",
279
+ "259": "Pomeranian",
280
+ "260": "chow, chow chow",
281
+ "261": "keeshond",
282
+ "262": "Brabancon griffon",
283
+ "263": "Pembroke, Pembroke Welsh corgi",
284
+ "264": "Cardigan, Cardigan Welsh corgi",
285
+ "265": "toy poodle",
286
+ "266": "miniature poodle",
287
+ "267": "standard poodle",
288
+ "268": "Mexican hairless",
289
+ "269": "timber wolf, grey wolf, gray wolf, Canis lupus",
290
+ "270": "white wolf, Arctic wolf, Canis lupus tundrarum",
291
+ "271": "red wolf, maned wolf, Canis rufus, Canis niger",
292
+ "272": "coyote, prairie wolf, brush wolf, Canis latrans",
293
+ "273": "dingo, warrigal, warragal, Canis dingo",
294
+ "274": "dhole, Cuon alpinus",
295
+ "275": "African hunting dog, hyena dog, Cape hunting dog, Lycaon pictus",
296
+ "276": "hyena, hyaena",
297
+ "277": "red fox, Vulpes vulpes",
298
+ "278": "kit fox, Vulpes macrotis",
299
+ "279": "Arctic fox, white fox, Alopex lagopus",
300
+ "280": "grey fox, gray fox, Urocyon cinereoargenteus",
301
+ "281": "tabby, tabby cat",
302
+ "282": "tiger cat",
303
+ "283": "Persian cat",
304
+ "284": "Siamese cat, Siamese",
305
+ "285": "Egyptian cat",
306
+ "286": "cougar, puma, catamount, mountain lion, painter, panther, Felis concolor",
307
+ "287": "lynx, catamount",
308
+ "288": "leopard, Panthera pardus",
309
+ "289": "snow leopard, ounce, Panthera uncia",
310
+ "290": "jaguar, panther, Panthera onca, Felis onca",
311
+ "291": "lion, king of beasts, Panthera leo",
312
+ "292": "tiger, Panthera tigris",
313
+ "293": "cheetah, chetah, Acinonyx jubatus",
314
+ "294": "brown bear, bruin, Ursus arctos",
315
+ "295": "American black bear, black bear, Ursus americanus, Euarctos americanus",
316
+ "296": "ice bear, polar bear, Ursus Maritimus, Thalarctos maritimus",
317
+ "297": "sloth bear, Melursus ursinus, Ursus ursinus",
318
+ "298": "mongoose",
319
+ "299": "meerkat, mierkat",
320
+ "300": "tiger beetle",
321
+ "301": "ladybug, ladybeetle, lady beetle, ladybird, ladybird beetle",
322
+ "302": "ground beetle, carabid beetle",
323
+ "303": "long-horned beetle, longicorn, longicorn beetle",
324
+ "304": "leaf beetle, chrysomelid",
325
+ "305": "dung beetle",
326
+ "306": "rhinoceros beetle",
327
+ "307": "weevil",
328
+ "308": "fly",
329
+ "309": "bee",
330
+ "310": "ant, emmet, pismire",
331
+ "311": "grasshopper, hopper",
332
+ "312": "cricket",
333
+ "313": "walking stick, walkingstick, stick insect",
334
+ "314": "cockroach, roach",
335
+ "315": "mantis, mantid",
336
+ "316": "cicada, cicala",
337
+ "317": "leafhopper",
338
+ "318": "lacewing, lacewing fly",
339
+ "319": "dragonfly, darning needle, devils darning needle, sewing needle, snake feeder, snake doctor, mosquito hawk, skeeter hawk",
340
+ "320": "damselfly",
341
+ "321": "admiral",
342
+ "322": "ringlet, ringlet butterfly",
343
+ "323": "monarch, monarch butterfly, milkweed butterfly, Danaus plexippus",
344
+ "324": "cabbage butterfly",
345
+ "325": "sulphur butterfly, sulfur butterfly",
346
+ "326": "lycaenid, lycaenid butterfly",
347
+ "327": "starfish, sea star",
348
+ "328": "sea urchin",
349
+ "329": "sea cucumber, holothurian",
350
+ "330": "wood rabbit, cottontail, cottontail rabbit",
351
+ "331": "hare",
352
+ "332": "Angora, Angora rabbit",
353
+ "333": "hamster",
354
+ "334": "porcupine, hedgehog",
355
+ "335": "fox squirrel, eastern fox squirrel, Sciurus niger",
356
+ "336": "marmot",
357
+ "337": "beaver",
358
+ "338": "guinea pig, Cavia cobaya",
359
+ "339": "sorrel",
360
+ "340": "zebra",
361
+ "341": "hog, pig, grunter, squealer, Sus scrofa",
362
+ "342": "wild boar, boar, Sus scrofa",
363
+ "343": "warthog",
364
+ "344": "hippopotamus, hippo, river horse, Hippopotamus amphibius",
365
+ "345": "ox",
366
+ "346": "water buffalo, water ox, Asiatic buffalo, Bubalus bubalis",
367
+ "347": "bison",
368
+ "348": "ram, tup",
369
+ "349": "bighorn, bighorn sheep, cimarron, Rocky Mountain bighorn, Rocky Mountain sheep, Ovis canadensis",
370
+ "350": "ibex, Capra ibex",
371
+ "351": "hartebeest",
372
+ "352": "impala, Aepyceros melampus",
373
+ "353": "gazelle",
374
+ "354": "Arabian camel, dromedary, Camelus dromedarius",
375
+ "355": "llama",
376
+ "356": "weasel",
377
+ "357": "mink",
378
+ "358": "polecat, fitch, foulmart, foumart, Mustela putorius",
379
+ "359": "black-footed ferret, ferret, Mustela nigripes",
380
+ "360": "otter",
381
+ "361": "skunk, polecat, wood pussy",
382
+ "362": "badger",
383
+ "363": "armadillo",
384
+ "364": "three-toed sloth, ai, Bradypus tridactylus",
385
+ "365": "orangutan, orang, orangutang, Pongo pygmaeus",
386
+ "366": "gorilla, Gorilla gorilla",
387
+ "367": "chimpanzee, chimp, Pan troglodytes",
388
+ "368": "gibbon, Hylobates lar",
389
+ "369": "siamang, Hylobates syndactylus, Symphalangus syndactylus",
390
+ "370": "guenon, guenon monkey",
391
+ "371": "patas, hussar monkey, Erythrocebus patas",
392
+ "372": "baboon",
393
+ "373": "macaque",
394
+ "374": "langur",
395
+ "375": "colobus, colobus monkey",
396
+ "376": "proboscis monkey, Nasalis larvatus",
397
+ "377": "marmoset",
398
+ "378": "capuchin, ringtail, Cebus capucinus",
399
+ "379": "howler monkey, howler",
400
+ "380": "titi, titi monkey",
401
+ "381": "spider monkey, Ateles geoffroyi",
402
+ "382": "squirrel monkey, Saimiri sciureus",
403
+ "383": "Madagascar cat, ring-tailed lemur, Lemur catta",
404
+ "384": "indri, indris, Indri indri, Indri brevicaudatus",
405
+ "385": "Indian elephant, Elephas maximus",
406
+ "386": "African elephant, Loxodonta africana",
407
+ "387": "lesser panda, red panda, panda, bear cat, cat bear, Ailurus fulgens",
408
+ "388": "giant panda, panda, panda bear, coon bear, Ailuropoda melanoleuca",
409
+ "389": "barracouta, snoek",
410
+ "390": "eel",
411
+ "391": "coho, cohoe, coho salmon, blue jack, silver salmon, Oncorhynchus kisutch",
412
+ "392": "rock beauty, Holocanthus tricolor",
413
+ "393": "anemone fish",
414
+ "394": "sturgeon",
415
+ "395": "gar, garfish, garpike, billfish, Lepisosteus osseus",
416
+ "396": "lionfish",
417
+ "397": "puffer, pufferfish, blowfish, globefish",
418
+ "398": "abacus",
419
+ "399": "abaya",
420
+ "400": "academic gown, academic robe, judge robe",
421
+ "401": "accordion, piano accordion, squeeze box",
422
+ "402": "acoustic guitar",
423
+ "403": "aircraft carrier, carrier, flattop, attack aircraft carrier",
424
+ "404": "airliner",
425
+ "405": "airship, dirigible",
426
+ "406": "altar",
427
+ "407": "ambulance",
428
+ "408": "amphibian, amphibious vehicle",
429
+ "409": "analog clock",
430
+ "410": "apiary, bee house",
431
+ "411": "apron",
432
+ "412": "ashcan, trash can, garbage can, wastebin, ash bin, ash-bin, ashbin, dustbin, trash barrel, trash bin",
433
+ "413": "assault rifle, assault gun",
434
+ "414": "backpack, back pack, knapsack, packsack, rucksack, haversack",
435
+ "415": "bakery, bakeshop, bakehouse",
436
+ "416": "balance beam, beam",
437
+ "417": "balloon",
438
+ "418": "ballpoint, ballpoint pen, ballpen, Biro",
439
+ "419": "Band Aid",
440
+ "420": "banjo",
441
+ "421": "bannister, banister, balustrade, balusters, handrail",
442
+ "422": "barbell",
443
+ "423": "barber chair",
444
+ "424": "barbershop",
445
+ "425": "barn",
446
+ "426": "barometer",
447
+ "427": "barrel, cask",
448
+ "428": "barrow, garden cart, lawn cart, wheelbarrow",
449
+ "429": "baseball",
450
+ "430": "basketball",
451
+ "431": "bassinet",
452
+ "432": "bassoon",
453
+ "433": "bathing cap, swimming cap",
454
+ "434": "bath towel",
455
+ "435": "bathtub, bathing tub, bath, tub",
456
+ "436": "beach wagon, station wagon, wagon, estate car, beach waggon, station waggon, waggon",
457
+ "437": "beacon, lighthouse, beacon light, pharos",
458
+ "438": "beaker",
459
+ "439": "bearskin, busby, shako",
460
+ "440": "beer bottle",
461
+ "441": "beer glass",
462
+ "442": "bell cote, bell cot",
463
+ "443": "bib",
464
+ "444": "bicycle-built-for-two, tandem bicycle, tandem",
465
+ "445": "bikini, two-piece",
466
+ "446": "binder, ring-binder",
467
+ "447": "binoculars, field glasses, opera glasses",
468
+ "448": "birdhouse",
469
+ "449": "boathouse",
470
+ "450": "bobsled, bobsleigh, bob",
471
+ "451": "bolo tie, bolo, bola tie, bola",
472
+ "452": "bonnet, poke bonnet",
473
+ "453": "bookcase",
474
+ "454": "bookshop, bookstore, bookstall",
475
+ "455": "bottlecap",
476
+ "456": "bow",
477
+ "457": "bow tie, bow-tie, bowtie",
478
+ "458": "brass, memorial tablet, plaque",
479
+ "459": "brassiere, bra, bandeau",
480
+ "460": "breakwater, groin, groyne, mole, bulwark, seawall, jetty",
481
+ "461": "breastplate, aegis, egis",
482
+ "462": "broom",
483
+ "463": "bucket, pail",
484
+ "464": "buckle",
485
+ "465": "bulletproof vest",
486
+ "466": "bullet train, bullet",
487
+ "467": "butcher shop, meat market",
488
+ "468": "cab, hack, taxi, taxicab",
489
+ "469": "caldron, cauldron",
490
+ "470": "candle, taper, wax light",
491
+ "471": "cannon",
492
+ "472": "canoe",
493
+ "473": "can opener, tin opener",
494
+ "474": "cardigan",
495
+ "475": "car mirror",
496
+ "476": "carousel, carrousel, merry-go-round, roundabout, whirligig",
497
+ "477": "carpenters kit, tool kit",
498
+ "478": "carton",
499
+ "479": "car wheel",
500
+ "480": "cash machine, cash dispenser, automated teller machine, automatic teller machine, automated teller, automatic teller, ATM",
501
+ "481": "cassette",
502
+ "482": "cassette player",
503
+ "483": "castle",
504
+ "484": "catamaran",
505
+ "485": "CD player",
506
+ "486": "cello, violoncello",
507
+ "487": "cellular telephone, cellular phone, cellphone, cell, mobile phone",
508
+ "488": "chain",
509
+ "489": "chainlink fence",
510
+ "490": "chain mail, ring mail, mail, chain armor, chain armour, ring armor, ring armour",
511
+ "491": "chain saw, chainsaw",
512
+ "492": "chest",
513
+ "493": "chiffonier, commode",
514
+ "494": "chime, bell, gong",
515
+ "495": "china cabinet, china closet",
516
+ "496": "Christmas stocking",
517
+ "497": "church, church building",
518
+ "498": "cinema, movie theater, movie theatre, movie house, picture palace",
519
+ "499": "cleaver, meat cleaver, chopper",
520
+ "500": "cliff dwelling",
521
+ "501": "cloak",
522
+ "502": "clog, geta, patten, sabot",
523
+ "503": "cocktail shaker",
524
+ "504": "coffee mug",
525
+ "505": "coffeepot",
526
+ "506": "coil, spiral, volute, whorl, helix",
527
+ "507": "combination lock",
528
+ "508": "computer keyboard, keypad",
529
+ "509": "confectionery, confectionary, candy store",
530
+ "510": "container ship, containership, container vessel",
531
+ "511": "convertible",
532
+ "512": "corkscrew, bottle screw",
533
+ "513": "cornet, horn, trumpet, trump",
534
+ "514": "cowboy boot",
535
+ "515": "cowboy hat, ten-gallon hat",
536
+ "516": "cradle",
537
+ "517": "crane",
538
+ "518": "crash helmet",
539
+ "519": "crate",
540
+ "520": "crib, cot",
541
+ "521": "Crock Pot",
542
+ "522": "croquet ball",
543
+ "523": "crutch",
544
+ "524": "cuirass",
545
+ "525": "dam, dike, dyke",
546
+ "526": "desk",
547
+ "527": "desktop computer",
548
+ "528": "dial telephone, dial phone",
549
+ "529": "diaper, nappy, napkin",
550
+ "530": "digital clock",
551
+ "531": "digital watch",
552
+ "532": "dining table, board",
553
+ "533": "dishrag, dishcloth",
554
+ "534": "dishwasher, dish washer, dishwashing machine",
555
+ "535": "disk brake, disc brake",
556
+ "536": "dock, dockage, docking facility",
557
+ "537": "dogsled, dog sled, dog sleigh",
558
+ "538": "dome",
559
+ "539": "doormat, welcome mat",
560
+ "540": "drilling platform, offshore rig",
561
+ "541": "drum, membranophone, tympan",
562
+ "542": "drumstick",
563
+ "543": "dumbbell",
564
+ "544": "Dutch oven",
565
+ "545": "electric fan, blower",
566
+ "546": "electric guitar",
567
+ "547": "electric locomotive",
568
+ "548": "entertainment center",
569
+ "549": "envelope",
570
+ "550": "espresso maker",
571
+ "551": "face powder",
572
+ "552": "feather boa, boa",
573
+ "553": "file, file cabinet, filing cabinet",
574
+ "554": "fireboat",
575
+ "555": "fire engine, fire truck",
576
+ "556": "fire screen, fireguard",
577
+ "557": "flagpole, flagstaff",
578
+ "558": "flute, transverse flute",
579
+ "559": "folding chair",
580
+ "560": "football helmet",
581
+ "561": "forklift",
582
+ "562": "fountain",
583
+ "563": "fountain pen",
584
+ "564": "four-poster",
585
+ "565": "freight car",
586
+ "566": "French horn, horn",
587
+ "567": "frying pan, frypan, skillet",
588
+ "568": "fur coat",
589
+ "569": "garbage truck, dustcart",
590
+ "570": "gasmask, respirator, gas helmet",
591
+ "571": "gas pump, gasoline pump, petrol pump, island dispenser",
592
+ "572": "goblet",
593
+ "573": "go-kart",
594
+ "574": "golf ball",
595
+ "575": "golfcart, golf cart",
596
+ "576": "gondola",
597
+ "577": "gong, tam-tam",
598
+ "578": "gown",
599
+ "579": "grand piano, grand",
600
+ "580": "greenhouse, nursery, glasshouse",
601
+ "581": "grille, radiator grille",
602
+ "582": "grocery store, grocery, food market, market",
603
+ "583": "guillotine",
604
+ "584": "hair slide",
605
+ "585": "hair spray",
606
+ "586": "half track",
607
+ "587": "hammer",
608
+ "588": "hamper",
609
+ "589": "hand blower, blow dryer, blow drier, hair dryer, hair drier",
610
+ "590": "hand-held computer, hand-held microcomputer",
611
+ "591": "handkerchief, hankie, hanky, hankey",
612
+ "592": "hard disc, hard disk, fixed disk",
613
+ "593": "harmonica, mouth organ, harp, mouth harp",
614
+ "594": "harp",
615
+ "595": "harvester, reaper",
616
+ "596": "hatchet",
617
+ "597": "holster",
618
+ "598": "home theater, home theatre",
619
+ "599": "honeycomb",
620
+ "600": "hook, claw",
621
+ "601": "hoopskirt, crinoline",
622
+ "602": "horizontal bar, high bar",
623
+ "603": "horse cart, horse-cart",
624
+ "604": "hourglass",
625
+ "605": "iPod",
626
+ "606": "iron, smoothing iron",
627
+ "607": "jack-o-lantern",
628
+ "608": "jean, blue jean, denim",
629
+ "609": "jeep, landrover",
630
+ "610": "jersey, T-shirt, tee shirt",
631
+ "611": "jigsaw puzzle",
632
+ "612": "jinrikisha, ricksha, rickshaw",
633
+ "613": "joystick",
634
+ "614": "kimono",
635
+ "615": "knee pad",
636
+ "616": "knot",
637
+ "617": "lab coat, laboratory coat",
638
+ "618": "ladle",
639
+ "619": "lampshade, lamp shade",
640
+ "620": "laptop, laptop computer",
641
+ "621": "lawn mower, mower",
642
+ "622": "lens cap, lens cover",
643
+ "623": "letter opener, paper knife, paperknife",
644
+ "624": "library",
645
+ "625": "lifeboat",
646
+ "626": "lighter, light, igniter, ignitor",
647
+ "627": "limousine, limo",
648
+ "628": "liner, ocean liner",
649
+ "629": "lipstick, lip rouge",
650
+ "630": "Loafer",
651
+ "631": "lotion",
652
+ "632": "loudspeaker, speaker, speaker unit, loudspeaker system, speaker system",
653
+ "633": "loupe, jewelers loupe",
654
+ "634": "lumbermill, sawmill",
655
+ "635": "magnetic compass",
656
+ "636": "mailbag, postbag",
657
+ "637": "mailbox, letter box",
658
+ "638": "maillot",
659
+ "639": "maillot, tank suit",
660
+ "640": "manhole cover",
661
+ "641": "maraca",
662
+ "642": "marimba, xylophone",
663
+ "643": "mask",
664
+ "644": "matchstick",
665
+ "645": "maypole",
666
+ "646": "maze, labyrinth",
667
+ "647": "measuring cup",
668
+ "648": "medicine chest, medicine cabinet",
669
+ "649": "megalith, megalithic structure",
670
+ "650": "microphone, mike",
671
+ "651": "microwave, microwave oven",
672
+ "652": "military uniform",
673
+ "653": "milk can",
674
+ "654": "minibus",
675
+ "655": "miniskirt, mini",
676
+ "656": "minivan",
677
+ "657": "missile",
678
+ "658": "mitten",
679
+ "659": "mixing bowl",
680
+ "660": "mobile home, manufactured home",
681
+ "661": "Model T",
682
+ "662": "modem",
683
+ "663": "monastery",
684
+ "664": "monitor",
685
+ "665": "moped",
686
+ "666": "mortar",
687
+ "667": "mortarboard",
688
+ "668": "mosque",
689
+ "669": "mosquito net",
690
+ "670": "motor scooter, scooter",
691
+ "671": "mountain bike, all-terrain bike, off-roader",
692
+ "672": "mountain tent",
693
+ "673": "mouse, computer mouse",
694
+ "674": "mousetrap",
695
+ "675": "moving van",
696
+ "676": "muzzle",
697
+ "677": "nail",
698
+ "678": "neck brace",
699
+ "679": "necklace",
700
+ "680": "nipple",
701
+ "681": "notebook, notebook computer",
702
+ "682": "obelisk",
703
+ "683": "oboe, hautboy, hautbois",
704
+ "684": "ocarina, sweet potato",
705
+ "685": "odometer, hodometer, mileometer, milometer",
706
+ "686": "oil filter",
707
+ "687": "organ, pipe organ",
708
+ "688": "oscilloscope, scope, cathode-ray oscilloscope, CRO",
709
+ "689": "overskirt",
710
+ "690": "oxcart",
711
+ "691": "oxygen mask",
712
+ "692": "packet",
713
+ "693": "paddle, boat paddle",
714
+ "694": "paddlewheel, paddle wheel",
715
+ "695": "padlock",
716
+ "696": "paintbrush",
717
+ "697": "pajama, pyjama, pjs, jammies",
718
+ "698": "palace",
719
+ "699": "panpipe, pandean pipe, syrinx",
720
+ "700": "paper towel",
721
+ "701": "parachute, chute",
722
+ "702": "parallel bars, bars",
723
+ "703": "park bench",
724
+ "704": "parking meter",
725
+ "705": "passenger car, coach, carriage",
726
+ "706": "patio, terrace",
727
+ "707": "pay-phone, pay-station",
728
+ "708": "pedestal, plinth, footstall",
729
+ "709": "pencil box, pencil case",
730
+ "710": "pencil sharpener",
731
+ "711": "perfume, essence",
732
+ "712": "Petri dish",
733
+ "713": "photocopier",
734
+ "714": "pick, plectrum, plectron",
735
+ "715": "pickelhaube",
736
+ "716": "picket fence, paling",
737
+ "717": "pickup, pickup truck",
738
+ "718": "pier",
739
+ "719": "piggy bank, penny bank",
740
+ "720": "pill bottle",
741
+ "721": "pillow",
742
+ "722": "ping-pong ball",
743
+ "723": "pinwheel",
744
+ "724": "pirate, pirate ship",
745
+ "725": "pitcher, ewer",
746
+ "726": "plane, carpenters plane, woodworking plane",
747
+ "727": "planetarium",
748
+ "728": "plastic bag",
749
+ "729": "plate rack",
750
+ "730": "plow, plough",
751
+ "731": "plunger, plumbers helper",
752
+ "732": "Polaroid camera, Polaroid Land camera",
753
+ "733": "pole",
754
+ "734": "police van, police wagon, paddy wagon, patrol wagon, wagon, black Maria",
755
+ "735": "poncho",
756
+ "736": "pool table, billiard table, snooker table",
757
+ "737": "pop bottle, soda bottle",
758
+ "738": "pot, flowerpot",
759
+ "739": "potters wheel",
760
+ "740": "power drill",
761
+ "741": "prayer rug, prayer mat",
762
+ "742": "printer",
763
+ "743": "prison, prison house",
764
+ "744": "projectile, missile",
765
+ "745": "projector",
766
+ "746": "puck, hockey puck",
767
+ "747": "punching bag, punch bag, punching ball, punchball",
768
+ "748": "purse",
769
+ "749": "quill, quill pen",
770
+ "750": "quilt, comforter, comfort, puff",
771
+ "751": "racer, race car, racing car",
772
+ "752": "racket, racquet",
773
+ "753": "radiator",
774
+ "754": "radio, wireless",
775
+ "755": "radio telescope, radio reflector",
776
+ "756": "rain barrel",
777
+ "757": "recreational vehicle, RV, R.V.",
778
+ "758": "reel",
779
+ "759": "reflex camera",
780
+ "760": "refrigerator, icebox",
781
+ "761": "remote control, remote",
782
+ "762": "restaurant, eating house, eating place, eatery",
783
+ "763": "revolver, six-gun, six-shooter",
784
+ "764": "rifle",
785
+ "765": "rocking chair, rocker",
786
+ "766": "rotisserie",
787
+ "767": "rubber eraser, rubber, pencil eraser",
788
+ "768": "rugby ball",
789
+ "769": "rule, ruler",
790
+ "770": "running shoe",
791
+ "771": "safe",
792
+ "772": "safety pin",
793
+ "773": "saltshaker, salt shaker",
794
+ "774": "sandal",
795
+ "775": "sarong",
796
+ "776": "sax, saxophone",
797
+ "777": "scabbard",
798
+ "778": "scale, weighing machine",
799
+ "779": "school bus",
800
+ "780": "schooner",
801
+ "781": "scoreboard",
802
+ "782": "screen, CRT screen",
803
+ "783": "screw",
804
+ "784": "screwdriver",
805
+ "785": "seat belt, seatbelt",
806
+ "786": "sewing machine",
807
+ "787": "shield, buckler",
808
+ "788": "shoe shop, shoe-shop, shoe store",
809
+ "789": "shoji",
810
+ "790": "shopping basket",
811
+ "791": "shopping cart",
812
+ "792": "shovel",
813
+ "793": "shower cap",
814
+ "794": "shower curtain",
815
+ "795": "ski",
816
+ "796": "ski mask",
817
+ "797": "sleeping bag",
818
+ "798": "slide rule, slipstick",
819
+ "799": "sliding door",
820
+ "800": "slot, one-armed bandit",
821
+ "801": "snorkel",
822
+ "802": "snowmobile",
823
+ "803": "snowplow, snowplough",
824
+ "804": "soap dispenser",
825
+ "805": "soccer ball",
826
+ "806": "sock",
827
+ "807": "solar dish, solar collector, solar furnace",
828
+ "808": "sombrero",
829
+ "809": "soup bowl",
830
+ "810": "space bar",
831
+ "811": "space heater",
832
+ "812": "space shuttle",
833
+ "813": "spatula",
834
+ "814": "speedboat",
835
+ "815": "spider web, spiders web",
836
+ "816": "spindle",
837
+ "817": "sports car, sport car",
838
+ "818": "spotlight, spot",
839
+ "819": "stage",
840
+ "820": "steam locomotive",
841
+ "821": "steel arch bridge",
842
+ "822": "steel drum",
843
+ "823": "stethoscope",
844
+ "824": "stole",
845
+ "825": "stone wall",
846
+ "826": "stopwatch, stop watch",
847
+ "827": "stove",
848
+ "828": "strainer",
849
+ "829": "streetcar, tram, tramcar, trolley, trolley car",
850
+ "830": "stretcher",
851
+ "831": "studio couch, day bed",
852
+ "832": "stupa, tope",
853
+ "833": "submarine, pigboat, sub, U-boat",
854
+ "834": "suit, suit of clothes",
855
+ "835": "sundial",
856
+ "836": "sunglass",
857
+ "837": "sunglasses, dark glasses, shades",
858
+ "838": "sunscreen, sunblock, sun blocker",
859
+ "839": "suspension bridge",
860
+ "840": "swab, swob, mop",
861
+ "841": "sweatshirt",
862
+ "842": "swimming trunks, bathing trunks",
863
+ "843": "swing",
864
+ "844": "switch, electric switch, electrical switch",
865
+ "845": "syringe",
866
+ "846": "table lamp",
867
+ "847": "tank, army tank, armored combat vehicle, armoured combat vehicle",
868
+ "848": "tape player",
869
+ "849": "teapot",
870
+ "850": "teddy, teddy bear",
871
+ "851": "television, television system",
872
+ "852": "tennis ball",
873
+ "853": "thatch, thatched roof",
874
+ "854": "theater curtain, theatre curtain",
875
+ "855": "thimble",
876
+ "856": "thresher, thrasher, threshing machine",
877
+ "857": "throne",
878
+ "858": "tile roof",
879
+ "859": "toaster",
880
+ "860": "tobacco shop, tobacconist shop, tobacconist",
881
+ "861": "toilet seat",
882
+ "862": "torch",
883
+ "863": "totem pole",
884
+ "864": "tow truck, tow car, wrecker",
885
+ "865": "toyshop",
886
+ "866": "tractor",
887
+ "867": "trailer truck, tractor trailer, trucking rig, rig, articulated lorry, semi",
888
+ "868": "tray",
889
+ "869": "trench coat",
890
+ "870": "tricycle, trike, velocipede",
891
+ "871": "trimaran",
892
+ "872": "tripod",
893
+ "873": "triumphal arch",
894
+ "874": "trolleybus, trolley coach, trackless trolley",
895
+ "875": "trombone",
896
+ "876": "tub, vat",
897
+ "877": "turnstile",
898
+ "878": "typewriter keyboard",
899
+ "879": "umbrella",
900
+ "880": "unicycle, monocycle",
901
+ "881": "upright, upright piano",
902
+ "882": "vacuum, vacuum cleaner",
903
+ "883": "vase",
904
+ "884": "vault",
905
+ "885": "velvet",
906
+ "886": "vending machine",
907
+ "887": "vestment",
908
+ "888": "viaduct",
909
+ "889": "violin, fiddle",
910
+ "890": "volleyball",
911
+ "891": "waffle iron",
912
+ "892": "wall clock",
913
+ "893": "wallet, billfold, notecase, pocketbook",
914
+ "894": "wardrobe, closet, press",
915
+ "895": "warplane, military plane",
916
+ "896": "washbasin, handbasin, washbowl, lavabo, wash-hand basin",
917
+ "897": "washer, automatic washer, washing machine",
918
+ "898": "water bottle",
919
+ "899": "water jug",
920
+ "900": "water tower",
921
+ "901": "whiskey jug",
922
+ "902": "whistle",
923
+ "903": "wig",
924
+ "904": "window screen",
925
+ "905": "window shade",
926
+ "906": "Windsor tie",
927
+ "907": "wine bottle",
928
+ "908": "wing",
929
+ "909": "wok",
930
+ "910": "wooden spoon",
931
+ "911": "wool, woolen, woollen",
932
+ "912": "worm fence, snake fence, snake-rail fence, Virginia fence",
933
+ "913": "wreck",
934
+ "914": "yawl",
935
+ "915": "yurt",
936
+ "916": "web site, website, internet site, site",
937
+ "917": "comic book",
938
+ "918": "crossword puzzle, crossword",
939
+ "919": "street sign",
940
+ "920": "traffic light, traffic signal, stoplight",
941
+ "921": "book jacket, dust cover, dust jacket, dust wrapper",
942
+ "922": "menu",
943
+ "923": "plate",
944
+ "924": "guacamole",
945
+ "925": "consomme",
946
+ "926": "hot pot, hotpot",
947
+ "927": "trifle",
948
+ "928": "ice cream, icecream",
949
+ "929": "ice lolly, lolly, lollipop, popsicle",
950
+ "930": "French loaf",
951
+ "931": "bagel, beigel",
952
+ "932": "pretzel",
953
+ "933": "cheeseburger",
954
+ "934": "hotdog, hot dog, red hot",
955
+ "935": "mashed potato",
956
+ "936": "head cabbage",
957
+ "937": "broccoli",
958
+ "938": "cauliflower",
959
+ "939": "zucchini, courgette",
960
+ "940": "spaghetti squash",
961
+ "941": "acorn squash",
962
+ "942": "butternut squash",
963
+ "943": "cucumber, cuke",
964
+ "944": "artichoke, globe artichoke",
965
+ "945": "bell pepper",
966
+ "946": "cardoon",
967
+ "947": "mushroom",
968
+ "948": "Granny Smith",
969
+ "949": "strawberry",
970
+ "950": "orange",
971
+ "951": "lemon",
972
+ "952": "fig",
973
+ "953": "pineapple, ananas",
974
+ "954": "banana",
975
+ "955": "jackfruit, jak, jack",
976
+ "956": "custard apple",
977
+ "957": "pomegranate",
978
+ "958": "hay",
979
+ "959": "carbonara",
980
+ "960": "chocolate sauce, chocolate syrup",
981
+ "961": "dough",
982
+ "962": "meat loaf, meatloaf",
983
+ "963": "pizza, pizza pie",
984
+ "964": "potpie",
985
+ "965": "burrito",
986
+ "966": "red wine",
987
+ "967": "espresso",
988
+ "968": "cup",
989
+ "969": "eggnog",
990
+ "970": "alp",
991
+ "971": "bubble",
992
+ "972": "cliff, drop, drop-off",
993
+ "973": "coral reef",
994
+ "974": "geyser",
995
+ "975": "lakeside, lakeshore",
996
+ "976": "promontory, headland, head, foreland",
997
+ "977": "sandbar, sand bar",
998
+ "978": "seashore, coast, seacoast, sea-coast",
999
+ "979": "valley, vale",
1000
+ "980": "volcano",
1001
+ "981": "ballplayer, baseball player",
1002
+ "982": "groom, bridegroom",
1003
+ "983": "scuba diver",
1004
+ "984": "rapeseed",
1005
+ "985": "daisy",
1006
+ "986": "yellow ladys slipper, yellow lady-slipper, Cypripedium calceolus, Cypripedium parviflorum",
1007
+ "987": "corn",
1008
+ "988": "acorn",
1009
+ "989": "hip, rose hip, rosehip",
1010
+ "990": "buckeye, horse chestnut, conker",
1011
+ "991": "coral fungus",
1012
+ "992": "agaric",
1013
+ "993": "gyromitra",
1014
+ "994": "stinkhorn, carrion fungus",
1015
+ "995": "earthstar",
1016
+ "996": "hen-of-the-woods, hen of the woods, Polyporus frondosus, Grifola frondosa",
1017
+ "997": "bolete",
1018
+ "998": "ear, spike, capitulum",
1019
+ "999": "toilet tissue, toilet paper, bathroom tissue"
1020
+ }
1021
+ }
W-Flow-B/pipeline.py ADDED
@@ -0,0 +1,754 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2026 The HuggingFace Team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import importlib.util
16
+ import inspect
17
+ import json
18
+ import sys
19
+ from pathlib import Path
20
+ from typing import Any, Callable
21
+
22
+ import torch
23
+ from diffusers.callbacks import MultiPipelineCallbacks, PipelineCallback
24
+ from diffusers.models.autoencoders.autoencoder_kl import AutoencoderKL
25
+ from diffusers.models.modeling_utils import ModelMixin
26
+ from diffusers.pipelines.pipeline_utils import DiffusionPipeline, ImagePipelineOutput
27
+ from diffusers.schedulers import KarrasDiffusionSchedulers
28
+ from diffusers.schedulers.scheduling_utils import SchedulerMixin
29
+ from diffusers.utils import deprecate, is_torch_xla_available, logging, replace_example_docstring
30
+ from PIL import Image
31
+
32
+ if is_torch_xla_available():
33
+ import torch_xla.core.xla_model as xm
34
+
35
+ XLA_AVAILABLE = True
36
+ else:
37
+ XLA_AVAILABLE = False
38
+
39
+ logger = logging.get_logger(__name__)
40
+
41
+ EXAMPLE_DOC_STRING = """
42
+ Examples:
43
+ ```py
44
+ >>> from pathlib import Path
45
+ >>> import torch
46
+ >>> from diffusers import DiffusionPipeline
47
+
48
+ >>> model_dir = Path("W-Flow-diffusers/W-Flow-B").resolve()
49
+ >>> pipe = DiffusionPipeline.from_pretrained(
50
+ ... str(model_dir),
51
+ ... local_files_only=True,
52
+ ... custom_pipeline=str(model_dir / "pipeline.py"),
53
+ ... trust_remote_code=True,
54
+ ... torch_dtype=torch.bfloat16,
55
+ ... ).to("cuda")
56
+
57
+ >>> image = pipe(
58
+ ... class_labels="golden retriever",
59
+ ... num_inference_steps=1,
60
+ ... guidance_scale=1.19,
61
+ ... generator=torch.Generator(device="cuda").manual_seed(1),
62
+ ... ).images[0]
63
+ >>> image.save("demo.png")
64
+
65
+ >>> # Hugging Face Hub style model id: UserID/RepoID
66
+ >>> # pipe = DiffusionPipeline.from_pretrained(
67
+ >>> # "BiliSakura/W-Flow-diffusers",
68
+ >>> # subfolder="W-Flow-B",
69
+ >>> # custom_pipeline="pipeline.py",
70
+ >>> # trust_remote_code=True,
71
+ >>> # torch_dtype=torch.bfloat16,
72
+ >>> # )
73
+ ```
74
+ """
75
+
76
+
77
+ class WFlowPipeline(DiffusionPipeline):
78
+ r"""
79
+ Class-conditional one-step pipeline for W-Flow.
80
+
81
+ W-Flow maps SD-VAE latent noise to a clean 32×32 latent in one forward pass, then decodes it
82
+ with `stabilityai/sd-vae-ft-mse` to a 256×256 image. Guidance is embedded in the generator
83
+ (the official `cfg_scale`, which is `w + 1` in the paper). There is no unconditional class
84
+ and no second forward.
85
+
86
+ The pipeline inherits from [`DiffusionPipeline`]. Check the superclass documentation for the
87
+ generic methods (download, save, device placement, CPU offload).
88
+
89
+ Args:
90
+ transformer ([`ModelMixin`]):
91
+ [`WFlowTransformer2DModel`] that predicts the clean latent.
92
+ vae ([`AutoencoderKL`]):
93
+ SD-VAE decoder. Released checkpoints use `stabilityai/sd-vae-ft-mse` and scaling 0.18215.
94
+ scheduler ([`WFlowScheduler`]):
95
+ One-step scheduler. Loaded from `scheduler/`.
96
+ id2label (`dict[int, str]`, *optional*):
97
+ ImageNet class id to English label mapping. Values may contain comma-separated synonyms.
98
+ Loaded from `model_index.json` when omitted.
99
+
100
+ The default guidance scale lives on `transformer.config.guidance_scale`.
101
+ """
102
+
103
+ model_cpu_offload_seq = "transformer->vae"
104
+ _callback_tensor_inputs = ["latents"]
105
+
106
+ def __init__(
107
+ self,
108
+ transformer: ModelMixin,
109
+ vae: AutoencoderKL,
110
+ scheduler: SchedulerMixin,
111
+ id2label: dict[int, str] | dict[str, str] | None = None,
112
+ ):
113
+ super().__init__()
114
+ if scheduler is None:
115
+ scheduler = self._default_scheduler()
116
+ self._reject_karras_scheduler(scheduler)
117
+ self.register_modules(transformer=transformer, vae=vae, scheduler=scheduler)
118
+ normalized_labels = self._normalize_id2label(id2label)
119
+ self.register_to_config(id2label={str(key): value for key, value in normalized_labels.items()})
120
+ self._id2label = normalized_labels
121
+ self.labels = self._build_label2id(self._id2label)
122
+ self._labels_loaded_from_model_index = bool(self._id2label)
123
+ self.vae_scale_factor = 2 ** (len(self.vae.config.block_out_channels) - 1)
124
+
125
+ def _sampling_default(self, name: str, fallback: float) -> float:
126
+ r"""
127
+ Read a sampling default from the transformer config.
128
+
129
+ Args:
130
+ name (`str`):
131
+ Key on `transformer.config`, such as `guidance_scale`.
132
+ fallback (`float`):
133
+ Value used when the transformer config does not define `name`.
134
+
135
+ Returns:
136
+ `float`: The configured value, or `fallback`.
137
+ """
138
+ value = getattr(self.transformer.config, name, None)
139
+ if value is None:
140
+ return fallback
141
+ return value
142
+
143
+ @staticmethod
144
+ def _reject_karras_scheduler(scheduler: SchedulerMixin) -> None:
145
+ r"""
146
+ Reject multi-step Karras schedulers.
147
+
148
+ W-Flow predicts the clean latent in one evaluation and has no diffusion timestep, so a
149
+ Karras noise schedule cannot be integrated.
150
+
151
+ Args:
152
+ scheduler ([`SchedulerMixin`]):
153
+ Scheduler attached to the pipeline.
154
+ """
155
+ scheduler_name = scheduler.__class__.__name__
156
+ if scheduler_name in KarrasDiffusionSchedulers.__members__:
157
+ raise TypeError(
158
+ "W-Flow is a one-step generator and does not integrate a Karras noise schedule. "
159
+ f"Received {scheduler_name}. Use WFlowScheduler."
160
+ )
161
+
162
+ @staticmethod
163
+ def _default_scheduler() -> SchedulerMixin:
164
+ r"""
165
+ Build [`WFlowScheduler`] from the variant directory.
166
+
167
+ Returns:
168
+ [`WFlowScheduler`]: One-step sample scheduler.
169
+ """
170
+ module_path = Path(__file__).resolve().parent / "scheduler" / "scheduling_wflow.py"
171
+ spec = importlib.util.spec_from_file_location("scheduling_wflow", module_path)
172
+ if spec is None or spec.loader is None:
173
+ raise ImportError(f"Could not load the W-Flow scheduler from {module_path}.")
174
+ module = importlib.util.module_from_spec(spec)
175
+ sys.modules["scheduling_wflow"] = module
176
+ spec.loader.exec_module(module)
177
+ return module.WFlowScheduler()
178
+
179
+ def _ensure_labels_loaded(self) -> None:
180
+ r"""
181
+ Fill `id2label` from `model_index.json` when the constructor did not receive it.
182
+ """
183
+ if self._labels_loaded_from_model_index:
184
+ return
185
+ loaded = self._read_id2label_from_model_index(getattr(self.config, "_name_or_path", None))
186
+ if loaded:
187
+ self._id2label = loaded
188
+ self.labels = self._build_label2id(self._id2label)
189
+ self._labels_loaded_from_model_index = True
190
+
191
+ @staticmethod
192
+ def _normalize_id2label(id2label: dict[int, str] | dict[str, str] | None) -> dict[int, str]:
193
+ r"""
194
+ Cast label-map keys to integers.
195
+
196
+ Args:
197
+ id2label (`dict`, *optional*):
198
+ Class id to English label. Keys may be strings, which is how JSON stores them.
199
+
200
+ Returns:
201
+ `dict[int, str]`: Integer-keyed map. Empty when `id2label` is missing.
202
+ """
203
+ if not id2label:
204
+ return {}
205
+ return {int(key): value for key, value in id2label.items()}
206
+
207
+ @staticmethod
208
+ def _read_id2label_from_model_index(variant_path: str | None) -> dict[int, str]:
209
+ r"""
210
+ Read `id2label` from a local variant directory.
211
+
212
+ Args:
213
+ variant_path (`str`, *optional*):
214
+ Directory that contains `model_index.json`.
215
+
216
+ Returns:
217
+ `dict[int, str]`: Loaded map, or an empty dict when the file or key is absent.
218
+ """
219
+ if not variant_path:
220
+ return {}
221
+ model_index_path = Path(variant_path).resolve() / "model_index.json"
222
+ if not model_index_path.exists():
223
+ return {}
224
+ raw = json.loads(model_index_path.read_text(encoding="utf-8"))
225
+ id2label = raw.get("id2label")
226
+ if not isinstance(id2label, dict):
227
+ return {}
228
+ return {int(key): value for key, value in id2label.items()}
229
+
230
+ @staticmethod
231
+ def _build_label2id(id2label: dict[int, str]) -> dict[str, int]:
232
+ r"""
233
+ Invert `id2label`, splitting comma-separated synonyms.
234
+
235
+ Args:
236
+ id2label (`dict[int, str]`):
237
+ Class id to one or more English names.
238
+
239
+ Returns:
240
+ `dict[str, int]`: Synonym to class id, sorted by synonym.
241
+ """
242
+ label2id: dict[str, int] = {}
243
+ for class_id, value in id2label.items():
244
+ for synonym in value.split(","):
245
+ synonym = synonym.strip()
246
+ if synonym:
247
+ label2id[synonym] = int(class_id)
248
+ return dict(sorted(label2id.items()))
249
+
250
+ @property
251
+ def interrupt(self) -> bool:
252
+ r"""
253
+ Whether the current call was asked to stop.
254
+
255
+ Returns:
256
+ `bool`: The `_interrupt` flag. `__call__` sets it to `False` at the start. Assign
257
+ `_interrupt = True` during a call to skip the remaining forward.
258
+ """
259
+ return self._interrupt
260
+
261
+ @property
262
+ def id2label(self) -> dict[int, str]:
263
+ r"""
264
+ ImageNet id to English label map.
265
+
266
+ Returns:
267
+ `dict[int, str]`: The map loaded from the constructor or `model_index.json`.
268
+ """
269
+ self._ensure_labels_loaded()
270
+ return self._id2label
271
+
272
+ def get_label_ids(self, label: str | list[str]) -> list[int]:
273
+ r"""
274
+ Map ImageNet English labels to class ids.
275
+
276
+ Args:
277
+ label (`str` or `list[str]`):
278
+ One label or a list of labels. Each string must match a synonym in `id2label`
279
+ after stripping whitespace. Synonyms are the comma-separated pieces of each value.
280
+
281
+ Returns:
282
+ `list[int]`: Class ids in the same order as `label`.
283
+ """
284
+ self._ensure_labels_loaded()
285
+ label2id = self.labels
286
+ if not label2id:
287
+ raise ValueError("No English labels loaded. Ensure `id2label` exists in model_index.json.")
288
+ if isinstance(label, str):
289
+ label = [label]
290
+ missing = [item for item in label if item not in label2id]
291
+ if missing:
292
+ preview = ", ".join(list(label2id.keys())[:8])
293
+ raise ValueError(f"Unknown English label(s): {missing}. Example valid labels: {preview}, ...")
294
+ return [label2id[item] for item in label]
295
+
296
+ def _normalize_class_labels(self, class_labels: int | str | list[int | str]) -> list[int]:
297
+ r"""
298
+ Turn a class-label argument into a list of integer ids.
299
+
300
+ Args:
301
+ class_labels (`int`, `str`, or `list`):
302
+ One id, one English label, or a list of either. A list must not mix types.
303
+
304
+ Returns:
305
+ `list[int]`: One id per requested image.
306
+ """
307
+ if isinstance(class_labels, int):
308
+ return [class_labels]
309
+ if isinstance(class_labels, str):
310
+ return self.get_label_ids(class_labels)
311
+ if len(class_labels) == 0:
312
+ raise ValueError("`class_labels` must contain at least one class id or label.")
313
+ if isinstance(class_labels[0], str):
314
+ if not all(isinstance(item, str) for item in class_labels):
315
+ raise TypeError("`class_labels` must be all strings or all integers.")
316
+ return self.get_label_ids(class_labels)
317
+ if not all(isinstance(item, int) for item in class_labels):
318
+ raise TypeError("`class_labels` must be all strings or all integers.")
319
+ return list(class_labels)
320
+
321
+ def prepare_extra_step_kwargs(
322
+ self,
323
+ generator: torch.Generator | list[torch.Generator] | None,
324
+ eta: float,
325
+ ) -> dict[str, Any]:
326
+ r"""
327
+ Extra arguments forwarded to `scheduler.step`, depending on what that method accepts.
328
+
329
+ Args:
330
+ generator (`torch.Generator` or `list[torch.Generator]`, *optional*):
331
+ Generator passed through when the scheduler step samples noise.
332
+ eta (`float`):
333
+ DDIM eta in `[0, 1]`. Ignored by [`WFlowScheduler`], whose `step` has no `eta` argument.
334
+
335
+ Returns:
336
+ `dict`: Keyword arguments for `scheduler.step`.
337
+ """
338
+ extra_step_kwargs: dict[str, Any] = {}
339
+ step_params = set(inspect.signature(self.scheduler.step).parameters.keys())
340
+ if "eta" in step_params:
341
+ extra_step_kwargs["eta"] = eta
342
+ if "generator" in step_params:
343
+ extra_step_kwargs["generator"] = generator
344
+ return extra_step_kwargs
345
+
346
+ def check_inputs(
347
+ self,
348
+ class_labels: int | str | list[int | str],
349
+ height: int,
350
+ width: int,
351
+ num_inference_steps: int,
352
+ guidance_scale: float,
353
+ noise_scale: float,
354
+ output_type: str,
355
+ callback_steps: int | None = None,
356
+ callback_on_step_end_tensor_inputs: list[str] | None = None,
357
+ ) -> None:
358
+ r"""
359
+ Reject arguments that the generator cannot run.
360
+
361
+ Args:
362
+ class_labels (`int`, `str`, or `list`):
363
+ Class ids or English labels. A list must be non-empty.
364
+ height (`int`):
365
+ Output height in pixels. Must be the pretrained resolution, 256.
366
+ width (`int`):
367
+ Output width in pixels. Must be the pretrained resolution, 256.
368
+ num_inference_steps (`int`):
369
+ Must be 1. W-Flow evaluates the network once.
370
+ guidance_scale (`float`):
371
+ Embedded guidance (`w + 1` in the paper). Must be finite and positive.
372
+ noise_scale (`float`):
373
+ Scale of the reference Gaussian, the official `temp`. Must be positive.
374
+ output_type (`str`):
375
+ One of `"pil"`, `"np"`, `"pt"`, `"latent"`.
376
+ callback_steps (`int`, *optional*):
377
+ Deprecated callback period. When set, must be a positive integer.
378
+ callback_on_step_end_tensor_inputs (`list[str]`, *optional*):
379
+ Tensor names the step callback may read. Each name must be in `_callback_tensor_inputs`.
380
+ """
381
+ if isinstance(class_labels, list) and len(class_labels) == 0:
382
+ raise ValueError("`class_labels` must contain at least one class id or label.")
383
+ native = int(self.transformer.config.sample_size) * int(self.vae_scale_factor)
384
+ if height != native or width != native:
385
+ raise ValueError(
386
+ f"`height` and `width` must be the pretrained resolution {native}. "
387
+ f"The patch embedding is fixed to a {self.transformer.config.sample_size} latent. Got {(height, width)}."
388
+ )
389
+ if num_inference_steps != 1:
390
+ raise ValueError(
391
+ "W-Flow generates in one forward pass. "
392
+ f"`num_inference_steps` must be 1, got {num_inference_steps}."
393
+ )
394
+ if not torch.isfinite(torch.tensor(float(guidance_scale))) or float(guidance_scale) <= 0:
395
+ raise ValueError(f"`guidance_scale` must be finite and positive, got {guidance_scale}.")
396
+ if noise_scale <= 0:
397
+ raise ValueError(f"`noise_scale` must be positive, got {noise_scale}.")
398
+ if output_type not in {"pil", "np", "pt", "latent"}:
399
+ raise ValueError(f"Unsupported `output_type` {output_type!r}. Choose from 'pil', 'np', 'pt', 'latent'.")
400
+ if callback_steps is not None and (not isinstance(callback_steps, int) or callback_steps < 1):
401
+ raise ValueError(f"`callback_steps` must be a positive integer, got {callback_steps}.")
402
+ if callback_on_step_end_tensor_inputs is not None:
403
+ unknown = [name for name in callback_on_step_end_tensor_inputs if name not in self._callback_tensor_inputs]
404
+ if unknown:
405
+ raise ValueError(
406
+ f"`callback_on_step_end_tensor_inputs` contains {unknown}, which are not in "
407
+ f"{self._callback_tensor_inputs}."
408
+ )
409
+
410
+ def prepare_latents(
411
+ self,
412
+ batch_size: int,
413
+ num_channels: int,
414
+ height: int,
415
+ width: int,
416
+ device: torch.device,
417
+ generator: torch.Generator | list[torch.Generator] | None,
418
+ latents: torch.Tensor | None,
419
+ noise_labels: torch.Tensor | None,
420
+ noise_scale: float,
421
+ ) -> tuple[torch.Tensor, torch.Tensor]:
422
+ r"""
423
+ Draw reference noise in the official generator order.
424
+
425
+ The official sampler draws `(batch, height, width, channels)` first, then integer noise
426
+ codes, from the same generator. This method follows that order so a seeded generator
427
+ matches `DitGen.forward`.
428
+
429
+ Args:
430
+ batch_size (`int`):
431
+ Number of images.
432
+ num_channels (`int`):
433
+ Latent channels. Released checkpoints use 4.
434
+ height (`int`):
435
+ Latent height. Released checkpoints use 32.
436
+ width (`int`):
437
+ Latent width. Released checkpoints use 32.
438
+ device (`torch.device`):
439
+ Device of the returned tensors.
440
+ generator (`torch.Generator` or `list[torch.Generator]`, *optional*):
441
+ RNG. A list must have one generator per image. Each generator is consumed in the
442
+ order Gaussian noise, then noise codes.
443
+ latents (`torch.Tensor`, *optional*):
444
+ Reference noise `(batch, channels, height, width)`. When set, it is not rescaled.
445
+ noise_labels (`torch.Tensor`, *optional*):
446
+ Integer codes `(batch, noise_coords)`. When omitted, they are drawn here.
447
+ noise_scale (`float`):
448
+ Multiplier on the Gaussian, the official `temp`. Ignored when `latents` is passed.
449
+
450
+ Returns:
451
+ `tuple[torch.Tensor, torch.Tensor]`:
452
+ Reference noise in BCHW float32, and noise codes `(batch, noise_coords)`.
453
+ """
454
+ noise_classes = int(self.transformer.config.noise_classes)
455
+ noise_coords = int(self.transformer.config.noise_coords)
456
+ if latents is None:
457
+ if isinstance(generator, list):
458
+ if len(generator) != batch_size:
459
+ raise ValueError(f"Got {len(generator)} generators for a batch of {batch_size}.")
460
+ pieces = [
461
+ torch.randn((1, height, width, num_channels), generator=one, device=device) for one in generator
462
+ ]
463
+ drawn = torch.cat(pieces, dim=0)
464
+ else:
465
+ drawn = torch.randn(
466
+ (batch_size, height, width, num_channels),
467
+ generator=generator,
468
+ device=device,
469
+ )
470
+ latents = drawn.permute(0, 3, 1, 2).contiguous() * float(noise_scale)
471
+ elif latents.shape != (batch_size, num_channels, height, width):
472
+ raise ValueError(
473
+ f"`latents` must have shape {(batch_size, num_channels, height, width)}, got {tuple(latents.shape)}."
474
+ )
475
+ else:
476
+ latents = latents.to(device=device)
477
+
478
+ if noise_labels is None:
479
+ if isinstance(generator, list) and latents is not None:
480
+ # When latents were supplied, generators have not been consumed yet only if the
481
+ # caller passed both. Drawing labels still uses those generators.
482
+ codes = [
483
+ torch.randint(0, noise_classes, (1, noise_coords), generator=one, device=device)
484
+ for one in generator
485
+ ]
486
+ noise_labels = torch.cat(codes, dim=0)
487
+ else:
488
+ noise_labels = torch.randint(
489
+ 0,
490
+ max(1, noise_classes),
491
+ (batch_size, max(1, noise_coords)),
492
+ generator=None if isinstance(generator, list) else generator,
493
+ device=device,
494
+ )
495
+ noise_labels = noise_labels.to(device=device, dtype=torch.long)
496
+ if noise_labels.shape != (batch_size, noise_coords):
497
+ raise ValueError(
498
+ f"`noise_labels` must have shape {(batch_size, noise_coords)}, got {tuple(noise_labels.shape)}."
499
+ )
500
+ return latents.float(), noise_labels
501
+
502
+ def _prepare_scheduler(self, num_inference_steps: int, device: torch.device) -> torch.Tensor:
503
+ r"""
504
+ Install the one-step schedule and return its timesteps.
505
+
506
+ Args:
507
+ num_inference_steps (`int`):
508
+ Must be 1.
509
+ device (`torch.device`):
510
+ Device of the timestep tensor.
511
+
512
+ Returns:
513
+ `torch.Tensor`: The single timestep.
514
+ """
515
+ self.scheduler.set_timesteps(num_inference_steps, device=device)
516
+ return self.scheduler.timesteps
517
+
518
+ def _decode_latents(self, latents: torch.Tensor) -> torch.Tensor:
519
+ r"""
520
+ Decode scaled SD-VAE latents to pixels in `[-1, 1]`.
521
+
522
+ Args:
523
+ latents (`torch.Tensor`):
524
+ Clean latents `(batch, 4, 32, 32)` in the training scale (`* 0.18215`).
525
+
526
+ Returns:
527
+ `torch.Tensor`: Images `(batch, 3, height, width)` in `[-1, 1]`.
528
+ """
529
+ scaling = float(getattr(self.vae.config, "scaling_factor", 0.18215))
530
+ needs_upcast = bool(getattr(self.vae.config, "force_upcast", False)) and self.vae.dtype != torch.float32
531
+ original_dtype = self.vae.dtype
532
+ if needs_upcast:
533
+ self.vae.to(dtype=torch.float32)
534
+ decoded = self.vae.decode((latents / scaling).to(dtype=self.vae.dtype), return_dict=False)[0]
535
+ if needs_upcast:
536
+ self.vae.to(dtype=original_dtype)
537
+ return decoded
538
+
539
+ def _images_from_pixels(self, pixels: torch.Tensor, output_type: str) -> list[Image.Image] | torch.Tensor | list:
540
+ r"""
541
+ Convert decoded pixels to the requested output type.
542
+
543
+ Args:
544
+ pixels (`torch.Tensor`):
545
+ Images `(batch, 3, height, width)` in `[-1, 1]`.
546
+ output_type (`str`):
547
+ `"pil"`, `"np"`, `"pt"` (float RGB in `[0, 1]`), or `"latent"`.
548
+
549
+ Returns:
550
+ Images in the requested type.
551
+ """
552
+ images = ((pixels.float() + 1) / 2).clamp(0, 1)
553
+ if output_type == "pt":
554
+ return images
555
+ images = (images * 255).round().to(torch.uint8)
556
+ arrays = images.permute(0, 2, 3, 1).cpu().numpy()
557
+ if output_type == "np":
558
+ return arrays
559
+ return [Image.fromarray(image) for image in arrays]
560
+
561
+ @torch.no_grad()
562
+ @replace_example_docstring(EXAMPLE_DOC_STRING)
563
+ def __call__(
564
+ self,
565
+ class_labels: int | str | list[int | str],
566
+ height: int | None = None,
567
+ width: int | None = None,
568
+ num_inference_steps: int | None = None,
569
+ guidance_scale: float | None = None,
570
+ noise_scale: float = 1.0,
571
+ eta: float = 0.0,
572
+ generator: torch.Generator | list[torch.Generator] | None = None,
573
+ latents: torch.Tensor | None = None,
574
+ noise_labels: torch.Tensor | None = None,
575
+ output_type: str = "pil",
576
+ return_dict: bool = True,
577
+ callback_on_step_end: Callable[[int, int, dict], dict] | PipelineCallback | MultiPipelineCallbacks | None = None,
578
+ callback_on_step_end_tensor_inputs: list[str] | None = None,
579
+ **kwargs,
580
+ ) -> ImagePipelineOutput | tuple:
581
+ r"""
582
+ Generate images from ImageNet class labels.
583
+
584
+ Args:
585
+ class_labels (`int`, `str`, or `list`):
586
+ One ImageNet class id, one English label, or a list of either. English labels are
587
+ resolved with [`get_label_ids`]. The list length is the batch size.
588
+ height (`int`, *optional*):
589
+ Image height in pixels. Defaults to 256 (`sample_size * vae_scale_factor`). Other
590
+ sizes are rejected because the patch embedding is fixed.
591
+ width (`int`, *optional*):
592
+ Image width in pixels. Defaults to 256.
593
+ num_inference_steps (`int`, *optional*):
594
+ Must be 1. Defaults to `transformer.config.default_num_inference_steps`.
595
+ guidance_scale (`float`, *optional*):
596
+ Official CFG value, equal to `w + 1` in the paper. Defaults to
597
+ `transformer.config.guidance_scale` (1.19 / 1.14 / 1.09 / 1.5 by variant). This
598
+ scale is embedded; the pipeline does not run an unconditional branch.
599
+ noise_scale (`float`, defaults to 1.0):
600
+ Multiplier on the reference Gaussian. The official sampler calls this `temp`.
601
+ Ignored when `latents` is passed.
602
+ eta (`float`, defaults to 0.0):
603
+ DDIM eta. Ignored by [`WFlowScheduler`].
604
+ generator (`torch.Generator` or `list[torch.Generator]`, *optional*):
605
+ RNG for the reference noise and the discrete noise codes. One generator is consumed
606
+ in that order, matching the official sampler.
607
+ latents (`torch.Tensor`, *optional*):
608
+ Reference noise `(batch, 4, 32, 32)`. Not multiplied by `noise_scale`.
609
+ noise_labels (`torch.Tensor`, *optional*):
610
+ Discrete noise codes `(batch, noise_coords)`. Drawn from `generator` when omitted.
611
+ output_type (`str`, defaults to `"pil"`):
612
+ `"pil"`, `"np"`, `"pt"` (float RGB in `[0, 1]`), or `"latent"` (scaled SD-VAE latent).
613
+ return_dict (`bool`, defaults to `True`):
614
+ Return [`ImagePipelineOutput`] when `True`, otherwise a one-tuple of images.
615
+ callback_on_step_end (`Callable` or `PipelineCallback`, *optional*):
616
+ Called as `callback_on_step_end(pipeline, step, timestep, callback_kwargs)` after the
617
+ scheduler step. Return a dict to replace tensors listed in
618
+ `callback_on_step_end_tensor_inputs`.
619
+ callback_on_step_end_tensor_inputs (`list[str]`, *optional*):
620
+ Tensor names passed to the step callback. Defaults to `["latents"]`.
621
+
622
+ Examples:
623
+
624
+ Returns:
625
+ [`ImagePipelineOutput`] or `tuple`:
626
+ When `return_dict` is `True`, [`ImagePipelineOutput`] with the images. Otherwise a tuple
627
+ whose first element is the images.
628
+ """
629
+ callback = kwargs.pop("callback", None)
630
+ callback_steps = kwargs.pop("callback_steps", None)
631
+ if kwargs:
632
+ raise TypeError(f"Unexpected arguments: {sorted(kwargs)}.")
633
+ if callback_on_step_end_tensor_inputs is None:
634
+ callback_on_step_end_tensor_inputs = ["latents"]
635
+
636
+ if callback is not None:
637
+ deprecate(
638
+ "callback",
639
+ "1.0.0",
640
+ "Passing `callback` as an input argument to `__call__` is deprecated, consider using `callback_on_step_end`",
641
+ )
642
+ if callback_steps is not None:
643
+ deprecate(
644
+ "callback_steps",
645
+ "1.0.0",
646
+ "Passing `callback_steps` as an input argument to `__call__` is deprecated, consider using `callback_on_step_end`",
647
+ )
648
+ if isinstance(callback_on_step_end, (PipelineCallback, MultiPipelineCallbacks)):
649
+ callback_on_step_end_tensor_inputs = callback_on_step_end.tensor_inputs
650
+
651
+ image_size = int(self.transformer.config.sample_size) * int(self.vae_scale_factor)
652
+ height = image_size if height is None else int(height)
653
+ width = image_size if width is None else int(width)
654
+ if num_inference_steps is None:
655
+ num_inference_steps = int(self._sampling_default("default_num_inference_steps", 1))
656
+ if guidance_scale is None:
657
+ guidance_scale = float(self._sampling_default("guidance_scale", 1.0))
658
+
659
+ # 1. Check inputs.
660
+ self.check_inputs(
661
+ class_labels,
662
+ height,
663
+ width,
664
+ num_inference_steps,
665
+ guidance_scale,
666
+ noise_scale,
667
+ output_type,
668
+ callback_steps,
669
+ callback_on_step_end_tensor_inputs,
670
+ )
671
+
672
+ self._guidance_scale = float(guidance_scale)
673
+ self._interrupt = False
674
+
675
+ # 2. Define call parameters.
676
+ class_label_ids = self._normalize_class_labels(class_labels)
677
+ batch_size = len(class_label_ids)
678
+ device = self._execution_device
679
+ num_classes = int(self.transformer.config.num_classes)
680
+ if any(class_id < 0 or class_id >= num_classes for class_id in class_label_ids):
681
+ raise ValueError(f"Class ids must lie in [0, {num_classes}), got {class_label_ids}.")
682
+
683
+ # 3. Encode input condition (class ids; guidance is embedded inside the transformer).
684
+ class_labels_t = torch.tensor(class_label_ids, device=device, dtype=torch.long)
685
+
686
+ # 4. Prepare timesteps.
687
+ scheduled_timesteps = self._prepare_scheduler(num_inference_steps, device)
688
+
689
+ # 5. Prepare latent variables. Noise codes are drawn here so one generator matches DitGen.
690
+ latent_height = height // int(self.vae_scale_factor)
691
+ latent_width = width // int(self.vae_scale_factor)
692
+ latents, noise_labels = self.prepare_latents(
693
+ batch_size,
694
+ int(self.transformer.config.in_channels),
695
+ latent_height,
696
+ latent_width,
697
+ device,
698
+ generator,
699
+ latents,
700
+ noise_labels,
701
+ noise_scale,
702
+ )
703
+
704
+ # 6. Prepare extra step kwargs.
705
+ extra_step_kwargs = self.prepare_extra_step_kwargs(generator, eta)
706
+ num_warmup_steps = len(scheduled_timesteps) - num_inference_steps * self.scheduler.order
707
+ self._num_timesteps = len(scheduled_timesteps)
708
+
709
+ # 7. Denoising loop.
710
+ with self.progress_bar(total=num_inference_steps) as progress_bar:
711
+ for i, timestep in enumerate(scheduled_timesteps):
712
+ if self.interrupt:
713
+ continue
714
+
715
+ latent_model_input = self.scheduler.scale_model_input(latents, timestep)
716
+ model_output = self.transformer(
717
+ latent_model_input,
718
+ class_labels=class_labels_t,
719
+ guidance_scale=self._guidance_scale,
720
+ noise_labels=noise_labels,
721
+ return_dict=False,
722
+ )[0]
723
+ latents = self.scheduler.step(
724
+ model_output,
725
+ timestep,
726
+ latents,
727
+ **extra_step_kwargs,
728
+ return_dict=False,
729
+ )[0]
730
+
731
+ if callback_on_step_end is not None:
732
+ callback_kwargs = {key: locals()[key] for key in callback_on_step_end_tensor_inputs}
733
+ callback_outputs = callback_on_step_end(self, i, timestep, callback_kwargs)
734
+ latents = callback_outputs.pop("latents", latents)
735
+
736
+ if i == len(scheduled_timesteps) - 1 or (
737
+ (i + 1) > num_warmup_steps and (i + 1) % self.scheduler.order == 0
738
+ ):
739
+ progress_bar.update()
740
+ if callback is not None and i % callback_steps == 0:
741
+ callback(i, timestep, latents)
742
+
743
+ if XLA_AVAILABLE:
744
+ xm.mark_step()
745
+
746
+ if output_type == "latent":
747
+ images = latents
748
+ else:
749
+ images = self._images_from_pixels(self._decode_latents(latents), output_type)
750
+ self.maybe_free_model_hooks()
751
+
752
+ if not return_dict:
753
+ return (images,)
754
+ return ImagePipelineOutput(images=images)
W-Flow-B/scheduler/scheduler_config.json ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ {
2
+ "_class_name": "WFlowScheduler",
3
+ "_diffusers_version": "0.39.0",
4
+ "num_train_timesteps": 1000,
5
+ "prediction_type": "sample"
6
+ }
W-Flow-B/scheduler/scheduling_wflow.py ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2026 The HuggingFace Team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from dataclasses import dataclass
16
+
17
+ import torch
18
+ from diffusers.configuration_utils import ConfigMixin, register_to_config
19
+ from diffusers.schedulers.scheduling_utils import SchedulerMixin
20
+ from diffusers.utils import BaseOutput
21
+
22
+
23
+ @dataclass
24
+ class WFlowSchedulerOutput(BaseOutput):
25
+ r"""
26
+ Output of [`WFlowScheduler.step`].
27
+
28
+ Args:
29
+ prev_sample (`torch.Tensor`):
30
+ The model prediction. W-Flow returns the clean latent in one evaluation.
31
+ """
32
+
33
+ prev_sample: torch.Tensor
34
+
35
+
36
+ class WFlowScheduler(SchedulerMixin, ConfigMixin):
37
+ r"""
38
+ One-step scheduler for W-Flow.
39
+
40
+ The transformer predicts the clean latent directly. `set_timesteps` accepts a single evaluation,
41
+ and `step` returns that prediction. `scale_model_input` leaves the reference noise unchanged.
42
+ A Karras noise schedule does not apply: the network has no diffusion timestep.
43
+
44
+ Args:
45
+ num_train_timesteps (`int`, defaults to 1000):
46
+ Stored for config compatibility. W-Flow does not index it.
47
+ prediction_type (`str`, defaults to `"sample"`):
48
+ The model output is the clean sample.
49
+ """
50
+
51
+ order = 1
52
+ _compatibles: list[str] = []
53
+
54
+ @register_to_config
55
+ def __init__(
56
+ self,
57
+ num_train_timesteps: int = 1000,
58
+ prediction_type: str = "sample",
59
+ ):
60
+ if num_train_timesteps < 1:
61
+ raise ValueError(f"num_train_timesteps must be >= 1, got {num_train_timesteps}.")
62
+ if prediction_type != "sample":
63
+ raise ValueError(f"WFlowScheduler prediction_type must be 'sample', got {prediction_type!r}.")
64
+ self.timesteps: torch.Tensor | None = None
65
+ self.num_inference_steps: int | None = None
66
+ self._step_index: int | None = None
67
+
68
+ @property
69
+ def init_noise_sigma(self) -> float:
70
+ r"""
71
+ Scale of the standard normal used to start sampling.
72
+
73
+ Returns:
74
+ `float`: `1.0`. The pipeline multiplies this by `noise_scale`.
75
+ """
76
+ return 1.0
77
+
78
+ def scale_model_input(self, sample: torch.Tensor, timestep: float | torch.Tensor) -> torch.Tensor:
79
+ r"""
80
+ Return the sample unchanged.
81
+
82
+ Args:
83
+ sample (`torch.Tensor`):
84
+ Reference noise `(batch, channels, height, width)`.
85
+ timestep (`float` or `torch.Tensor`):
86
+ Unused. W-Flow has no diffusion timestep.
87
+
88
+ Returns:
89
+ `torch.Tensor`: `sample`.
90
+ """
91
+ del timestep
92
+ return sample
93
+
94
+ def set_timesteps(
95
+ self,
96
+ num_inference_steps: int,
97
+ device: str | torch.device | None = None,
98
+ ) -> None:
99
+ r"""
100
+ Install the single evaluation step.
101
+
102
+ Args:
103
+ num_inference_steps (`int`):
104
+ Must be 1. W-Flow generates the latent in one forward pass.
105
+ device (`str` or `torch.device`, *optional*):
106
+ Device of `self.timesteps`.
107
+ """
108
+ if num_inference_steps != 1:
109
+ raise ValueError(
110
+ "W-Flow generates in one forward pass. "
111
+ f"num_inference_steps must be 1, got {num_inference_steps}."
112
+ )
113
+ self.num_inference_steps = 1
114
+ self.timesteps = torch.tensor([0.0], device=device, dtype=torch.float32)
115
+ self._step_index = 0
116
+
117
+ def step(
118
+ self,
119
+ model_output: torch.Tensor,
120
+ timestep: float | torch.Tensor,
121
+ sample: torch.Tensor,
122
+ generator: torch.Generator | list[torch.Generator] | None = None,
123
+ return_dict: bool = True,
124
+ ) -> WFlowSchedulerOutput | tuple[torch.Tensor]:
125
+ r"""
126
+ Replace the reference noise with the predicted clean latent.
127
+
128
+ Args:
129
+ model_output (`torch.Tensor`):
130
+ Clean-latent prediction `(batch, channels, height, width)`.
131
+ timestep (`float` or `torch.Tensor`):
132
+ The single scheduled timestep. Accepted for the Diffusers step signature.
133
+ sample (`torch.Tensor`):
134
+ Current reference noise. Same shape as `model_output`.
135
+ generator (`torch.Generator` or `list[torch.Generator]`, *optional*):
136
+ Accepted so pipelines can pass it through. W-Flow does not draw noise in `step`.
137
+ return_dict (`bool`, defaults to `True`):
138
+ Return [`WFlowSchedulerOutput`] when `True`, otherwise a one-tuple.
139
+
140
+ Returns:
141
+ [`WFlowSchedulerOutput`] or `tuple`:
142
+ `prev_sample` is `model_output`.
143
+ """
144
+ del timestep, sample, generator
145
+ if self.timesteps is None:
146
+ raise ValueError("Call set_timesteps before step.")
147
+ if self._step_index is None or self._step_index > 0:
148
+ raise ValueError("WFlowScheduler has already consumed its single step. Call set_timesteps again.")
149
+ self._step_index = 1
150
+ if not return_dict:
151
+ return (model_output,)
152
+ return WFlowSchedulerOutput(prev_sample=model_output)
W-Flow-B/transformer/config.json ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_class_name": "WFlowTransformer2DModel",
3
+ "_diffusers_version": "0.39.0",
4
+ "attn_fp32": false,
5
+ "cond_dim": 768,
6
+ "default_num_inference_steps": 1,
7
+ "depth": 12,
8
+ "guidance_scale": 1.19,
9
+ "hidden_size": 768,
10
+ "in_channels": 4,
11
+ "mlp_ratio": 4.0,
12
+ "model_type": "W-Flow-B",
13
+ "n_cls_tokens": 16,
14
+ "noise_classes": 64,
15
+ "noise_coords": 32,
16
+ "num_attention_heads": 12,
17
+ "num_classes": 1000,
18
+ "out_channels": 4,
19
+ "patch_size": 2,
20
+ "sample_size": 32,
21
+ "use_bf16": true,
22
+ "use_qknorm": true,
23
+ "use_rmsnorm": true,
24
+ "use_rope": true,
25
+ "use_swiglu": true
26
+ }
W-Flow-B/transformer/diffusion_pytorch_model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a2bd00f19d761e7f18b364a78737806eb388bfdce82aaac40838937e1248cec9
3
+ size 530860624
W-Flow-B/transformer/transformer_wflow.py ADDED
@@ -0,0 +1,720 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2026 The HuggingFace Team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import math
16
+ from dataclasses import dataclass
17
+
18
+ import numpy as np
19
+ import torch
20
+ import torch.nn as nn
21
+ from diffusers.configuration_utils import ConfigMixin, register_to_config
22
+ from diffusers.models.modeling_utils import ModelMixin
23
+ from diffusers.utils import BaseOutput
24
+
25
+
26
+ @dataclass
27
+ class WFlowTransformer2DModelOutput(BaseOutput):
28
+ r"""
29
+ Output of [`WFlowTransformer2DModel`].
30
+
31
+ Args:
32
+ sample (`torch.Tensor`):
33
+ Predicted SD-VAE latent of shape `(batch, channels, height, width)`. Values are in the
34
+ scaled latent space used at training time (`encoder_mean * 0.18215`).
35
+ """
36
+
37
+ sample: torch.Tensor
38
+
39
+
40
+ def _init_linear(linear: nn.Linear, weight_init: str = "xavier_uniform", bias_init: str = "zeros") -> None:
41
+ r"""
42
+ Initialize a linear layer the way the official generator does.
43
+
44
+ Args:
45
+ linear (`torch.nn.Linear`):
46
+ Layer to initialize in place.
47
+ weight_init (`str`, defaults to `"xavier_uniform"`):
48
+ `"xavier_uniform"`, `"zeros"`, or `"normal"` (std 0.02).
49
+ bias_init (`str`, defaults to `"zeros"`):
50
+ Bias fill. Only `"zeros"` is used by the released architecture.
51
+ """
52
+ if weight_init == "xavier_uniform":
53
+ nn.init.xavier_uniform_(linear.weight)
54
+ elif weight_init == "zeros":
55
+ nn.init.zeros_(linear.weight)
56
+ elif weight_init == "normal":
57
+ nn.init.normal_(linear.weight, std=0.02)
58
+ else:
59
+ raise ValueError(f"weight_init must be xavier_uniform, zeros, or normal, got {weight_init!r}.")
60
+ if linear.bias is not None:
61
+ if bias_init != "zeros":
62
+ raise ValueError(f"bias_init must be 'zeros', got {bias_init!r}.")
63
+ nn.init.zeros_(linear.bias)
64
+
65
+
66
+ class _TorchLinear(nn.Module):
67
+ r"""
68
+ Linear wrapper whose parameter names match the official `TorchLinear` (`*.linear.weight`).
69
+ """
70
+
71
+ def __init__(
72
+ self,
73
+ in_features: int,
74
+ out_features: int,
75
+ bias: bool = True,
76
+ weight_init: str = "xavier_uniform",
77
+ bias_init: str = "zeros",
78
+ ):
79
+ super().__init__()
80
+ self.linear = nn.Linear(in_features, out_features, bias=bias)
81
+ _init_linear(self.linear, weight_init=weight_init, bias_init=bias_init)
82
+
83
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
84
+ r"""
85
+ Apply the wrapped linear layer.
86
+
87
+ Args:
88
+ x (`torch.Tensor`):
89
+ Input of shape `(..., in_features)`.
90
+
91
+ Returns:
92
+ `torch.Tensor`: Output of shape `(..., out_features)`.
93
+ """
94
+ return self.linear(x)
95
+
96
+
97
+ class _RMSNorm(nn.Module):
98
+ def __init__(self, dim: int, eps: float = 1e-6):
99
+ super().__init__()
100
+ self.eps = float(eps)
101
+ self.weight = nn.Parameter(torch.ones(int(dim)))
102
+
103
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
104
+ r"""
105
+ Root-mean-square normalize the last dimension.
106
+
107
+ Args:
108
+ x (`torch.Tensor`):
109
+ Input of shape `(..., dim)`.
110
+
111
+ Returns:
112
+ `torch.Tensor`: Normalized tensor, same shape and dtype as `x`.
113
+ """
114
+ input_dtype = x.dtype
115
+ variance = x.float().pow(2).mean(dim=-1, keepdim=True)
116
+ normalized = x * torch.rsqrt(variance + self.eps)
117
+ return (normalized * self.weight).to(dtype=input_dtype)
118
+
119
+
120
+ def _modulate(x: torch.Tensor, shift: torch.Tensor, scale: torch.Tensor) -> torch.Tensor:
121
+ r"""
122
+ Apply an adaLN-Zero shift and scale.
123
+
124
+ Args:
125
+ x (`torch.Tensor`):
126
+ Token tensor `(batch, tokens, hidden)`.
127
+ shift (`torch.Tensor`):
128
+ Per-sample shift `(batch, hidden)`.
129
+ scale (`torch.Tensor`):
130
+ Per-sample scale `(batch, hidden)`.
131
+
132
+ Returns:
133
+ `torch.Tensor`: `x * (1 + scale) + shift`, broadcast over tokens.
134
+ """
135
+ return x * (1.0 + scale.unsqueeze(1)) + shift.unsqueeze(1)
136
+
137
+
138
+ def _sincos_1d(embed_dim: int, pos: np.ndarray) -> np.ndarray:
139
+ r"""
140
+ Sine-cosine embedding of 1-D positions.
141
+
142
+ Args:
143
+ embed_dim (`int`):
144
+ Even embedding width.
145
+ pos (`numpy.ndarray`):
146
+ Positions, flattened inside the function.
147
+
148
+ Returns:
149
+ `numpy.ndarray`: Array of shape `(positions, embed_dim)`.
150
+ """
151
+ if embed_dim % 2 != 0:
152
+ raise ValueError(f"embed_dim must be even, got {embed_dim}.")
153
+ omega = np.arange(embed_dim // 2, dtype=np.float64)
154
+ omega = 1.0 / 10000 ** (omega / (embed_dim / 2.0))
155
+ out = np.einsum("m,d->md", pos.reshape(-1), omega)
156
+ return np.concatenate([np.sin(out), np.cos(out)], axis=1)
157
+
158
+
159
+ def _sincos_2d(embed_dim: int, grid_size: int) -> np.ndarray:
160
+ r"""
161
+ Sine-cosine embedding of a square grid, matching the official generator.
162
+
163
+ Args:
164
+ embed_dim (`int`):
165
+ Full embedding width. Half is used for each axis.
166
+ grid_size (`int`):
167
+ Tokens along one side of the latent grid.
168
+
169
+ Returns:
170
+ `numpy.ndarray`: Array of shape `(grid_size * grid_size, embed_dim)`.
171
+ """
172
+ grid_h = np.arange(grid_size, dtype=np.float32)
173
+ grid_w = np.arange(grid_size, dtype=np.float32)
174
+ grid = np.stack(np.meshgrid(grid_w, grid_h), axis=0).reshape(2, 1, grid_size, grid_size)
175
+ half = embed_dim // 2
176
+ return np.concatenate([_sincos_1d(half, grid[0]), _sincos_1d(half, grid[1])], axis=1)
177
+
178
+
179
+ def _swiglu_hidden(hidden_size: int, mlp_ratio: float) -> int:
180
+ r"""
181
+ SwiGLU intermediate width used by the official blocks.
182
+
183
+ Args:
184
+ hidden_size (`int`):
185
+ Transformer width.
186
+ mlp_ratio (`float`):
187
+ Expansion ratio before the 2/3 SwiGLU reduction.
188
+
189
+ Returns:
190
+ `int`: Intermediate width, rounded up to a multiple of 32.
191
+ """
192
+ mlp_hidden = int(hidden_size * float(mlp_ratio))
193
+ hidden = int((2.0 / 3.0) * mlp_hidden)
194
+ return ((hidden + 31) // 32) * 32
195
+
196
+
197
+ class _StandardMLP(nn.Module):
198
+ def __init__(self, hidden_size: int, mlp_hidden_dim: int):
199
+ super().__init__()
200
+ self.fc1 = _TorchLinear(hidden_size, mlp_hidden_dim, bias=True)
201
+ self.fc2 = _TorchLinear(mlp_hidden_dim, hidden_size, bias=True)
202
+
203
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
204
+ r"""
205
+ GELU MLP.
206
+
207
+ Args:
208
+ x (`torch.Tensor`):
209
+ Input `(..., hidden_size)`.
210
+
211
+ Returns:
212
+ `torch.Tensor`: Output `(..., hidden_size)`.
213
+ """
214
+ return self.fc2(nn.functional.gelu(self.fc1(x), approximate="none"))
215
+
216
+
217
+ class _SwiGLUFFN(nn.Module):
218
+ def __init__(self, hidden_size: int, intermediate_size: int):
219
+ super().__init__()
220
+ self.w1 = _TorchLinear(hidden_size, intermediate_size, bias=True)
221
+ self.w3 = _TorchLinear(hidden_size, intermediate_size, bias=True)
222
+ self.w2 = _TorchLinear(intermediate_size, hidden_size, bias=True)
223
+
224
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
225
+ r"""
226
+ SwiGLU feed-forward.
227
+
228
+ Args:
229
+ x (`torch.Tensor`):
230
+ Input `(..., hidden_size)`.
231
+
232
+ Returns:
233
+ `torch.Tensor`: Output `(..., hidden_size)`.
234
+ """
235
+ return self.w2(nn.functional.silu(self.w1(x)) * self.w3(x))
236
+
237
+
238
+ class _Attention(nn.Module):
239
+ def __init__(
240
+ self,
241
+ dim: int,
242
+ num_heads: int,
243
+ qk_norm: bool,
244
+ use_rmsnorm: bool,
245
+ use_rope: bool,
246
+ attn_fp32: bool,
247
+ max_seq_len: int,
248
+ ):
249
+ super().__init__()
250
+ self.dim = int(dim)
251
+ self.num_heads = int(num_heads)
252
+ self.use_rope = bool(use_rope)
253
+ self.attn_fp32 = bool(attn_fp32)
254
+ self.qkv = _TorchLinear(self.dim, self.dim * 3, bias=True)
255
+ head_dim = self.dim // self.num_heads
256
+ if qk_norm:
257
+ if use_rmsnorm:
258
+ self.q_norm = _RMSNorm(head_dim)
259
+ self.k_norm = _RMSNorm(head_dim)
260
+ else:
261
+ self.q_norm = nn.LayerNorm(head_dim, eps=1e-6, elementwise_affine=True)
262
+ self.k_norm = nn.LayerNorm(head_dim, eps=1e-6, elementwise_affine=True)
263
+ else:
264
+ self.q_norm = None
265
+ self.k_norm = None
266
+ self.proj = _TorchLinear(self.dim, self.dim, bias=True)
267
+ if use_rope:
268
+ half_dim = head_dim // 2
269
+ freqs = 1.0 / (10000 ** (torch.arange(0, half_dim, dtype=torch.float32) / half_dim))
270
+ positions = torch.arange(max_seq_len, dtype=torch.float32)
271
+ emb = torch.cat([torch.outer(positions, freqs)] * 2, dim=-1)
272
+ self.register_buffer("_rope_cos", torch.cos(emb)[None, :, None, :], persistent=False)
273
+ self.register_buffer("_rope_sin", torch.sin(emb)[None, :, None, :], persistent=False)
274
+
275
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
276
+ r"""
277
+ Multi-head self-attention. Dropout is off, matching inference (`deterministic=True`).
278
+
279
+ Args:
280
+ x (`torch.Tensor`):
281
+ Tokens `(batch, tokens, hidden)`.
282
+
283
+ Returns:
284
+ `torch.Tensor`: Attention output `(batch, tokens, hidden)`.
285
+ """
286
+ batch, tokens, _channels = x.shape
287
+ head_dim = self.dim // self.num_heads
288
+ qkv = self.qkv(x).reshape(batch, tokens, 3, self.num_heads, head_dim)
289
+ query, key, value = qkv[:, :, 0], qkv[:, :, 1], qkv[:, :, 2]
290
+ if self.q_norm is not None:
291
+ query = self.q_norm(query)
292
+ key = self.k_norm(key)
293
+ if self.use_rope:
294
+ rope_dtype = torch.float32 if self.attn_fp32 else query.dtype
295
+ cos = self._rope_cos[:, :tokens].to(dtype=rope_dtype)
296
+ sin = self._rope_sin[:, :tokens].to(dtype=rope_dtype)
297
+ half_dim = head_dim // 2
298
+
299
+ def _rotate(tensor: torch.Tensor) -> torch.Tensor:
300
+ first, second = tensor[..., :half_dim], tensor[..., half_dim:]
301
+ return torch.cat([-second, first], dim=-1)
302
+
303
+ query = (query * cos) + (_rotate(query) * sin)
304
+ key = (key * cos) + (_rotate(key) * sin)
305
+ if self.attn_fp32:
306
+ query = query.float()
307
+ key = key.float()
308
+ value = value.float()
309
+ query = query.permute(0, 2, 1, 3)
310
+ key = key.permute(0, 2, 1, 3)
311
+ value = value.permute(0, 2, 1, 3)
312
+ if self.attn_fp32:
313
+ with torch.amp.autocast(device_type=query.device.type, enabled=False):
314
+ out = nn.functional.scaled_dot_product_attention(query, key, value, dropout_p=0.0)
315
+ else:
316
+ out = nn.functional.scaled_dot_product_attention(query, key, value, dropout_p=0.0)
317
+ out = out.permute(0, 2, 1, 3).reshape(batch, tokens, self.dim)
318
+ return self.proj(out)
319
+
320
+
321
+ class _DiTBlock(nn.Module):
322
+ def __init__(
323
+ self,
324
+ hidden_size: int,
325
+ num_heads: int,
326
+ mlp_ratio: float,
327
+ use_qknorm: bool,
328
+ use_swiglu: bool,
329
+ use_rmsnorm: bool,
330
+ use_rope: bool,
331
+ attn_fp32: bool,
332
+ max_seq_len: int,
333
+ ):
334
+ super().__init__()
335
+ self.hidden_size = int(hidden_size)
336
+ if use_rmsnorm:
337
+ self.norm1 = _RMSNorm(self.hidden_size)
338
+ self.norm2 = _RMSNorm(self.hidden_size)
339
+ else:
340
+ self.norm1 = nn.LayerNorm(self.hidden_size, eps=1e-6, elementwise_affine=False)
341
+ self.norm2 = nn.LayerNorm(self.hidden_size, eps=1e-6, elementwise_affine=False)
342
+ self.attn = _Attention(
343
+ dim=self.hidden_size,
344
+ num_heads=num_heads,
345
+ qk_norm=use_qknorm,
346
+ use_rmsnorm=use_rmsnorm,
347
+ use_rope=use_rope,
348
+ attn_fp32=attn_fp32,
349
+ max_seq_len=max_seq_len,
350
+ )
351
+ if use_swiglu:
352
+ self.mlp = _SwiGLUFFN(self.hidden_size, _swiglu_hidden(self.hidden_size, mlp_ratio))
353
+ else:
354
+ self.mlp = _StandardMLP(self.hidden_size, int(self.hidden_size * float(mlp_ratio)))
355
+ self.adaLN_mod = nn.Sequential(
356
+ nn.SiLU(),
357
+ _TorchLinear(self.hidden_size, 6 * self.hidden_size, bias=True, weight_init="zeros"),
358
+ )
359
+
360
+ def forward(self, x: torch.Tensor, condition: torch.Tensor) -> torch.Tensor:
361
+ r"""
362
+ One Lightning-DiT block conditioned by adaLN-Zero.
363
+
364
+ Args:
365
+ x (`torch.Tensor`):
366
+ Tokens `(batch, tokens, hidden)`.
367
+ condition (`torch.Tensor`):
368
+ Per-sample condition `(batch, hidden)`.
369
+
370
+ Returns:
371
+ `torch.Tensor`: Updated tokens, same shape as `x`.
372
+ """
373
+ chunks = self.adaLN_mod(condition.float()).to(dtype=x.dtype)
374
+ shift_msa, scale_msa, gate_msa, shift_mlp, scale_mlp, gate_mlp = torch.chunk(chunks, 6, dim=1)
375
+ attended = self.attn(_modulate(self.norm1(x), shift_msa, scale_msa))
376
+ x = x + gate_msa.unsqueeze(1) * attended
377
+ x = x + gate_mlp.unsqueeze(1) * self.mlp(_modulate(self.norm2(x), shift_mlp, scale_mlp))
378
+ return x
379
+
380
+
381
+ class _FinalLayer(nn.Module):
382
+ def __init__(self, hidden_size: int, patch_size: int, out_channels: int, use_rmsnorm: bool):
383
+ super().__init__()
384
+ self.norm_final = _RMSNorm(hidden_size) if use_rmsnorm else nn.LayerNorm(hidden_size, eps=1e-6, elementwise_affine=False)
385
+ self.adaLN_mod = nn.Sequential(
386
+ nn.SiLU(),
387
+ _TorchLinear(hidden_size, 2 * hidden_size, bias=True, weight_init="zeros"),
388
+ )
389
+ self.linear = _TorchLinear(hidden_size, patch_size * patch_size * out_channels, bias=True, weight_init="zeros")
390
+
391
+ def forward(self, x: torch.Tensor, condition: torch.Tensor) -> torch.Tensor:
392
+ r"""
393
+ Project tokens to patch pixels.
394
+
395
+ Args:
396
+ x (`torch.Tensor`):
397
+ Tokens `(batch, tokens, hidden)`.
398
+ condition (`torch.Tensor`):
399
+ Per-sample condition `(batch, hidden)`.
400
+
401
+ Returns:
402
+ `torch.Tensor`: Patch pixels `(batch, tokens, patch_size * patch_size * out_channels)`.
403
+ """
404
+ shift, scale = torch.chunk(self.adaLN_mod(condition.float()).to(dtype=x.dtype), 2, dim=1)
405
+ return self.linear(_modulate(self.norm_final(x), shift, scale))
406
+
407
+
408
+ class _LightningDiT(nn.Module):
409
+ def __init__(
410
+ self,
411
+ input_size: int,
412
+ patch_size: int,
413
+ in_channels: int,
414
+ hidden_size: int,
415
+ depth: int,
416
+ num_heads: int,
417
+ mlp_ratio: float,
418
+ out_channels: int,
419
+ use_qknorm: bool,
420
+ use_swiglu: bool,
421
+ use_rope: bool,
422
+ use_rmsnorm: bool,
423
+ cond_dim: int,
424
+ n_cls_tokens: int,
425
+ attn_fp32: bool,
426
+ ):
427
+ super().__init__()
428
+ self.input_size = int(input_size)
429
+ self.patch_size = int(patch_size)
430
+ self.in_channels = int(in_channels)
431
+ self.hidden_size = int(hidden_size)
432
+ self.out_channels = int(out_channels)
433
+ self.n_cls_tokens = int(n_cls_tokens)
434
+ self.patch_embed = _TorchLinear(self.patch_size * self.patch_size * self.in_channels, self.hidden_size, bias=True)
435
+ grid = self.input_size // self.patch_size
436
+ max_seq_len = grid * grid + self.n_cls_tokens
437
+ self.blocks = nn.ModuleList(
438
+ [
439
+ _DiTBlock(
440
+ hidden_size=self.hidden_size,
441
+ num_heads=num_heads,
442
+ mlp_ratio=mlp_ratio,
443
+ use_qknorm=use_qknorm,
444
+ use_swiglu=use_swiglu,
445
+ use_rmsnorm=use_rmsnorm,
446
+ use_rope=use_rope,
447
+ attn_fp32=attn_fp32,
448
+ max_seq_len=max_seq_len,
449
+ )
450
+ for _ in range(int(depth))
451
+ ]
452
+ )
453
+ self.final_layer = _FinalLayer(self.hidden_size, self.patch_size, self.out_channels, use_rmsnorm)
454
+ position = _sincos_2d(self.hidden_size, grid)
455
+ self.pos_embed = nn.Parameter(torch.as_tensor(position, dtype=torch.float32).unsqueeze(0))
456
+ if self.n_cls_tokens > 0:
457
+ self.cls_embed = nn.Parameter(torch.randn(1, self.n_cls_tokens, self.hidden_size) * 0.02)
458
+ self.c_token_proj = _TorchLinear(int(cond_dim), self.hidden_size, bias=True)
459
+ else:
460
+ self.register_parameter("cls_embed", None)
461
+ self.c_token_proj = None
462
+
463
+ def forward(self, hidden_states_bhwc: torch.Tensor, condition: torch.Tensor) -> torch.Tensor:
464
+ r"""
465
+ Map a latent grid to a clean latent grid.
466
+
467
+ Args:
468
+ hidden_states_bhwc (`torch.Tensor`):
469
+ Reference noise `(batch, height, width, channels)`. Height and width must equal
470
+ `input_size`. The official generator uses this layout.
471
+ condition (`torch.Tensor`):
472
+ Class, noise-code, and guidance embedding `(batch, cond_dim)`.
473
+
474
+ Returns:
475
+ `torch.Tensor`: Clean latent `(batch, height, width, channels)`.
476
+ """
477
+ batch, height, width, channels = hidden_states_bhwc.shape
478
+ patch = self.patch_size
479
+ grid = self.input_size // patch
480
+ if (height, width, channels) != (self.input_size, self.input_size, self.in_channels):
481
+ raise ValueError(
482
+ f"Expected latent {(self.input_size, self.input_size, self.in_channels)} in BHWC, "
483
+ f"got {(height, width, channels)}."
484
+ )
485
+ tokens = hidden_states_bhwc.reshape(batch, grid, patch, grid, patch, channels)
486
+ tokens = tokens.permute(0, 1, 3, 2, 4, 5).contiguous().reshape(batch, grid * grid, patch * patch * channels)
487
+ tokens = self.patch_embed(tokens)
488
+ tokens = (tokens + self.pos_embed.to(device=tokens.device, dtype=tokens.dtype)).to(dtype=tokens.dtype)
489
+ if self.n_cls_tokens > 0:
490
+ class_tokens = self.c_token_proj(condition).unsqueeze(1).repeat(1, self.n_cls_tokens, 1)
491
+ class_tokens = class_tokens + self.cls_embed.to(device=tokens.device, dtype=tokens.dtype)
492
+ tokens = torch.cat([class_tokens, tokens], dim=1)
493
+ for block in self.blocks:
494
+ tokens = block(tokens, condition)
495
+ tokens = self.final_layer(tokens, condition)
496
+ if self.n_cls_tokens > 0:
497
+ tokens = tokens[:, self.n_cls_tokens :, :]
498
+ tokens = tokens.reshape(batch, grid, grid, patch, patch, self.out_channels)
499
+ tokens = tokens.permute(0, 1, 3, 2, 4, 5).contiguous()
500
+ return tokens.reshape(batch, self.input_size, self.input_size, self.out_channels)
501
+
502
+
503
+ class _TimestepEmbedder(nn.Module):
504
+ def __init__(self, hidden_size: int, frequency_embedding_size: int = 256):
505
+ super().__init__()
506
+ self.frequency_embedding_size = int(frequency_embedding_size)
507
+ self.fc1 = _TorchLinear(self.frequency_embedding_size, hidden_size, bias=True, weight_init="normal")
508
+ self.fc2 = _TorchLinear(hidden_size, hidden_size, bias=True, weight_init="normal")
509
+
510
+ def forward(self, timesteps: torch.Tensor) -> torch.Tensor:
511
+ r"""
512
+ Embed a scalar guidance value with sinusoidal features.
513
+
514
+ Args:
515
+ timesteps (`torch.Tensor`):
516
+ Shape `(batch,)`. This is the guidance scale, not a diffusion time.
517
+
518
+ Returns:
519
+ `torch.Tensor`: Embedding `(batch, hidden)`.
520
+ """
521
+ timesteps = timesteps.to(dtype=torch.float32)
522
+ half = self.frequency_embedding_size // 2
523
+ freqs = torch.exp(-math.log(10000) * torch.arange(0, half, device=timesteps.device, dtype=torch.float32) / half)
524
+ arguments = timesteps[:, None] * freqs[None]
525
+ embedding = torch.cat([torch.cos(arguments), torch.sin(arguments)], dim=-1)
526
+ if self.frequency_embedding_size % 2:
527
+ embedding = torch.cat([embedding, torch.zeros_like(embedding[:, :1])], dim=-1)
528
+ hidden = nn.functional.silu(self.fc1(embedding))
529
+ return self.fc2(hidden)
530
+
531
+
532
+ class WFlowTransformer2DModel(ModelMixin, ConfigMixin):
533
+ r"""
534
+ One-step ImageNet generator used by W-Flow.
535
+
536
+ The network maps unit Gaussian SD-VAE noise plus a class label to a clean latent in one pass.
537
+ Guidance is a continuous embedding (the official `cfg_scale`, equal to `w + 1` in the paper),
538
+ not a second unconditional forward. Discrete noise codes (`noise_classes` by `noise_coords`)
539
+ are added to the class embedding.
540
+
541
+ Parameter names match `DitGen` in the official repository, so an `ema_model` state dict loads
542
+ without renaming.
543
+
544
+ Args:
545
+ sample_size (`int`, defaults to 32):
546
+ Latent spatial size. Released checkpoints use 32, which decodes to 256 pixels.
547
+ patch_size (`int`, defaults to 2):
548
+ Patch size on the latent grid.
549
+ in_channels (`int`, defaults to 4):
550
+ Latent channels.
551
+ out_channels (`int`, defaults to 4):
552
+ Predicted latent channels.
553
+ cond_dim (`int`, defaults to 768):
554
+ Width of the class, noise-code, and guidance embeddings.
555
+ num_classes (`int`, defaults to 1000):
556
+ ImageNet class count. There is no null-class slot.
557
+ noise_classes (`int`, defaults to 64):
558
+ Cardinality of each discrete noise code.
559
+ noise_coords (`int`, defaults to 32):
560
+ Number of independent noise-code embeddings that are summed.
561
+ n_cls_tokens (`int`, defaults to 16):
562
+ Learned class tokens prepended to the patch sequence.
563
+ hidden_size (`int`, defaults to 768):
564
+ Transformer width.
565
+ depth (`int`, defaults to 12):
566
+ Number of blocks.
567
+ num_attention_heads (`int`, defaults to 12):
568
+ Attention heads.
569
+ mlp_ratio (`float`, defaults to 4.0):
570
+ MLP expansion before the SwiGLU 2/3 reduction.
571
+ use_qknorm (`bool`, defaults to `True`):
572
+ QK normalization.
573
+ use_swiglu (`bool`, defaults to `True`):
574
+ SwiGLU MLP. Released checkpoints turn this on.
575
+ use_rope (`bool`, defaults to `True`):
576
+ 1-D rotary embeddings over the token sequence, including class tokens.
577
+ use_rmsnorm (`bool`, defaults to `True`):
578
+ RMSNorm instead of LayerNorm.
579
+ use_bf16 (`bool`, defaults to `True`):
580
+ Autocast the forward to bfloat16 on CUDA, matching the official sampler.
581
+ attn_fp32 (`bool`, defaults to `False`):
582
+ Run attention in float32. The ablation checkpoint sets this to `True`.
583
+ guidance_scale (`float`, defaults to 1.0):
584
+ Default embedded guidance. The pipeline reads this when the caller omits a scale.
585
+ default_num_inference_steps (`int`, defaults to 1):
586
+ Sampling is one network evaluation.
587
+ model_type (`str`, defaults to `"W-Flow-B"`):
588
+ Variant name stored in the config.
589
+ """
590
+
591
+ @register_to_config
592
+ def __init__(
593
+ self,
594
+ sample_size: int = 32,
595
+ patch_size: int = 2,
596
+ in_channels: int = 4,
597
+ out_channels: int = 4,
598
+ cond_dim: int = 768,
599
+ num_classes: int = 1000,
600
+ noise_classes: int = 64,
601
+ noise_coords: int = 32,
602
+ n_cls_tokens: int = 16,
603
+ hidden_size: int = 768,
604
+ depth: int = 12,
605
+ num_attention_heads: int = 12,
606
+ mlp_ratio: float = 4.0,
607
+ use_qknorm: bool = True,
608
+ use_swiglu: bool = True,
609
+ use_rope: bool = True,
610
+ use_rmsnorm: bool = True,
611
+ use_bf16: bool = True,
612
+ attn_fp32: bool = False,
613
+ guidance_scale: float = 1.0,
614
+ default_num_inference_steps: int = 1,
615
+ model_type: str = "W-Flow-B",
616
+ ):
617
+ super().__init__()
618
+ self.class_embed = nn.Embedding(int(num_classes), int(cond_dim))
619
+ nn.init.normal_(self.class_embed.weight, std=0.02)
620
+ self.noise_embeds = nn.ModuleList()
621
+ for _ in range(int(noise_coords)):
622
+ embedding = nn.Embedding(int(noise_classes), int(cond_dim))
623
+ nn.init.normal_(embedding.weight, std=0.02)
624
+ self.noise_embeds.append(embedding)
625
+ self.cfg_embedder = _TimestepEmbedder(int(cond_dim))
626
+ self.cfg_norm = _RMSNorm(int(cond_dim))
627
+ self.model = _LightningDiT(
628
+ input_size=int(sample_size),
629
+ patch_size=int(patch_size),
630
+ in_channels=int(in_channels),
631
+ hidden_size=int(hidden_size),
632
+ depth=int(depth),
633
+ num_heads=int(num_attention_heads),
634
+ mlp_ratio=float(mlp_ratio),
635
+ out_channels=int(out_channels),
636
+ use_qknorm=bool(use_qknorm),
637
+ use_swiglu=bool(use_swiglu),
638
+ use_rope=bool(use_rope),
639
+ use_rmsnorm=bool(use_rmsnorm),
640
+ cond_dim=int(cond_dim),
641
+ n_cls_tokens=int(n_cls_tokens),
642
+ attn_fp32=bool(attn_fp32),
643
+ )
644
+
645
+ def condition(
646
+ self,
647
+ class_labels: torch.Tensor,
648
+ guidance_scale: float | torch.Tensor,
649
+ noise_labels: torch.Tensor,
650
+ ) -> torch.Tensor:
651
+ r"""
652
+ Build the conditioning vector from class, noise codes, and guidance.
653
+
654
+ Args:
655
+ class_labels (`torch.Tensor`):
656
+ Integer class ids `(batch,)`, in `[0, num_classes)`.
657
+ guidance_scale (`float` or `torch.Tensor`):
658
+ Official CFG value `(w + 1)`. A float is broadcast across the batch. A tensor
659
+ must be `(batch,)` or a scalar.
660
+ noise_labels (`torch.Tensor`):
661
+ Integer codes `(batch, noise_coords)` in `[0, noise_classes)`.
662
+
663
+ Returns:
664
+ `torch.Tensor`: Condition `(batch, cond_dim)`.
665
+ """
666
+ batch = class_labels.shape[0]
667
+ cond = self.class_embed(class_labels)
668
+ for index, embedding in enumerate(self.noise_embeds):
669
+ cond = cond + embedding(noise_labels[:, index])
670
+ if isinstance(guidance_scale, (float, int)):
671
+ scale = torch.full((batch,), float(guidance_scale), device=class_labels.device, dtype=torch.float32)
672
+ else:
673
+ scale = torch.as_tensor(guidance_scale, device=class_labels.device, dtype=torch.float32)
674
+ if scale.ndim == 0:
675
+ scale = scale[None].repeat(batch)
676
+ embedded = self.cfg_norm(self.cfg_embedder(scale.float()).float())
677
+ return cond + embedded.to(dtype=cond.dtype) * 0.02
678
+
679
+ def forward(
680
+ self,
681
+ hidden_states: torch.Tensor,
682
+ class_labels: torch.Tensor,
683
+ guidance_scale: float | torch.Tensor = 1.0,
684
+ noise_labels: torch.Tensor | None = None,
685
+ return_dict: bool = True,
686
+ ) -> WFlowTransformer2DModelOutput | tuple[torch.Tensor]:
687
+ r"""
688
+ Predict a clean latent from reference noise.
689
+
690
+ Args:
691
+ hidden_states (`torch.Tensor`):
692
+ Gaussian reference noise `(batch, channels, height, width)` in BCHW. Height and
693
+ width must equal `config.sample_size`.
694
+ class_labels (`torch.Tensor`):
695
+ Integer ImageNet ids `(batch,)`.
696
+ guidance_scale (`float` or `torch.Tensor`, defaults to 1.0):
697
+ Embedded guidance. This is the official `cfg_scale` (`w + 1` in the paper).
698
+ noise_labels (`torch.Tensor`, *optional*):
699
+ Discrete noise codes `(batch, noise_coords)`. Required. The pipeline samples these
700
+ with the same generator as `hidden_states`.
701
+ return_dict (`bool`, defaults to `True`):
702
+ Return [`WFlowTransformer2DModelOutput`] when `True`, otherwise a one-tuple.
703
+
704
+ Returns:
705
+ [`WFlowTransformer2DModelOutput`] or `tuple`:
706
+ `sample` is the clean latent `(batch, channels, height, width)`.
707
+ """
708
+ if noise_labels is None:
709
+ raise ValueError("`noise_labels` is required and must have shape (batch, noise_coords).")
710
+ if hidden_states.ndim != 4:
711
+ raise ValueError(f"`hidden_states` must be BCHW, got {tuple(hidden_states.shape)}.")
712
+ hidden_bhwc = hidden_states.permute(0, 2, 3, 1).contiguous()
713
+ use_autocast = bool(self.config.use_bf16) and hidden_states.device.type == "cuda"
714
+ with torch.amp.autocast(device_type=hidden_states.device.type, dtype=torch.bfloat16, enabled=use_autocast):
715
+ cond = self.condition(class_labels, guidance_scale, noise_labels)
716
+ sample_bhwc = self.model(hidden_bhwc, cond)
717
+ sample = sample_bhwc.permute(0, 3, 1, 2).contiguous()
718
+ if not return_dict:
719
+ return (sample,)
720
+ return WFlowTransformer2DModelOutput(sample=sample)
W-Flow-B/vae/config.json ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_class_name": "AutoencoderKL",
3
+ "_diffusers_version": "0.36.0",
4
+ "_name_or_path": "stabilityai/sd-vae-ft-mse",
5
+ "act_fn": "silu",
6
+ "block_out_channels": [
7
+ 128,
8
+ 256,
9
+ 512,
10
+ 512
11
+ ],
12
+ "down_block_types": [
13
+ "DownEncoderBlock2D",
14
+ "DownEncoderBlock2D",
15
+ "DownEncoderBlock2D",
16
+ "DownEncoderBlock2D"
17
+ ],
18
+ "force_upcast": true,
19
+ "in_channels": 3,
20
+ "latent_channels": 4,
21
+ "latents_mean": null,
22
+ "latents_std": null,
23
+ "layers_per_block": 2,
24
+ "mid_block_add_attention": true,
25
+ "norm_num_groups": 32,
26
+ "out_channels": 3,
27
+ "sample_size": 256,
28
+ "scaling_factor": 0.18215,
29
+ "shift_factor": null,
30
+ "up_block_types": [
31
+ "UpDecoderBlock2D",
32
+ "UpDecoderBlock2D",
33
+ "UpDecoderBlock2D",
34
+ "UpDecoderBlock2D"
35
+ ],
36
+ "use_post_quant_conv": true,
37
+ "use_quant_conv": true
38
+ }
W-Flow-B/vae/diffusion_pytorch_model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:2aa1f43011b553a4cba7f37456465cdbd48aab7b54b9348b890e8058ea7683ec
3
+ size 334643268
W-Flow-L/model_index.json ADDED
@@ -0,0 +1,1021 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_class_name": [
3
+ "pipeline",
4
+ "WFlowPipeline"
5
+ ],
6
+ "_diffusers_version": "0.39.0",
7
+ "scheduler": [
8
+ "scheduling_wflow",
9
+ "WFlowScheduler"
10
+ ],
11
+ "transformer": [
12
+ "transformer_wflow",
13
+ "WFlowTransformer2DModel"
14
+ ],
15
+ "vae": [
16
+ "diffusers",
17
+ "AutoencoderKL"
18
+ ],
19
+ "id2label": {
20
+ "0": "tench, Tinca tinca",
21
+ "1": "goldfish, Carassius auratus",
22
+ "2": "great white shark, white shark, man-eater, man-eating shark, Carcharodon carcharias",
23
+ "3": "tiger shark, Galeocerdo cuvieri",
24
+ "4": "hammerhead, hammerhead shark",
25
+ "5": "electric ray, crampfish, numbfish, torpedo",
26
+ "6": "stingray",
27
+ "7": "cock",
28
+ "8": "hen",
29
+ "9": "ostrich, Struthio camelus",
30
+ "10": "brambling, Fringilla montifringilla",
31
+ "11": "goldfinch, Carduelis carduelis",
32
+ "12": "house finch, linnet, Carpodacus mexicanus",
33
+ "13": "junco, snowbird",
34
+ "14": "indigo bunting, indigo finch, indigo bird, Passerina cyanea",
35
+ "15": "robin, American robin, Turdus migratorius",
36
+ "16": "bulbul",
37
+ "17": "jay",
38
+ "18": "magpie",
39
+ "19": "chickadee",
40
+ "20": "water ouzel, dipper",
41
+ "21": "kite",
42
+ "22": "bald eagle, American eagle, Haliaeetus leucocephalus",
43
+ "23": "vulture",
44
+ "24": "great grey owl, great gray owl, Strix nebulosa",
45
+ "25": "European fire salamander, Salamandra salamandra",
46
+ "26": "common newt, Triturus vulgaris",
47
+ "27": "eft",
48
+ "28": "spotted salamander, Ambystoma maculatum",
49
+ "29": "axolotl, mud puppy, Ambystoma mexicanum",
50
+ "30": "bullfrog, Rana catesbeiana",
51
+ "31": "tree frog, tree-frog",
52
+ "32": "tailed frog, bell toad, ribbed toad, tailed toad, Ascaphus trui",
53
+ "33": "loggerhead, loggerhead turtle, Caretta caretta",
54
+ "34": "leatherback turtle, leatherback, leathery turtle, Dermochelys coriacea",
55
+ "35": "mud turtle",
56
+ "36": "terrapin",
57
+ "37": "box turtle, box tortoise",
58
+ "38": "banded gecko",
59
+ "39": "common iguana, iguana, Iguana iguana",
60
+ "40": "American chameleon, anole, Anolis carolinensis",
61
+ "41": "whiptail, whiptail lizard",
62
+ "42": "agama",
63
+ "43": "frilled lizard, Chlamydosaurus kingi",
64
+ "44": "alligator lizard",
65
+ "45": "Gila monster, Heloderma suspectum",
66
+ "46": "green lizard, Lacerta viridis",
67
+ "47": "African chameleon, Chamaeleo chamaeleon",
68
+ "48": "Komodo dragon, Komodo lizard, dragon lizard, giant lizard, Varanus komodoensis",
69
+ "49": "African crocodile, Nile crocodile, Crocodylus niloticus",
70
+ "50": "American alligator, Alligator mississipiensis",
71
+ "51": "triceratops",
72
+ "52": "thunder snake, worm snake, Carphophis amoenus",
73
+ "53": "ringneck snake, ring-necked snake, ring snake",
74
+ "54": "hognose snake, puff adder, sand viper",
75
+ "55": "green snake, grass snake",
76
+ "56": "king snake, kingsnake",
77
+ "57": "garter snake, grass snake",
78
+ "58": "water snake",
79
+ "59": "vine snake",
80
+ "60": "night snake, Hypsiglena torquata",
81
+ "61": "boa constrictor, Constrictor constrictor",
82
+ "62": "rock python, rock snake, Python sebae",
83
+ "63": "Indian cobra, Naja naja",
84
+ "64": "green mamba",
85
+ "65": "sea snake",
86
+ "66": "horned viper, cerastes, sand viper, horned asp, Cerastes cornutus",
87
+ "67": "diamondback, diamondback rattlesnake, Crotalus adamanteus",
88
+ "68": "sidewinder, horned rattlesnake, Crotalus cerastes",
89
+ "69": "trilobite",
90
+ "70": "harvestman, daddy longlegs, Phalangium opilio",
91
+ "71": "scorpion",
92
+ "72": "black and gold garden spider, Argiope aurantia",
93
+ "73": "barn spider, Araneus cavaticus",
94
+ "74": "garden spider, Aranea diademata",
95
+ "75": "black widow, Latrodectus mactans",
96
+ "76": "tarantula",
97
+ "77": "wolf spider, hunting spider",
98
+ "78": "tick",
99
+ "79": "centipede",
100
+ "80": "black grouse",
101
+ "81": "ptarmigan",
102
+ "82": "ruffed grouse, partridge, Bonasa umbellus",
103
+ "83": "prairie chicken, prairie grouse, prairie fowl",
104
+ "84": "peacock",
105
+ "85": "quail",
106
+ "86": "partridge",
107
+ "87": "African grey, African gray, Psittacus erithacus",
108
+ "88": "macaw",
109
+ "89": "sulphur-crested cockatoo, Kakatoe galerita, Cacatua galerita",
110
+ "90": "lorikeet",
111
+ "91": "coucal",
112
+ "92": "bee eater",
113
+ "93": "hornbill",
114
+ "94": "hummingbird",
115
+ "95": "jacamar",
116
+ "96": "toucan",
117
+ "97": "drake",
118
+ "98": "red-breasted merganser, Mergus serrator",
119
+ "99": "goose",
120
+ "100": "black swan, Cygnus atratus",
121
+ "101": "tusker",
122
+ "102": "echidna, spiny anteater, anteater",
123
+ "103": "platypus, duckbill, duckbilled platypus, duck-billed platypus, Ornithorhynchus anatinus",
124
+ "104": "wallaby, brush kangaroo",
125
+ "105": "koala, koala bear, kangaroo bear, native bear, Phascolarctos cinereus",
126
+ "106": "wombat",
127
+ "107": "jellyfish",
128
+ "108": "sea anemone, anemone",
129
+ "109": "brain coral",
130
+ "110": "flatworm, platyhelminth",
131
+ "111": "nematode, nematode worm, roundworm",
132
+ "112": "conch",
133
+ "113": "snail",
134
+ "114": "slug",
135
+ "115": "sea slug, nudibranch",
136
+ "116": "chiton, coat-of-mail shell, sea cradle, polyplacophore",
137
+ "117": "chambered nautilus, pearly nautilus, nautilus",
138
+ "118": "Dungeness crab, Cancer magister",
139
+ "119": "rock crab, Cancer irroratus",
140
+ "120": "fiddler crab",
141
+ "121": "king crab, Alaska crab, Alaskan king crab, Alaska king crab, Paralithodes camtschatica",
142
+ "122": "American lobster, Northern lobster, Maine lobster, Homarus americanus",
143
+ "123": "spiny lobster, langouste, rock lobster, crawfish, crayfish, sea crawfish",
144
+ "124": "crayfish, crawfish, crawdad, crawdaddy",
145
+ "125": "hermit crab",
146
+ "126": "isopod",
147
+ "127": "white stork, Ciconia ciconia",
148
+ "128": "black stork, Ciconia nigra",
149
+ "129": "spoonbill",
150
+ "130": "flamingo",
151
+ "131": "little blue heron, Egretta caerulea",
152
+ "132": "American egret, great white heron, Egretta albus",
153
+ "133": "bittern",
154
+ "134": "crane",
155
+ "135": "limpkin, Aramus pictus",
156
+ "136": "European gallinule, Porphyrio porphyrio",
157
+ "137": "American coot, marsh hen, mud hen, water hen, Fulica americana",
158
+ "138": "bustard",
159
+ "139": "ruddy turnstone, Arenaria interpres",
160
+ "140": "red-backed sandpiper, dunlin, Erolia alpina",
161
+ "141": "redshank, Tringa totanus",
162
+ "142": "dowitcher",
163
+ "143": "oystercatcher, oyster catcher",
164
+ "144": "pelican",
165
+ "145": "king penguin, Aptenodytes patagonica",
166
+ "146": "albatross, mollymawk",
167
+ "147": "grey whale, gray whale, devilfish, Eschrichtius gibbosus, Eschrichtius robustus",
168
+ "148": "killer whale, killer, orca, grampus, sea wolf, Orcinus orca",
169
+ "149": "dugong, Dugong dugon",
170
+ "150": "sea lion",
171
+ "151": "Chihuahua",
172
+ "152": "Japanese spaniel",
173
+ "153": "Maltese dog, Maltese terrier, Maltese",
174
+ "154": "Pekinese, Pekingese, Peke",
175
+ "155": "Shih-Tzu",
176
+ "156": "Blenheim spaniel",
177
+ "157": "papillon",
178
+ "158": "toy terrier",
179
+ "159": "Rhodesian ridgeback",
180
+ "160": "Afghan hound, Afghan",
181
+ "161": "basset, basset hound",
182
+ "162": "beagle",
183
+ "163": "bloodhound, sleuthhound",
184
+ "164": "bluetick",
185
+ "165": "black-and-tan coonhound",
186
+ "166": "Walker hound, Walker foxhound",
187
+ "167": "English foxhound",
188
+ "168": "redbone",
189
+ "169": "borzoi, Russian wolfhound",
190
+ "170": "Irish wolfhound",
191
+ "171": "Italian greyhound",
192
+ "172": "whippet",
193
+ "173": "Ibizan hound, Ibizan Podenco",
194
+ "174": "Norwegian elkhound, elkhound",
195
+ "175": "otterhound, otter hound",
196
+ "176": "Saluki, gazelle hound",
197
+ "177": "Scottish deerhound, deerhound",
198
+ "178": "Weimaraner",
199
+ "179": "Staffordshire bullterrier, Staffordshire bull terrier",
200
+ "180": "American Staffordshire terrier, Staffordshire terrier, American pit bull terrier, pit bull terrier",
201
+ "181": "Bedlington terrier",
202
+ "182": "Border terrier",
203
+ "183": "Kerry blue terrier",
204
+ "184": "Irish terrier",
205
+ "185": "Norfolk terrier",
206
+ "186": "Norwich terrier",
207
+ "187": "Yorkshire terrier",
208
+ "188": "wire-haired fox terrier",
209
+ "189": "Lakeland terrier",
210
+ "190": "Sealyham terrier, Sealyham",
211
+ "191": "Airedale, Airedale terrier",
212
+ "192": "cairn, cairn terrier",
213
+ "193": "Australian terrier",
214
+ "194": "Dandie Dinmont, Dandie Dinmont terrier",
215
+ "195": "Boston bull, Boston terrier",
216
+ "196": "miniature schnauzer",
217
+ "197": "giant schnauzer",
218
+ "198": "standard schnauzer",
219
+ "199": "Scotch terrier, Scottish terrier, Scottie",
220
+ "200": "Tibetan terrier, chrysanthemum dog",
221
+ "201": "silky terrier, Sydney silky",
222
+ "202": "soft-coated wheaten terrier",
223
+ "203": "West Highland white terrier",
224
+ "204": "Lhasa, Lhasa apso",
225
+ "205": "flat-coated retriever",
226
+ "206": "curly-coated retriever",
227
+ "207": "golden retriever",
228
+ "208": "Labrador retriever",
229
+ "209": "Chesapeake Bay retriever",
230
+ "210": "German short-haired pointer",
231
+ "211": "vizsla, Hungarian pointer",
232
+ "212": "English setter",
233
+ "213": "Irish setter, red setter",
234
+ "214": "Gordon setter",
235
+ "215": "Brittany spaniel",
236
+ "216": "clumber, clumber spaniel",
237
+ "217": "English springer, English springer spaniel",
238
+ "218": "Welsh springer spaniel",
239
+ "219": "cocker spaniel, English cocker spaniel, cocker",
240
+ "220": "Sussex spaniel",
241
+ "221": "Irish water spaniel",
242
+ "222": "kuvasz",
243
+ "223": "schipperke",
244
+ "224": "groenendael",
245
+ "225": "malinois",
246
+ "226": "briard",
247
+ "227": "kelpie",
248
+ "228": "komondor",
249
+ "229": "Old English sheepdog, bobtail",
250
+ "230": "Shetland sheepdog, Shetland sheep dog, Shetland",
251
+ "231": "collie",
252
+ "232": "Border collie",
253
+ "233": "Bouvier des Flandres, Bouviers des Flandres",
254
+ "234": "Rottweiler",
255
+ "235": "German shepherd, German shepherd dog, German police dog, alsatian",
256
+ "236": "Doberman, Doberman pinscher",
257
+ "237": "miniature pinscher",
258
+ "238": "Greater Swiss Mountain dog",
259
+ "239": "Bernese mountain dog",
260
+ "240": "Appenzeller",
261
+ "241": "EntleBucher",
262
+ "242": "boxer",
263
+ "243": "bull mastiff",
264
+ "244": "Tibetan mastiff",
265
+ "245": "French bulldog",
266
+ "246": "Great Dane",
267
+ "247": "Saint Bernard, St Bernard",
268
+ "248": "Eskimo dog, husky",
269
+ "249": "malamute, malemute, Alaskan malamute",
270
+ "250": "Siberian husky",
271
+ "251": "dalmatian, coach dog, carriage dog",
272
+ "252": "affenpinscher, monkey pinscher, monkey dog",
273
+ "253": "basenji",
274
+ "254": "pug, pug-dog",
275
+ "255": "Leonberg",
276
+ "256": "Newfoundland, Newfoundland dog",
277
+ "257": "Great Pyrenees",
278
+ "258": "Samoyed, Samoyede",
279
+ "259": "Pomeranian",
280
+ "260": "chow, chow chow",
281
+ "261": "keeshond",
282
+ "262": "Brabancon griffon",
283
+ "263": "Pembroke, Pembroke Welsh corgi",
284
+ "264": "Cardigan, Cardigan Welsh corgi",
285
+ "265": "toy poodle",
286
+ "266": "miniature poodle",
287
+ "267": "standard poodle",
288
+ "268": "Mexican hairless",
289
+ "269": "timber wolf, grey wolf, gray wolf, Canis lupus",
290
+ "270": "white wolf, Arctic wolf, Canis lupus tundrarum",
291
+ "271": "red wolf, maned wolf, Canis rufus, Canis niger",
292
+ "272": "coyote, prairie wolf, brush wolf, Canis latrans",
293
+ "273": "dingo, warrigal, warragal, Canis dingo",
294
+ "274": "dhole, Cuon alpinus",
295
+ "275": "African hunting dog, hyena dog, Cape hunting dog, Lycaon pictus",
296
+ "276": "hyena, hyaena",
297
+ "277": "red fox, Vulpes vulpes",
298
+ "278": "kit fox, Vulpes macrotis",
299
+ "279": "Arctic fox, white fox, Alopex lagopus",
300
+ "280": "grey fox, gray fox, Urocyon cinereoargenteus",
301
+ "281": "tabby, tabby cat",
302
+ "282": "tiger cat",
303
+ "283": "Persian cat",
304
+ "284": "Siamese cat, Siamese",
305
+ "285": "Egyptian cat",
306
+ "286": "cougar, puma, catamount, mountain lion, painter, panther, Felis concolor",
307
+ "287": "lynx, catamount",
308
+ "288": "leopard, Panthera pardus",
309
+ "289": "snow leopard, ounce, Panthera uncia",
310
+ "290": "jaguar, panther, Panthera onca, Felis onca",
311
+ "291": "lion, king of beasts, Panthera leo",
312
+ "292": "tiger, Panthera tigris",
313
+ "293": "cheetah, chetah, Acinonyx jubatus",
314
+ "294": "brown bear, bruin, Ursus arctos",
315
+ "295": "American black bear, black bear, Ursus americanus, Euarctos americanus",
316
+ "296": "ice bear, polar bear, Ursus Maritimus, Thalarctos maritimus",
317
+ "297": "sloth bear, Melursus ursinus, Ursus ursinus",
318
+ "298": "mongoose",
319
+ "299": "meerkat, mierkat",
320
+ "300": "tiger beetle",
321
+ "301": "ladybug, ladybeetle, lady beetle, ladybird, ladybird beetle",
322
+ "302": "ground beetle, carabid beetle",
323
+ "303": "long-horned beetle, longicorn, longicorn beetle",
324
+ "304": "leaf beetle, chrysomelid",
325
+ "305": "dung beetle",
326
+ "306": "rhinoceros beetle",
327
+ "307": "weevil",
328
+ "308": "fly",
329
+ "309": "bee",
330
+ "310": "ant, emmet, pismire",
331
+ "311": "grasshopper, hopper",
332
+ "312": "cricket",
333
+ "313": "walking stick, walkingstick, stick insect",
334
+ "314": "cockroach, roach",
335
+ "315": "mantis, mantid",
336
+ "316": "cicada, cicala",
337
+ "317": "leafhopper",
338
+ "318": "lacewing, lacewing fly",
339
+ "319": "dragonfly, darning needle, devils darning needle, sewing needle, snake feeder, snake doctor, mosquito hawk, skeeter hawk",
340
+ "320": "damselfly",
341
+ "321": "admiral",
342
+ "322": "ringlet, ringlet butterfly",
343
+ "323": "monarch, monarch butterfly, milkweed butterfly, Danaus plexippus",
344
+ "324": "cabbage butterfly",
345
+ "325": "sulphur butterfly, sulfur butterfly",
346
+ "326": "lycaenid, lycaenid butterfly",
347
+ "327": "starfish, sea star",
348
+ "328": "sea urchin",
349
+ "329": "sea cucumber, holothurian",
350
+ "330": "wood rabbit, cottontail, cottontail rabbit",
351
+ "331": "hare",
352
+ "332": "Angora, Angora rabbit",
353
+ "333": "hamster",
354
+ "334": "porcupine, hedgehog",
355
+ "335": "fox squirrel, eastern fox squirrel, Sciurus niger",
356
+ "336": "marmot",
357
+ "337": "beaver",
358
+ "338": "guinea pig, Cavia cobaya",
359
+ "339": "sorrel",
360
+ "340": "zebra",
361
+ "341": "hog, pig, grunter, squealer, Sus scrofa",
362
+ "342": "wild boar, boar, Sus scrofa",
363
+ "343": "warthog",
364
+ "344": "hippopotamus, hippo, river horse, Hippopotamus amphibius",
365
+ "345": "ox",
366
+ "346": "water buffalo, water ox, Asiatic buffalo, Bubalus bubalis",
367
+ "347": "bison",
368
+ "348": "ram, tup",
369
+ "349": "bighorn, bighorn sheep, cimarron, Rocky Mountain bighorn, Rocky Mountain sheep, Ovis canadensis",
370
+ "350": "ibex, Capra ibex",
371
+ "351": "hartebeest",
372
+ "352": "impala, Aepyceros melampus",
373
+ "353": "gazelle",
374
+ "354": "Arabian camel, dromedary, Camelus dromedarius",
375
+ "355": "llama",
376
+ "356": "weasel",
377
+ "357": "mink",
378
+ "358": "polecat, fitch, foulmart, foumart, Mustela putorius",
379
+ "359": "black-footed ferret, ferret, Mustela nigripes",
380
+ "360": "otter",
381
+ "361": "skunk, polecat, wood pussy",
382
+ "362": "badger",
383
+ "363": "armadillo",
384
+ "364": "three-toed sloth, ai, Bradypus tridactylus",
385
+ "365": "orangutan, orang, orangutang, Pongo pygmaeus",
386
+ "366": "gorilla, Gorilla gorilla",
387
+ "367": "chimpanzee, chimp, Pan troglodytes",
388
+ "368": "gibbon, Hylobates lar",
389
+ "369": "siamang, Hylobates syndactylus, Symphalangus syndactylus",
390
+ "370": "guenon, guenon monkey",
391
+ "371": "patas, hussar monkey, Erythrocebus patas",
392
+ "372": "baboon",
393
+ "373": "macaque",
394
+ "374": "langur",
395
+ "375": "colobus, colobus monkey",
396
+ "376": "proboscis monkey, Nasalis larvatus",
397
+ "377": "marmoset",
398
+ "378": "capuchin, ringtail, Cebus capucinus",
399
+ "379": "howler monkey, howler",
400
+ "380": "titi, titi monkey",
401
+ "381": "spider monkey, Ateles geoffroyi",
402
+ "382": "squirrel monkey, Saimiri sciureus",
403
+ "383": "Madagascar cat, ring-tailed lemur, Lemur catta",
404
+ "384": "indri, indris, Indri indri, Indri brevicaudatus",
405
+ "385": "Indian elephant, Elephas maximus",
406
+ "386": "African elephant, Loxodonta africana",
407
+ "387": "lesser panda, red panda, panda, bear cat, cat bear, Ailurus fulgens",
408
+ "388": "giant panda, panda, panda bear, coon bear, Ailuropoda melanoleuca",
409
+ "389": "barracouta, snoek",
410
+ "390": "eel",
411
+ "391": "coho, cohoe, coho salmon, blue jack, silver salmon, Oncorhynchus kisutch",
412
+ "392": "rock beauty, Holocanthus tricolor",
413
+ "393": "anemone fish",
414
+ "394": "sturgeon",
415
+ "395": "gar, garfish, garpike, billfish, Lepisosteus osseus",
416
+ "396": "lionfish",
417
+ "397": "puffer, pufferfish, blowfish, globefish",
418
+ "398": "abacus",
419
+ "399": "abaya",
420
+ "400": "academic gown, academic robe, judge robe",
421
+ "401": "accordion, piano accordion, squeeze box",
422
+ "402": "acoustic guitar",
423
+ "403": "aircraft carrier, carrier, flattop, attack aircraft carrier",
424
+ "404": "airliner",
425
+ "405": "airship, dirigible",
426
+ "406": "altar",
427
+ "407": "ambulance",
428
+ "408": "amphibian, amphibious vehicle",
429
+ "409": "analog clock",
430
+ "410": "apiary, bee house",
431
+ "411": "apron",
432
+ "412": "ashcan, trash can, garbage can, wastebin, ash bin, ash-bin, ashbin, dustbin, trash barrel, trash bin",
433
+ "413": "assault rifle, assault gun",
434
+ "414": "backpack, back pack, knapsack, packsack, rucksack, haversack",
435
+ "415": "bakery, bakeshop, bakehouse",
436
+ "416": "balance beam, beam",
437
+ "417": "balloon",
438
+ "418": "ballpoint, ballpoint pen, ballpen, Biro",
439
+ "419": "Band Aid",
440
+ "420": "banjo",
441
+ "421": "bannister, banister, balustrade, balusters, handrail",
442
+ "422": "barbell",
443
+ "423": "barber chair",
444
+ "424": "barbershop",
445
+ "425": "barn",
446
+ "426": "barometer",
447
+ "427": "barrel, cask",
448
+ "428": "barrow, garden cart, lawn cart, wheelbarrow",
449
+ "429": "baseball",
450
+ "430": "basketball",
451
+ "431": "bassinet",
452
+ "432": "bassoon",
453
+ "433": "bathing cap, swimming cap",
454
+ "434": "bath towel",
455
+ "435": "bathtub, bathing tub, bath, tub",
456
+ "436": "beach wagon, station wagon, wagon, estate car, beach waggon, station waggon, waggon",
457
+ "437": "beacon, lighthouse, beacon light, pharos",
458
+ "438": "beaker",
459
+ "439": "bearskin, busby, shako",
460
+ "440": "beer bottle",
461
+ "441": "beer glass",
462
+ "442": "bell cote, bell cot",
463
+ "443": "bib",
464
+ "444": "bicycle-built-for-two, tandem bicycle, tandem",
465
+ "445": "bikini, two-piece",
466
+ "446": "binder, ring-binder",
467
+ "447": "binoculars, field glasses, opera glasses",
468
+ "448": "birdhouse",
469
+ "449": "boathouse",
470
+ "450": "bobsled, bobsleigh, bob",
471
+ "451": "bolo tie, bolo, bola tie, bola",
472
+ "452": "bonnet, poke bonnet",
473
+ "453": "bookcase",
474
+ "454": "bookshop, bookstore, bookstall",
475
+ "455": "bottlecap",
476
+ "456": "bow",
477
+ "457": "bow tie, bow-tie, bowtie",
478
+ "458": "brass, memorial tablet, plaque",
479
+ "459": "brassiere, bra, bandeau",
480
+ "460": "breakwater, groin, groyne, mole, bulwark, seawall, jetty",
481
+ "461": "breastplate, aegis, egis",
482
+ "462": "broom",
483
+ "463": "bucket, pail",
484
+ "464": "buckle",
485
+ "465": "bulletproof vest",
486
+ "466": "bullet train, bullet",
487
+ "467": "butcher shop, meat market",
488
+ "468": "cab, hack, taxi, taxicab",
489
+ "469": "caldron, cauldron",
490
+ "470": "candle, taper, wax light",
491
+ "471": "cannon",
492
+ "472": "canoe",
493
+ "473": "can opener, tin opener",
494
+ "474": "cardigan",
495
+ "475": "car mirror",
496
+ "476": "carousel, carrousel, merry-go-round, roundabout, whirligig",
497
+ "477": "carpenters kit, tool kit",
498
+ "478": "carton",
499
+ "479": "car wheel",
500
+ "480": "cash machine, cash dispenser, automated teller machine, automatic teller machine, automated teller, automatic teller, ATM",
501
+ "481": "cassette",
502
+ "482": "cassette player",
503
+ "483": "castle",
504
+ "484": "catamaran",
505
+ "485": "CD player",
506
+ "486": "cello, violoncello",
507
+ "487": "cellular telephone, cellular phone, cellphone, cell, mobile phone",
508
+ "488": "chain",
509
+ "489": "chainlink fence",
510
+ "490": "chain mail, ring mail, mail, chain armor, chain armour, ring armor, ring armour",
511
+ "491": "chain saw, chainsaw",
512
+ "492": "chest",
513
+ "493": "chiffonier, commode",
514
+ "494": "chime, bell, gong",
515
+ "495": "china cabinet, china closet",
516
+ "496": "Christmas stocking",
517
+ "497": "church, church building",
518
+ "498": "cinema, movie theater, movie theatre, movie house, picture palace",
519
+ "499": "cleaver, meat cleaver, chopper",
520
+ "500": "cliff dwelling",
521
+ "501": "cloak",
522
+ "502": "clog, geta, patten, sabot",
523
+ "503": "cocktail shaker",
524
+ "504": "coffee mug",
525
+ "505": "coffeepot",
526
+ "506": "coil, spiral, volute, whorl, helix",
527
+ "507": "combination lock",
528
+ "508": "computer keyboard, keypad",
529
+ "509": "confectionery, confectionary, candy store",
530
+ "510": "container ship, containership, container vessel",
531
+ "511": "convertible",
532
+ "512": "corkscrew, bottle screw",
533
+ "513": "cornet, horn, trumpet, trump",
534
+ "514": "cowboy boot",
535
+ "515": "cowboy hat, ten-gallon hat",
536
+ "516": "cradle",
537
+ "517": "crane",
538
+ "518": "crash helmet",
539
+ "519": "crate",
540
+ "520": "crib, cot",
541
+ "521": "Crock Pot",
542
+ "522": "croquet ball",
543
+ "523": "crutch",
544
+ "524": "cuirass",
545
+ "525": "dam, dike, dyke",
546
+ "526": "desk",
547
+ "527": "desktop computer",
548
+ "528": "dial telephone, dial phone",
549
+ "529": "diaper, nappy, napkin",
550
+ "530": "digital clock",
551
+ "531": "digital watch",
552
+ "532": "dining table, board",
553
+ "533": "dishrag, dishcloth",
554
+ "534": "dishwasher, dish washer, dishwashing machine",
555
+ "535": "disk brake, disc brake",
556
+ "536": "dock, dockage, docking facility",
557
+ "537": "dogsled, dog sled, dog sleigh",
558
+ "538": "dome",
559
+ "539": "doormat, welcome mat",
560
+ "540": "drilling platform, offshore rig",
561
+ "541": "drum, membranophone, tympan",
562
+ "542": "drumstick",
563
+ "543": "dumbbell",
564
+ "544": "Dutch oven",
565
+ "545": "electric fan, blower",
566
+ "546": "electric guitar",
567
+ "547": "electric locomotive",
568
+ "548": "entertainment center",
569
+ "549": "envelope",
570
+ "550": "espresso maker",
571
+ "551": "face powder",
572
+ "552": "feather boa, boa",
573
+ "553": "file, file cabinet, filing cabinet",
574
+ "554": "fireboat",
575
+ "555": "fire engine, fire truck",
576
+ "556": "fire screen, fireguard",
577
+ "557": "flagpole, flagstaff",
578
+ "558": "flute, transverse flute",
579
+ "559": "folding chair",
580
+ "560": "football helmet",
581
+ "561": "forklift",
582
+ "562": "fountain",
583
+ "563": "fountain pen",
584
+ "564": "four-poster",
585
+ "565": "freight car",
586
+ "566": "French horn, horn",
587
+ "567": "frying pan, frypan, skillet",
588
+ "568": "fur coat",
589
+ "569": "garbage truck, dustcart",
590
+ "570": "gasmask, respirator, gas helmet",
591
+ "571": "gas pump, gasoline pump, petrol pump, island dispenser",
592
+ "572": "goblet",
593
+ "573": "go-kart",
594
+ "574": "golf ball",
595
+ "575": "golfcart, golf cart",
596
+ "576": "gondola",
597
+ "577": "gong, tam-tam",
598
+ "578": "gown",
599
+ "579": "grand piano, grand",
600
+ "580": "greenhouse, nursery, glasshouse",
601
+ "581": "grille, radiator grille",
602
+ "582": "grocery store, grocery, food market, market",
603
+ "583": "guillotine",
604
+ "584": "hair slide",
605
+ "585": "hair spray",
606
+ "586": "half track",
607
+ "587": "hammer",
608
+ "588": "hamper",
609
+ "589": "hand blower, blow dryer, blow drier, hair dryer, hair drier",
610
+ "590": "hand-held computer, hand-held microcomputer",
611
+ "591": "handkerchief, hankie, hanky, hankey",
612
+ "592": "hard disc, hard disk, fixed disk",
613
+ "593": "harmonica, mouth organ, harp, mouth harp",
614
+ "594": "harp",
615
+ "595": "harvester, reaper",
616
+ "596": "hatchet",
617
+ "597": "holster",
618
+ "598": "home theater, home theatre",
619
+ "599": "honeycomb",
620
+ "600": "hook, claw",
621
+ "601": "hoopskirt, crinoline",
622
+ "602": "horizontal bar, high bar",
623
+ "603": "horse cart, horse-cart",
624
+ "604": "hourglass",
625
+ "605": "iPod",
626
+ "606": "iron, smoothing iron",
627
+ "607": "jack-o-lantern",
628
+ "608": "jean, blue jean, denim",
629
+ "609": "jeep, landrover",
630
+ "610": "jersey, T-shirt, tee shirt",
631
+ "611": "jigsaw puzzle",
632
+ "612": "jinrikisha, ricksha, rickshaw",
633
+ "613": "joystick",
634
+ "614": "kimono",
635
+ "615": "knee pad",
636
+ "616": "knot",
637
+ "617": "lab coat, laboratory coat",
638
+ "618": "ladle",
639
+ "619": "lampshade, lamp shade",
640
+ "620": "laptop, laptop computer",
641
+ "621": "lawn mower, mower",
642
+ "622": "lens cap, lens cover",
643
+ "623": "letter opener, paper knife, paperknife",
644
+ "624": "library",
645
+ "625": "lifeboat",
646
+ "626": "lighter, light, igniter, ignitor",
647
+ "627": "limousine, limo",
648
+ "628": "liner, ocean liner",
649
+ "629": "lipstick, lip rouge",
650
+ "630": "Loafer",
651
+ "631": "lotion",
652
+ "632": "loudspeaker, speaker, speaker unit, loudspeaker system, speaker system",
653
+ "633": "loupe, jewelers loupe",
654
+ "634": "lumbermill, sawmill",
655
+ "635": "magnetic compass",
656
+ "636": "mailbag, postbag",
657
+ "637": "mailbox, letter box",
658
+ "638": "maillot",
659
+ "639": "maillot, tank suit",
660
+ "640": "manhole cover",
661
+ "641": "maraca",
662
+ "642": "marimba, xylophone",
663
+ "643": "mask",
664
+ "644": "matchstick",
665
+ "645": "maypole",
666
+ "646": "maze, labyrinth",
667
+ "647": "measuring cup",
668
+ "648": "medicine chest, medicine cabinet",
669
+ "649": "megalith, megalithic structure",
670
+ "650": "microphone, mike",
671
+ "651": "microwave, microwave oven",
672
+ "652": "military uniform",
673
+ "653": "milk can",
674
+ "654": "minibus",
675
+ "655": "miniskirt, mini",
676
+ "656": "minivan",
677
+ "657": "missile",
678
+ "658": "mitten",
679
+ "659": "mixing bowl",
680
+ "660": "mobile home, manufactured home",
681
+ "661": "Model T",
682
+ "662": "modem",
683
+ "663": "monastery",
684
+ "664": "monitor",
685
+ "665": "moped",
686
+ "666": "mortar",
687
+ "667": "mortarboard",
688
+ "668": "mosque",
689
+ "669": "mosquito net",
690
+ "670": "motor scooter, scooter",
691
+ "671": "mountain bike, all-terrain bike, off-roader",
692
+ "672": "mountain tent",
693
+ "673": "mouse, computer mouse",
694
+ "674": "mousetrap",
695
+ "675": "moving van",
696
+ "676": "muzzle",
697
+ "677": "nail",
698
+ "678": "neck brace",
699
+ "679": "necklace",
700
+ "680": "nipple",
701
+ "681": "notebook, notebook computer",
702
+ "682": "obelisk",
703
+ "683": "oboe, hautboy, hautbois",
704
+ "684": "ocarina, sweet potato",
705
+ "685": "odometer, hodometer, mileometer, milometer",
706
+ "686": "oil filter",
707
+ "687": "organ, pipe organ",
708
+ "688": "oscilloscope, scope, cathode-ray oscilloscope, CRO",
709
+ "689": "overskirt",
710
+ "690": "oxcart",
711
+ "691": "oxygen mask",
712
+ "692": "packet",
713
+ "693": "paddle, boat paddle",
714
+ "694": "paddlewheel, paddle wheel",
715
+ "695": "padlock",
716
+ "696": "paintbrush",
717
+ "697": "pajama, pyjama, pjs, jammies",
718
+ "698": "palace",
719
+ "699": "panpipe, pandean pipe, syrinx",
720
+ "700": "paper towel",
721
+ "701": "parachute, chute",
722
+ "702": "parallel bars, bars",
723
+ "703": "park bench",
724
+ "704": "parking meter",
725
+ "705": "passenger car, coach, carriage",
726
+ "706": "patio, terrace",
727
+ "707": "pay-phone, pay-station",
728
+ "708": "pedestal, plinth, footstall",
729
+ "709": "pencil box, pencil case",
730
+ "710": "pencil sharpener",
731
+ "711": "perfume, essence",
732
+ "712": "Petri dish",
733
+ "713": "photocopier",
734
+ "714": "pick, plectrum, plectron",
735
+ "715": "pickelhaube",
736
+ "716": "picket fence, paling",
737
+ "717": "pickup, pickup truck",
738
+ "718": "pier",
739
+ "719": "piggy bank, penny bank",
740
+ "720": "pill bottle",
741
+ "721": "pillow",
742
+ "722": "ping-pong ball",
743
+ "723": "pinwheel",
744
+ "724": "pirate, pirate ship",
745
+ "725": "pitcher, ewer",
746
+ "726": "plane, carpenters plane, woodworking plane",
747
+ "727": "planetarium",
748
+ "728": "plastic bag",
749
+ "729": "plate rack",
750
+ "730": "plow, plough",
751
+ "731": "plunger, plumbers helper",
752
+ "732": "Polaroid camera, Polaroid Land camera",
753
+ "733": "pole",
754
+ "734": "police van, police wagon, paddy wagon, patrol wagon, wagon, black Maria",
755
+ "735": "poncho",
756
+ "736": "pool table, billiard table, snooker table",
757
+ "737": "pop bottle, soda bottle",
758
+ "738": "pot, flowerpot",
759
+ "739": "potters wheel",
760
+ "740": "power drill",
761
+ "741": "prayer rug, prayer mat",
762
+ "742": "printer",
763
+ "743": "prison, prison house",
764
+ "744": "projectile, missile",
765
+ "745": "projector",
766
+ "746": "puck, hockey puck",
767
+ "747": "punching bag, punch bag, punching ball, punchball",
768
+ "748": "purse",
769
+ "749": "quill, quill pen",
770
+ "750": "quilt, comforter, comfort, puff",
771
+ "751": "racer, race car, racing car",
772
+ "752": "racket, racquet",
773
+ "753": "radiator",
774
+ "754": "radio, wireless",
775
+ "755": "radio telescope, radio reflector",
776
+ "756": "rain barrel",
777
+ "757": "recreational vehicle, RV, R.V.",
778
+ "758": "reel",
779
+ "759": "reflex camera",
780
+ "760": "refrigerator, icebox",
781
+ "761": "remote control, remote",
782
+ "762": "restaurant, eating house, eating place, eatery",
783
+ "763": "revolver, six-gun, six-shooter",
784
+ "764": "rifle",
785
+ "765": "rocking chair, rocker",
786
+ "766": "rotisserie",
787
+ "767": "rubber eraser, rubber, pencil eraser",
788
+ "768": "rugby ball",
789
+ "769": "rule, ruler",
790
+ "770": "running shoe",
791
+ "771": "safe",
792
+ "772": "safety pin",
793
+ "773": "saltshaker, salt shaker",
794
+ "774": "sandal",
795
+ "775": "sarong",
796
+ "776": "sax, saxophone",
797
+ "777": "scabbard",
798
+ "778": "scale, weighing machine",
799
+ "779": "school bus",
800
+ "780": "schooner",
801
+ "781": "scoreboard",
802
+ "782": "screen, CRT screen",
803
+ "783": "screw",
804
+ "784": "screwdriver",
805
+ "785": "seat belt, seatbelt",
806
+ "786": "sewing machine",
807
+ "787": "shield, buckler",
808
+ "788": "shoe shop, shoe-shop, shoe store",
809
+ "789": "shoji",
810
+ "790": "shopping basket",
811
+ "791": "shopping cart",
812
+ "792": "shovel",
813
+ "793": "shower cap",
814
+ "794": "shower curtain",
815
+ "795": "ski",
816
+ "796": "ski mask",
817
+ "797": "sleeping bag",
818
+ "798": "slide rule, slipstick",
819
+ "799": "sliding door",
820
+ "800": "slot, one-armed bandit",
821
+ "801": "snorkel",
822
+ "802": "snowmobile",
823
+ "803": "snowplow, snowplough",
824
+ "804": "soap dispenser",
825
+ "805": "soccer ball",
826
+ "806": "sock",
827
+ "807": "solar dish, solar collector, solar furnace",
828
+ "808": "sombrero",
829
+ "809": "soup bowl",
830
+ "810": "space bar",
831
+ "811": "space heater",
832
+ "812": "space shuttle",
833
+ "813": "spatula",
834
+ "814": "speedboat",
835
+ "815": "spider web, spiders web",
836
+ "816": "spindle",
837
+ "817": "sports car, sport car",
838
+ "818": "spotlight, spot",
839
+ "819": "stage",
840
+ "820": "steam locomotive",
841
+ "821": "steel arch bridge",
842
+ "822": "steel drum",
843
+ "823": "stethoscope",
844
+ "824": "stole",
845
+ "825": "stone wall",
846
+ "826": "stopwatch, stop watch",
847
+ "827": "stove",
848
+ "828": "strainer",
849
+ "829": "streetcar, tram, tramcar, trolley, trolley car",
850
+ "830": "stretcher",
851
+ "831": "studio couch, day bed",
852
+ "832": "stupa, tope",
853
+ "833": "submarine, pigboat, sub, U-boat",
854
+ "834": "suit, suit of clothes",
855
+ "835": "sundial",
856
+ "836": "sunglass",
857
+ "837": "sunglasses, dark glasses, shades",
858
+ "838": "sunscreen, sunblock, sun blocker",
859
+ "839": "suspension bridge",
860
+ "840": "swab, swob, mop",
861
+ "841": "sweatshirt",
862
+ "842": "swimming trunks, bathing trunks",
863
+ "843": "swing",
864
+ "844": "switch, electric switch, electrical switch",
865
+ "845": "syringe",
866
+ "846": "table lamp",
867
+ "847": "tank, army tank, armored combat vehicle, armoured combat vehicle",
868
+ "848": "tape player",
869
+ "849": "teapot",
870
+ "850": "teddy, teddy bear",
871
+ "851": "television, television system",
872
+ "852": "tennis ball",
873
+ "853": "thatch, thatched roof",
874
+ "854": "theater curtain, theatre curtain",
875
+ "855": "thimble",
876
+ "856": "thresher, thrasher, threshing machine",
877
+ "857": "throne",
878
+ "858": "tile roof",
879
+ "859": "toaster",
880
+ "860": "tobacco shop, tobacconist shop, tobacconist",
881
+ "861": "toilet seat",
882
+ "862": "torch",
883
+ "863": "totem pole",
884
+ "864": "tow truck, tow car, wrecker",
885
+ "865": "toyshop",
886
+ "866": "tractor",
887
+ "867": "trailer truck, tractor trailer, trucking rig, rig, articulated lorry, semi",
888
+ "868": "tray",
889
+ "869": "trench coat",
890
+ "870": "tricycle, trike, velocipede",
891
+ "871": "trimaran",
892
+ "872": "tripod",
893
+ "873": "triumphal arch",
894
+ "874": "trolleybus, trolley coach, trackless trolley",
895
+ "875": "trombone",
896
+ "876": "tub, vat",
897
+ "877": "turnstile",
898
+ "878": "typewriter keyboard",
899
+ "879": "umbrella",
900
+ "880": "unicycle, monocycle",
901
+ "881": "upright, upright piano",
902
+ "882": "vacuum, vacuum cleaner",
903
+ "883": "vase",
904
+ "884": "vault",
905
+ "885": "velvet",
906
+ "886": "vending machine",
907
+ "887": "vestment",
908
+ "888": "viaduct",
909
+ "889": "violin, fiddle",
910
+ "890": "volleyball",
911
+ "891": "waffle iron",
912
+ "892": "wall clock",
913
+ "893": "wallet, billfold, notecase, pocketbook",
914
+ "894": "wardrobe, closet, press",
915
+ "895": "warplane, military plane",
916
+ "896": "washbasin, handbasin, washbowl, lavabo, wash-hand basin",
917
+ "897": "washer, automatic washer, washing machine",
918
+ "898": "water bottle",
919
+ "899": "water jug",
920
+ "900": "water tower",
921
+ "901": "whiskey jug",
922
+ "902": "whistle",
923
+ "903": "wig",
924
+ "904": "window screen",
925
+ "905": "window shade",
926
+ "906": "Windsor tie",
927
+ "907": "wine bottle",
928
+ "908": "wing",
929
+ "909": "wok",
930
+ "910": "wooden spoon",
931
+ "911": "wool, woolen, woollen",
932
+ "912": "worm fence, snake fence, snake-rail fence, Virginia fence",
933
+ "913": "wreck",
934
+ "914": "yawl",
935
+ "915": "yurt",
936
+ "916": "web site, website, internet site, site",
937
+ "917": "comic book",
938
+ "918": "crossword puzzle, crossword",
939
+ "919": "street sign",
940
+ "920": "traffic light, traffic signal, stoplight",
941
+ "921": "book jacket, dust cover, dust jacket, dust wrapper",
942
+ "922": "menu",
943
+ "923": "plate",
944
+ "924": "guacamole",
945
+ "925": "consomme",
946
+ "926": "hot pot, hotpot",
947
+ "927": "trifle",
948
+ "928": "ice cream, icecream",
949
+ "929": "ice lolly, lolly, lollipop, popsicle",
950
+ "930": "French loaf",
951
+ "931": "bagel, beigel",
952
+ "932": "pretzel",
953
+ "933": "cheeseburger",
954
+ "934": "hotdog, hot dog, red hot",
955
+ "935": "mashed potato",
956
+ "936": "head cabbage",
957
+ "937": "broccoli",
958
+ "938": "cauliflower",
959
+ "939": "zucchini, courgette",
960
+ "940": "spaghetti squash",
961
+ "941": "acorn squash",
962
+ "942": "butternut squash",
963
+ "943": "cucumber, cuke",
964
+ "944": "artichoke, globe artichoke",
965
+ "945": "bell pepper",
966
+ "946": "cardoon",
967
+ "947": "mushroom",
968
+ "948": "Granny Smith",
969
+ "949": "strawberry",
970
+ "950": "orange",
971
+ "951": "lemon",
972
+ "952": "fig",
973
+ "953": "pineapple, ananas",
974
+ "954": "banana",
975
+ "955": "jackfruit, jak, jack",
976
+ "956": "custard apple",
977
+ "957": "pomegranate",
978
+ "958": "hay",
979
+ "959": "carbonara",
980
+ "960": "chocolate sauce, chocolate syrup",
981
+ "961": "dough",
982
+ "962": "meat loaf, meatloaf",
983
+ "963": "pizza, pizza pie",
984
+ "964": "potpie",
985
+ "965": "burrito",
986
+ "966": "red wine",
987
+ "967": "espresso",
988
+ "968": "cup",
989
+ "969": "eggnog",
990
+ "970": "alp",
991
+ "971": "bubble",
992
+ "972": "cliff, drop, drop-off",
993
+ "973": "coral reef",
994
+ "974": "geyser",
995
+ "975": "lakeside, lakeshore",
996
+ "976": "promontory, headland, head, foreland",
997
+ "977": "sandbar, sand bar",
998
+ "978": "seashore, coast, seacoast, sea-coast",
999
+ "979": "valley, vale",
1000
+ "980": "volcano",
1001
+ "981": "ballplayer, baseball player",
1002
+ "982": "groom, bridegroom",
1003
+ "983": "scuba diver",
1004
+ "984": "rapeseed",
1005
+ "985": "daisy",
1006
+ "986": "yellow ladys slipper, yellow lady-slipper, Cypripedium calceolus, Cypripedium parviflorum",
1007
+ "987": "corn",
1008
+ "988": "acorn",
1009
+ "989": "hip, rose hip, rosehip",
1010
+ "990": "buckeye, horse chestnut, conker",
1011
+ "991": "coral fungus",
1012
+ "992": "agaric",
1013
+ "993": "gyromitra",
1014
+ "994": "stinkhorn, carrion fungus",
1015
+ "995": "earthstar",
1016
+ "996": "hen-of-the-woods, hen of the woods, Polyporus frondosus, Grifola frondosa",
1017
+ "997": "bolete",
1018
+ "998": "ear, spike, capitulum",
1019
+ "999": "toilet tissue, toilet paper, bathroom tissue"
1020
+ }
1021
+ }
W-Flow-L/pipeline.py ADDED
@@ -0,0 +1,754 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2026 The HuggingFace Team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import importlib.util
16
+ import inspect
17
+ import json
18
+ import sys
19
+ from pathlib import Path
20
+ from typing import Any, Callable
21
+
22
+ import torch
23
+ from diffusers.callbacks import MultiPipelineCallbacks, PipelineCallback
24
+ from diffusers.models.autoencoders.autoencoder_kl import AutoencoderKL
25
+ from diffusers.models.modeling_utils import ModelMixin
26
+ from diffusers.pipelines.pipeline_utils import DiffusionPipeline, ImagePipelineOutput
27
+ from diffusers.schedulers import KarrasDiffusionSchedulers
28
+ from diffusers.schedulers.scheduling_utils import SchedulerMixin
29
+ from diffusers.utils import deprecate, is_torch_xla_available, logging, replace_example_docstring
30
+ from PIL import Image
31
+
32
+ if is_torch_xla_available():
33
+ import torch_xla.core.xla_model as xm
34
+
35
+ XLA_AVAILABLE = True
36
+ else:
37
+ XLA_AVAILABLE = False
38
+
39
+ logger = logging.get_logger(__name__)
40
+
41
+ EXAMPLE_DOC_STRING = """
42
+ Examples:
43
+ ```py
44
+ >>> from pathlib import Path
45
+ >>> import torch
46
+ >>> from diffusers import DiffusionPipeline
47
+
48
+ >>> model_dir = Path("W-Flow-diffusers/W-Flow-L").resolve()
49
+ >>> pipe = DiffusionPipeline.from_pretrained(
50
+ ... str(model_dir),
51
+ ... local_files_only=True,
52
+ ... custom_pipeline=str(model_dir / "pipeline.py"),
53
+ ... trust_remote_code=True,
54
+ ... torch_dtype=torch.bfloat16,
55
+ ... ).to("cuda")
56
+
57
+ >>> image = pipe(
58
+ ... class_labels="golden retriever",
59
+ ... num_inference_steps=1,
60
+ ... guidance_scale=1.14,
61
+ ... generator=torch.Generator(device="cuda").manual_seed(1),
62
+ ... ).images[0]
63
+ >>> image.save("demo.png")
64
+
65
+ >>> # Hugging Face Hub style model id: UserID/RepoID
66
+ >>> # pipe = DiffusionPipeline.from_pretrained(
67
+ >>> # "BiliSakura/W-Flow-diffusers",
68
+ >>> # subfolder="W-Flow-L",
69
+ >>> # custom_pipeline="pipeline.py",
70
+ >>> # trust_remote_code=True,
71
+ >>> # torch_dtype=torch.bfloat16,
72
+ >>> # )
73
+ ```
74
+ """
75
+
76
+
77
+ class WFlowPipeline(DiffusionPipeline):
78
+ r"""
79
+ Class-conditional one-step pipeline for W-Flow.
80
+
81
+ W-Flow maps SD-VAE latent noise to a clean 32×32 latent in one forward pass, then decodes it
82
+ with `stabilityai/sd-vae-ft-mse` to a 256×256 image. Guidance is embedded in the generator
83
+ (the official `cfg_scale`, which is `w + 1` in the paper). There is no unconditional class
84
+ and no second forward.
85
+
86
+ The pipeline inherits from [`DiffusionPipeline`]. Check the superclass documentation for the
87
+ generic methods (download, save, device placement, CPU offload).
88
+
89
+ Args:
90
+ transformer ([`ModelMixin`]):
91
+ [`WFlowTransformer2DModel`] that predicts the clean latent.
92
+ vae ([`AutoencoderKL`]):
93
+ SD-VAE decoder. Released checkpoints use `stabilityai/sd-vae-ft-mse` and scaling 0.18215.
94
+ scheduler ([`WFlowScheduler`]):
95
+ One-step scheduler. Loaded from `scheduler/`.
96
+ id2label (`dict[int, str]`, *optional*):
97
+ ImageNet class id to English label mapping. Values may contain comma-separated synonyms.
98
+ Loaded from `model_index.json` when omitted.
99
+
100
+ The default guidance scale lives on `transformer.config.guidance_scale`.
101
+ """
102
+
103
+ model_cpu_offload_seq = "transformer->vae"
104
+ _callback_tensor_inputs = ["latents"]
105
+
106
+ def __init__(
107
+ self,
108
+ transformer: ModelMixin,
109
+ vae: AutoencoderKL,
110
+ scheduler: SchedulerMixin,
111
+ id2label: dict[int, str] | dict[str, str] | None = None,
112
+ ):
113
+ super().__init__()
114
+ if scheduler is None:
115
+ scheduler = self._default_scheduler()
116
+ self._reject_karras_scheduler(scheduler)
117
+ self.register_modules(transformer=transformer, vae=vae, scheduler=scheduler)
118
+ normalized_labels = self._normalize_id2label(id2label)
119
+ self.register_to_config(id2label={str(key): value for key, value in normalized_labels.items()})
120
+ self._id2label = normalized_labels
121
+ self.labels = self._build_label2id(self._id2label)
122
+ self._labels_loaded_from_model_index = bool(self._id2label)
123
+ self.vae_scale_factor = 2 ** (len(self.vae.config.block_out_channels) - 1)
124
+
125
+ def _sampling_default(self, name: str, fallback: float) -> float:
126
+ r"""
127
+ Read a sampling default from the transformer config.
128
+
129
+ Args:
130
+ name (`str`):
131
+ Key on `transformer.config`, such as `guidance_scale`.
132
+ fallback (`float`):
133
+ Value used when the transformer config does not define `name`.
134
+
135
+ Returns:
136
+ `float`: The configured value, or `fallback`.
137
+ """
138
+ value = getattr(self.transformer.config, name, None)
139
+ if value is None:
140
+ return fallback
141
+ return value
142
+
143
+ @staticmethod
144
+ def _reject_karras_scheduler(scheduler: SchedulerMixin) -> None:
145
+ r"""
146
+ Reject multi-step Karras schedulers.
147
+
148
+ W-Flow predicts the clean latent in one evaluation and has no diffusion timestep, so a
149
+ Karras noise schedule cannot be integrated.
150
+
151
+ Args:
152
+ scheduler ([`SchedulerMixin`]):
153
+ Scheduler attached to the pipeline.
154
+ """
155
+ scheduler_name = scheduler.__class__.__name__
156
+ if scheduler_name in KarrasDiffusionSchedulers.__members__:
157
+ raise TypeError(
158
+ "W-Flow is a one-step generator and does not integrate a Karras noise schedule. "
159
+ f"Received {scheduler_name}. Use WFlowScheduler."
160
+ )
161
+
162
+ @staticmethod
163
+ def _default_scheduler() -> SchedulerMixin:
164
+ r"""
165
+ Build [`WFlowScheduler`] from the variant directory.
166
+
167
+ Returns:
168
+ [`WFlowScheduler`]: One-step sample scheduler.
169
+ """
170
+ module_path = Path(__file__).resolve().parent / "scheduler" / "scheduling_wflow.py"
171
+ spec = importlib.util.spec_from_file_location("scheduling_wflow", module_path)
172
+ if spec is None or spec.loader is None:
173
+ raise ImportError(f"Could not load the W-Flow scheduler from {module_path}.")
174
+ module = importlib.util.module_from_spec(spec)
175
+ sys.modules["scheduling_wflow"] = module
176
+ spec.loader.exec_module(module)
177
+ return module.WFlowScheduler()
178
+
179
+ def _ensure_labels_loaded(self) -> None:
180
+ r"""
181
+ Fill `id2label` from `model_index.json` when the constructor did not receive it.
182
+ """
183
+ if self._labels_loaded_from_model_index:
184
+ return
185
+ loaded = self._read_id2label_from_model_index(getattr(self.config, "_name_or_path", None))
186
+ if loaded:
187
+ self._id2label = loaded
188
+ self.labels = self._build_label2id(self._id2label)
189
+ self._labels_loaded_from_model_index = True
190
+
191
+ @staticmethod
192
+ def _normalize_id2label(id2label: dict[int, str] | dict[str, str] | None) -> dict[int, str]:
193
+ r"""
194
+ Cast label-map keys to integers.
195
+
196
+ Args:
197
+ id2label (`dict`, *optional*):
198
+ Class id to English label. Keys may be strings, which is how JSON stores them.
199
+
200
+ Returns:
201
+ `dict[int, str]`: Integer-keyed map. Empty when `id2label` is missing.
202
+ """
203
+ if not id2label:
204
+ return {}
205
+ return {int(key): value for key, value in id2label.items()}
206
+
207
+ @staticmethod
208
+ def _read_id2label_from_model_index(variant_path: str | None) -> dict[int, str]:
209
+ r"""
210
+ Read `id2label` from a local variant directory.
211
+
212
+ Args:
213
+ variant_path (`str`, *optional*):
214
+ Directory that contains `model_index.json`.
215
+
216
+ Returns:
217
+ `dict[int, str]`: Loaded map, or an empty dict when the file or key is absent.
218
+ """
219
+ if not variant_path:
220
+ return {}
221
+ model_index_path = Path(variant_path).resolve() / "model_index.json"
222
+ if not model_index_path.exists():
223
+ return {}
224
+ raw = json.loads(model_index_path.read_text(encoding="utf-8"))
225
+ id2label = raw.get("id2label")
226
+ if not isinstance(id2label, dict):
227
+ return {}
228
+ return {int(key): value for key, value in id2label.items()}
229
+
230
+ @staticmethod
231
+ def _build_label2id(id2label: dict[int, str]) -> dict[str, int]:
232
+ r"""
233
+ Invert `id2label`, splitting comma-separated synonyms.
234
+
235
+ Args:
236
+ id2label (`dict[int, str]`):
237
+ Class id to one or more English names.
238
+
239
+ Returns:
240
+ `dict[str, int]`: Synonym to class id, sorted by synonym.
241
+ """
242
+ label2id: dict[str, int] = {}
243
+ for class_id, value in id2label.items():
244
+ for synonym in value.split(","):
245
+ synonym = synonym.strip()
246
+ if synonym:
247
+ label2id[synonym] = int(class_id)
248
+ return dict(sorted(label2id.items()))
249
+
250
+ @property
251
+ def interrupt(self) -> bool:
252
+ r"""
253
+ Whether the current call was asked to stop.
254
+
255
+ Returns:
256
+ `bool`: The `_interrupt` flag. `__call__` sets it to `False` at the start. Assign
257
+ `_interrupt = True` during a call to skip the remaining forward.
258
+ """
259
+ return self._interrupt
260
+
261
+ @property
262
+ def id2label(self) -> dict[int, str]:
263
+ r"""
264
+ ImageNet id to English label map.
265
+
266
+ Returns:
267
+ `dict[int, str]`: The map loaded from the constructor or `model_index.json`.
268
+ """
269
+ self._ensure_labels_loaded()
270
+ return self._id2label
271
+
272
+ def get_label_ids(self, label: str | list[str]) -> list[int]:
273
+ r"""
274
+ Map ImageNet English labels to class ids.
275
+
276
+ Args:
277
+ label (`str` or `list[str]`):
278
+ One label or a list of labels. Each string must match a synonym in `id2label`
279
+ after stripping whitespace. Synonyms are the comma-separated pieces of each value.
280
+
281
+ Returns:
282
+ `list[int]`: Class ids in the same order as `label`.
283
+ """
284
+ self._ensure_labels_loaded()
285
+ label2id = self.labels
286
+ if not label2id:
287
+ raise ValueError("No English labels loaded. Ensure `id2label` exists in model_index.json.")
288
+ if isinstance(label, str):
289
+ label = [label]
290
+ missing = [item for item in label if item not in label2id]
291
+ if missing:
292
+ preview = ", ".join(list(label2id.keys())[:8])
293
+ raise ValueError(f"Unknown English label(s): {missing}. Example valid labels: {preview}, ...")
294
+ return [label2id[item] for item in label]
295
+
296
+ def _normalize_class_labels(self, class_labels: int | str | list[int | str]) -> list[int]:
297
+ r"""
298
+ Turn a class-label argument into a list of integer ids.
299
+
300
+ Args:
301
+ class_labels (`int`, `str`, or `list`):
302
+ One id, one English label, or a list of either. A list must not mix types.
303
+
304
+ Returns:
305
+ `list[int]`: One id per requested image.
306
+ """
307
+ if isinstance(class_labels, int):
308
+ return [class_labels]
309
+ if isinstance(class_labels, str):
310
+ return self.get_label_ids(class_labels)
311
+ if len(class_labels) == 0:
312
+ raise ValueError("`class_labels` must contain at least one class id or label.")
313
+ if isinstance(class_labels[0], str):
314
+ if not all(isinstance(item, str) for item in class_labels):
315
+ raise TypeError("`class_labels` must be all strings or all integers.")
316
+ return self.get_label_ids(class_labels)
317
+ if not all(isinstance(item, int) for item in class_labels):
318
+ raise TypeError("`class_labels` must be all strings or all integers.")
319
+ return list(class_labels)
320
+
321
+ def prepare_extra_step_kwargs(
322
+ self,
323
+ generator: torch.Generator | list[torch.Generator] | None,
324
+ eta: float,
325
+ ) -> dict[str, Any]:
326
+ r"""
327
+ Extra arguments forwarded to `scheduler.step`, depending on what that method accepts.
328
+
329
+ Args:
330
+ generator (`torch.Generator` or `list[torch.Generator]`, *optional*):
331
+ Generator passed through when the scheduler step samples noise.
332
+ eta (`float`):
333
+ DDIM eta in `[0, 1]`. Ignored by [`WFlowScheduler`], whose `step` has no `eta` argument.
334
+
335
+ Returns:
336
+ `dict`: Keyword arguments for `scheduler.step`.
337
+ """
338
+ extra_step_kwargs: dict[str, Any] = {}
339
+ step_params = set(inspect.signature(self.scheduler.step).parameters.keys())
340
+ if "eta" in step_params:
341
+ extra_step_kwargs["eta"] = eta
342
+ if "generator" in step_params:
343
+ extra_step_kwargs["generator"] = generator
344
+ return extra_step_kwargs
345
+
346
+ def check_inputs(
347
+ self,
348
+ class_labels: int | str | list[int | str],
349
+ height: int,
350
+ width: int,
351
+ num_inference_steps: int,
352
+ guidance_scale: float,
353
+ noise_scale: float,
354
+ output_type: str,
355
+ callback_steps: int | None = None,
356
+ callback_on_step_end_tensor_inputs: list[str] | None = None,
357
+ ) -> None:
358
+ r"""
359
+ Reject arguments that the generator cannot run.
360
+
361
+ Args:
362
+ class_labels (`int`, `str`, or `list`):
363
+ Class ids or English labels. A list must be non-empty.
364
+ height (`int`):
365
+ Output height in pixels. Must be the pretrained resolution, 256.
366
+ width (`int`):
367
+ Output width in pixels. Must be the pretrained resolution, 256.
368
+ num_inference_steps (`int`):
369
+ Must be 1. W-Flow evaluates the network once.
370
+ guidance_scale (`float`):
371
+ Embedded guidance (`w + 1` in the paper). Must be finite and positive.
372
+ noise_scale (`float`):
373
+ Scale of the reference Gaussian, the official `temp`. Must be positive.
374
+ output_type (`str`):
375
+ One of `"pil"`, `"np"`, `"pt"`, `"latent"`.
376
+ callback_steps (`int`, *optional*):
377
+ Deprecated callback period. When set, must be a positive integer.
378
+ callback_on_step_end_tensor_inputs (`list[str]`, *optional*):
379
+ Tensor names the step callback may read. Each name must be in `_callback_tensor_inputs`.
380
+ """
381
+ if isinstance(class_labels, list) and len(class_labels) == 0:
382
+ raise ValueError("`class_labels` must contain at least one class id or label.")
383
+ native = int(self.transformer.config.sample_size) * int(self.vae_scale_factor)
384
+ if height != native or width != native:
385
+ raise ValueError(
386
+ f"`height` and `width` must be the pretrained resolution {native}. "
387
+ f"The patch embedding is fixed to a {self.transformer.config.sample_size} latent. Got {(height, width)}."
388
+ )
389
+ if num_inference_steps != 1:
390
+ raise ValueError(
391
+ "W-Flow generates in one forward pass. "
392
+ f"`num_inference_steps` must be 1, got {num_inference_steps}."
393
+ )
394
+ if not torch.isfinite(torch.tensor(float(guidance_scale))) or float(guidance_scale) <= 0:
395
+ raise ValueError(f"`guidance_scale` must be finite and positive, got {guidance_scale}.")
396
+ if noise_scale <= 0:
397
+ raise ValueError(f"`noise_scale` must be positive, got {noise_scale}.")
398
+ if output_type not in {"pil", "np", "pt", "latent"}:
399
+ raise ValueError(f"Unsupported `output_type` {output_type!r}. Choose from 'pil', 'np', 'pt', 'latent'.")
400
+ if callback_steps is not None and (not isinstance(callback_steps, int) or callback_steps < 1):
401
+ raise ValueError(f"`callback_steps` must be a positive integer, got {callback_steps}.")
402
+ if callback_on_step_end_tensor_inputs is not None:
403
+ unknown = [name for name in callback_on_step_end_tensor_inputs if name not in self._callback_tensor_inputs]
404
+ if unknown:
405
+ raise ValueError(
406
+ f"`callback_on_step_end_tensor_inputs` contains {unknown}, which are not in "
407
+ f"{self._callback_tensor_inputs}."
408
+ )
409
+
410
+ def prepare_latents(
411
+ self,
412
+ batch_size: int,
413
+ num_channels: int,
414
+ height: int,
415
+ width: int,
416
+ device: torch.device,
417
+ generator: torch.Generator | list[torch.Generator] | None,
418
+ latents: torch.Tensor | None,
419
+ noise_labels: torch.Tensor | None,
420
+ noise_scale: float,
421
+ ) -> tuple[torch.Tensor, torch.Tensor]:
422
+ r"""
423
+ Draw reference noise in the official generator order.
424
+
425
+ The official sampler draws `(batch, height, width, channels)` first, then integer noise
426
+ codes, from the same generator. This method follows that order so a seeded generator
427
+ matches `DitGen.forward`.
428
+
429
+ Args:
430
+ batch_size (`int`):
431
+ Number of images.
432
+ num_channels (`int`):
433
+ Latent channels. Released checkpoints use 4.
434
+ height (`int`):
435
+ Latent height. Released checkpoints use 32.
436
+ width (`int`):
437
+ Latent width. Released checkpoints use 32.
438
+ device (`torch.device`):
439
+ Device of the returned tensors.
440
+ generator (`torch.Generator` or `list[torch.Generator]`, *optional*):
441
+ RNG. A list must have one generator per image. Each generator is consumed in the
442
+ order Gaussian noise, then noise codes.
443
+ latents (`torch.Tensor`, *optional*):
444
+ Reference noise `(batch, channels, height, width)`. When set, it is not rescaled.
445
+ noise_labels (`torch.Tensor`, *optional*):
446
+ Integer codes `(batch, noise_coords)`. When omitted, they are drawn here.
447
+ noise_scale (`float`):
448
+ Multiplier on the Gaussian, the official `temp`. Ignored when `latents` is passed.
449
+
450
+ Returns:
451
+ `tuple[torch.Tensor, torch.Tensor]`:
452
+ Reference noise in BCHW float32, and noise codes `(batch, noise_coords)`.
453
+ """
454
+ noise_classes = int(self.transformer.config.noise_classes)
455
+ noise_coords = int(self.transformer.config.noise_coords)
456
+ if latents is None:
457
+ if isinstance(generator, list):
458
+ if len(generator) != batch_size:
459
+ raise ValueError(f"Got {len(generator)} generators for a batch of {batch_size}.")
460
+ pieces = [
461
+ torch.randn((1, height, width, num_channels), generator=one, device=device) for one in generator
462
+ ]
463
+ drawn = torch.cat(pieces, dim=0)
464
+ else:
465
+ drawn = torch.randn(
466
+ (batch_size, height, width, num_channels),
467
+ generator=generator,
468
+ device=device,
469
+ )
470
+ latents = drawn.permute(0, 3, 1, 2).contiguous() * float(noise_scale)
471
+ elif latents.shape != (batch_size, num_channels, height, width):
472
+ raise ValueError(
473
+ f"`latents` must have shape {(batch_size, num_channels, height, width)}, got {tuple(latents.shape)}."
474
+ )
475
+ else:
476
+ latents = latents.to(device=device)
477
+
478
+ if noise_labels is None:
479
+ if isinstance(generator, list) and latents is not None:
480
+ # When latents were supplied, generators have not been consumed yet only if the
481
+ # caller passed both. Drawing labels still uses those generators.
482
+ codes = [
483
+ torch.randint(0, noise_classes, (1, noise_coords), generator=one, device=device)
484
+ for one in generator
485
+ ]
486
+ noise_labels = torch.cat(codes, dim=0)
487
+ else:
488
+ noise_labels = torch.randint(
489
+ 0,
490
+ max(1, noise_classes),
491
+ (batch_size, max(1, noise_coords)),
492
+ generator=None if isinstance(generator, list) else generator,
493
+ device=device,
494
+ )
495
+ noise_labels = noise_labels.to(device=device, dtype=torch.long)
496
+ if noise_labels.shape != (batch_size, noise_coords):
497
+ raise ValueError(
498
+ f"`noise_labels` must have shape {(batch_size, noise_coords)}, got {tuple(noise_labels.shape)}."
499
+ )
500
+ return latents.float(), noise_labels
501
+
502
+ def _prepare_scheduler(self, num_inference_steps: int, device: torch.device) -> torch.Tensor:
503
+ r"""
504
+ Install the one-step schedule and return its timesteps.
505
+
506
+ Args:
507
+ num_inference_steps (`int`):
508
+ Must be 1.
509
+ device (`torch.device`):
510
+ Device of the timestep tensor.
511
+
512
+ Returns:
513
+ `torch.Tensor`: The single timestep.
514
+ """
515
+ self.scheduler.set_timesteps(num_inference_steps, device=device)
516
+ return self.scheduler.timesteps
517
+
518
+ def _decode_latents(self, latents: torch.Tensor) -> torch.Tensor:
519
+ r"""
520
+ Decode scaled SD-VAE latents to pixels in `[-1, 1]`.
521
+
522
+ Args:
523
+ latents (`torch.Tensor`):
524
+ Clean latents `(batch, 4, 32, 32)` in the training scale (`* 0.18215`).
525
+
526
+ Returns:
527
+ `torch.Tensor`: Images `(batch, 3, height, width)` in `[-1, 1]`.
528
+ """
529
+ scaling = float(getattr(self.vae.config, "scaling_factor", 0.18215))
530
+ needs_upcast = bool(getattr(self.vae.config, "force_upcast", False)) and self.vae.dtype != torch.float32
531
+ original_dtype = self.vae.dtype
532
+ if needs_upcast:
533
+ self.vae.to(dtype=torch.float32)
534
+ decoded = self.vae.decode((latents / scaling).to(dtype=self.vae.dtype), return_dict=False)[0]
535
+ if needs_upcast:
536
+ self.vae.to(dtype=original_dtype)
537
+ return decoded
538
+
539
+ def _images_from_pixels(self, pixels: torch.Tensor, output_type: str) -> list[Image.Image] | torch.Tensor | list:
540
+ r"""
541
+ Convert decoded pixels to the requested output type.
542
+
543
+ Args:
544
+ pixels (`torch.Tensor`):
545
+ Images `(batch, 3, height, width)` in `[-1, 1]`.
546
+ output_type (`str`):
547
+ `"pil"`, `"np"`, `"pt"` (float RGB in `[0, 1]`), or `"latent"`.
548
+
549
+ Returns:
550
+ Images in the requested type.
551
+ """
552
+ images = ((pixels.float() + 1) / 2).clamp(0, 1)
553
+ if output_type == "pt":
554
+ return images
555
+ images = (images * 255).round().to(torch.uint8)
556
+ arrays = images.permute(0, 2, 3, 1).cpu().numpy()
557
+ if output_type == "np":
558
+ return arrays
559
+ return [Image.fromarray(image) for image in arrays]
560
+
561
+ @torch.no_grad()
562
+ @replace_example_docstring(EXAMPLE_DOC_STRING)
563
+ def __call__(
564
+ self,
565
+ class_labels: int | str | list[int | str],
566
+ height: int | None = None,
567
+ width: int | None = None,
568
+ num_inference_steps: int | None = None,
569
+ guidance_scale: float | None = None,
570
+ noise_scale: float = 1.0,
571
+ eta: float = 0.0,
572
+ generator: torch.Generator | list[torch.Generator] | None = None,
573
+ latents: torch.Tensor | None = None,
574
+ noise_labels: torch.Tensor | None = None,
575
+ output_type: str = "pil",
576
+ return_dict: bool = True,
577
+ callback_on_step_end: Callable[[int, int, dict], dict] | PipelineCallback | MultiPipelineCallbacks | None = None,
578
+ callback_on_step_end_tensor_inputs: list[str] | None = None,
579
+ **kwargs,
580
+ ) -> ImagePipelineOutput | tuple:
581
+ r"""
582
+ Generate images from ImageNet class labels.
583
+
584
+ Args:
585
+ class_labels (`int`, `str`, or `list`):
586
+ One ImageNet class id, one English label, or a list of either. English labels are
587
+ resolved with [`get_label_ids`]. The list length is the batch size.
588
+ height (`int`, *optional*):
589
+ Image height in pixels. Defaults to 256 (`sample_size * vae_scale_factor`). Other
590
+ sizes are rejected because the patch embedding is fixed.
591
+ width (`int`, *optional*):
592
+ Image width in pixels. Defaults to 256.
593
+ num_inference_steps (`int`, *optional*):
594
+ Must be 1. Defaults to `transformer.config.default_num_inference_steps`.
595
+ guidance_scale (`float`, *optional*):
596
+ Official CFG value, equal to `w + 1` in the paper. Defaults to
597
+ `transformer.config.guidance_scale` (1.19 / 1.14 / 1.09 / 1.5 by variant). This
598
+ scale is embedded; the pipeline does not run an unconditional branch.
599
+ noise_scale (`float`, defaults to 1.0):
600
+ Multiplier on the reference Gaussian. The official sampler calls this `temp`.
601
+ Ignored when `latents` is passed.
602
+ eta (`float`, defaults to 0.0):
603
+ DDIM eta. Ignored by [`WFlowScheduler`].
604
+ generator (`torch.Generator` or `list[torch.Generator]`, *optional*):
605
+ RNG for the reference noise and the discrete noise codes. One generator is consumed
606
+ in that order, matching the official sampler.
607
+ latents (`torch.Tensor`, *optional*):
608
+ Reference noise `(batch, 4, 32, 32)`. Not multiplied by `noise_scale`.
609
+ noise_labels (`torch.Tensor`, *optional*):
610
+ Discrete noise codes `(batch, noise_coords)`. Drawn from `generator` when omitted.
611
+ output_type (`str`, defaults to `"pil"`):
612
+ `"pil"`, `"np"`, `"pt"` (float RGB in `[0, 1]`), or `"latent"` (scaled SD-VAE latent).
613
+ return_dict (`bool`, defaults to `True`):
614
+ Return [`ImagePipelineOutput`] when `True`, otherwise a one-tuple of images.
615
+ callback_on_step_end (`Callable` or `PipelineCallback`, *optional*):
616
+ Called as `callback_on_step_end(pipeline, step, timestep, callback_kwargs)` after the
617
+ scheduler step. Return a dict to replace tensors listed in
618
+ `callback_on_step_end_tensor_inputs`.
619
+ callback_on_step_end_tensor_inputs (`list[str]`, *optional*):
620
+ Tensor names passed to the step callback. Defaults to `["latents"]`.
621
+
622
+ Examples:
623
+
624
+ Returns:
625
+ [`ImagePipelineOutput`] or `tuple`:
626
+ When `return_dict` is `True`, [`ImagePipelineOutput`] with the images. Otherwise a tuple
627
+ whose first element is the images.
628
+ """
629
+ callback = kwargs.pop("callback", None)
630
+ callback_steps = kwargs.pop("callback_steps", None)
631
+ if kwargs:
632
+ raise TypeError(f"Unexpected arguments: {sorted(kwargs)}.")
633
+ if callback_on_step_end_tensor_inputs is None:
634
+ callback_on_step_end_tensor_inputs = ["latents"]
635
+
636
+ if callback is not None:
637
+ deprecate(
638
+ "callback",
639
+ "1.0.0",
640
+ "Passing `callback` as an input argument to `__call__` is deprecated, consider using `callback_on_step_end`",
641
+ )
642
+ if callback_steps is not None:
643
+ deprecate(
644
+ "callback_steps",
645
+ "1.0.0",
646
+ "Passing `callback_steps` as an input argument to `__call__` is deprecated, consider using `callback_on_step_end`",
647
+ )
648
+ if isinstance(callback_on_step_end, (PipelineCallback, MultiPipelineCallbacks)):
649
+ callback_on_step_end_tensor_inputs = callback_on_step_end.tensor_inputs
650
+
651
+ image_size = int(self.transformer.config.sample_size) * int(self.vae_scale_factor)
652
+ height = image_size if height is None else int(height)
653
+ width = image_size if width is None else int(width)
654
+ if num_inference_steps is None:
655
+ num_inference_steps = int(self._sampling_default("default_num_inference_steps", 1))
656
+ if guidance_scale is None:
657
+ guidance_scale = float(self._sampling_default("guidance_scale", 1.0))
658
+
659
+ # 1. Check inputs.
660
+ self.check_inputs(
661
+ class_labels,
662
+ height,
663
+ width,
664
+ num_inference_steps,
665
+ guidance_scale,
666
+ noise_scale,
667
+ output_type,
668
+ callback_steps,
669
+ callback_on_step_end_tensor_inputs,
670
+ )
671
+
672
+ self._guidance_scale = float(guidance_scale)
673
+ self._interrupt = False
674
+
675
+ # 2. Define call parameters.
676
+ class_label_ids = self._normalize_class_labels(class_labels)
677
+ batch_size = len(class_label_ids)
678
+ device = self._execution_device
679
+ num_classes = int(self.transformer.config.num_classes)
680
+ if any(class_id < 0 or class_id >= num_classes for class_id in class_label_ids):
681
+ raise ValueError(f"Class ids must lie in [0, {num_classes}), got {class_label_ids}.")
682
+
683
+ # 3. Encode input condition (class ids; guidance is embedded inside the transformer).
684
+ class_labels_t = torch.tensor(class_label_ids, device=device, dtype=torch.long)
685
+
686
+ # 4. Prepare timesteps.
687
+ scheduled_timesteps = self._prepare_scheduler(num_inference_steps, device)
688
+
689
+ # 5. Prepare latent variables. Noise codes are drawn here so one generator matches DitGen.
690
+ latent_height = height // int(self.vae_scale_factor)
691
+ latent_width = width // int(self.vae_scale_factor)
692
+ latents, noise_labels = self.prepare_latents(
693
+ batch_size,
694
+ int(self.transformer.config.in_channels),
695
+ latent_height,
696
+ latent_width,
697
+ device,
698
+ generator,
699
+ latents,
700
+ noise_labels,
701
+ noise_scale,
702
+ )
703
+
704
+ # 6. Prepare extra step kwargs.
705
+ extra_step_kwargs = self.prepare_extra_step_kwargs(generator, eta)
706
+ num_warmup_steps = len(scheduled_timesteps) - num_inference_steps * self.scheduler.order
707
+ self._num_timesteps = len(scheduled_timesteps)
708
+
709
+ # 7. Denoising loop.
710
+ with self.progress_bar(total=num_inference_steps) as progress_bar:
711
+ for i, timestep in enumerate(scheduled_timesteps):
712
+ if self.interrupt:
713
+ continue
714
+
715
+ latent_model_input = self.scheduler.scale_model_input(latents, timestep)
716
+ model_output = self.transformer(
717
+ latent_model_input,
718
+ class_labels=class_labels_t,
719
+ guidance_scale=self._guidance_scale,
720
+ noise_labels=noise_labels,
721
+ return_dict=False,
722
+ )[0]
723
+ latents = self.scheduler.step(
724
+ model_output,
725
+ timestep,
726
+ latents,
727
+ **extra_step_kwargs,
728
+ return_dict=False,
729
+ )[0]
730
+
731
+ if callback_on_step_end is not None:
732
+ callback_kwargs = {key: locals()[key] for key in callback_on_step_end_tensor_inputs}
733
+ callback_outputs = callback_on_step_end(self, i, timestep, callback_kwargs)
734
+ latents = callback_outputs.pop("latents", latents)
735
+
736
+ if i == len(scheduled_timesteps) - 1 or (
737
+ (i + 1) > num_warmup_steps and (i + 1) % self.scheduler.order == 0
738
+ ):
739
+ progress_bar.update()
740
+ if callback is not None and i % callback_steps == 0:
741
+ callback(i, timestep, latents)
742
+
743
+ if XLA_AVAILABLE:
744
+ xm.mark_step()
745
+
746
+ if output_type == "latent":
747
+ images = latents
748
+ else:
749
+ images = self._images_from_pixels(self._decode_latents(latents), output_type)
750
+ self.maybe_free_model_hooks()
751
+
752
+ if not return_dict:
753
+ return (images,)
754
+ return ImagePipelineOutput(images=images)
W-Flow-L/scheduler/scheduler_config.json ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ {
2
+ "_class_name": "WFlowScheduler",
3
+ "_diffusers_version": "0.39.0",
4
+ "num_train_timesteps": 1000,
5
+ "prediction_type": "sample"
6
+ }
W-Flow-L/scheduler/scheduling_wflow.py ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2026 The HuggingFace Team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from dataclasses import dataclass
16
+
17
+ import torch
18
+ from diffusers.configuration_utils import ConfigMixin, register_to_config
19
+ from diffusers.schedulers.scheduling_utils import SchedulerMixin
20
+ from diffusers.utils import BaseOutput
21
+
22
+
23
+ @dataclass
24
+ class WFlowSchedulerOutput(BaseOutput):
25
+ r"""
26
+ Output of [`WFlowScheduler.step`].
27
+
28
+ Args:
29
+ prev_sample (`torch.Tensor`):
30
+ The model prediction. W-Flow returns the clean latent in one evaluation.
31
+ """
32
+
33
+ prev_sample: torch.Tensor
34
+
35
+
36
+ class WFlowScheduler(SchedulerMixin, ConfigMixin):
37
+ r"""
38
+ One-step scheduler for W-Flow.
39
+
40
+ The transformer predicts the clean latent directly. `set_timesteps` accepts a single evaluation,
41
+ and `step` returns that prediction. `scale_model_input` leaves the reference noise unchanged.
42
+ A Karras noise schedule does not apply: the network has no diffusion timestep.
43
+
44
+ Args:
45
+ num_train_timesteps (`int`, defaults to 1000):
46
+ Stored for config compatibility. W-Flow does not index it.
47
+ prediction_type (`str`, defaults to `"sample"`):
48
+ The model output is the clean sample.
49
+ """
50
+
51
+ order = 1
52
+ _compatibles: list[str] = []
53
+
54
+ @register_to_config
55
+ def __init__(
56
+ self,
57
+ num_train_timesteps: int = 1000,
58
+ prediction_type: str = "sample",
59
+ ):
60
+ if num_train_timesteps < 1:
61
+ raise ValueError(f"num_train_timesteps must be >= 1, got {num_train_timesteps}.")
62
+ if prediction_type != "sample":
63
+ raise ValueError(f"WFlowScheduler prediction_type must be 'sample', got {prediction_type!r}.")
64
+ self.timesteps: torch.Tensor | None = None
65
+ self.num_inference_steps: int | None = None
66
+ self._step_index: int | None = None
67
+
68
+ @property
69
+ def init_noise_sigma(self) -> float:
70
+ r"""
71
+ Scale of the standard normal used to start sampling.
72
+
73
+ Returns:
74
+ `float`: `1.0`. The pipeline multiplies this by `noise_scale`.
75
+ """
76
+ return 1.0
77
+
78
+ def scale_model_input(self, sample: torch.Tensor, timestep: float | torch.Tensor) -> torch.Tensor:
79
+ r"""
80
+ Return the sample unchanged.
81
+
82
+ Args:
83
+ sample (`torch.Tensor`):
84
+ Reference noise `(batch, channels, height, width)`.
85
+ timestep (`float` or `torch.Tensor`):
86
+ Unused. W-Flow has no diffusion timestep.
87
+
88
+ Returns:
89
+ `torch.Tensor`: `sample`.
90
+ """
91
+ del timestep
92
+ return sample
93
+
94
+ def set_timesteps(
95
+ self,
96
+ num_inference_steps: int,
97
+ device: str | torch.device | None = None,
98
+ ) -> None:
99
+ r"""
100
+ Install the single evaluation step.
101
+
102
+ Args:
103
+ num_inference_steps (`int`):
104
+ Must be 1. W-Flow generates the latent in one forward pass.
105
+ device (`str` or `torch.device`, *optional*):
106
+ Device of `self.timesteps`.
107
+ """
108
+ if num_inference_steps != 1:
109
+ raise ValueError(
110
+ "W-Flow generates in one forward pass. "
111
+ f"num_inference_steps must be 1, got {num_inference_steps}."
112
+ )
113
+ self.num_inference_steps = 1
114
+ self.timesteps = torch.tensor([0.0], device=device, dtype=torch.float32)
115
+ self._step_index = 0
116
+
117
+ def step(
118
+ self,
119
+ model_output: torch.Tensor,
120
+ timestep: float | torch.Tensor,
121
+ sample: torch.Tensor,
122
+ generator: torch.Generator | list[torch.Generator] | None = None,
123
+ return_dict: bool = True,
124
+ ) -> WFlowSchedulerOutput | tuple[torch.Tensor]:
125
+ r"""
126
+ Replace the reference noise with the predicted clean latent.
127
+
128
+ Args:
129
+ model_output (`torch.Tensor`):
130
+ Clean-latent prediction `(batch, channels, height, width)`.
131
+ timestep (`float` or `torch.Tensor`):
132
+ The single scheduled timestep. Accepted for the Diffusers step signature.
133
+ sample (`torch.Tensor`):
134
+ Current reference noise. Same shape as `model_output`.
135
+ generator (`torch.Generator` or `list[torch.Generator]`, *optional*):
136
+ Accepted so pipelines can pass it through. W-Flow does not draw noise in `step`.
137
+ return_dict (`bool`, defaults to `True`):
138
+ Return [`WFlowSchedulerOutput`] when `True`, otherwise a one-tuple.
139
+
140
+ Returns:
141
+ [`WFlowSchedulerOutput`] or `tuple`:
142
+ `prev_sample` is `model_output`.
143
+ """
144
+ del timestep, sample, generator
145
+ if self.timesteps is None:
146
+ raise ValueError("Call set_timesteps before step.")
147
+ if self._step_index is None or self._step_index > 0:
148
+ raise ValueError("WFlowScheduler has already consumed its single step. Call set_timesteps again.")
149
+ self._step_index = 1
150
+ if not return_dict:
151
+ return (model_output,)
152
+ return WFlowSchedulerOutput(prev_sample=model_output)
W-Flow-L/transformer/config.json ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_class_name": "WFlowTransformer2DModel",
3
+ "_diffusers_version": "0.39.0",
4
+ "attn_fp32": false,
5
+ "cond_dim": 1024,
6
+ "default_num_inference_steps": 1,
7
+ "depth": 24,
8
+ "guidance_scale": 1.14,
9
+ "hidden_size": 1024,
10
+ "in_channels": 4,
11
+ "mlp_ratio": 4.0,
12
+ "model_type": "W-Flow-L",
13
+ "n_cls_tokens": 16,
14
+ "noise_classes": 64,
15
+ "noise_coords": 32,
16
+ "num_attention_heads": 16,
17
+ "num_classes": 1000,
18
+ "out_channels": 4,
19
+ "patch_size": 2,
20
+ "sample_size": 32,
21
+ "use_bf16": true,
22
+ "use_qknorm": true,
23
+ "use_rmsnorm": true,
24
+ "use_rope": true,
25
+ "use_swiglu": true
26
+ }
W-Flow-L/transformer/diffusion_pytorch_model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:06f82e2147e82fcc502d5b72861836bc0cb150abd6d0f5f1aa03e1cc46596874
3
+ size 1851684296
W-Flow-L/transformer/transformer_wflow.py ADDED
@@ -0,0 +1,720 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2026 The HuggingFace Team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import math
16
+ from dataclasses import dataclass
17
+
18
+ import numpy as np
19
+ import torch
20
+ import torch.nn as nn
21
+ from diffusers.configuration_utils import ConfigMixin, register_to_config
22
+ from diffusers.models.modeling_utils import ModelMixin
23
+ from diffusers.utils import BaseOutput
24
+
25
+
26
+ @dataclass
27
+ class WFlowTransformer2DModelOutput(BaseOutput):
28
+ r"""
29
+ Output of [`WFlowTransformer2DModel`].
30
+
31
+ Args:
32
+ sample (`torch.Tensor`):
33
+ Predicted SD-VAE latent of shape `(batch, channels, height, width)`. Values are in the
34
+ scaled latent space used at training time (`encoder_mean * 0.18215`).
35
+ """
36
+
37
+ sample: torch.Tensor
38
+
39
+
40
+ def _init_linear(linear: nn.Linear, weight_init: str = "xavier_uniform", bias_init: str = "zeros") -> None:
41
+ r"""
42
+ Initialize a linear layer the way the official generator does.
43
+
44
+ Args:
45
+ linear (`torch.nn.Linear`):
46
+ Layer to initialize in place.
47
+ weight_init (`str`, defaults to `"xavier_uniform"`):
48
+ `"xavier_uniform"`, `"zeros"`, or `"normal"` (std 0.02).
49
+ bias_init (`str`, defaults to `"zeros"`):
50
+ Bias fill. Only `"zeros"` is used by the released architecture.
51
+ """
52
+ if weight_init == "xavier_uniform":
53
+ nn.init.xavier_uniform_(linear.weight)
54
+ elif weight_init == "zeros":
55
+ nn.init.zeros_(linear.weight)
56
+ elif weight_init == "normal":
57
+ nn.init.normal_(linear.weight, std=0.02)
58
+ else:
59
+ raise ValueError(f"weight_init must be xavier_uniform, zeros, or normal, got {weight_init!r}.")
60
+ if linear.bias is not None:
61
+ if bias_init != "zeros":
62
+ raise ValueError(f"bias_init must be 'zeros', got {bias_init!r}.")
63
+ nn.init.zeros_(linear.bias)
64
+
65
+
66
+ class _TorchLinear(nn.Module):
67
+ r"""
68
+ Linear wrapper whose parameter names match the official `TorchLinear` (`*.linear.weight`).
69
+ """
70
+
71
+ def __init__(
72
+ self,
73
+ in_features: int,
74
+ out_features: int,
75
+ bias: bool = True,
76
+ weight_init: str = "xavier_uniform",
77
+ bias_init: str = "zeros",
78
+ ):
79
+ super().__init__()
80
+ self.linear = nn.Linear(in_features, out_features, bias=bias)
81
+ _init_linear(self.linear, weight_init=weight_init, bias_init=bias_init)
82
+
83
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
84
+ r"""
85
+ Apply the wrapped linear layer.
86
+
87
+ Args:
88
+ x (`torch.Tensor`):
89
+ Input of shape `(..., in_features)`.
90
+
91
+ Returns:
92
+ `torch.Tensor`: Output of shape `(..., out_features)`.
93
+ """
94
+ return self.linear(x)
95
+
96
+
97
+ class _RMSNorm(nn.Module):
98
+ def __init__(self, dim: int, eps: float = 1e-6):
99
+ super().__init__()
100
+ self.eps = float(eps)
101
+ self.weight = nn.Parameter(torch.ones(int(dim)))
102
+
103
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
104
+ r"""
105
+ Root-mean-square normalize the last dimension.
106
+
107
+ Args:
108
+ x (`torch.Tensor`):
109
+ Input of shape `(..., dim)`.
110
+
111
+ Returns:
112
+ `torch.Tensor`: Normalized tensor, same shape and dtype as `x`.
113
+ """
114
+ input_dtype = x.dtype
115
+ variance = x.float().pow(2).mean(dim=-1, keepdim=True)
116
+ normalized = x * torch.rsqrt(variance + self.eps)
117
+ return (normalized * self.weight).to(dtype=input_dtype)
118
+
119
+
120
+ def _modulate(x: torch.Tensor, shift: torch.Tensor, scale: torch.Tensor) -> torch.Tensor:
121
+ r"""
122
+ Apply an adaLN-Zero shift and scale.
123
+
124
+ Args:
125
+ x (`torch.Tensor`):
126
+ Token tensor `(batch, tokens, hidden)`.
127
+ shift (`torch.Tensor`):
128
+ Per-sample shift `(batch, hidden)`.
129
+ scale (`torch.Tensor`):
130
+ Per-sample scale `(batch, hidden)`.
131
+
132
+ Returns:
133
+ `torch.Tensor`: `x * (1 + scale) + shift`, broadcast over tokens.
134
+ """
135
+ return x * (1.0 + scale.unsqueeze(1)) + shift.unsqueeze(1)
136
+
137
+
138
+ def _sincos_1d(embed_dim: int, pos: np.ndarray) -> np.ndarray:
139
+ r"""
140
+ Sine-cosine embedding of 1-D positions.
141
+
142
+ Args:
143
+ embed_dim (`int`):
144
+ Even embedding width.
145
+ pos (`numpy.ndarray`):
146
+ Positions, flattened inside the function.
147
+
148
+ Returns:
149
+ `numpy.ndarray`: Array of shape `(positions, embed_dim)`.
150
+ """
151
+ if embed_dim % 2 != 0:
152
+ raise ValueError(f"embed_dim must be even, got {embed_dim}.")
153
+ omega = np.arange(embed_dim // 2, dtype=np.float64)
154
+ omega = 1.0 / 10000 ** (omega / (embed_dim / 2.0))
155
+ out = np.einsum("m,d->md", pos.reshape(-1), omega)
156
+ return np.concatenate([np.sin(out), np.cos(out)], axis=1)
157
+
158
+
159
+ def _sincos_2d(embed_dim: int, grid_size: int) -> np.ndarray:
160
+ r"""
161
+ Sine-cosine embedding of a square grid, matching the official generator.
162
+
163
+ Args:
164
+ embed_dim (`int`):
165
+ Full embedding width. Half is used for each axis.
166
+ grid_size (`int`):
167
+ Tokens along one side of the latent grid.
168
+
169
+ Returns:
170
+ `numpy.ndarray`: Array of shape `(grid_size * grid_size, embed_dim)`.
171
+ """
172
+ grid_h = np.arange(grid_size, dtype=np.float32)
173
+ grid_w = np.arange(grid_size, dtype=np.float32)
174
+ grid = np.stack(np.meshgrid(grid_w, grid_h), axis=0).reshape(2, 1, grid_size, grid_size)
175
+ half = embed_dim // 2
176
+ return np.concatenate([_sincos_1d(half, grid[0]), _sincos_1d(half, grid[1])], axis=1)
177
+
178
+
179
+ def _swiglu_hidden(hidden_size: int, mlp_ratio: float) -> int:
180
+ r"""
181
+ SwiGLU intermediate width used by the official blocks.
182
+
183
+ Args:
184
+ hidden_size (`int`):
185
+ Transformer width.
186
+ mlp_ratio (`float`):
187
+ Expansion ratio before the 2/3 SwiGLU reduction.
188
+
189
+ Returns:
190
+ `int`: Intermediate width, rounded up to a multiple of 32.
191
+ """
192
+ mlp_hidden = int(hidden_size * float(mlp_ratio))
193
+ hidden = int((2.0 / 3.0) * mlp_hidden)
194
+ return ((hidden + 31) // 32) * 32
195
+
196
+
197
+ class _StandardMLP(nn.Module):
198
+ def __init__(self, hidden_size: int, mlp_hidden_dim: int):
199
+ super().__init__()
200
+ self.fc1 = _TorchLinear(hidden_size, mlp_hidden_dim, bias=True)
201
+ self.fc2 = _TorchLinear(mlp_hidden_dim, hidden_size, bias=True)
202
+
203
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
204
+ r"""
205
+ GELU MLP.
206
+
207
+ Args:
208
+ x (`torch.Tensor`):
209
+ Input `(..., hidden_size)`.
210
+
211
+ Returns:
212
+ `torch.Tensor`: Output `(..., hidden_size)`.
213
+ """
214
+ return self.fc2(nn.functional.gelu(self.fc1(x), approximate="none"))
215
+
216
+
217
+ class _SwiGLUFFN(nn.Module):
218
+ def __init__(self, hidden_size: int, intermediate_size: int):
219
+ super().__init__()
220
+ self.w1 = _TorchLinear(hidden_size, intermediate_size, bias=True)
221
+ self.w3 = _TorchLinear(hidden_size, intermediate_size, bias=True)
222
+ self.w2 = _TorchLinear(intermediate_size, hidden_size, bias=True)
223
+
224
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
225
+ r"""
226
+ SwiGLU feed-forward.
227
+
228
+ Args:
229
+ x (`torch.Tensor`):
230
+ Input `(..., hidden_size)`.
231
+
232
+ Returns:
233
+ `torch.Tensor`: Output `(..., hidden_size)`.
234
+ """
235
+ return self.w2(nn.functional.silu(self.w1(x)) * self.w3(x))
236
+
237
+
238
+ class _Attention(nn.Module):
239
+ def __init__(
240
+ self,
241
+ dim: int,
242
+ num_heads: int,
243
+ qk_norm: bool,
244
+ use_rmsnorm: bool,
245
+ use_rope: bool,
246
+ attn_fp32: bool,
247
+ max_seq_len: int,
248
+ ):
249
+ super().__init__()
250
+ self.dim = int(dim)
251
+ self.num_heads = int(num_heads)
252
+ self.use_rope = bool(use_rope)
253
+ self.attn_fp32 = bool(attn_fp32)
254
+ self.qkv = _TorchLinear(self.dim, self.dim * 3, bias=True)
255
+ head_dim = self.dim // self.num_heads
256
+ if qk_norm:
257
+ if use_rmsnorm:
258
+ self.q_norm = _RMSNorm(head_dim)
259
+ self.k_norm = _RMSNorm(head_dim)
260
+ else:
261
+ self.q_norm = nn.LayerNorm(head_dim, eps=1e-6, elementwise_affine=True)
262
+ self.k_norm = nn.LayerNorm(head_dim, eps=1e-6, elementwise_affine=True)
263
+ else:
264
+ self.q_norm = None
265
+ self.k_norm = None
266
+ self.proj = _TorchLinear(self.dim, self.dim, bias=True)
267
+ if use_rope:
268
+ half_dim = head_dim // 2
269
+ freqs = 1.0 / (10000 ** (torch.arange(0, half_dim, dtype=torch.float32) / half_dim))
270
+ positions = torch.arange(max_seq_len, dtype=torch.float32)
271
+ emb = torch.cat([torch.outer(positions, freqs)] * 2, dim=-1)
272
+ self.register_buffer("_rope_cos", torch.cos(emb)[None, :, None, :], persistent=False)
273
+ self.register_buffer("_rope_sin", torch.sin(emb)[None, :, None, :], persistent=False)
274
+
275
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
276
+ r"""
277
+ Multi-head self-attention. Dropout is off, matching inference (`deterministic=True`).
278
+
279
+ Args:
280
+ x (`torch.Tensor`):
281
+ Tokens `(batch, tokens, hidden)`.
282
+
283
+ Returns:
284
+ `torch.Tensor`: Attention output `(batch, tokens, hidden)`.
285
+ """
286
+ batch, tokens, _channels = x.shape
287
+ head_dim = self.dim // self.num_heads
288
+ qkv = self.qkv(x).reshape(batch, tokens, 3, self.num_heads, head_dim)
289
+ query, key, value = qkv[:, :, 0], qkv[:, :, 1], qkv[:, :, 2]
290
+ if self.q_norm is not None:
291
+ query = self.q_norm(query)
292
+ key = self.k_norm(key)
293
+ if self.use_rope:
294
+ rope_dtype = torch.float32 if self.attn_fp32 else query.dtype
295
+ cos = self._rope_cos[:, :tokens].to(dtype=rope_dtype)
296
+ sin = self._rope_sin[:, :tokens].to(dtype=rope_dtype)
297
+ half_dim = head_dim // 2
298
+
299
+ def _rotate(tensor: torch.Tensor) -> torch.Tensor:
300
+ first, second = tensor[..., :half_dim], tensor[..., half_dim:]
301
+ return torch.cat([-second, first], dim=-1)
302
+
303
+ query = (query * cos) + (_rotate(query) * sin)
304
+ key = (key * cos) + (_rotate(key) * sin)
305
+ if self.attn_fp32:
306
+ query = query.float()
307
+ key = key.float()
308
+ value = value.float()
309
+ query = query.permute(0, 2, 1, 3)
310
+ key = key.permute(0, 2, 1, 3)
311
+ value = value.permute(0, 2, 1, 3)
312
+ if self.attn_fp32:
313
+ with torch.amp.autocast(device_type=query.device.type, enabled=False):
314
+ out = nn.functional.scaled_dot_product_attention(query, key, value, dropout_p=0.0)
315
+ else:
316
+ out = nn.functional.scaled_dot_product_attention(query, key, value, dropout_p=0.0)
317
+ out = out.permute(0, 2, 1, 3).reshape(batch, tokens, self.dim)
318
+ return self.proj(out)
319
+
320
+
321
+ class _DiTBlock(nn.Module):
322
+ def __init__(
323
+ self,
324
+ hidden_size: int,
325
+ num_heads: int,
326
+ mlp_ratio: float,
327
+ use_qknorm: bool,
328
+ use_swiglu: bool,
329
+ use_rmsnorm: bool,
330
+ use_rope: bool,
331
+ attn_fp32: bool,
332
+ max_seq_len: int,
333
+ ):
334
+ super().__init__()
335
+ self.hidden_size = int(hidden_size)
336
+ if use_rmsnorm:
337
+ self.norm1 = _RMSNorm(self.hidden_size)
338
+ self.norm2 = _RMSNorm(self.hidden_size)
339
+ else:
340
+ self.norm1 = nn.LayerNorm(self.hidden_size, eps=1e-6, elementwise_affine=False)
341
+ self.norm2 = nn.LayerNorm(self.hidden_size, eps=1e-6, elementwise_affine=False)
342
+ self.attn = _Attention(
343
+ dim=self.hidden_size,
344
+ num_heads=num_heads,
345
+ qk_norm=use_qknorm,
346
+ use_rmsnorm=use_rmsnorm,
347
+ use_rope=use_rope,
348
+ attn_fp32=attn_fp32,
349
+ max_seq_len=max_seq_len,
350
+ )
351
+ if use_swiglu:
352
+ self.mlp = _SwiGLUFFN(self.hidden_size, _swiglu_hidden(self.hidden_size, mlp_ratio))
353
+ else:
354
+ self.mlp = _StandardMLP(self.hidden_size, int(self.hidden_size * float(mlp_ratio)))
355
+ self.adaLN_mod = nn.Sequential(
356
+ nn.SiLU(),
357
+ _TorchLinear(self.hidden_size, 6 * self.hidden_size, bias=True, weight_init="zeros"),
358
+ )
359
+
360
+ def forward(self, x: torch.Tensor, condition: torch.Tensor) -> torch.Tensor:
361
+ r"""
362
+ One Lightning-DiT block conditioned by adaLN-Zero.
363
+
364
+ Args:
365
+ x (`torch.Tensor`):
366
+ Tokens `(batch, tokens, hidden)`.
367
+ condition (`torch.Tensor`):
368
+ Per-sample condition `(batch, hidden)`.
369
+
370
+ Returns:
371
+ `torch.Tensor`: Updated tokens, same shape as `x`.
372
+ """
373
+ chunks = self.adaLN_mod(condition.float()).to(dtype=x.dtype)
374
+ shift_msa, scale_msa, gate_msa, shift_mlp, scale_mlp, gate_mlp = torch.chunk(chunks, 6, dim=1)
375
+ attended = self.attn(_modulate(self.norm1(x), shift_msa, scale_msa))
376
+ x = x + gate_msa.unsqueeze(1) * attended
377
+ x = x + gate_mlp.unsqueeze(1) * self.mlp(_modulate(self.norm2(x), shift_mlp, scale_mlp))
378
+ return x
379
+
380
+
381
+ class _FinalLayer(nn.Module):
382
+ def __init__(self, hidden_size: int, patch_size: int, out_channels: int, use_rmsnorm: bool):
383
+ super().__init__()
384
+ self.norm_final = _RMSNorm(hidden_size) if use_rmsnorm else nn.LayerNorm(hidden_size, eps=1e-6, elementwise_affine=False)
385
+ self.adaLN_mod = nn.Sequential(
386
+ nn.SiLU(),
387
+ _TorchLinear(hidden_size, 2 * hidden_size, bias=True, weight_init="zeros"),
388
+ )
389
+ self.linear = _TorchLinear(hidden_size, patch_size * patch_size * out_channels, bias=True, weight_init="zeros")
390
+
391
+ def forward(self, x: torch.Tensor, condition: torch.Tensor) -> torch.Tensor:
392
+ r"""
393
+ Project tokens to patch pixels.
394
+
395
+ Args:
396
+ x (`torch.Tensor`):
397
+ Tokens `(batch, tokens, hidden)`.
398
+ condition (`torch.Tensor`):
399
+ Per-sample condition `(batch, hidden)`.
400
+
401
+ Returns:
402
+ `torch.Tensor`: Patch pixels `(batch, tokens, patch_size * patch_size * out_channels)`.
403
+ """
404
+ shift, scale = torch.chunk(self.adaLN_mod(condition.float()).to(dtype=x.dtype), 2, dim=1)
405
+ return self.linear(_modulate(self.norm_final(x), shift, scale))
406
+
407
+
408
+ class _LightningDiT(nn.Module):
409
+ def __init__(
410
+ self,
411
+ input_size: int,
412
+ patch_size: int,
413
+ in_channels: int,
414
+ hidden_size: int,
415
+ depth: int,
416
+ num_heads: int,
417
+ mlp_ratio: float,
418
+ out_channels: int,
419
+ use_qknorm: bool,
420
+ use_swiglu: bool,
421
+ use_rope: bool,
422
+ use_rmsnorm: bool,
423
+ cond_dim: int,
424
+ n_cls_tokens: int,
425
+ attn_fp32: bool,
426
+ ):
427
+ super().__init__()
428
+ self.input_size = int(input_size)
429
+ self.patch_size = int(patch_size)
430
+ self.in_channels = int(in_channels)
431
+ self.hidden_size = int(hidden_size)
432
+ self.out_channels = int(out_channels)
433
+ self.n_cls_tokens = int(n_cls_tokens)
434
+ self.patch_embed = _TorchLinear(self.patch_size * self.patch_size * self.in_channels, self.hidden_size, bias=True)
435
+ grid = self.input_size // self.patch_size
436
+ max_seq_len = grid * grid + self.n_cls_tokens
437
+ self.blocks = nn.ModuleList(
438
+ [
439
+ _DiTBlock(
440
+ hidden_size=self.hidden_size,
441
+ num_heads=num_heads,
442
+ mlp_ratio=mlp_ratio,
443
+ use_qknorm=use_qknorm,
444
+ use_swiglu=use_swiglu,
445
+ use_rmsnorm=use_rmsnorm,
446
+ use_rope=use_rope,
447
+ attn_fp32=attn_fp32,
448
+ max_seq_len=max_seq_len,
449
+ )
450
+ for _ in range(int(depth))
451
+ ]
452
+ )
453
+ self.final_layer = _FinalLayer(self.hidden_size, self.patch_size, self.out_channels, use_rmsnorm)
454
+ position = _sincos_2d(self.hidden_size, grid)
455
+ self.pos_embed = nn.Parameter(torch.as_tensor(position, dtype=torch.float32).unsqueeze(0))
456
+ if self.n_cls_tokens > 0:
457
+ self.cls_embed = nn.Parameter(torch.randn(1, self.n_cls_tokens, self.hidden_size) * 0.02)
458
+ self.c_token_proj = _TorchLinear(int(cond_dim), self.hidden_size, bias=True)
459
+ else:
460
+ self.register_parameter("cls_embed", None)
461
+ self.c_token_proj = None
462
+
463
+ def forward(self, hidden_states_bhwc: torch.Tensor, condition: torch.Tensor) -> torch.Tensor:
464
+ r"""
465
+ Map a latent grid to a clean latent grid.
466
+
467
+ Args:
468
+ hidden_states_bhwc (`torch.Tensor`):
469
+ Reference noise `(batch, height, width, channels)`. Height and width must equal
470
+ `input_size`. The official generator uses this layout.
471
+ condition (`torch.Tensor`):
472
+ Class, noise-code, and guidance embedding `(batch, cond_dim)`.
473
+
474
+ Returns:
475
+ `torch.Tensor`: Clean latent `(batch, height, width, channels)`.
476
+ """
477
+ batch, height, width, channels = hidden_states_bhwc.shape
478
+ patch = self.patch_size
479
+ grid = self.input_size // patch
480
+ if (height, width, channels) != (self.input_size, self.input_size, self.in_channels):
481
+ raise ValueError(
482
+ f"Expected latent {(self.input_size, self.input_size, self.in_channels)} in BHWC, "
483
+ f"got {(height, width, channels)}."
484
+ )
485
+ tokens = hidden_states_bhwc.reshape(batch, grid, patch, grid, patch, channels)
486
+ tokens = tokens.permute(0, 1, 3, 2, 4, 5).contiguous().reshape(batch, grid * grid, patch * patch * channels)
487
+ tokens = self.patch_embed(tokens)
488
+ tokens = (tokens + self.pos_embed.to(device=tokens.device, dtype=tokens.dtype)).to(dtype=tokens.dtype)
489
+ if self.n_cls_tokens > 0:
490
+ class_tokens = self.c_token_proj(condition).unsqueeze(1).repeat(1, self.n_cls_tokens, 1)
491
+ class_tokens = class_tokens + self.cls_embed.to(device=tokens.device, dtype=tokens.dtype)
492
+ tokens = torch.cat([class_tokens, tokens], dim=1)
493
+ for block in self.blocks:
494
+ tokens = block(tokens, condition)
495
+ tokens = self.final_layer(tokens, condition)
496
+ if self.n_cls_tokens > 0:
497
+ tokens = tokens[:, self.n_cls_tokens :, :]
498
+ tokens = tokens.reshape(batch, grid, grid, patch, patch, self.out_channels)
499
+ tokens = tokens.permute(0, 1, 3, 2, 4, 5).contiguous()
500
+ return tokens.reshape(batch, self.input_size, self.input_size, self.out_channels)
501
+
502
+
503
+ class _TimestepEmbedder(nn.Module):
504
+ def __init__(self, hidden_size: int, frequency_embedding_size: int = 256):
505
+ super().__init__()
506
+ self.frequency_embedding_size = int(frequency_embedding_size)
507
+ self.fc1 = _TorchLinear(self.frequency_embedding_size, hidden_size, bias=True, weight_init="normal")
508
+ self.fc2 = _TorchLinear(hidden_size, hidden_size, bias=True, weight_init="normal")
509
+
510
+ def forward(self, timesteps: torch.Tensor) -> torch.Tensor:
511
+ r"""
512
+ Embed a scalar guidance value with sinusoidal features.
513
+
514
+ Args:
515
+ timesteps (`torch.Tensor`):
516
+ Shape `(batch,)`. This is the guidance scale, not a diffusion time.
517
+
518
+ Returns:
519
+ `torch.Tensor`: Embedding `(batch, hidden)`.
520
+ """
521
+ timesteps = timesteps.to(dtype=torch.float32)
522
+ half = self.frequency_embedding_size // 2
523
+ freqs = torch.exp(-math.log(10000) * torch.arange(0, half, device=timesteps.device, dtype=torch.float32) / half)
524
+ arguments = timesteps[:, None] * freqs[None]
525
+ embedding = torch.cat([torch.cos(arguments), torch.sin(arguments)], dim=-1)
526
+ if self.frequency_embedding_size % 2:
527
+ embedding = torch.cat([embedding, torch.zeros_like(embedding[:, :1])], dim=-1)
528
+ hidden = nn.functional.silu(self.fc1(embedding))
529
+ return self.fc2(hidden)
530
+
531
+
532
+ class WFlowTransformer2DModel(ModelMixin, ConfigMixin):
533
+ r"""
534
+ One-step ImageNet generator used by W-Flow.
535
+
536
+ The network maps unit Gaussian SD-VAE noise plus a class label to a clean latent in one pass.
537
+ Guidance is a continuous embedding (the official `cfg_scale`, equal to `w + 1` in the paper),
538
+ not a second unconditional forward. Discrete noise codes (`noise_classes` by `noise_coords`)
539
+ are added to the class embedding.
540
+
541
+ Parameter names match `DitGen` in the official repository, so an `ema_model` state dict loads
542
+ without renaming.
543
+
544
+ Args:
545
+ sample_size (`int`, defaults to 32):
546
+ Latent spatial size. Released checkpoints use 32, which decodes to 256 pixels.
547
+ patch_size (`int`, defaults to 2):
548
+ Patch size on the latent grid.
549
+ in_channels (`int`, defaults to 4):
550
+ Latent channels.
551
+ out_channels (`int`, defaults to 4):
552
+ Predicted latent channels.
553
+ cond_dim (`int`, defaults to 768):
554
+ Width of the class, noise-code, and guidance embeddings.
555
+ num_classes (`int`, defaults to 1000):
556
+ ImageNet class count. There is no null-class slot.
557
+ noise_classes (`int`, defaults to 64):
558
+ Cardinality of each discrete noise code.
559
+ noise_coords (`int`, defaults to 32):
560
+ Number of independent noise-code embeddings that are summed.
561
+ n_cls_tokens (`int`, defaults to 16):
562
+ Learned class tokens prepended to the patch sequence.
563
+ hidden_size (`int`, defaults to 768):
564
+ Transformer width.
565
+ depth (`int`, defaults to 12):
566
+ Number of blocks.
567
+ num_attention_heads (`int`, defaults to 12):
568
+ Attention heads.
569
+ mlp_ratio (`float`, defaults to 4.0):
570
+ MLP expansion before the SwiGLU 2/3 reduction.
571
+ use_qknorm (`bool`, defaults to `True`):
572
+ QK normalization.
573
+ use_swiglu (`bool`, defaults to `True`):
574
+ SwiGLU MLP. Released checkpoints turn this on.
575
+ use_rope (`bool`, defaults to `True`):
576
+ 1-D rotary embeddings over the token sequence, including class tokens.
577
+ use_rmsnorm (`bool`, defaults to `True`):
578
+ RMSNorm instead of LayerNorm.
579
+ use_bf16 (`bool`, defaults to `True`):
580
+ Autocast the forward to bfloat16 on CUDA, matching the official sampler.
581
+ attn_fp32 (`bool`, defaults to `False`):
582
+ Run attention in float32. The ablation checkpoint sets this to `True`.
583
+ guidance_scale (`float`, defaults to 1.0):
584
+ Default embedded guidance. The pipeline reads this when the caller omits a scale.
585
+ default_num_inference_steps (`int`, defaults to 1):
586
+ Sampling is one network evaluation.
587
+ model_type (`str`, defaults to `"W-Flow-B"`):
588
+ Variant name stored in the config.
589
+ """
590
+
591
+ @register_to_config
592
+ def __init__(
593
+ self,
594
+ sample_size: int = 32,
595
+ patch_size: int = 2,
596
+ in_channels: int = 4,
597
+ out_channels: int = 4,
598
+ cond_dim: int = 768,
599
+ num_classes: int = 1000,
600
+ noise_classes: int = 64,
601
+ noise_coords: int = 32,
602
+ n_cls_tokens: int = 16,
603
+ hidden_size: int = 768,
604
+ depth: int = 12,
605
+ num_attention_heads: int = 12,
606
+ mlp_ratio: float = 4.0,
607
+ use_qknorm: bool = True,
608
+ use_swiglu: bool = True,
609
+ use_rope: bool = True,
610
+ use_rmsnorm: bool = True,
611
+ use_bf16: bool = True,
612
+ attn_fp32: bool = False,
613
+ guidance_scale: float = 1.0,
614
+ default_num_inference_steps: int = 1,
615
+ model_type: str = "W-Flow-B",
616
+ ):
617
+ super().__init__()
618
+ self.class_embed = nn.Embedding(int(num_classes), int(cond_dim))
619
+ nn.init.normal_(self.class_embed.weight, std=0.02)
620
+ self.noise_embeds = nn.ModuleList()
621
+ for _ in range(int(noise_coords)):
622
+ embedding = nn.Embedding(int(noise_classes), int(cond_dim))
623
+ nn.init.normal_(embedding.weight, std=0.02)
624
+ self.noise_embeds.append(embedding)
625
+ self.cfg_embedder = _TimestepEmbedder(int(cond_dim))
626
+ self.cfg_norm = _RMSNorm(int(cond_dim))
627
+ self.model = _LightningDiT(
628
+ input_size=int(sample_size),
629
+ patch_size=int(patch_size),
630
+ in_channels=int(in_channels),
631
+ hidden_size=int(hidden_size),
632
+ depth=int(depth),
633
+ num_heads=int(num_attention_heads),
634
+ mlp_ratio=float(mlp_ratio),
635
+ out_channels=int(out_channels),
636
+ use_qknorm=bool(use_qknorm),
637
+ use_swiglu=bool(use_swiglu),
638
+ use_rope=bool(use_rope),
639
+ use_rmsnorm=bool(use_rmsnorm),
640
+ cond_dim=int(cond_dim),
641
+ n_cls_tokens=int(n_cls_tokens),
642
+ attn_fp32=bool(attn_fp32),
643
+ )
644
+
645
+ def condition(
646
+ self,
647
+ class_labels: torch.Tensor,
648
+ guidance_scale: float | torch.Tensor,
649
+ noise_labels: torch.Tensor,
650
+ ) -> torch.Tensor:
651
+ r"""
652
+ Build the conditioning vector from class, noise codes, and guidance.
653
+
654
+ Args:
655
+ class_labels (`torch.Tensor`):
656
+ Integer class ids `(batch,)`, in `[0, num_classes)`.
657
+ guidance_scale (`float` or `torch.Tensor`):
658
+ Official CFG value `(w + 1)`. A float is broadcast across the batch. A tensor
659
+ must be `(batch,)` or a scalar.
660
+ noise_labels (`torch.Tensor`):
661
+ Integer codes `(batch, noise_coords)` in `[0, noise_classes)`.
662
+
663
+ Returns:
664
+ `torch.Tensor`: Condition `(batch, cond_dim)`.
665
+ """
666
+ batch = class_labels.shape[0]
667
+ cond = self.class_embed(class_labels)
668
+ for index, embedding in enumerate(self.noise_embeds):
669
+ cond = cond + embedding(noise_labels[:, index])
670
+ if isinstance(guidance_scale, (float, int)):
671
+ scale = torch.full((batch,), float(guidance_scale), device=class_labels.device, dtype=torch.float32)
672
+ else:
673
+ scale = torch.as_tensor(guidance_scale, device=class_labels.device, dtype=torch.float32)
674
+ if scale.ndim == 0:
675
+ scale = scale[None].repeat(batch)
676
+ embedded = self.cfg_norm(self.cfg_embedder(scale.float()).float())
677
+ return cond + embedded.to(dtype=cond.dtype) * 0.02
678
+
679
+ def forward(
680
+ self,
681
+ hidden_states: torch.Tensor,
682
+ class_labels: torch.Tensor,
683
+ guidance_scale: float | torch.Tensor = 1.0,
684
+ noise_labels: torch.Tensor | None = None,
685
+ return_dict: bool = True,
686
+ ) -> WFlowTransformer2DModelOutput | tuple[torch.Tensor]:
687
+ r"""
688
+ Predict a clean latent from reference noise.
689
+
690
+ Args:
691
+ hidden_states (`torch.Tensor`):
692
+ Gaussian reference noise `(batch, channels, height, width)` in BCHW. Height and
693
+ width must equal `config.sample_size`.
694
+ class_labels (`torch.Tensor`):
695
+ Integer ImageNet ids `(batch,)`.
696
+ guidance_scale (`float` or `torch.Tensor`, defaults to 1.0):
697
+ Embedded guidance. This is the official `cfg_scale` (`w + 1` in the paper).
698
+ noise_labels (`torch.Tensor`, *optional*):
699
+ Discrete noise codes `(batch, noise_coords)`. Required. The pipeline samples these
700
+ with the same generator as `hidden_states`.
701
+ return_dict (`bool`, defaults to `True`):
702
+ Return [`WFlowTransformer2DModelOutput`] when `True`, otherwise a one-tuple.
703
+
704
+ Returns:
705
+ [`WFlowTransformer2DModelOutput`] or `tuple`:
706
+ `sample` is the clean latent `(batch, channels, height, width)`.
707
+ """
708
+ if noise_labels is None:
709
+ raise ValueError("`noise_labels` is required and must have shape (batch, noise_coords).")
710
+ if hidden_states.ndim != 4:
711
+ raise ValueError(f"`hidden_states` must be BCHW, got {tuple(hidden_states.shape)}.")
712
+ hidden_bhwc = hidden_states.permute(0, 2, 3, 1).contiguous()
713
+ use_autocast = bool(self.config.use_bf16) and hidden_states.device.type == "cuda"
714
+ with torch.amp.autocast(device_type=hidden_states.device.type, dtype=torch.bfloat16, enabled=use_autocast):
715
+ cond = self.condition(class_labels, guidance_scale, noise_labels)
716
+ sample_bhwc = self.model(hidden_bhwc, cond)
717
+ sample = sample_bhwc.permute(0, 3, 1, 2).contiguous()
718
+ if not return_dict:
719
+ return (sample,)
720
+ return WFlowTransformer2DModelOutput(sample=sample)
W-Flow-L/vae/config.json ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_class_name": "AutoencoderKL",
3
+ "_diffusers_version": "0.36.0",
4
+ "_name_or_path": "stabilityai/sd-vae-ft-mse",
5
+ "act_fn": "silu",
6
+ "block_out_channels": [
7
+ 128,
8
+ 256,
9
+ 512,
10
+ 512
11
+ ],
12
+ "down_block_types": [
13
+ "DownEncoderBlock2D",
14
+ "DownEncoderBlock2D",
15
+ "DownEncoderBlock2D",
16
+ "DownEncoderBlock2D"
17
+ ],
18
+ "force_upcast": true,
19
+ "in_channels": 3,
20
+ "latent_channels": 4,
21
+ "latents_mean": null,
22
+ "latents_std": null,
23
+ "layers_per_block": 2,
24
+ "mid_block_add_attention": true,
25
+ "norm_num_groups": 32,
26
+ "out_channels": 3,
27
+ "sample_size": 256,
28
+ "scaling_factor": 0.18215,
29
+ "shift_factor": null,
30
+ "up_block_types": [
31
+ "UpDecoderBlock2D",
32
+ "UpDecoderBlock2D",
33
+ "UpDecoderBlock2D",
34
+ "UpDecoderBlock2D"
35
+ ],
36
+ "use_post_quant_conv": true,
37
+ "use_quant_conv": true
38
+ }
W-Flow-L/vae/diffusion_pytorch_model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:2aa1f43011b553a4cba7f37456465cdbd48aab7b54b9348b890e8058ea7683ec
3
+ size 334643268
W-Flow-XL/model_index.json ADDED
@@ -0,0 +1,1021 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_class_name": [
3
+ "pipeline",
4
+ "WFlowPipeline"
5
+ ],
6
+ "_diffusers_version": "0.39.0",
7
+ "scheduler": [
8
+ "scheduling_wflow",
9
+ "WFlowScheduler"
10
+ ],
11
+ "transformer": [
12
+ "transformer_wflow",
13
+ "WFlowTransformer2DModel"
14
+ ],
15
+ "vae": [
16
+ "diffusers",
17
+ "AutoencoderKL"
18
+ ],
19
+ "id2label": {
20
+ "0": "tench, Tinca tinca",
21
+ "1": "goldfish, Carassius auratus",
22
+ "2": "great white shark, white shark, man-eater, man-eating shark, Carcharodon carcharias",
23
+ "3": "tiger shark, Galeocerdo cuvieri",
24
+ "4": "hammerhead, hammerhead shark",
25
+ "5": "electric ray, crampfish, numbfish, torpedo",
26
+ "6": "stingray",
27
+ "7": "cock",
28
+ "8": "hen",
29
+ "9": "ostrich, Struthio camelus",
30
+ "10": "brambling, Fringilla montifringilla",
31
+ "11": "goldfinch, Carduelis carduelis",
32
+ "12": "house finch, linnet, Carpodacus mexicanus",
33
+ "13": "junco, snowbird",
34
+ "14": "indigo bunting, indigo finch, indigo bird, Passerina cyanea",
35
+ "15": "robin, American robin, Turdus migratorius",
36
+ "16": "bulbul",
37
+ "17": "jay",
38
+ "18": "magpie",
39
+ "19": "chickadee",
40
+ "20": "water ouzel, dipper",
41
+ "21": "kite",
42
+ "22": "bald eagle, American eagle, Haliaeetus leucocephalus",
43
+ "23": "vulture",
44
+ "24": "great grey owl, great gray owl, Strix nebulosa",
45
+ "25": "European fire salamander, Salamandra salamandra",
46
+ "26": "common newt, Triturus vulgaris",
47
+ "27": "eft",
48
+ "28": "spotted salamander, Ambystoma maculatum",
49
+ "29": "axolotl, mud puppy, Ambystoma mexicanum",
50
+ "30": "bullfrog, Rana catesbeiana",
51
+ "31": "tree frog, tree-frog",
52
+ "32": "tailed frog, bell toad, ribbed toad, tailed toad, Ascaphus trui",
53
+ "33": "loggerhead, loggerhead turtle, Caretta caretta",
54
+ "34": "leatherback turtle, leatherback, leathery turtle, Dermochelys coriacea",
55
+ "35": "mud turtle",
56
+ "36": "terrapin",
57
+ "37": "box turtle, box tortoise",
58
+ "38": "banded gecko",
59
+ "39": "common iguana, iguana, Iguana iguana",
60
+ "40": "American chameleon, anole, Anolis carolinensis",
61
+ "41": "whiptail, whiptail lizard",
62
+ "42": "agama",
63
+ "43": "frilled lizard, Chlamydosaurus kingi",
64
+ "44": "alligator lizard",
65
+ "45": "Gila monster, Heloderma suspectum",
66
+ "46": "green lizard, Lacerta viridis",
67
+ "47": "African chameleon, Chamaeleo chamaeleon",
68
+ "48": "Komodo dragon, Komodo lizard, dragon lizard, giant lizard, Varanus komodoensis",
69
+ "49": "African crocodile, Nile crocodile, Crocodylus niloticus",
70
+ "50": "American alligator, Alligator mississipiensis",
71
+ "51": "triceratops",
72
+ "52": "thunder snake, worm snake, Carphophis amoenus",
73
+ "53": "ringneck snake, ring-necked snake, ring snake",
74
+ "54": "hognose snake, puff adder, sand viper",
75
+ "55": "green snake, grass snake",
76
+ "56": "king snake, kingsnake",
77
+ "57": "garter snake, grass snake",
78
+ "58": "water snake",
79
+ "59": "vine snake",
80
+ "60": "night snake, Hypsiglena torquata",
81
+ "61": "boa constrictor, Constrictor constrictor",
82
+ "62": "rock python, rock snake, Python sebae",
83
+ "63": "Indian cobra, Naja naja",
84
+ "64": "green mamba",
85
+ "65": "sea snake",
86
+ "66": "horned viper, cerastes, sand viper, horned asp, Cerastes cornutus",
87
+ "67": "diamondback, diamondback rattlesnake, Crotalus adamanteus",
88
+ "68": "sidewinder, horned rattlesnake, Crotalus cerastes",
89
+ "69": "trilobite",
90
+ "70": "harvestman, daddy longlegs, Phalangium opilio",
91
+ "71": "scorpion",
92
+ "72": "black and gold garden spider, Argiope aurantia",
93
+ "73": "barn spider, Araneus cavaticus",
94
+ "74": "garden spider, Aranea diademata",
95
+ "75": "black widow, Latrodectus mactans",
96
+ "76": "tarantula",
97
+ "77": "wolf spider, hunting spider",
98
+ "78": "tick",
99
+ "79": "centipede",
100
+ "80": "black grouse",
101
+ "81": "ptarmigan",
102
+ "82": "ruffed grouse, partridge, Bonasa umbellus",
103
+ "83": "prairie chicken, prairie grouse, prairie fowl",
104
+ "84": "peacock",
105
+ "85": "quail",
106
+ "86": "partridge",
107
+ "87": "African grey, African gray, Psittacus erithacus",
108
+ "88": "macaw",
109
+ "89": "sulphur-crested cockatoo, Kakatoe galerita, Cacatua galerita",
110
+ "90": "lorikeet",
111
+ "91": "coucal",
112
+ "92": "bee eater",
113
+ "93": "hornbill",
114
+ "94": "hummingbird",
115
+ "95": "jacamar",
116
+ "96": "toucan",
117
+ "97": "drake",
118
+ "98": "red-breasted merganser, Mergus serrator",
119
+ "99": "goose",
120
+ "100": "black swan, Cygnus atratus",
121
+ "101": "tusker",
122
+ "102": "echidna, spiny anteater, anteater",
123
+ "103": "platypus, duckbill, duckbilled platypus, duck-billed platypus, Ornithorhynchus anatinus",
124
+ "104": "wallaby, brush kangaroo",
125
+ "105": "koala, koala bear, kangaroo bear, native bear, Phascolarctos cinereus",
126
+ "106": "wombat",
127
+ "107": "jellyfish",
128
+ "108": "sea anemone, anemone",
129
+ "109": "brain coral",
130
+ "110": "flatworm, platyhelminth",
131
+ "111": "nematode, nematode worm, roundworm",
132
+ "112": "conch",
133
+ "113": "snail",
134
+ "114": "slug",
135
+ "115": "sea slug, nudibranch",
136
+ "116": "chiton, coat-of-mail shell, sea cradle, polyplacophore",
137
+ "117": "chambered nautilus, pearly nautilus, nautilus",
138
+ "118": "Dungeness crab, Cancer magister",
139
+ "119": "rock crab, Cancer irroratus",
140
+ "120": "fiddler crab",
141
+ "121": "king crab, Alaska crab, Alaskan king crab, Alaska king crab, Paralithodes camtschatica",
142
+ "122": "American lobster, Northern lobster, Maine lobster, Homarus americanus",
143
+ "123": "spiny lobster, langouste, rock lobster, crawfish, crayfish, sea crawfish",
144
+ "124": "crayfish, crawfish, crawdad, crawdaddy",
145
+ "125": "hermit crab",
146
+ "126": "isopod",
147
+ "127": "white stork, Ciconia ciconia",
148
+ "128": "black stork, Ciconia nigra",
149
+ "129": "spoonbill",
150
+ "130": "flamingo",
151
+ "131": "little blue heron, Egretta caerulea",
152
+ "132": "American egret, great white heron, Egretta albus",
153
+ "133": "bittern",
154
+ "134": "crane",
155
+ "135": "limpkin, Aramus pictus",
156
+ "136": "European gallinule, Porphyrio porphyrio",
157
+ "137": "American coot, marsh hen, mud hen, water hen, Fulica americana",
158
+ "138": "bustard",
159
+ "139": "ruddy turnstone, Arenaria interpres",
160
+ "140": "red-backed sandpiper, dunlin, Erolia alpina",
161
+ "141": "redshank, Tringa totanus",
162
+ "142": "dowitcher",
163
+ "143": "oystercatcher, oyster catcher",
164
+ "144": "pelican",
165
+ "145": "king penguin, Aptenodytes patagonica",
166
+ "146": "albatross, mollymawk",
167
+ "147": "grey whale, gray whale, devilfish, Eschrichtius gibbosus, Eschrichtius robustus",
168
+ "148": "killer whale, killer, orca, grampus, sea wolf, Orcinus orca",
169
+ "149": "dugong, Dugong dugon",
170
+ "150": "sea lion",
171
+ "151": "Chihuahua",
172
+ "152": "Japanese spaniel",
173
+ "153": "Maltese dog, Maltese terrier, Maltese",
174
+ "154": "Pekinese, Pekingese, Peke",
175
+ "155": "Shih-Tzu",
176
+ "156": "Blenheim spaniel",
177
+ "157": "papillon",
178
+ "158": "toy terrier",
179
+ "159": "Rhodesian ridgeback",
180
+ "160": "Afghan hound, Afghan",
181
+ "161": "basset, basset hound",
182
+ "162": "beagle",
183
+ "163": "bloodhound, sleuthhound",
184
+ "164": "bluetick",
185
+ "165": "black-and-tan coonhound",
186
+ "166": "Walker hound, Walker foxhound",
187
+ "167": "English foxhound",
188
+ "168": "redbone",
189
+ "169": "borzoi, Russian wolfhound",
190
+ "170": "Irish wolfhound",
191
+ "171": "Italian greyhound",
192
+ "172": "whippet",
193
+ "173": "Ibizan hound, Ibizan Podenco",
194
+ "174": "Norwegian elkhound, elkhound",
195
+ "175": "otterhound, otter hound",
196
+ "176": "Saluki, gazelle hound",
197
+ "177": "Scottish deerhound, deerhound",
198
+ "178": "Weimaraner",
199
+ "179": "Staffordshire bullterrier, Staffordshire bull terrier",
200
+ "180": "American Staffordshire terrier, Staffordshire terrier, American pit bull terrier, pit bull terrier",
201
+ "181": "Bedlington terrier",
202
+ "182": "Border terrier",
203
+ "183": "Kerry blue terrier",
204
+ "184": "Irish terrier",
205
+ "185": "Norfolk terrier",
206
+ "186": "Norwich terrier",
207
+ "187": "Yorkshire terrier",
208
+ "188": "wire-haired fox terrier",
209
+ "189": "Lakeland terrier",
210
+ "190": "Sealyham terrier, Sealyham",
211
+ "191": "Airedale, Airedale terrier",
212
+ "192": "cairn, cairn terrier",
213
+ "193": "Australian terrier",
214
+ "194": "Dandie Dinmont, Dandie Dinmont terrier",
215
+ "195": "Boston bull, Boston terrier",
216
+ "196": "miniature schnauzer",
217
+ "197": "giant schnauzer",
218
+ "198": "standard schnauzer",
219
+ "199": "Scotch terrier, Scottish terrier, Scottie",
220
+ "200": "Tibetan terrier, chrysanthemum dog",
221
+ "201": "silky terrier, Sydney silky",
222
+ "202": "soft-coated wheaten terrier",
223
+ "203": "West Highland white terrier",
224
+ "204": "Lhasa, Lhasa apso",
225
+ "205": "flat-coated retriever",
226
+ "206": "curly-coated retriever",
227
+ "207": "golden retriever",
228
+ "208": "Labrador retriever",
229
+ "209": "Chesapeake Bay retriever",
230
+ "210": "German short-haired pointer",
231
+ "211": "vizsla, Hungarian pointer",
232
+ "212": "English setter",
233
+ "213": "Irish setter, red setter",
234
+ "214": "Gordon setter",
235
+ "215": "Brittany spaniel",
236
+ "216": "clumber, clumber spaniel",
237
+ "217": "English springer, English springer spaniel",
238
+ "218": "Welsh springer spaniel",
239
+ "219": "cocker spaniel, English cocker spaniel, cocker",
240
+ "220": "Sussex spaniel",
241
+ "221": "Irish water spaniel",
242
+ "222": "kuvasz",
243
+ "223": "schipperke",
244
+ "224": "groenendael",
245
+ "225": "malinois",
246
+ "226": "briard",
247
+ "227": "kelpie",
248
+ "228": "komondor",
249
+ "229": "Old English sheepdog, bobtail",
250
+ "230": "Shetland sheepdog, Shetland sheep dog, Shetland",
251
+ "231": "collie",
252
+ "232": "Border collie",
253
+ "233": "Bouvier des Flandres, Bouviers des Flandres",
254
+ "234": "Rottweiler",
255
+ "235": "German shepherd, German shepherd dog, German police dog, alsatian",
256
+ "236": "Doberman, Doberman pinscher",
257
+ "237": "miniature pinscher",
258
+ "238": "Greater Swiss Mountain dog",
259
+ "239": "Bernese mountain dog",
260
+ "240": "Appenzeller",
261
+ "241": "EntleBucher",
262
+ "242": "boxer",
263
+ "243": "bull mastiff",
264
+ "244": "Tibetan mastiff",
265
+ "245": "French bulldog",
266
+ "246": "Great Dane",
267
+ "247": "Saint Bernard, St Bernard",
268
+ "248": "Eskimo dog, husky",
269
+ "249": "malamute, malemute, Alaskan malamute",
270
+ "250": "Siberian husky",
271
+ "251": "dalmatian, coach dog, carriage dog",
272
+ "252": "affenpinscher, monkey pinscher, monkey dog",
273
+ "253": "basenji",
274
+ "254": "pug, pug-dog",
275
+ "255": "Leonberg",
276
+ "256": "Newfoundland, Newfoundland dog",
277
+ "257": "Great Pyrenees",
278
+ "258": "Samoyed, Samoyede",
279
+ "259": "Pomeranian",
280
+ "260": "chow, chow chow",
281
+ "261": "keeshond",
282
+ "262": "Brabancon griffon",
283
+ "263": "Pembroke, Pembroke Welsh corgi",
284
+ "264": "Cardigan, Cardigan Welsh corgi",
285
+ "265": "toy poodle",
286
+ "266": "miniature poodle",
287
+ "267": "standard poodle",
288
+ "268": "Mexican hairless",
289
+ "269": "timber wolf, grey wolf, gray wolf, Canis lupus",
290
+ "270": "white wolf, Arctic wolf, Canis lupus tundrarum",
291
+ "271": "red wolf, maned wolf, Canis rufus, Canis niger",
292
+ "272": "coyote, prairie wolf, brush wolf, Canis latrans",
293
+ "273": "dingo, warrigal, warragal, Canis dingo",
294
+ "274": "dhole, Cuon alpinus",
295
+ "275": "African hunting dog, hyena dog, Cape hunting dog, Lycaon pictus",
296
+ "276": "hyena, hyaena",
297
+ "277": "red fox, Vulpes vulpes",
298
+ "278": "kit fox, Vulpes macrotis",
299
+ "279": "Arctic fox, white fox, Alopex lagopus",
300
+ "280": "grey fox, gray fox, Urocyon cinereoargenteus",
301
+ "281": "tabby, tabby cat",
302
+ "282": "tiger cat",
303
+ "283": "Persian cat",
304
+ "284": "Siamese cat, Siamese",
305
+ "285": "Egyptian cat",
306
+ "286": "cougar, puma, catamount, mountain lion, painter, panther, Felis concolor",
307
+ "287": "lynx, catamount",
308
+ "288": "leopard, Panthera pardus",
309
+ "289": "snow leopard, ounce, Panthera uncia",
310
+ "290": "jaguar, panther, Panthera onca, Felis onca",
311
+ "291": "lion, king of beasts, Panthera leo",
312
+ "292": "tiger, Panthera tigris",
313
+ "293": "cheetah, chetah, Acinonyx jubatus",
314
+ "294": "brown bear, bruin, Ursus arctos",
315
+ "295": "American black bear, black bear, Ursus americanus, Euarctos americanus",
316
+ "296": "ice bear, polar bear, Ursus Maritimus, Thalarctos maritimus",
317
+ "297": "sloth bear, Melursus ursinus, Ursus ursinus",
318
+ "298": "mongoose",
319
+ "299": "meerkat, mierkat",
320
+ "300": "tiger beetle",
321
+ "301": "ladybug, ladybeetle, lady beetle, ladybird, ladybird beetle",
322
+ "302": "ground beetle, carabid beetle",
323
+ "303": "long-horned beetle, longicorn, longicorn beetle",
324
+ "304": "leaf beetle, chrysomelid",
325
+ "305": "dung beetle",
326
+ "306": "rhinoceros beetle",
327
+ "307": "weevil",
328
+ "308": "fly",
329
+ "309": "bee",
330
+ "310": "ant, emmet, pismire",
331
+ "311": "grasshopper, hopper",
332
+ "312": "cricket",
333
+ "313": "walking stick, walkingstick, stick insect",
334
+ "314": "cockroach, roach",
335
+ "315": "mantis, mantid",
336
+ "316": "cicada, cicala",
337
+ "317": "leafhopper",
338
+ "318": "lacewing, lacewing fly",
339
+ "319": "dragonfly, darning needle, devils darning needle, sewing needle, snake feeder, snake doctor, mosquito hawk, skeeter hawk",
340
+ "320": "damselfly",
341
+ "321": "admiral",
342
+ "322": "ringlet, ringlet butterfly",
343
+ "323": "monarch, monarch butterfly, milkweed butterfly, Danaus plexippus",
344
+ "324": "cabbage butterfly",
345
+ "325": "sulphur butterfly, sulfur butterfly",
346
+ "326": "lycaenid, lycaenid butterfly",
347
+ "327": "starfish, sea star",
348
+ "328": "sea urchin",
349
+ "329": "sea cucumber, holothurian",
350
+ "330": "wood rabbit, cottontail, cottontail rabbit",
351
+ "331": "hare",
352
+ "332": "Angora, Angora rabbit",
353
+ "333": "hamster",
354
+ "334": "porcupine, hedgehog",
355
+ "335": "fox squirrel, eastern fox squirrel, Sciurus niger",
356
+ "336": "marmot",
357
+ "337": "beaver",
358
+ "338": "guinea pig, Cavia cobaya",
359
+ "339": "sorrel",
360
+ "340": "zebra",
361
+ "341": "hog, pig, grunter, squealer, Sus scrofa",
362
+ "342": "wild boar, boar, Sus scrofa",
363
+ "343": "warthog",
364
+ "344": "hippopotamus, hippo, river horse, Hippopotamus amphibius",
365
+ "345": "ox",
366
+ "346": "water buffalo, water ox, Asiatic buffalo, Bubalus bubalis",
367
+ "347": "bison",
368
+ "348": "ram, tup",
369
+ "349": "bighorn, bighorn sheep, cimarron, Rocky Mountain bighorn, Rocky Mountain sheep, Ovis canadensis",
370
+ "350": "ibex, Capra ibex",
371
+ "351": "hartebeest",
372
+ "352": "impala, Aepyceros melampus",
373
+ "353": "gazelle",
374
+ "354": "Arabian camel, dromedary, Camelus dromedarius",
375
+ "355": "llama",
376
+ "356": "weasel",
377
+ "357": "mink",
378
+ "358": "polecat, fitch, foulmart, foumart, Mustela putorius",
379
+ "359": "black-footed ferret, ferret, Mustela nigripes",
380
+ "360": "otter",
381
+ "361": "skunk, polecat, wood pussy",
382
+ "362": "badger",
383
+ "363": "armadillo",
384
+ "364": "three-toed sloth, ai, Bradypus tridactylus",
385
+ "365": "orangutan, orang, orangutang, Pongo pygmaeus",
386
+ "366": "gorilla, Gorilla gorilla",
387
+ "367": "chimpanzee, chimp, Pan troglodytes",
388
+ "368": "gibbon, Hylobates lar",
389
+ "369": "siamang, Hylobates syndactylus, Symphalangus syndactylus",
390
+ "370": "guenon, guenon monkey",
391
+ "371": "patas, hussar monkey, Erythrocebus patas",
392
+ "372": "baboon",
393
+ "373": "macaque",
394
+ "374": "langur",
395
+ "375": "colobus, colobus monkey",
396
+ "376": "proboscis monkey, Nasalis larvatus",
397
+ "377": "marmoset",
398
+ "378": "capuchin, ringtail, Cebus capucinus",
399
+ "379": "howler monkey, howler",
400
+ "380": "titi, titi monkey",
401
+ "381": "spider monkey, Ateles geoffroyi",
402
+ "382": "squirrel monkey, Saimiri sciureus",
403
+ "383": "Madagascar cat, ring-tailed lemur, Lemur catta",
404
+ "384": "indri, indris, Indri indri, Indri brevicaudatus",
405
+ "385": "Indian elephant, Elephas maximus",
406
+ "386": "African elephant, Loxodonta africana",
407
+ "387": "lesser panda, red panda, panda, bear cat, cat bear, Ailurus fulgens",
408
+ "388": "giant panda, panda, panda bear, coon bear, Ailuropoda melanoleuca",
409
+ "389": "barracouta, snoek",
410
+ "390": "eel",
411
+ "391": "coho, cohoe, coho salmon, blue jack, silver salmon, Oncorhynchus kisutch",
412
+ "392": "rock beauty, Holocanthus tricolor",
413
+ "393": "anemone fish",
414
+ "394": "sturgeon",
415
+ "395": "gar, garfish, garpike, billfish, Lepisosteus osseus",
416
+ "396": "lionfish",
417
+ "397": "puffer, pufferfish, blowfish, globefish",
418
+ "398": "abacus",
419
+ "399": "abaya",
420
+ "400": "academic gown, academic robe, judge robe",
421
+ "401": "accordion, piano accordion, squeeze box",
422
+ "402": "acoustic guitar",
423
+ "403": "aircraft carrier, carrier, flattop, attack aircraft carrier",
424
+ "404": "airliner",
425
+ "405": "airship, dirigible",
426
+ "406": "altar",
427
+ "407": "ambulance",
428
+ "408": "amphibian, amphibious vehicle",
429
+ "409": "analog clock",
430
+ "410": "apiary, bee house",
431
+ "411": "apron",
432
+ "412": "ashcan, trash can, garbage can, wastebin, ash bin, ash-bin, ashbin, dustbin, trash barrel, trash bin",
433
+ "413": "assault rifle, assault gun",
434
+ "414": "backpack, back pack, knapsack, packsack, rucksack, haversack",
435
+ "415": "bakery, bakeshop, bakehouse",
436
+ "416": "balance beam, beam",
437
+ "417": "balloon",
438
+ "418": "ballpoint, ballpoint pen, ballpen, Biro",
439
+ "419": "Band Aid",
440
+ "420": "banjo",
441
+ "421": "bannister, banister, balustrade, balusters, handrail",
442
+ "422": "barbell",
443
+ "423": "barber chair",
444
+ "424": "barbershop",
445
+ "425": "barn",
446
+ "426": "barometer",
447
+ "427": "barrel, cask",
448
+ "428": "barrow, garden cart, lawn cart, wheelbarrow",
449
+ "429": "baseball",
450
+ "430": "basketball",
451
+ "431": "bassinet",
452
+ "432": "bassoon",
453
+ "433": "bathing cap, swimming cap",
454
+ "434": "bath towel",
455
+ "435": "bathtub, bathing tub, bath, tub",
456
+ "436": "beach wagon, station wagon, wagon, estate car, beach waggon, station waggon, waggon",
457
+ "437": "beacon, lighthouse, beacon light, pharos",
458
+ "438": "beaker",
459
+ "439": "bearskin, busby, shako",
460
+ "440": "beer bottle",
461
+ "441": "beer glass",
462
+ "442": "bell cote, bell cot",
463
+ "443": "bib",
464
+ "444": "bicycle-built-for-two, tandem bicycle, tandem",
465
+ "445": "bikini, two-piece",
466
+ "446": "binder, ring-binder",
467
+ "447": "binoculars, field glasses, opera glasses",
468
+ "448": "birdhouse",
469
+ "449": "boathouse",
470
+ "450": "bobsled, bobsleigh, bob",
471
+ "451": "bolo tie, bolo, bola tie, bola",
472
+ "452": "bonnet, poke bonnet",
473
+ "453": "bookcase",
474
+ "454": "bookshop, bookstore, bookstall",
475
+ "455": "bottlecap",
476
+ "456": "bow",
477
+ "457": "bow tie, bow-tie, bowtie",
478
+ "458": "brass, memorial tablet, plaque",
479
+ "459": "brassiere, bra, bandeau",
480
+ "460": "breakwater, groin, groyne, mole, bulwark, seawall, jetty",
481
+ "461": "breastplate, aegis, egis",
482
+ "462": "broom",
483
+ "463": "bucket, pail",
484
+ "464": "buckle",
485
+ "465": "bulletproof vest",
486
+ "466": "bullet train, bullet",
487
+ "467": "butcher shop, meat market",
488
+ "468": "cab, hack, taxi, taxicab",
489
+ "469": "caldron, cauldron",
490
+ "470": "candle, taper, wax light",
491
+ "471": "cannon",
492
+ "472": "canoe",
493
+ "473": "can opener, tin opener",
494
+ "474": "cardigan",
495
+ "475": "car mirror",
496
+ "476": "carousel, carrousel, merry-go-round, roundabout, whirligig",
497
+ "477": "carpenters kit, tool kit",
498
+ "478": "carton",
499
+ "479": "car wheel",
500
+ "480": "cash machine, cash dispenser, automated teller machine, automatic teller machine, automated teller, automatic teller, ATM",
501
+ "481": "cassette",
502
+ "482": "cassette player",
503
+ "483": "castle",
504
+ "484": "catamaran",
505
+ "485": "CD player",
506
+ "486": "cello, violoncello",
507
+ "487": "cellular telephone, cellular phone, cellphone, cell, mobile phone",
508
+ "488": "chain",
509
+ "489": "chainlink fence",
510
+ "490": "chain mail, ring mail, mail, chain armor, chain armour, ring armor, ring armour",
511
+ "491": "chain saw, chainsaw",
512
+ "492": "chest",
513
+ "493": "chiffonier, commode",
514
+ "494": "chime, bell, gong",
515
+ "495": "china cabinet, china closet",
516
+ "496": "Christmas stocking",
517
+ "497": "church, church building",
518
+ "498": "cinema, movie theater, movie theatre, movie house, picture palace",
519
+ "499": "cleaver, meat cleaver, chopper",
520
+ "500": "cliff dwelling",
521
+ "501": "cloak",
522
+ "502": "clog, geta, patten, sabot",
523
+ "503": "cocktail shaker",
524
+ "504": "coffee mug",
525
+ "505": "coffeepot",
526
+ "506": "coil, spiral, volute, whorl, helix",
527
+ "507": "combination lock",
528
+ "508": "computer keyboard, keypad",
529
+ "509": "confectionery, confectionary, candy store",
530
+ "510": "container ship, containership, container vessel",
531
+ "511": "convertible",
532
+ "512": "corkscrew, bottle screw",
533
+ "513": "cornet, horn, trumpet, trump",
534
+ "514": "cowboy boot",
535
+ "515": "cowboy hat, ten-gallon hat",
536
+ "516": "cradle",
537
+ "517": "crane",
538
+ "518": "crash helmet",
539
+ "519": "crate",
540
+ "520": "crib, cot",
541
+ "521": "Crock Pot",
542
+ "522": "croquet ball",
543
+ "523": "crutch",
544
+ "524": "cuirass",
545
+ "525": "dam, dike, dyke",
546
+ "526": "desk",
547
+ "527": "desktop computer",
548
+ "528": "dial telephone, dial phone",
549
+ "529": "diaper, nappy, napkin",
550
+ "530": "digital clock",
551
+ "531": "digital watch",
552
+ "532": "dining table, board",
553
+ "533": "dishrag, dishcloth",
554
+ "534": "dishwasher, dish washer, dishwashing machine",
555
+ "535": "disk brake, disc brake",
556
+ "536": "dock, dockage, docking facility",
557
+ "537": "dogsled, dog sled, dog sleigh",
558
+ "538": "dome",
559
+ "539": "doormat, welcome mat",
560
+ "540": "drilling platform, offshore rig",
561
+ "541": "drum, membranophone, tympan",
562
+ "542": "drumstick",
563
+ "543": "dumbbell",
564
+ "544": "Dutch oven",
565
+ "545": "electric fan, blower",
566
+ "546": "electric guitar",
567
+ "547": "electric locomotive",
568
+ "548": "entertainment center",
569
+ "549": "envelope",
570
+ "550": "espresso maker",
571
+ "551": "face powder",
572
+ "552": "feather boa, boa",
573
+ "553": "file, file cabinet, filing cabinet",
574
+ "554": "fireboat",
575
+ "555": "fire engine, fire truck",
576
+ "556": "fire screen, fireguard",
577
+ "557": "flagpole, flagstaff",
578
+ "558": "flute, transverse flute",
579
+ "559": "folding chair",
580
+ "560": "football helmet",
581
+ "561": "forklift",
582
+ "562": "fountain",
583
+ "563": "fountain pen",
584
+ "564": "four-poster",
585
+ "565": "freight car",
586
+ "566": "French horn, horn",
587
+ "567": "frying pan, frypan, skillet",
588
+ "568": "fur coat",
589
+ "569": "garbage truck, dustcart",
590
+ "570": "gasmask, respirator, gas helmet",
591
+ "571": "gas pump, gasoline pump, petrol pump, island dispenser",
592
+ "572": "goblet",
593
+ "573": "go-kart",
594
+ "574": "golf ball",
595
+ "575": "golfcart, golf cart",
596
+ "576": "gondola",
597
+ "577": "gong, tam-tam",
598
+ "578": "gown",
599
+ "579": "grand piano, grand",
600
+ "580": "greenhouse, nursery, glasshouse",
601
+ "581": "grille, radiator grille",
602
+ "582": "grocery store, grocery, food market, market",
603
+ "583": "guillotine",
604
+ "584": "hair slide",
605
+ "585": "hair spray",
606
+ "586": "half track",
607
+ "587": "hammer",
608
+ "588": "hamper",
609
+ "589": "hand blower, blow dryer, blow drier, hair dryer, hair drier",
610
+ "590": "hand-held computer, hand-held microcomputer",
611
+ "591": "handkerchief, hankie, hanky, hankey",
612
+ "592": "hard disc, hard disk, fixed disk",
613
+ "593": "harmonica, mouth organ, harp, mouth harp",
614
+ "594": "harp",
615
+ "595": "harvester, reaper",
616
+ "596": "hatchet",
617
+ "597": "holster",
618
+ "598": "home theater, home theatre",
619
+ "599": "honeycomb",
620
+ "600": "hook, claw",
621
+ "601": "hoopskirt, crinoline",
622
+ "602": "horizontal bar, high bar",
623
+ "603": "horse cart, horse-cart",
624
+ "604": "hourglass",
625
+ "605": "iPod",
626
+ "606": "iron, smoothing iron",
627
+ "607": "jack-o-lantern",
628
+ "608": "jean, blue jean, denim",
629
+ "609": "jeep, landrover",
630
+ "610": "jersey, T-shirt, tee shirt",
631
+ "611": "jigsaw puzzle",
632
+ "612": "jinrikisha, ricksha, rickshaw",
633
+ "613": "joystick",
634
+ "614": "kimono",
635
+ "615": "knee pad",
636
+ "616": "knot",
637
+ "617": "lab coat, laboratory coat",
638
+ "618": "ladle",
639
+ "619": "lampshade, lamp shade",
640
+ "620": "laptop, laptop computer",
641
+ "621": "lawn mower, mower",
642
+ "622": "lens cap, lens cover",
643
+ "623": "letter opener, paper knife, paperknife",
644
+ "624": "library",
645
+ "625": "lifeboat",
646
+ "626": "lighter, light, igniter, ignitor",
647
+ "627": "limousine, limo",
648
+ "628": "liner, ocean liner",
649
+ "629": "lipstick, lip rouge",
650
+ "630": "Loafer",
651
+ "631": "lotion",
652
+ "632": "loudspeaker, speaker, speaker unit, loudspeaker system, speaker system",
653
+ "633": "loupe, jewelers loupe",
654
+ "634": "lumbermill, sawmill",
655
+ "635": "magnetic compass",
656
+ "636": "mailbag, postbag",
657
+ "637": "mailbox, letter box",
658
+ "638": "maillot",
659
+ "639": "maillot, tank suit",
660
+ "640": "manhole cover",
661
+ "641": "maraca",
662
+ "642": "marimba, xylophone",
663
+ "643": "mask",
664
+ "644": "matchstick",
665
+ "645": "maypole",
666
+ "646": "maze, labyrinth",
667
+ "647": "measuring cup",
668
+ "648": "medicine chest, medicine cabinet",
669
+ "649": "megalith, megalithic structure",
670
+ "650": "microphone, mike",
671
+ "651": "microwave, microwave oven",
672
+ "652": "military uniform",
673
+ "653": "milk can",
674
+ "654": "minibus",
675
+ "655": "miniskirt, mini",
676
+ "656": "minivan",
677
+ "657": "missile",
678
+ "658": "mitten",
679
+ "659": "mixing bowl",
680
+ "660": "mobile home, manufactured home",
681
+ "661": "Model T",
682
+ "662": "modem",
683
+ "663": "monastery",
684
+ "664": "monitor",
685
+ "665": "moped",
686
+ "666": "mortar",
687
+ "667": "mortarboard",
688
+ "668": "mosque",
689
+ "669": "mosquito net",
690
+ "670": "motor scooter, scooter",
691
+ "671": "mountain bike, all-terrain bike, off-roader",
692
+ "672": "mountain tent",
693
+ "673": "mouse, computer mouse",
694
+ "674": "mousetrap",
695
+ "675": "moving van",
696
+ "676": "muzzle",
697
+ "677": "nail",
698
+ "678": "neck brace",
699
+ "679": "necklace",
700
+ "680": "nipple",
701
+ "681": "notebook, notebook computer",
702
+ "682": "obelisk",
703
+ "683": "oboe, hautboy, hautbois",
704
+ "684": "ocarina, sweet potato",
705
+ "685": "odometer, hodometer, mileometer, milometer",
706
+ "686": "oil filter",
707
+ "687": "organ, pipe organ",
708
+ "688": "oscilloscope, scope, cathode-ray oscilloscope, CRO",
709
+ "689": "overskirt",
710
+ "690": "oxcart",
711
+ "691": "oxygen mask",
712
+ "692": "packet",
713
+ "693": "paddle, boat paddle",
714
+ "694": "paddlewheel, paddle wheel",
715
+ "695": "padlock",
716
+ "696": "paintbrush",
717
+ "697": "pajama, pyjama, pjs, jammies",
718
+ "698": "palace",
719
+ "699": "panpipe, pandean pipe, syrinx",
720
+ "700": "paper towel",
721
+ "701": "parachute, chute",
722
+ "702": "parallel bars, bars",
723
+ "703": "park bench",
724
+ "704": "parking meter",
725
+ "705": "passenger car, coach, carriage",
726
+ "706": "patio, terrace",
727
+ "707": "pay-phone, pay-station",
728
+ "708": "pedestal, plinth, footstall",
729
+ "709": "pencil box, pencil case",
730
+ "710": "pencil sharpener",
731
+ "711": "perfume, essence",
732
+ "712": "Petri dish",
733
+ "713": "photocopier",
734
+ "714": "pick, plectrum, plectron",
735
+ "715": "pickelhaube",
736
+ "716": "picket fence, paling",
737
+ "717": "pickup, pickup truck",
738
+ "718": "pier",
739
+ "719": "piggy bank, penny bank",
740
+ "720": "pill bottle",
741
+ "721": "pillow",
742
+ "722": "ping-pong ball",
743
+ "723": "pinwheel",
744
+ "724": "pirate, pirate ship",
745
+ "725": "pitcher, ewer",
746
+ "726": "plane, carpenters plane, woodworking plane",
747
+ "727": "planetarium",
748
+ "728": "plastic bag",
749
+ "729": "plate rack",
750
+ "730": "plow, plough",
751
+ "731": "plunger, plumbers helper",
752
+ "732": "Polaroid camera, Polaroid Land camera",
753
+ "733": "pole",
754
+ "734": "police van, police wagon, paddy wagon, patrol wagon, wagon, black Maria",
755
+ "735": "poncho",
756
+ "736": "pool table, billiard table, snooker table",
757
+ "737": "pop bottle, soda bottle",
758
+ "738": "pot, flowerpot",
759
+ "739": "potters wheel",
760
+ "740": "power drill",
761
+ "741": "prayer rug, prayer mat",
762
+ "742": "printer",
763
+ "743": "prison, prison house",
764
+ "744": "projectile, missile",
765
+ "745": "projector",
766
+ "746": "puck, hockey puck",
767
+ "747": "punching bag, punch bag, punching ball, punchball",
768
+ "748": "purse",
769
+ "749": "quill, quill pen",
770
+ "750": "quilt, comforter, comfort, puff",
771
+ "751": "racer, race car, racing car",
772
+ "752": "racket, racquet",
773
+ "753": "radiator",
774
+ "754": "radio, wireless",
775
+ "755": "radio telescope, radio reflector",
776
+ "756": "rain barrel",
777
+ "757": "recreational vehicle, RV, R.V.",
778
+ "758": "reel",
779
+ "759": "reflex camera",
780
+ "760": "refrigerator, icebox",
781
+ "761": "remote control, remote",
782
+ "762": "restaurant, eating house, eating place, eatery",
783
+ "763": "revolver, six-gun, six-shooter",
784
+ "764": "rifle",
785
+ "765": "rocking chair, rocker",
786
+ "766": "rotisserie",
787
+ "767": "rubber eraser, rubber, pencil eraser",
788
+ "768": "rugby ball",
789
+ "769": "rule, ruler",
790
+ "770": "running shoe",
791
+ "771": "safe",
792
+ "772": "safety pin",
793
+ "773": "saltshaker, salt shaker",
794
+ "774": "sandal",
795
+ "775": "sarong",
796
+ "776": "sax, saxophone",
797
+ "777": "scabbard",
798
+ "778": "scale, weighing machine",
799
+ "779": "school bus",
800
+ "780": "schooner",
801
+ "781": "scoreboard",
802
+ "782": "screen, CRT screen",
803
+ "783": "screw",
804
+ "784": "screwdriver",
805
+ "785": "seat belt, seatbelt",
806
+ "786": "sewing machine",
807
+ "787": "shield, buckler",
808
+ "788": "shoe shop, shoe-shop, shoe store",
809
+ "789": "shoji",
810
+ "790": "shopping basket",
811
+ "791": "shopping cart",
812
+ "792": "shovel",
813
+ "793": "shower cap",
814
+ "794": "shower curtain",
815
+ "795": "ski",
816
+ "796": "ski mask",
817
+ "797": "sleeping bag",
818
+ "798": "slide rule, slipstick",
819
+ "799": "sliding door",
820
+ "800": "slot, one-armed bandit",
821
+ "801": "snorkel",
822
+ "802": "snowmobile",
823
+ "803": "snowplow, snowplough",
824
+ "804": "soap dispenser",
825
+ "805": "soccer ball",
826
+ "806": "sock",
827
+ "807": "solar dish, solar collector, solar furnace",
828
+ "808": "sombrero",
829
+ "809": "soup bowl",
830
+ "810": "space bar",
831
+ "811": "space heater",
832
+ "812": "space shuttle",
833
+ "813": "spatula",
834
+ "814": "speedboat",
835
+ "815": "spider web, spiders web",
836
+ "816": "spindle",
837
+ "817": "sports car, sport car",
838
+ "818": "spotlight, spot",
839
+ "819": "stage",
840
+ "820": "steam locomotive",
841
+ "821": "steel arch bridge",
842
+ "822": "steel drum",
843
+ "823": "stethoscope",
844
+ "824": "stole",
845
+ "825": "stone wall",
846
+ "826": "stopwatch, stop watch",
847
+ "827": "stove",
848
+ "828": "strainer",
849
+ "829": "streetcar, tram, tramcar, trolley, trolley car",
850
+ "830": "stretcher",
851
+ "831": "studio couch, day bed",
852
+ "832": "stupa, tope",
853
+ "833": "submarine, pigboat, sub, U-boat",
854
+ "834": "suit, suit of clothes",
855
+ "835": "sundial",
856
+ "836": "sunglass",
857
+ "837": "sunglasses, dark glasses, shades",
858
+ "838": "sunscreen, sunblock, sun blocker",
859
+ "839": "suspension bridge",
860
+ "840": "swab, swob, mop",
861
+ "841": "sweatshirt",
862
+ "842": "swimming trunks, bathing trunks",
863
+ "843": "swing",
864
+ "844": "switch, electric switch, electrical switch",
865
+ "845": "syringe",
866
+ "846": "table lamp",
867
+ "847": "tank, army tank, armored combat vehicle, armoured combat vehicle",
868
+ "848": "tape player",
869
+ "849": "teapot",
870
+ "850": "teddy, teddy bear",
871
+ "851": "television, television system",
872
+ "852": "tennis ball",
873
+ "853": "thatch, thatched roof",
874
+ "854": "theater curtain, theatre curtain",
875
+ "855": "thimble",
876
+ "856": "thresher, thrasher, threshing machine",
877
+ "857": "throne",
878
+ "858": "tile roof",
879
+ "859": "toaster",
880
+ "860": "tobacco shop, tobacconist shop, tobacconist",
881
+ "861": "toilet seat",
882
+ "862": "torch",
883
+ "863": "totem pole",
884
+ "864": "tow truck, tow car, wrecker",
885
+ "865": "toyshop",
886
+ "866": "tractor",
887
+ "867": "trailer truck, tractor trailer, trucking rig, rig, articulated lorry, semi",
888
+ "868": "tray",
889
+ "869": "trench coat",
890
+ "870": "tricycle, trike, velocipede",
891
+ "871": "trimaran",
892
+ "872": "tripod",
893
+ "873": "triumphal arch",
894
+ "874": "trolleybus, trolley coach, trackless trolley",
895
+ "875": "trombone",
896
+ "876": "tub, vat",
897
+ "877": "turnstile",
898
+ "878": "typewriter keyboard",
899
+ "879": "umbrella",
900
+ "880": "unicycle, monocycle",
901
+ "881": "upright, upright piano",
902
+ "882": "vacuum, vacuum cleaner",
903
+ "883": "vase",
904
+ "884": "vault",
905
+ "885": "velvet",
906
+ "886": "vending machine",
907
+ "887": "vestment",
908
+ "888": "viaduct",
909
+ "889": "violin, fiddle",
910
+ "890": "volleyball",
911
+ "891": "waffle iron",
912
+ "892": "wall clock",
913
+ "893": "wallet, billfold, notecase, pocketbook",
914
+ "894": "wardrobe, closet, press",
915
+ "895": "warplane, military plane",
916
+ "896": "washbasin, handbasin, washbowl, lavabo, wash-hand basin",
917
+ "897": "washer, automatic washer, washing machine",
918
+ "898": "water bottle",
919
+ "899": "water jug",
920
+ "900": "water tower",
921
+ "901": "whiskey jug",
922
+ "902": "whistle",
923
+ "903": "wig",
924
+ "904": "window screen",
925
+ "905": "window shade",
926
+ "906": "Windsor tie",
927
+ "907": "wine bottle",
928
+ "908": "wing",
929
+ "909": "wok",
930
+ "910": "wooden spoon",
931
+ "911": "wool, woolen, woollen",
932
+ "912": "worm fence, snake fence, snake-rail fence, Virginia fence",
933
+ "913": "wreck",
934
+ "914": "yawl",
935
+ "915": "yurt",
936
+ "916": "web site, website, internet site, site",
937
+ "917": "comic book",
938
+ "918": "crossword puzzle, crossword",
939
+ "919": "street sign",
940
+ "920": "traffic light, traffic signal, stoplight",
941
+ "921": "book jacket, dust cover, dust jacket, dust wrapper",
942
+ "922": "menu",
943
+ "923": "plate",
944
+ "924": "guacamole",
945
+ "925": "consomme",
946
+ "926": "hot pot, hotpot",
947
+ "927": "trifle",
948
+ "928": "ice cream, icecream",
949
+ "929": "ice lolly, lolly, lollipop, popsicle",
950
+ "930": "French loaf",
951
+ "931": "bagel, beigel",
952
+ "932": "pretzel",
953
+ "933": "cheeseburger",
954
+ "934": "hotdog, hot dog, red hot",
955
+ "935": "mashed potato",
956
+ "936": "head cabbage",
957
+ "937": "broccoli",
958
+ "938": "cauliflower",
959
+ "939": "zucchini, courgette",
960
+ "940": "spaghetti squash",
961
+ "941": "acorn squash",
962
+ "942": "butternut squash",
963
+ "943": "cucumber, cuke",
964
+ "944": "artichoke, globe artichoke",
965
+ "945": "bell pepper",
966
+ "946": "cardoon",
967
+ "947": "mushroom",
968
+ "948": "Granny Smith",
969
+ "949": "strawberry",
970
+ "950": "orange",
971
+ "951": "lemon",
972
+ "952": "fig",
973
+ "953": "pineapple, ananas",
974
+ "954": "banana",
975
+ "955": "jackfruit, jak, jack",
976
+ "956": "custard apple",
977
+ "957": "pomegranate",
978
+ "958": "hay",
979
+ "959": "carbonara",
980
+ "960": "chocolate sauce, chocolate syrup",
981
+ "961": "dough",
982
+ "962": "meat loaf, meatloaf",
983
+ "963": "pizza, pizza pie",
984
+ "964": "potpie",
985
+ "965": "burrito",
986
+ "966": "red wine",
987
+ "967": "espresso",
988
+ "968": "cup",
989
+ "969": "eggnog",
990
+ "970": "alp",
991
+ "971": "bubble",
992
+ "972": "cliff, drop, drop-off",
993
+ "973": "coral reef",
994
+ "974": "geyser",
995
+ "975": "lakeside, lakeshore",
996
+ "976": "promontory, headland, head, foreland",
997
+ "977": "sandbar, sand bar",
998
+ "978": "seashore, coast, seacoast, sea-coast",
999
+ "979": "valley, vale",
1000
+ "980": "volcano",
1001
+ "981": "ballplayer, baseball player",
1002
+ "982": "groom, bridegroom",
1003
+ "983": "scuba diver",
1004
+ "984": "rapeseed",
1005
+ "985": "daisy",
1006
+ "986": "yellow ladys slipper, yellow lady-slipper, Cypripedium calceolus, Cypripedium parviflorum",
1007
+ "987": "corn",
1008
+ "988": "acorn",
1009
+ "989": "hip, rose hip, rosehip",
1010
+ "990": "buckeye, horse chestnut, conker",
1011
+ "991": "coral fungus",
1012
+ "992": "agaric",
1013
+ "993": "gyromitra",
1014
+ "994": "stinkhorn, carrion fungus",
1015
+ "995": "earthstar",
1016
+ "996": "hen-of-the-woods, hen of the woods, Polyporus frondosus, Grifola frondosa",
1017
+ "997": "bolete",
1018
+ "998": "ear, spike, capitulum",
1019
+ "999": "toilet tissue, toilet paper, bathroom tissue"
1020
+ }
1021
+ }
W-Flow-XL/pipeline.py ADDED
@@ -0,0 +1,754 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2026 The HuggingFace Team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import importlib.util
16
+ import inspect
17
+ import json
18
+ import sys
19
+ from pathlib import Path
20
+ from typing import Any, Callable
21
+
22
+ import torch
23
+ from diffusers.callbacks import MultiPipelineCallbacks, PipelineCallback
24
+ from diffusers.models.autoencoders.autoencoder_kl import AutoencoderKL
25
+ from diffusers.models.modeling_utils import ModelMixin
26
+ from diffusers.pipelines.pipeline_utils import DiffusionPipeline, ImagePipelineOutput
27
+ from diffusers.schedulers import KarrasDiffusionSchedulers
28
+ from diffusers.schedulers.scheduling_utils import SchedulerMixin
29
+ from diffusers.utils import deprecate, is_torch_xla_available, logging, replace_example_docstring
30
+ from PIL import Image
31
+
32
+ if is_torch_xla_available():
33
+ import torch_xla.core.xla_model as xm
34
+
35
+ XLA_AVAILABLE = True
36
+ else:
37
+ XLA_AVAILABLE = False
38
+
39
+ logger = logging.get_logger(__name__)
40
+
41
+ EXAMPLE_DOC_STRING = """
42
+ Examples:
43
+ ```py
44
+ >>> from pathlib import Path
45
+ >>> import torch
46
+ >>> from diffusers import DiffusionPipeline
47
+
48
+ >>> model_dir = Path("W-Flow-diffusers/W-Flow-XL").resolve()
49
+ >>> pipe = DiffusionPipeline.from_pretrained(
50
+ ... str(model_dir),
51
+ ... local_files_only=True,
52
+ ... custom_pipeline=str(model_dir / "pipeline.py"),
53
+ ... trust_remote_code=True,
54
+ ... torch_dtype=torch.bfloat16,
55
+ ... ).to("cuda")
56
+
57
+ >>> image = pipe(
58
+ ... class_labels="golden retriever",
59
+ ... num_inference_steps=1,
60
+ ... guidance_scale=1.09,
61
+ ... generator=torch.Generator(device="cuda").manual_seed(1),
62
+ ... ).images[0]
63
+ >>> image.save("demo.png")
64
+
65
+ >>> # Hugging Face Hub style model id: UserID/RepoID
66
+ >>> # pipe = DiffusionPipeline.from_pretrained(
67
+ >>> # "BiliSakura/W-Flow-diffusers",
68
+ >>> # subfolder="W-Flow-XL",
69
+ >>> # custom_pipeline="pipeline.py",
70
+ >>> # trust_remote_code=True,
71
+ >>> # torch_dtype=torch.bfloat16,
72
+ >>> # )
73
+ ```
74
+ """
75
+
76
+
77
+ class WFlowPipeline(DiffusionPipeline):
78
+ r"""
79
+ Class-conditional one-step pipeline for W-Flow.
80
+
81
+ W-Flow maps SD-VAE latent noise to a clean 32×32 latent in one forward pass, then decodes it
82
+ with `stabilityai/sd-vae-ft-mse` to a 256×256 image. Guidance is embedded in the generator
83
+ (the official `cfg_scale`, which is `w + 1` in the paper). There is no unconditional class
84
+ and no second forward.
85
+
86
+ The pipeline inherits from [`DiffusionPipeline`]. Check the superclass documentation for the
87
+ generic methods (download, save, device placement, CPU offload).
88
+
89
+ Args:
90
+ transformer ([`ModelMixin`]):
91
+ [`WFlowTransformer2DModel`] that predicts the clean latent.
92
+ vae ([`AutoencoderKL`]):
93
+ SD-VAE decoder. Released checkpoints use `stabilityai/sd-vae-ft-mse` and scaling 0.18215.
94
+ scheduler ([`WFlowScheduler`]):
95
+ One-step scheduler. Loaded from `scheduler/`.
96
+ id2label (`dict[int, str]`, *optional*):
97
+ ImageNet class id to English label mapping. Values may contain comma-separated synonyms.
98
+ Loaded from `model_index.json` when omitted.
99
+
100
+ The default guidance scale lives on `transformer.config.guidance_scale`.
101
+ """
102
+
103
+ model_cpu_offload_seq = "transformer->vae"
104
+ _callback_tensor_inputs = ["latents"]
105
+
106
+ def __init__(
107
+ self,
108
+ transformer: ModelMixin,
109
+ vae: AutoencoderKL,
110
+ scheduler: SchedulerMixin,
111
+ id2label: dict[int, str] | dict[str, str] | None = None,
112
+ ):
113
+ super().__init__()
114
+ if scheduler is None:
115
+ scheduler = self._default_scheduler()
116
+ self._reject_karras_scheduler(scheduler)
117
+ self.register_modules(transformer=transformer, vae=vae, scheduler=scheduler)
118
+ normalized_labels = self._normalize_id2label(id2label)
119
+ self.register_to_config(id2label={str(key): value for key, value in normalized_labels.items()})
120
+ self._id2label = normalized_labels
121
+ self.labels = self._build_label2id(self._id2label)
122
+ self._labels_loaded_from_model_index = bool(self._id2label)
123
+ self.vae_scale_factor = 2 ** (len(self.vae.config.block_out_channels) - 1)
124
+
125
+ def _sampling_default(self, name: str, fallback: float) -> float:
126
+ r"""
127
+ Read a sampling default from the transformer config.
128
+
129
+ Args:
130
+ name (`str`):
131
+ Key on `transformer.config`, such as `guidance_scale`.
132
+ fallback (`float`):
133
+ Value used when the transformer config does not define `name`.
134
+
135
+ Returns:
136
+ `float`: The configured value, or `fallback`.
137
+ """
138
+ value = getattr(self.transformer.config, name, None)
139
+ if value is None:
140
+ return fallback
141
+ return value
142
+
143
+ @staticmethod
144
+ def _reject_karras_scheduler(scheduler: SchedulerMixin) -> None:
145
+ r"""
146
+ Reject multi-step Karras schedulers.
147
+
148
+ W-Flow predicts the clean latent in one evaluation and has no diffusion timestep, so a
149
+ Karras noise schedule cannot be integrated.
150
+
151
+ Args:
152
+ scheduler ([`SchedulerMixin`]):
153
+ Scheduler attached to the pipeline.
154
+ """
155
+ scheduler_name = scheduler.__class__.__name__
156
+ if scheduler_name in KarrasDiffusionSchedulers.__members__:
157
+ raise TypeError(
158
+ "W-Flow is a one-step generator and does not integrate a Karras noise schedule. "
159
+ f"Received {scheduler_name}. Use WFlowScheduler."
160
+ )
161
+
162
+ @staticmethod
163
+ def _default_scheduler() -> SchedulerMixin:
164
+ r"""
165
+ Build [`WFlowScheduler`] from the variant directory.
166
+
167
+ Returns:
168
+ [`WFlowScheduler`]: One-step sample scheduler.
169
+ """
170
+ module_path = Path(__file__).resolve().parent / "scheduler" / "scheduling_wflow.py"
171
+ spec = importlib.util.spec_from_file_location("scheduling_wflow", module_path)
172
+ if spec is None or spec.loader is None:
173
+ raise ImportError(f"Could not load the W-Flow scheduler from {module_path}.")
174
+ module = importlib.util.module_from_spec(spec)
175
+ sys.modules["scheduling_wflow"] = module
176
+ spec.loader.exec_module(module)
177
+ return module.WFlowScheduler()
178
+
179
+ def _ensure_labels_loaded(self) -> None:
180
+ r"""
181
+ Fill `id2label` from `model_index.json` when the constructor did not receive it.
182
+ """
183
+ if self._labels_loaded_from_model_index:
184
+ return
185
+ loaded = self._read_id2label_from_model_index(getattr(self.config, "_name_or_path", None))
186
+ if loaded:
187
+ self._id2label = loaded
188
+ self.labels = self._build_label2id(self._id2label)
189
+ self._labels_loaded_from_model_index = True
190
+
191
+ @staticmethod
192
+ def _normalize_id2label(id2label: dict[int, str] | dict[str, str] | None) -> dict[int, str]:
193
+ r"""
194
+ Cast label-map keys to integers.
195
+
196
+ Args:
197
+ id2label (`dict`, *optional*):
198
+ Class id to English label. Keys may be strings, which is how JSON stores them.
199
+
200
+ Returns:
201
+ `dict[int, str]`: Integer-keyed map. Empty when `id2label` is missing.
202
+ """
203
+ if not id2label:
204
+ return {}
205
+ return {int(key): value for key, value in id2label.items()}
206
+
207
+ @staticmethod
208
+ def _read_id2label_from_model_index(variant_path: str | None) -> dict[int, str]:
209
+ r"""
210
+ Read `id2label` from a local variant directory.
211
+
212
+ Args:
213
+ variant_path (`str`, *optional*):
214
+ Directory that contains `model_index.json`.
215
+
216
+ Returns:
217
+ `dict[int, str]`: Loaded map, or an empty dict when the file or key is absent.
218
+ """
219
+ if not variant_path:
220
+ return {}
221
+ model_index_path = Path(variant_path).resolve() / "model_index.json"
222
+ if not model_index_path.exists():
223
+ return {}
224
+ raw = json.loads(model_index_path.read_text(encoding="utf-8"))
225
+ id2label = raw.get("id2label")
226
+ if not isinstance(id2label, dict):
227
+ return {}
228
+ return {int(key): value for key, value in id2label.items()}
229
+
230
+ @staticmethod
231
+ def _build_label2id(id2label: dict[int, str]) -> dict[str, int]:
232
+ r"""
233
+ Invert `id2label`, splitting comma-separated synonyms.
234
+
235
+ Args:
236
+ id2label (`dict[int, str]`):
237
+ Class id to one or more English names.
238
+
239
+ Returns:
240
+ `dict[str, int]`: Synonym to class id, sorted by synonym.
241
+ """
242
+ label2id: dict[str, int] = {}
243
+ for class_id, value in id2label.items():
244
+ for synonym in value.split(","):
245
+ synonym = synonym.strip()
246
+ if synonym:
247
+ label2id[synonym] = int(class_id)
248
+ return dict(sorted(label2id.items()))
249
+
250
+ @property
251
+ def interrupt(self) -> bool:
252
+ r"""
253
+ Whether the current call was asked to stop.
254
+
255
+ Returns:
256
+ `bool`: The `_interrupt` flag. `__call__` sets it to `False` at the start. Assign
257
+ `_interrupt = True` during a call to skip the remaining forward.
258
+ """
259
+ return self._interrupt
260
+
261
+ @property
262
+ def id2label(self) -> dict[int, str]:
263
+ r"""
264
+ ImageNet id to English label map.
265
+
266
+ Returns:
267
+ `dict[int, str]`: The map loaded from the constructor or `model_index.json`.
268
+ """
269
+ self._ensure_labels_loaded()
270
+ return self._id2label
271
+
272
+ def get_label_ids(self, label: str | list[str]) -> list[int]:
273
+ r"""
274
+ Map ImageNet English labels to class ids.
275
+
276
+ Args:
277
+ label (`str` or `list[str]`):
278
+ One label or a list of labels. Each string must match a synonym in `id2label`
279
+ after stripping whitespace. Synonyms are the comma-separated pieces of each value.
280
+
281
+ Returns:
282
+ `list[int]`: Class ids in the same order as `label`.
283
+ """
284
+ self._ensure_labels_loaded()
285
+ label2id = self.labels
286
+ if not label2id:
287
+ raise ValueError("No English labels loaded. Ensure `id2label` exists in model_index.json.")
288
+ if isinstance(label, str):
289
+ label = [label]
290
+ missing = [item for item in label if item not in label2id]
291
+ if missing:
292
+ preview = ", ".join(list(label2id.keys())[:8])
293
+ raise ValueError(f"Unknown English label(s): {missing}. Example valid labels: {preview}, ...")
294
+ return [label2id[item] for item in label]
295
+
296
+ def _normalize_class_labels(self, class_labels: int | str | list[int | str]) -> list[int]:
297
+ r"""
298
+ Turn a class-label argument into a list of integer ids.
299
+
300
+ Args:
301
+ class_labels (`int`, `str`, or `list`):
302
+ One id, one English label, or a list of either. A list must not mix types.
303
+
304
+ Returns:
305
+ `list[int]`: One id per requested image.
306
+ """
307
+ if isinstance(class_labels, int):
308
+ return [class_labels]
309
+ if isinstance(class_labels, str):
310
+ return self.get_label_ids(class_labels)
311
+ if len(class_labels) == 0:
312
+ raise ValueError("`class_labels` must contain at least one class id or label.")
313
+ if isinstance(class_labels[0], str):
314
+ if not all(isinstance(item, str) for item in class_labels):
315
+ raise TypeError("`class_labels` must be all strings or all integers.")
316
+ return self.get_label_ids(class_labels)
317
+ if not all(isinstance(item, int) for item in class_labels):
318
+ raise TypeError("`class_labels` must be all strings or all integers.")
319
+ return list(class_labels)
320
+
321
+ def prepare_extra_step_kwargs(
322
+ self,
323
+ generator: torch.Generator | list[torch.Generator] | None,
324
+ eta: float,
325
+ ) -> dict[str, Any]:
326
+ r"""
327
+ Extra arguments forwarded to `scheduler.step`, depending on what that method accepts.
328
+
329
+ Args:
330
+ generator (`torch.Generator` or `list[torch.Generator]`, *optional*):
331
+ Generator passed through when the scheduler step samples noise.
332
+ eta (`float`):
333
+ DDIM eta in `[0, 1]`. Ignored by [`WFlowScheduler`], whose `step` has no `eta` argument.
334
+
335
+ Returns:
336
+ `dict`: Keyword arguments for `scheduler.step`.
337
+ """
338
+ extra_step_kwargs: dict[str, Any] = {}
339
+ step_params = set(inspect.signature(self.scheduler.step).parameters.keys())
340
+ if "eta" in step_params:
341
+ extra_step_kwargs["eta"] = eta
342
+ if "generator" in step_params:
343
+ extra_step_kwargs["generator"] = generator
344
+ return extra_step_kwargs
345
+
346
+ def check_inputs(
347
+ self,
348
+ class_labels: int | str | list[int | str],
349
+ height: int,
350
+ width: int,
351
+ num_inference_steps: int,
352
+ guidance_scale: float,
353
+ noise_scale: float,
354
+ output_type: str,
355
+ callback_steps: int | None = None,
356
+ callback_on_step_end_tensor_inputs: list[str] | None = None,
357
+ ) -> None:
358
+ r"""
359
+ Reject arguments that the generator cannot run.
360
+
361
+ Args:
362
+ class_labels (`int`, `str`, or `list`):
363
+ Class ids or English labels. A list must be non-empty.
364
+ height (`int`):
365
+ Output height in pixels. Must be the pretrained resolution, 256.
366
+ width (`int`):
367
+ Output width in pixels. Must be the pretrained resolution, 256.
368
+ num_inference_steps (`int`):
369
+ Must be 1. W-Flow evaluates the network once.
370
+ guidance_scale (`float`):
371
+ Embedded guidance (`w + 1` in the paper). Must be finite and positive.
372
+ noise_scale (`float`):
373
+ Scale of the reference Gaussian, the official `temp`. Must be positive.
374
+ output_type (`str`):
375
+ One of `"pil"`, `"np"`, `"pt"`, `"latent"`.
376
+ callback_steps (`int`, *optional*):
377
+ Deprecated callback period. When set, must be a positive integer.
378
+ callback_on_step_end_tensor_inputs (`list[str]`, *optional*):
379
+ Tensor names the step callback may read. Each name must be in `_callback_tensor_inputs`.
380
+ """
381
+ if isinstance(class_labels, list) and len(class_labels) == 0:
382
+ raise ValueError("`class_labels` must contain at least one class id or label.")
383
+ native = int(self.transformer.config.sample_size) * int(self.vae_scale_factor)
384
+ if height != native or width != native:
385
+ raise ValueError(
386
+ f"`height` and `width` must be the pretrained resolution {native}. "
387
+ f"The patch embedding is fixed to a {self.transformer.config.sample_size} latent. Got {(height, width)}."
388
+ )
389
+ if num_inference_steps != 1:
390
+ raise ValueError(
391
+ "W-Flow generates in one forward pass. "
392
+ f"`num_inference_steps` must be 1, got {num_inference_steps}."
393
+ )
394
+ if not torch.isfinite(torch.tensor(float(guidance_scale))) or float(guidance_scale) <= 0:
395
+ raise ValueError(f"`guidance_scale` must be finite and positive, got {guidance_scale}.")
396
+ if noise_scale <= 0:
397
+ raise ValueError(f"`noise_scale` must be positive, got {noise_scale}.")
398
+ if output_type not in {"pil", "np", "pt", "latent"}:
399
+ raise ValueError(f"Unsupported `output_type` {output_type!r}. Choose from 'pil', 'np', 'pt', 'latent'.")
400
+ if callback_steps is not None and (not isinstance(callback_steps, int) or callback_steps < 1):
401
+ raise ValueError(f"`callback_steps` must be a positive integer, got {callback_steps}.")
402
+ if callback_on_step_end_tensor_inputs is not None:
403
+ unknown = [name for name in callback_on_step_end_tensor_inputs if name not in self._callback_tensor_inputs]
404
+ if unknown:
405
+ raise ValueError(
406
+ f"`callback_on_step_end_tensor_inputs` contains {unknown}, which are not in "
407
+ f"{self._callback_tensor_inputs}."
408
+ )
409
+
410
+ def prepare_latents(
411
+ self,
412
+ batch_size: int,
413
+ num_channels: int,
414
+ height: int,
415
+ width: int,
416
+ device: torch.device,
417
+ generator: torch.Generator | list[torch.Generator] | None,
418
+ latents: torch.Tensor | None,
419
+ noise_labels: torch.Tensor | None,
420
+ noise_scale: float,
421
+ ) -> tuple[torch.Tensor, torch.Tensor]:
422
+ r"""
423
+ Draw reference noise in the official generator order.
424
+
425
+ The official sampler draws `(batch, height, width, channels)` first, then integer noise
426
+ codes, from the same generator. This method follows that order so a seeded generator
427
+ matches `DitGen.forward`.
428
+
429
+ Args:
430
+ batch_size (`int`):
431
+ Number of images.
432
+ num_channels (`int`):
433
+ Latent channels. Released checkpoints use 4.
434
+ height (`int`):
435
+ Latent height. Released checkpoints use 32.
436
+ width (`int`):
437
+ Latent width. Released checkpoints use 32.
438
+ device (`torch.device`):
439
+ Device of the returned tensors.
440
+ generator (`torch.Generator` or `list[torch.Generator]`, *optional*):
441
+ RNG. A list must have one generator per image. Each generator is consumed in the
442
+ order Gaussian noise, then noise codes.
443
+ latents (`torch.Tensor`, *optional*):
444
+ Reference noise `(batch, channels, height, width)`. When set, it is not rescaled.
445
+ noise_labels (`torch.Tensor`, *optional*):
446
+ Integer codes `(batch, noise_coords)`. When omitted, they are drawn here.
447
+ noise_scale (`float`):
448
+ Multiplier on the Gaussian, the official `temp`. Ignored when `latents` is passed.
449
+
450
+ Returns:
451
+ `tuple[torch.Tensor, torch.Tensor]`:
452
+ Reference noise in BCHW float32, and noise codes `(batch, noise_coords)`.
453
+ """
454
+ noise_classes = int(self.transformer.config.noise_classes)
455
+ noise_coords = int(self.transformer.config.noise_coords)
456
+ if latents is None:
457
+ if isinstance(generator, list):
458
+ if len(generator) != batch_size:
459
+ raise ValueError(f"Got {len(generator)} generators for a batch of {batch_size}.")
460
+ pieces = [
461
+ torch.randn((1, height, width, num_channels), generator=one, device=device) for one in generator
462
+ ]
463
+ drawn = torch.cat(pieces, dim=0)
464
+ else:
465
+ drawn = torch.randn(
466
+ (batch_size, height, width, num_channels),
467
+ generator=generator,
468
+ device=device,
469
+ )
470
+ latents = drawn.permute(0, 3, 1, 2).contiguous() * float(noise_scale)
471
+ elif latents.shape != (batch_size, num_channels, height, width):
472
+ raise ValueError(
473
+ f"`latents` must have shape {(batch_size, num_channels, height, width)}, got {tuple(latents.shape)}."
474
+ )
475
+ else:
476
+ latents = latents.to(device=device)
477
+
478
+ if noise_labels is None:
479
+ if isinstance(generator, list) and latents is not None:
480
+ # When latents were supplied, generators have not been consumed yet only if the
481
+ # caller passed both. Drawing labels still uses those generators.
482
+ codes = [
483
+ torch.randint(0, noise_classes, (1, noise_coords), generator=one, device=device)
484
+ for one in generator
485
+ ]
486
+ noise_labels = torch.cat(codes, dim=0)
487
+ else:
488
+ noise_labels = torch.randint(
489
+ 0,
490
+ max(1, noise_classes),
491
+ (batch_size, max(1, noise_coords)),
492
+ generator=None if isinstance(generator, list) else generator,
493
+ device=device,
494
+ )
495
+ noise_labels = noise_labels.to(device=device, dtype=torch.long)
496
+ if noise_labels.shape != (batch_size, noise_coords):
497
+ raise ValueError(
498
+ f"`noise_labels` must have shape {(batch_size, noise_coords)}, got {tuple(noise_labels.shape)}."
499
+ )
500
+ return latents.float(), noise_labels
501
+
502
+ def _prepare_scheduler(self, num_inference_steps: int, device: torch.device) -> torch.Tensor:
503
+ r"""
504
+ Install the one-step schedule and return its timesteps.
505
+
506
+ Args:
507
+ num_inference_steps (`int`):
508
+ Must be 1.
509
+ device (`torch.device`):
510
+ Device of the timestep tensor.
511
+
512
+ Returns:
513
+ `torch.Tensor`: The single timestep.
514
+ """
515
+ self.scheduler.set_timesteps(num_inference_steps, device=device)
516
+ return self.scheduler.timesteps
517
+
518
+ def _decode_latents(self, latents: torch.Tensor) -> torch.Tensor:
519
+ r"""
520
+ Decode scaled SD-VAE latents to pixels in `[-1, 1]`.
521
+
522
+ Args:
523
+ latents (`torch.Tensor`):
524
+ Clean latents `(batch, 4, 32, 32)` in the training scale (`* 0.18215`).
525
+
526
+ Returns:
527
+ `torch.Tensor`: Images `(batch, 3, height, width)` in `[-1, 1]`.
528
+ """
529
+ scaling = float(getattr(self.vae.config, "scaling_factor", 0.18215))
530
+ needs_upcast = bool(getattr(self.vae.config, "force_upcast", False)) and self.vae.dtype != torch.float32
531
+ original_dtype = self.vae.dtype
532
+ if needs_upcast:
533
+ self.vae.to(dtype=torch.float32)
534
+ decoded = self.vae.decode((latents / scaling).to(dtype=self.vae.dtype), return_dict=False)[0]
535
+ if needs_upcast:
536
+ self.vae.to(dtype=original_dtype)
537
+ return decoded
538
+
539
+ def _images_from_pixels(self, pixels: torch.Tensor, output_type: str) -> list[Image.Image] | torch.Tensor | list:
540
+ r"""
541
+ Convert decoded pixels to the requested output type.
542
+
543
+ Args:
544
+ pixels (`torch.Tensor`):
545
+ Images `(batch, 3, height, width)` in `[-1, 1]`.
546
+ output_type (`str`):
547
+ `"pil"`, `"np"`, `"pt"` (float RGB in `[0, 1]`), or `"latent"`.
548
+
549
+ Returns:
550
+ Images in the requested type.
551
+ """
552
+ images = ((pixels.float() + 1) / 2).clamp(0, 1)
553
+ if output_type == "pt":
554
+ return images
555
+ images = (images * 255).round().to(torch.uint8)
556
+ arrays = images.permute(0, 2, 3, 1).cpu().numpy()
557
+ if output_type == "np":
558
+ return arrays
559
+ return [Image.fromarray(image) for image in arrays]
560
+
561
+ @torch.no_grad()
562
+ @replace_example_docstring(EXAMPLE_DOC_STRING)
563
+ def __call__(
564
+ self,
565
+ class_labels: int | str | list[int | str],
566
+ height: int | None = None,
567
+ width: int | None = None,
568
+ num_inference_steps: int | None = None,
569
+ guidance_scale: float | None = None,
570
+ noise_scale: float = 1.0,
571
+ eta: float = 0.0,
572
+ generator: torch.Generator | list[torch.Generator] | None = None,
573
+ latents: torch.Tensor | None = None,
574
+ noise_labels: torch.Tensor | None = None,
575
+ output_type: str = "pil",
576
+ return_dict: bool = True,
577
+ callback_on_step_end: Callable[[int, int, dict], dict] | PipelineCallback | MultiPipelineCallbacks | None = None,
578
+ callback_on_step_end_tensor_inputs: list[str] | None = None,
579
+ **kwargs,
580
+ ) -> ImagePipelineOutput | tuple:
581
+ r"""
582
+ Generate images from ImageNet class labels.
583
+
584
+ Args:
585
+ class_labels (`int`, `str`, or `list`):
586
+ One ImageNet class id, one English label, or a list of either. English labels are
587
+ resolved with [`get_label_ids`]. The list length is the batch size.
588
+ height (`int`, *optional*):
589
+ Image height in pixels. Defaults to 256 (`sample_size * vae_scale_factor`). Other
590
+ sizes are rejected because the patch embedding is fixed.
591
+ width (`int`, *optional*):
592
+ Image width in pixels. Defaults to 256.
593
+ num_inference_steps (`int`, *optional*):
594
+ Must be 1. Defaults to `transformer.config.default_num_inference_steps`.
595
+ guidance_scale (`float`, *optional*):
596
+ Official CFG value, equal to `w + 1` in the paper. Defaults to
597
+ `transformer.config.guidance_scale` (1.19 / 1.14 / 1.09 / 1.5 by variant). This
598
+ scale is embedded; the pipeline does not run an unconditional branch.
599
+ noise_scale (`float`, defaults to 1.0):
600
+ Multiplier on the reference Gaussian. The official sampler calls this `temp`.
601
+ Ignored when `latents` is passed.
602
+ eta (`float`, defaults to 0.0):
603
+ DDIM eta. Ignored by [`WFlowScheduler`].
604
+ generator (`torch.Generator` or `list[torch.Generator]`, *optional*):
605
+ RNG for the reference noise and the discrete noise codes. One generator is consumed
606
+ in that order, matching the official sampler.
607
+ latents (`torch.Tensor`, *optional*):
608
+ Reference noise `(batch, 4, 32, 32)`. Not multiplied by `noise_scale`.
609
+ noise_labels (`torch.Tensor`, *optional*):
610
+ Discrete noise codes `(batch, noise_coords)`. Drawn from `generator` when omitted.
611
+ output_type (`str`, defaults to `"pil"`):
612
+ `"pil"`, `"np"`, `"pt"` (float RGB in `[0, 1]`), or `"latent"` (scaled SD-VAE latent).
613
+ return_dict (`bool`, defaults to `True`):
614
+ Return [`ImagePipelineOutput`] when `True`, otherwise a one-tuple of images.
615
+ callback_on_step_end (`Callable` or `PipelineCallback`, *optional*):
616
+ Called as `callback_on_step_end(pipeline, step, timestep, callback_kwargs)` after the
617
+ scheduler step. Return a dict to replace tensors listed in
618
+ `callback_on_step_end_tensor_inputs`.
619
+ callback_on_step_end_tensor_inputs (`list[str]`, *optional*):
620
+ Tensor names passed to the step callback. Defaults to `["latents"]`.
621
+
622
+ Examples:
623
+
624
+ Returns:
625
+ [`ImagePipelineOutput`] or `tuple`:
626
+ When `return_dict` is `True`, [`ImagePipelineOutput`] with the images. Otherwise a tuple
627
+ whose first element is the images.
628
+ """
629
+ callback = kwargs.pop("callback", None)
630
+ callback_steps = kwargs.pop("callback_steps", None)
631
+ if kwargs:
632
+ raise TypeError(f"Unexpected arguments: {sorted(kwargs)}.")
633
+ if callback_on_step_end_tensor_inputs is None:
634
+ callback_on_step_end_tensor_inputs = ["latents"]
635
+
636
+ if callback is not None:
637
+ deprecate(
638
+ "callback",
639
+ "1.0.0",
640
+ "Passing `callback` as an input argument to `__call__` is deprecated, consider using `callback_on_step_end`",
641
+ )
642
+ if callback_steps is not None:
643
+ deprecate(
644
+ "callback_steps",
645
+ "1.0.0",
646
+ "Passing `callback_steps` as an input argument to `__call__` is deprecated, consider using `callback_on_step_end`",
647
+ )
648
+ if isinstance(callback_on_step_end, (PipelineCallback, MultiPipelineCallbacks)):
649
+ callback_on_step_end_tensor_inputs = callback_on_step_end.tensor_inputs
650
+
651
+ image_size = int(self.transformer.config.sample_size) * int(self.vae_scale_factor)
652
+ height = image_size if height is None else int(height)
653
+ width = image_size if width is None else int(width)
654
+ if num_inference_steps is None:
655
+ num_inference_steps = int(self._sampling_default("default_num_inference_steps", 1))
656
+ if guidance_scale is None:
657
+ guidance_scale = float(self._sampling_default("guidance_scale", 1.0))
658
+
659
+ # 1. Check inputs.
660
+ self.check_inputs(
661
+ class_labels,
662
+ height,
663
+ width,
664
+ num_inference_steps,
665
+ guidance_scale,
666
+ noise_scale,
667
+ output_type,
668
+ callback_steps,
669
+ callback_on_step_end_tensor_inputs,
670
+ )
671
+
672
+ self._guidance_scale = float(guidance_scale)
673
+ self._interrupt = False
674
+
675
+ # 2. Define call parameters.
676
+ class_label_ids = self._normalize_class_labels(class_labels)
677
+ batch_size = len(class_label_ids)
678
+ device = self._execution_device
679
+ num_classes = int(self.transformer.config.num_classes)
680
+ if any(class_id < 0 or class_id >= num_classes for class_id in class_label_ids):
681
+ raise ValueError(f"Class ids must lie in [0, {num_classes}), got {class_label_ids}.")
682
+
683
+ # 3. Encode input condition (class ids; guidance is embedded inside the transformer).
684
+ class_labels_t = torch.tensor(class_label_ids, device=device, dtype=torch.long)
685
+
686
+ # 4. Prepare timesteps.
687
+ scheduled_timesteps = self._prepare_scheduler(num_inference_steps, device)
688
+
689
+ # 5. Prepare latent variables. Noise codes are drawn here so one generator matches DitGen.
690
+ latent_height = height // int(self.vae_scale_factor)
691
+ latent_width = width // int(self.vae_scale_factor)
692
+ latents, noise_labels = self.prepare_latents(
693
+ batch_size,
694
+ int(self.transformer.config.in_channels),
695
+ latent_height,
696
+ latent_width,
697
+ device,
698
+ generator,
699
+ latents,
700
+ noise_labels,
701
+ noise_scale,
702
+ )
703
+
704
+ # 6. Prepare extra step kwargs.
705
+ extra_step_kwargs = self.prepare_extra_step_kwargs(generator, eta)
706
+ num_warmup_steps = len(scheduled_timesteps) - num_inference_steps * self.scheduler.order
707
+ self._num_timesteps = len(scheduled_timesteps)
708
+
709
+ # 7. Denoising loop.
710
+ with self.progress_bar(total=num_inference_steps) as progress_bar:
711
+ for i, timestep in enumerate(scheduled_timesteps):
712
+ if self.interrupt:
713
+ continue
714
+
715
+ latent_model_input = self.scheduler.scale_model_input(latents, timestep)
716
+ model_output = self.transformer(
717
+ latent_model_input,
718
+ class_labels=class_labels_t,
719
+ guidance_scale=self._guidance_scale,
720
+ noise_labels=noise_labels,
721
+ return_dict=False,
722
+ )[0]
723
+ latents = self.scheduler.step(
724
+ model_output,
725
+ timestep,
726
+ latents,
727
+ **extra_step_kwargs,
728
+ return_dict=False,
729
+ )[0]
730
+
731
+ if callback_on_step_end is not None:
732
+ callback_kwargs = {key: locals()[key] for key in callback_on_step_end_tensor_inputs}
733
+ callback_outputs = callback_on_step_end(self, i, timestep, callback_kwargs)
734
+ latents = callback_outputs.pop("latents", latents)
735
+
736
+ if i == len(scheduled_timesteps) - 1 or (
737
+ (i + 1) > num_warmup_steps and (i + 1) % self.scheduler.order == 0
738
+ ):
739
+ progress_bar.update()
740
+ if callback is not None and i % callback_steps == 0:
741
+ callback(i, timestep, latents)
742
+
743
+ if XLA_AVAILABLE:
744
+ xm.mark_step()
745
+
746
+ if output_type == "latent":
747
+ images = latents
748
+ else:
749
+ images = self._images_from_pixels(self._decode_latents(latents), output_type)
750
+ self.maybe_free_model_hooks()
751
+
752
+ if not return_dict:
753
+ return (images,)
754
+ return ImagePipelineOutput(images=images)
W-Flow-XL/scheduler/scheduler_config.json ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ {
2
+ "_class_name": "WFlowScheduler",
3
+ "_diffusers_version": "0.39.0",
4
+ "num_train_timesteps": 1000,
5
+ "prediction_type": "sample"
6
+ }
W-Flow-XL/scheduler/scheduling_wflow.py ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2026 The HuggingFace Team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from dataclasses import dataclass
16
+
17
+ import torch
18
+ from diffusers.configuration_utils import ConfigMixin, register_to_config
19
+ from diffusers.schedulers.scheduling_utils import SchedulerMixin
20
+ from diffusers.utils import BaseOutput
21
+
22
+
23
+ @dataclass
24
+ class WFlowSchedulerOutput(BaseOutput):
25
+ r"""
26
+ Output of [`WFlowScheduler.step`].
27
+
28
+ Args:
29
+ prev_sample (`torch.Tensor`):
30
+ The model prediction. W-Flow returns the clean latent in one evaluation.
31
+ """
32
+
33
+ prev_sample: torch.Tensor
34
+
35
+
36
+ class WFlowScheduler(SchedulerMixin, ConfigMixin):
37
+ r"""
38
+ One-step scheduler for W-Flow.
39
+
40
+ The transformer predicts the clean latent directly. `set_timesteps` accepts a single evaluation,
41
+ and `step` returns that prediction. `scale_model_input` leaves the reference noise unchanged.
42
+ A Karras noise schedule does not apply: the network has no diffusion timestep.
43
+
44
+ Args:
45
+ num_train_timesteps (`int`, defaults to 1000):
46
+ Stored for config compatibility. W-Flow does not index it.
47
+ prediction_type (`str`, defaults to `"sample"`):
48
+ The model output is the clean sample.
49
+ """
50
+
51
+ order = 1
52
+ _compatibles: list[str] = []
53
+
54
+ @register_to_config
55
+ def __init__(
56
+ self,
57
+ num_train_timesteps: int = 1000,
58
+ prediction_type: str = "sample",
59
+ ):
60
+ if num_train_timesteps < 1:
61
+ raise ValueError(f"num_train_timesteps must be >= 1, got {num_train_timesteps}.")
62
+ if prediction_type != "sample":
63
+ raise ValueError(f"WFlowScheduler prediction_type must be 'sample', got {prediction_type!r}.")
64
+ self.timesteps: torch.Tensor | None = None
65
+ self.num_inference_steps: int | None = None
66
+ self._step_index: int | None = None
67
+
68
+ @property
69
+ def init_noise_sigma(self) -> float:
70
+ r"""
71
+ Scale of the standard normal used to start sampling.
72
+
73
+ Returns:
74
+ `float`: `1.0`. The pipeline multiplies this by `noise_scale`.
75
+ """
76
+ return 1.0
77
+
78
+ def scale_model_input(self, sample: torch.Tensor, timestep: float | torch.Tensor) -> torch.Tensor:
79
+ r"""
80
+ Return the sample unchanged.
81
+
82
+ Args:
83
+ sample (`torch.Tensor`):
84
+ Reference noise `(batch, channels, height, width)`.
85
+ timestep (`float` or `torch.Tensor`):
86
+ Unused. W-Flow has no diffusion timestep.
87
+
88
+ Returns:
89
+ `torch.Tensor`: `sample`.
90
+ """
91
+ del timestep
92
+ return sample
93
+
94
+ def set_timesteps(
95
+ self,
96
+ num_inference_steps: int,
97
+ device: str | torch.device | None = None,
98
+ ) -> None:
99
+ r"""
100
+ Install the single evaluation step.
101
+
102
+ Args:
103
+ num_inference_steps (`int`):
104
+ Must be 1. W-Flow generates the latent in one forward pass.
105
+ device (`str` or `torch.device`, *optional*):
106
+ Device of `self.timesteps`.
107
+ """
108
+ if num_inference_steps != 1:
109
+ raise ValueError(
110
+ "W-Flow generates in one forward pass. "
111
+ f"num_inference_steps must be 1, got {num_inference_steps}."
112
+ )
113
+ self.num_inference_steps = 1
114
+ self.timesteps = torch.tensor([0.0], device=device, dtype=torch.float32)
115
+ self._step_index = 0
116
+
117
+ def step(
118
+ self,
119
+ model_output: torch.Tensor,
120
+ timestep: float | torch.Tensor,
121
+ sample: torch.Tensor,
122
+ generator: torch.Generator | list[torch.Generator] | None = None,
123
+ return_dict: bool = True,
124
+ ) -> WFlowSchedulerOutput | tuple[torch.Tensor]:
125
+ r"""
126
+ Replace the reference noise with the predicted clean latent.
127
+
128
+ Args:
129
+ model_output (`torch.Tensor`):
130
+ Clean-latent prediction `(batch, channels, height, width)`.
131
+ timestep (`float` or `torch.Tensor`):
132
+ The single scheduled timestep. Accepted for the Diffusers step signature.
133
+ sample (`torch.Tensor`):
134
+ Current reference noise. Same shape as `model_output`.
135
+ generator (`torch.Generator` or `list[torch.Generator]`, *optional*):
136
+ Accepted so pipelines can pass it through. W-Flow does not draw noise in `step`.
137
+ return_dict (`bool`, defaults to `True`):
138
+ Return [`WFlowSchedulerOutput`] when `True`, otherwise a one-tuple.
139
+
140
+ Returns:
141
+ [`WFlowSchedulerOutput`] or `tuple`:
142
+ `prev_sample` is `model_output`.
143
+ """
144
+ del timestep, sample, generator
145
+ if self.timesteps is None:
146
+ raise ValueError("Call set_timesteps before step.")
147
+ if self._step_index is None or self._step_index > 0:
148
+ raise ValueError("WFlowScheduler has already consumed its single step. Call set_timesteps again.")
149
+ self._step_index = 1
150
+ if not return_dict:
151
+ return (model_output,)
152
+ return WFlowSchedulerOutput(prev_sample=model_output)
W-Flow-XL/transformer/config.json ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_class_name": "WFlowTransformer2DModel",
3
+ "_diffusers_version": "0.39.0",
4
+ "attn_fp32": false,
5
+ "cond_dim": 1152,
6
+ "default_num_inference_steps": 1,
7
+ "depth": 28,
8
+ "guidance_scale": 1.09,
9
+ "hidden_size": 1152,
10
+ "in_channels": 4,
11
+ "mlp_ratio": 4.0,
12
+ "model_type": "W-Flow-XL",
13
+ "n_cls_tokens": 16,
14
+ "noise_classes": 64,
15
+ "noise_coords": 32,
16
+ "num_attention_heads": 16,
17
+ "num_classes": 1000,
18
+ "out_channels": 4,
19
+ "patch_size": 2,
20
+ "sample_size": 32,
21
+ "use_bf16": true,
22
+ "use_qknorm": true,
23
+ "use_rmsnorm": true,
24
+ "use_rope": true,
25
+ "use_swiglu": true
26
+ }
W-Flow-XL/transformer/diffusion_pytorch_model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:bbaca21dc747096da7d30a87b5a8838d044eff0fea2e1fa886b72f061aba1a34
3
+ size 2715773096
W-Flow-XL/transformer/transformer_wflow.py ADDED
@@ -0,0 +1,720 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2026 The HuggingFace Team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import math
16
+ from dataclasses import dataclass
17
+
18
+ import numpy as np
19
+ import torch
20
+ import torch.nn as nn
21
+ from diffusers.configuration_utils import ConfigMixin, register_to_config
22
+ from diffusers.models.modeling_utils import ModelMixin
23
+ from diffusers.utils import BaseOutput
24
+
25
+
26
+ @dataclass
27
+ class WFlowTransformer2DModelOutput(BaseOutput):
28
+ r"""
29
+ Output of [`WFlowTransformer2DModel`].
30
+
31
+ Args:
32
+ sample (`torch.Tensor`):
33
+ Predicted SD-VAE latent of shape `(batch, channels, height, width)`. Values are in the
34
+ scaled latent space used at training time (`encoder_mean * 0.18215`).
35
+ """
36
+
37
+ sample: torch.Tensor
38
+
39
+
40
+ def _init_linear(linear: nn.Linear, weight_init: str = "xavier_uniform", bias_init: str = "zeros") -> None:
41
+ r"""
42
+ Initialize a linear layer the way the official generator does.
43
+
44
+ Args:
45
+ linear (`torch.nn.Linear`):
46
+ Layer to initialize in place.
47
+ weight_init (`str`, defaults to `"xavier_uniform"`):
48
+ `"xavier_uniform"`, `"zeros"`, or `"normal"` (std 0.02).
49
+ bias_init (`str`, defaults to `"zeros"`):
50
+ Bias fill. Only `"zeros"` is used by the released architecture.
51
+ """
52
+ if weight_init == "xavier_uniform":
53
+ nn.init.xavier_uniform_(linear.weight)
54
+ elif weight_init == "zeros":
55
+ nn.init.zeros_(linear.weight)
56
+ elif weight_init == "normal":
57
+ nn.init.normal_(linear.weight, std=0.02)
58
+ else:
59
+ raise ValueError(f"weight_init must be xavier_uniform, zeros, or normal, got {weight_init!r}.")
60
+ if linear.bias is not None:
61
+ if bias_init != "zeros":
62
+ raise ValueError(f"bias_init must be 'zeros', got {bias_init!r}.")
63
+ nn.init.zeros_(linear.bias)
64
+
65
+
66
+ class _TorchLinear(nn.Module):
67
+ r"""
68
+ Linear wrapper whose parameter names match the official `TorchLinear` (`*.linear.weight`).
69
+ """
70
+
71
+ def __init__(
72
+ self,
73
+ in_features: int,
74
+ out_features: int,
75
+ bias: bool = True,
76
+ weight_init: str = "xavier_uniform",
77
+ bias_init: str = "zeros",
78
+ ):
79
+ super().__init__()
80
+ self.linear = nn.Linear(in_features, out_features, bias=bias)
81
+ _init_linear(self.linear, weight_init=weight_init, bias_init=bias_init)
82
+
83
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
84
+ r"""
85
+ Apply the wrapped linear layer.
86
+
87
+ Args:
88
+ x (`torch.Tensor`):
89
+ Input of shape `(..., in_features)`.
90
+
91
+ Returns:
92
+ `torch.Tensor`: Output of shape `(..., out_features)`.
93
+ """
94
+ return self.linear(x)
95
+
96
+
97
+ class _RMSNorm(nn.Module):
98
+ def __init__(self, dim: int, eps: float = 1e-6):
99
+ super().__init__()
100
+ self.eps = float(eps)
101
+ self.weight = nn.Parameter(torch.ones(int(dim)))
102
+
103
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
104
+ r"""
105
+ Root-mean-square normalize the last dimension.
106
+
107
+ Args:
108
+ x (`torch.Tensor`):
109
+ Input of shape `(..., dim)`.
110
+
111
+ Returns:
112
+ `torch.Tensor`: Normalized tensor, same shape and dtype as `x`.
113
+ """
114
+ input_dtype = x.dtype
115
+ variance = x.float().pow(2).mean(dim=-1, keepdim=True)
116
+ normalized = x * torch.rsqrt(variance + self.eps)
117
+ return (normalized * self.weight).to(dtype=input_dtype)
118
+
119
+
120
+ def _modulate(x: torch.Tensor, shift: torch.Tensor, scale: torch.Tensor) -> torch.Tensor:
121
+ r"""
122
+ Apply an adaLN-Zero shift and scale.
123
+
124
+ Args:
125
+ x (`torch.Tensor`):
126
+ Token tensor `(batch, tokens, hidden)`.
127
+ shift (`torch.Tensor`):
128
+ Per-sample shift `(batch, hidden)`.
129
+ scale (`torch.Tensor`):
130
+ Per-sample scale `(batch, hidden)`.
131
+
132
+ Returns:
133
+ `torch.Tensor`: `x * (1 + scale) + shift`, broadcast over tokens.
134
+ """
135
+ return x * (1.0 + scale.unsqueeze(1)) + shift.unsqueeze(1)
136
+
137
+
138
+ def _sincos_1d(embed_dim: int, pos: np.ndarray) -> np.ndarray:
139
+ r"""
140
+ Sine-cosine embedding of 1-D positions.
141
+
142
+ Args:
143
+ embed_dim (`int`):
144
+ Even embedding width.
145
+ pos (`numpy.ndarray`):
146
+ Positions, flattened inside the function.
147
+
148
+ Returns:
149
+ `numpy.ndarray`: Array of shape `(positions, embed_dim)`.
150
+ """
151
+ if embed_dim % 2 != 0:
152
+ raise ValueError(f"embed_dim must be even, got {embed_dim}.")
153
+ omega = np.arange(embed_dim // 2, dtype=np.float64)
154
+ omega = 1.0 / 10000 ** (omega / (embed_dim / 2.0))
155
+ out = np.einsum("m,d->md", pos.reshape(-1), omega)
156
+ return np.concatenate([np.sin(out), np.cos(out)], axis=1)
157
+
158
+
159
+ def _sincos_2d(embed_dim: int, grid_size: int) -> np.ndarray:
160
+ r"""
161
+ Sine-cosine embedding of a square grid, matching the official generator.
162
+
163
+ Args:
164
+ embed_dim (`int`):
165
+ Full embedding width. Half is used for each axis.
166
+ grid_size (`int`):
167
+ Tokens along one side of the latent grid.
168
+
169
+ Returns:
170
+ `numpy.ndarray`: Array of shape `(grid_size * grid_size, embed_dim)`.
171
+ """
172
+ grid_h = np.arange(grid_size, dtype=np.float32)
173
+ grid_w = np.arange(grid_size, dtype=np.float32)
174
+ grid = np.stack(np.meshgrid(grid_w, grid_h), axis=0).reshape(2, 1, grid_size, grid_size)
175
+ half = embed_dim // 2
176
+ return np.concatenate([_sincos_1d(half, grid[0]), _sincos_1d(half, grid[1])], axis=1)
177
+
178
+
179
+ def _swiglu_hidden(hidden_size: int, mlp_ratio: float) -> int:
180
+ r"""
181
+ SwiGLU intermediate width used by the official blocks.
182
+
183
+ Args:
184
+ hidden_size (`int`):
185
+ Transformer width.
186
+ mlp_ratio (`float`):
187
+ Expansion ratio before the 2/3 SwiGLU reduction.
188
+
189
+ Returns:
190
+ `int`: Intermediate width, rounded up to a multiple of 32.
191
+ """
192
+ mlp_hidden = int(hidden_size * float(mlp_ratio))
193
+ hidden = int((2.0 / 3.0) * mlp_hidden)
194
+ return ((hidden + 31) // 32) * 32
195
+
196
+
197
+ class _StandardMLP(nn.Module):
198
+ def __init__(self, hidden_size: int, mlp_hidden_dim: int):
199
+ super().__init__()
200
+ self.fc1 = _TorchLinear(hidden_size, mlp_hidden_dim, bias=True)
201
+ self.fc2 = _TorchLinear(mlp_hidden_dim, hidden_size, bias=True)
202
+
203
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
204
+ r"""
205
+ GELU MLP.
206
+
207
+ Args:
208
+ x (`torch.Tensor`):
209
+ Input `(..., hidden_size)`.
210
+
211
+ Returns:
212
+ `torch.Tensor`: Output `(..., hidden_size)`.
213
+ """
214
+ return self.fc2(nn.functional.gelu(self.fc1(x), approximate="none"))
215
+
216
+
217
+ class _SwiGLUFFN(nn.Module):
218
+ def __init__(self, hidden_size: int, intermediate_size: int):
219
+ super().__init__()
220
+ self.w1 = _TorchLinear(hidden_size, intermediate_size, bias=True)
221
+ self.w3 = _TorchLinear(hidden_size, intermediate_size, bias=True)
222
+ self.w2 = _TorchLinear(intermediate_size, hidden_size, bias=True)
223
+
224
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
225
+ r"""
226
+ SwiGLU feed-forward.
227
+
228
+ Args:
229
+ x (`torch.Tensor`):
230
+ Input `(..., hidden_size)`.
231
+
232
+ Returns:
233
+ `torch.Tensor`: Output `(..., hidden_size)`.
234
+ """
235
+ return self.w2(nn.functional.silu(self.w1(x)) * self.w3(x))
236
+
237
+
238
+ class _Attention(nn.Module):
239
+ def __init__(
240
+ self,
241
+ dim: int,
242
+ num_heads: int,
243
+ qk_norm: bool,
244
+ use_rmsnorm: bool,
245
+ use_rope: bool,
246
+ attn_fp32: bool,
247
+ max_seq_len: int,
248
+ ):
249
+ super().__init__()
250
+ self.dim = int(dim)
251
+ self.num_heads = int(num_heads)
252
+ self.use_rope = bool(use_rope)
253
+ self.attn_fp32 = bool(attn_fp32)
254
+ self.qkv = _TorchLinear(self.dim, self.dim * 3, bias=True)
255
+ head_dim = self.dim // self.num_heads
256
+ if qk_norm:
257
+ if use_rmsnorm:
258
+ self.q_norm = _RMSNorm(head_dim)
259
+ self.k_norm = _RMSNorm(head_dim)
260
+ else:
261
+ self.q_norm = nn.LayerNorm(head_dim, eps=1e-6, elementwise_affine=True)
262
+ self.k_norm = nn.LayerNorm(head_dim, eps=1e-6, elementwise_affine=True)
263
+ else:
264
+ self.q_norm = None
265
+ self.k_norm = None
266
+ self.proj = _TorchLinear(self.dim, self.dim, bias=True)
267
+ if use_rope:
268
+ half_dim = head_dim // 2
269
+ freqs = 1.0 / (10000 ** (torch.arange(0, half_dim, dtype=torch.float32) / half_dim))
270
+ positions = torch.arange(max_seq_len, dtype=torch.float32)
271
+ emb = torch.cat([torch.outer(positions, freqs)] * 2, dim=-1)
272
+ self.register_buffer("_rope_cos", torch.cos(emb)[None, :, None, :], persistent=False)
273
+ self.register_buffer("_rope_sin", torch.sin(emb)[None, :, None, :], persistent=False)
274
+
275
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
276
+ r"""
277
+ Multi-head self-attention. Dropout is off, matching inference (`deterministic=True`).
278
+
279
+ Args:
280
+ x (`torch.Tensor`):
281
+ Tokens `(batch, tokens, hidden)`.
282
+
283
+ Returns:
284
+ `torch.Tensor`: Attention output `(batch, tokens, hidden)`.
285
+ """
286
+ batch, tokens, _channels = x.shape
287
+ head_dim = self.dim // self.num_heads
288
+ qkv = self.qkv(x).reshape(batch, tokens, 3, self.num_heads, head_dim)
289
+ query, key, value = qkv[:, :, 0], qkv[:, :, 1], qkv[:, :, 2]
290
+ if self.q_norm is not None:
291
+ query = self.q_norm(query)
292
+ key = self.k_norm(key)
293
+ if self.use_rope:
294
+ rope_dtype = torch.float32 if self.attn_fp32 else query.dtype
295
+ cos = self._rope_cos[:, :tokens].to(dtype=rope_dtype)
296
+ sin = self._rope_sin[:, :tokens].to(dtype=rope_dtype)
297
+ half_dim = head_dim // 2
298
+
299
+ def _rotate(tensor: torch.Tensor) -> torch.Tensor:
300
+ first, second = tensor[..., :half_dim], tensor[..., half_dim:]
301
+ return torch.cat([-second, first], dim=-1)
302
+
303
+ query = (query * cos) + (_rotate(query) * sin)
304
+ key = (key * cos) + (_rotate(key) * sin)
305
+ if self.attn_fp32:
306
+ query = query.float()
307
+ key = key.float()
308
+ value = value.float()
309
+ query = query.permute(0, 2, 1, 3)
310
+ key = key.permute(0, 2, 1, 3)
311
+ value = value.permute(0, 2, 1, 3)
312
+ if self.attn_fp32:
313
+ with torch.amp.autocast(device_type=query.device.type, enabled=False):
314
+ out = nn.functional.scaled_dot_product_attention(query, key, value, dropout_p=0.0)
315
+ else:
316
+ out = nn.functional.scaled_dot_product_attention(query, key, value, dropout_p=0.0)
317
+ out = out.permute(0, 2, 1, 3).reshape(batch, tokens, self.dim)
318
+ return self.proj(out)
319
+
320
+
321
+ class _DiTBlock(nn.Module):
322
+ def __init__(
323
+ self,
324
+ hidden_size: int,
325
+ num_heads: int,
326
+ mlp_ratio: float,
327
+ use_qknorm: bool,
328
+ use_swiglu: bool,
329
+ use_rmsnorm: bool,
330
+ use_rope: bool,
331
+ attn_fp32: bool,
332
+ max_seq_len: int,
333
+ ):
334
+ super().__init__()
335
+ self.hidden_size = int(hidden_size)
336
+ if use_rmsnorm:
337
+ self.norm1 = _RMSNorm(self.hidden_size)
338
+ self.norm2 = _RMSNorm(self.hidden_size)
339
+ else:
340
+ self.norm1 = nn.LayerNorm(self.hidden_size, eps=1e-6, elementwise_affine=False)
341
+ self.norm2 = nn.LayerNorm(self.hidden_size, eps=1e-6, elementwise_affine=False)
342
+ self.attn = _Attention(
343
+ dim=self.hidden_size,
344
+ num_heads=num_heads,
345
+ qk_norm=use_qknorm,
346
+ use_rmsnorm=use_rmsnorm,
347
+ use_rope=use_rope,
348
+ attn_fp32=attn_fp32,
349
+ max_seq_len=max_seq_len,
350
+ )
351
+ if use_swiglu:
352
+ self.mlp = _SwiGLUFFN(self.hidden_size, _swiglu_hidden(self.hidden_size, mlp_ratio))
353
+ else:
354
+ self.mlp = _StandardMLP(self.hidden_size, int(self.hidden_size * float(mlp_ratio)))
355
+ self.adaLN_mod = nn.Sequential(
356
+ nn.SiLU(),
357
+ _TorchLinear(self.hidden_size, 6 * self.hidden_size, bias=True, weight_init="zeros"),
358
+ )
359
+
360
+ def forward(self, x: torch.Tensor, condition: torch.Tensor) -> torch.Tensor:
361
+ r"""
362
+ One Lightning-DiT block conditioned by adaLN-Zero.
363
+
364
+ Args:
365
+ x (`torch.Tensor`):
366
+ Tokens `(batch, tokens, hidden)`.
367
+ condition (`torch.Tensor`):
368
+ Per-sample condition `(batch, hidden)`.
369
+
370
+ Returns:
371
+ `torch.Tensor`: Updated tokens, same shape as `x`.
372
+ """
373
+ chunks = self.adaLN_mod(condition.float()).to(dtype=x.dtype)
374
+ shift_msa, scale_msa, gate_msa, shift_mlp, scale_mlp, gate_mlp = torch.chunk(chunks, 6, dim=1)
375
+ attended = self.attn(_modulate(self.norm1(x), shift_msa, scale_msa))
376
+ x = x + gate_msa.unsqueeze(1) * attended
377
+ x = x + gate_mlp.unsqueeze(1) * self.mlp(_modulate(self.norm2(x), shift_mlp, scale_mlp))
378
+ return x
379
+
380
+
381
+ class _FinalLayer(nn.Module):
382
+ def __init__(self, hidden_size: int, patch_size: int, out_channels: int, use_rmsnorm: bool):
383
+ super().__init__()
384
+ self.norm_final = _RMSNorm(hidden_size) if use_rmsnorm else nn.LayerNorm(hidden_size, eps=1e-6, elementwise_affine=False)
385
+ self.adaLN_mod = nn.Sequential(
386
+ nn.SiLU(),
387
+ _TorchLinear(hidden_size, 2 * hidden_size, bias=True, weight_init="zeros"),
388
+ )
389
+ self.linear = _TorchLinear(hidden_size, patch_size * patch_size * out_channels, bias=True, weight_init="zeros")
390
+
391
+ def forward(self, x: torch.Tensor, condition: torch.Tensor) -> torch.Tensor:
392
+ r"""
393
+ Project tokens to patch pixels.
394
+
395
+ Args:
396
+ x (`torch.Tensor`):
397
+ Tokens `(batch, tokens, hidden)`.
398
+ condition (`torch.Tensor`):
399
+ Per-sample condition `(batch, hidden)`.
400
+
401
+ Returns:
402
+ `torch.Tensor`: Patch pixels `(batch, tokens, patch_size * patch_size * out_channels)`.
403
+ """
404
+ shift, scale = torch.chunk(self.adaLN_mod(condition.float()).to(dtype=x.dtype), 2, dim=1)
405
+ return self.linear(_modulate(self.norm_final(x), shift, scale))
406
+
407
+
408
+ class _LightningDiT(nn.Module):
409
+ def __init__(
410
+ self,
411
+ input_size: int,
412
+ patch_size: int,
413
+ in_channels: int,
414
+ hidden_size: int,
415
+ depth: int,
416
+ num_heads: int,
417
+ mlp_ratio: float,
418
+ out_channels: int,
419
+ use_qknorm: bool,
420
+ use_swiglu: bool,
421
+ use_rope: bool,
422
+ use_rmsnorm: bool,
423
+ cond_dim: int,
424
+ n_cls_tokens: int,
425
+ attn_fp32: bool,
426
+ ):
427
+ super().__init__()
428
+ self.input_size = int(input_size)
429
+ self.patch_size = int(patch_size)
430
+ self.in_channels = int(in_channels)
431
+ self.hidden_size = int(hidden_size)
432
+ self.out_channels = int(out_channels)
433
+ self.n_cls_tokens = int(n_cls_tokens)
434
+ self.patch_embed = _TorchLinear(self.patch_size * self.patch_size * self.in_channels, self.hidden_size, bias=True)
435
+ grid = self.input_size // self.patch_size
436
+ max_seq_len = grid * grid + self.n_cls_tokens
437
+ self.blocks = nn.ModuleList(
438
+ [
439
+ _DiTBlock(
440
+ hidden_size=self.hidden_size,
441
+ num_heads=num_heads,
442
+ mlp_ratio=mlp_ratio,
443
+ use_qknorm=use_qknorm,
444
+ use_swiglu=use_swiglu,
445
+ use_rmsnorm=use_rmsnorm,
446
+ use_rope=use_rope,
447
+ attn_fp32=attn_fp32,
448
+ max_seq_len=max_seq_len,
449
+ )
450
+ for _ in range(int(depth))
451
+ ]
452
+ )
453
+ self.final_layer = _FinalLayer(self.hidden_size, self.patch_size, self.out_channels, use_rmsnorm)
454
+ position = _sincos_2d(self.hidden_size, grid)
455
+ self.pos_embed = nn.Parameter(torch.as_tensor(position, dtype=torch.float32).unsqueeze(0))
456
+ if self.n_cls_tokens > 0:
457
+ self.cls_embed = nn.Parameter(torch.randn(1, self.n_cls_tokens, self.hidden_size) * 0.02)
458
+ self.c_token_proj = _TorchLinear(int(cond_dim), self.hidden_size, bias=True)
459
+ else:
460
+ self.register_parameter("cls_embed", None)
461
+ self.c_token_proj = None
462
+
463
+ def forward(self, hidden_states_bhwc: torch.Tensor, condition: torch.Tensor) -> torch.Tensor:
464
+ r"""
465
+ Map a latent grid to a clean latent grid.
466
+
467
+ Args:
468
+ hidden_states_bhwc (`torch.Tensor`):
469
+ Reference noise `(batch, height, width, channels)`. Height and width must equal
470
+ `input_size`. The official generator uses this layout.
471
+ condition (`torch.Tensor`):
472
+ Class, noise-code, and guidance embedding `(batch, cond_dim)`.
473
+
474
+ Returns:
475
+ `torch.Tensor`: Clean latent `(batch, height, width, channels)`.
476
+ """
477
+ batch, height, width, channels = hidden_states_bhwc.shape
478
+ patch = self.patch_size
479
+ grid = self.input_size // patch
480
+ if (height, width, channels) != (self.input_size, self.input_size, self.in_channels):
481
+ raise ValueError(
482
+ f"Expected latent {(self.input_size, self.input_size, self.in_channels)} in BHWC, "
483
+ f"got {(height, width, channels)}."
484
+ )
485
+ tokens = hidden_states_bhwc.reshape(batch, grid, patch, grid, patch, channels)
486
+ tokens = tokens.permute(0, 1, 3, 2, 4, 5).contiguous().reshape(batch, grid * grid, patch * patch * channels)
487
+ tokens = self.patch_embed(tokens)
488
+ tokens = (tokens + self.pos_embed.to(device=tokens.device, dtype=tokens.dtype)).to(dtype=tokens.dtype)
489
+ if self.n_cls_tokens > 0:
490
+ class_tokens = self.c_token_proj(condition).unsqueeze(1).repeat(1, self.n_cls_tokens, 1)
491
+ class_tokens = class_tokens + self.cls_embed.to(device=tokens.device, dtype=tokens.dtype)
492
+ tokens = torch.cat([class_tokens, tokens], dim=1)
493
+ for block in self.blocks:
494
+ tokens = block(tokens, condition)
495
+ tokens = self.final_layer(tokens, condition)
496
+ if self.n_cls_tokens > 0:
497
+ tokens = tokens[:, self.n_cls_tokens :, :]
498
+ tokens = tokens.reshape(batch, grid, grid, patch, patch, self.out_channels)
499
+ tokens = tokens.permute(0, 1, 3, 2, 4, 5).contiguous()
500
+ return tokens.reshape(batch, self.input_size, self.input_size, self.out_channels)
501
+
502
+
503
+ class _TimestepEmbedder(nn.Module):
504
+ def __init__(self, hidden_size: int, frequency_embedding_size: int = 256):
505
+ super().__init__()
506
+ self.frequency_embedding_size = int(frequency_embedding_size)
507
+ self.fc1 = _TorchLinear(self.frequency_embedding_size, hidden_size, bias=True, weight_init="normal")
508
+ self.fc2 = _TorchLinear(hidden_size, hidden_size, bias=True, weight_init="normal")
509
+
510
+ def forward(self, timesteps: torch.Tensor) -> torch.Tensor:
511
+ r"""
512
+ Embed a scalar guidance value with sinusoidal features.
513
+
514
+ Args:
515
+ timesteps (`torch.Tensor`):
516
+ Shape `(batch,)`. This is the guidance scale, not a diffusion time.
517
+
518
+ Returns:
519
+ `torch.Tensor`: Embedding `(batch, hidden)`.
520
+ """
521
+ timesteps = timesteps.to(dtype=torch.float32)
522
+ half = self.frequency_embedding_size // 2
523
+ freqs = torch.exp(-math.log(10000) * torch.arange(0, half, device=timesteps.device, dtype=torch.float32) / half)
524
+ arguments = timesteps[:, None] * freqs[None]
525
+ embedding = torch.cat([torch.cos(arguments), torch.sin(arguments)], dim=-1)
526
+ if self.frequency_embedding_size % 2:
527
+ embedding = torch.cat([embedding, torch.zeros_like(embedding[:, :1])], dim=-1)
528
+ hidden = nn.functional.silu(self.fc1(embedding))
529
+ return self.fc2(hidden)
530
+
531
+
532
+ class WFlowTransformer2DModel(ModelMixin, ConfigMixin):
533
+ r"""
534
+ One-step ImageNet generator used by W-Flow.
535
+
536
+ The network maps unit Gaussian SD-VAE noise plus a class label to a clean latent in one pass.
537
+ Guidance is a continuous embedding (the official `cfg_scale`, equal to `w + 1` in the paper),
538
+ not a second unconditional forward. Discrete noise codes (`noise_classes` by `noise_coords`)
539
+ are added to the class embedding.
540
+
541
+ Parameter names match `DitGen` in the official repository, so an `ema_model` state dict loads
542
+ without renaming.
543
+
544
+ Args:
545
+ sample_size (`int`, defaults to 32):
546
+ Latent spatial size. Released checkpoints use 32, which decodes to 256 pixels.
547
+ patch_size (`int`, defaults to 2):
548
+ Patch size on the latent grid.
549
+ in_channels (`int`, defaults to 4):
550
+ Latent channels.
551
+ out_channels (`int`, defaults to 4):
552
+ Predicted latent channels.
553
+ cond_dim (`int`, defaults to 768):
554
+ Width of the class, noise-code, and guidance embeddings.
555
+ num_classes (`int`, defaults to 1000):
556
+ ImageNet class count. There is no null-class slot.
557
+ noise_classes (`int`, defaults to 64):
558
+ Cardinality of each discrete noise code.
559
+ noise_coords (`int`, defaults to 32):
560
+ Number of independent noise-code embeddings that are summed.
561
+ n_cls_tokens (`int`, defaults to 16):
562
+ Learned class tokens prepended to the patch sequence.
563
+ hidden_size (`int`, defaults to 768):
564
+ Transformer width.
565
+ depth (`int`, defaults to 12):
566
+ Number of blocks.
567
+ num_attention_heads (`int`, defaults to 12):
568
+ Attention heads.
569
+ mlp_ratio (`float`, defaults to 4.0):
570
+ MLP expansion before the SwiGLU 2/3 reduction.
571
+ use_qknorm (`bool`, defaults to `True`):
572
+ QK normalization.
573
+ use_swiglu (`bool`, defaults to `True`):
574
+ SwiGLU MLP. Released checkpoints turn this on.
575
+ use_rope (`bool`, defaults to `True`):
576
+ 1-D rotary embeddings over the token sequence, including class tokens.
577
+ use_rmsnorm (`bool`, defaults to `True`):
578
+ RMSNorm instead of LayerNorm.
579
+ use_bf16 (`bool`, defaults to `True`):
580
+ Autocast the forward to bfloat16 on CUDA, matching the official sampler.
581
+ attn_fp32 (`bool`, defaults to `False`):
582
+ Run attention in float32. The ablation checkpoint sets this to `True`.
583
+ guidance_scale (`float`, defaults to 1.0):
584
+ Default embedded guidance. The pipeline reads this when the caller omits a scale.
585
+ default_num_inference_steps (`int`, defaults to 1):
586
+ Sampling is one network evaluation.
587
+ model_type (`str`, defaults to `"W-Flow-B"`):
588
+ Variant name stored in the config.
589
+ """
590
+
591
+ @register_to_config
592
+ def __init__(
593
+ self,
594
+ sample_size: int = 32,
595
+ patch_size: int = 2,
596
+ in_channels: int = 4,
597
+ out_channels: int = 4,
598
+ cond_dim: int = 768,
599
+ num_classes: int = 1000,
600
+ noise_classes: int = 64,
601
+ noise_coords: int = 32,
602
+ n_cls_tokens: int = 16,
603
+ hidden_size: int = 768,
604
+ depth: int = 12,
605
+ num_attention_heads: int = 12,
606
+ mlp_ratio: float = 4.0,
607
+ use_qknorm: bool = True,
608
+ use_swiglu: bool = True,
609
+ use_rope: bool = True,
610
+ use_rmsnorm: bool = True,
611
+ use_bf16: bool = True,
612
+ attn_fp32: bool = False,
613
+ guidance_scale: float = 1.0,
614
+ default_num_inference_steps: int = 1,
615
+ model_type: str = "W-Flow-B",
616
+ ):
617
+ super().__init__()
618
+ self.class_embed = nn.Embedding(int(num_classes), int(cond_dim))
619
+ nn.init.normal_(self.class_embed.weight, std=0.02)
620
+ self.noise_embeds = nn.ModuleList()
621
+ for _ in range(int(noise_coords)):
622
+ embedding = nn.Embedding(int(noise_classes), int(cond_dim))
623
+ nn.init.normal_(embedding.weight, std=0.02)
624
+ self.noise_embeds.append(embedding)
625
+ self.cfg_embedder = _TimestepEmbedder(int(cond_dim))
626
+ self.cfg_norm = _RMSNorm(int(cond_dim))
627
+ self.model = _LightningDiT(
628
+ input_size=int(sample_size),
629
+ patch_size=int(patch_size),
630
+ in_channels=int(in_channels),
631
+ hidden_size=int(hidden_size),
632
+ depth=int(depth),
633
+ num_heads=int(num_attention_heads),
634
+ mlp_ratio=float(mlp_ratio),
635
+ out_channels=int(out_channels),
636
+ use_qknorm=bool(use_qknorm),
637
+ use_swiglu=bool(use_swiglu),
638
+ use_rope=bool(use_rope),
639
+ use_rmsnorm=bool(use_rmsnorm),
640
+ cond_dim=int(cond_dim),
641
+ n_cls_tokens=int(n_cls_tokens),
642
+ attn_fp32=bool(attn_fp32),
643
+ )
644
+
645
+ def condition(
646
+ self,
647
+ class_labels: torch.Tensor,
648
+ guidance_scale: float | torch.Tensor,
649
+ noise_labels: torch.Tensor,
650
+ ) -> torch.Tensor:
651
+ r"""
652
+ Build the conditioning vector from class, noise codes, and guidance.
653
+
654
+ Args:
655
+ class_labels (`torch.Tensor`):
656
+ Integer class ids `(batch,)`, in `[0, num_classes)`.
657
+ guidance_scale (`float` or `torch.Tensor`):
658
+ Official CFG value `(w + 1)`. A float is broadcast across the batch. A tensor
659
+ must be `(batch,)` or a scalar.
660
+ noise_labels (`torch.Tensor`):
661
+ Integer codes `(batch, noise_coords)` in `[0, noise_classes)`.
662
+
663
+ Returns:
664
+ `torch.Tensor`: Condition `(batch, cond_dim)`.
665
+ """
666
+ batch = class_labels.shape[0]
667
+ cond = self.class_embed(class_labels)
668
+ for index, embedding in enumerate(self.noise_embeds):
669
+ cond = cond + embedding(noise_labels[:, index])
670
+ if isinstance(guidance_scale, (float, int)):
671
+ scale = torch.full((batch,), float(guidance_scale), device=class_labels.device, dtype=torch.float32)
672
+ else:
673
+ scale = torch.as_tensor(guidance_scale, device=class_labels.device, dtype=torch.float32)
674
+ if scale.ndim == 0:
675
+ scale = scale[None].repeat(batch)
676
+ embedded = self.cfg_norm(self.cfg_embedder(scale.float()).float())
677
+ return cond + embedded.to(dtype=cond.dtype) * 0.02
678
+
679
+ def forward(
680
+ self,
681
+ hidden_states: torch.Tensor,
682
+ class_labels: torch.Tensor,
683
+ guidance_scale: float | torch.Tensor = 1.0,
684
+ noise_labels: torch.Tensor | None = None,
685
+ return_dict: bool = True,
686
+ ) -> WFlowTransformer2DModelOutput | tuple[torch.Tensor]:
687
+ r"""
688
+ Predict a clean latent from reference noise.
689
+
690
+ Args:
691
+ hidden_states (`torch.Tensor`):
692
+ Gaussian reference noise `(batch, channels, height, width)` in BCHW. Height and
693
+ width must equal `config.sample_size`.
694
+ class_labels (`torch.Tensor`):
695
+ Integer ImageNet ids `(batch,)`.
696
+ guidance_scale (`float` or `torch.Tensor`, defaults to 1.0):
697
+ Embedded guidance. This is the official `cfg_scale` (`w + 1` in the paper).
698
+ noise_labels (`torch.Tensor`, *optional*):
699
+ Discrete noise codes `(batch, noise_coords)`. Required. The pipeline samples these
700
+ with the same generator as `hidden_states`.
701
+ return_dict (`bool`, defaults to `True`):
702
+ Return [`WFlowTransformer2DModelOutput`] when `True`, otherwise a one-tuple.
703
+
704
+ Returns:
705
+ [`WFlowTransformer2DModelOutput`] or `tuple`:
706
+ `sample` is the clean latent `(batch, channels, height, width)`.
707
+ """
708
+ if noise_labels is None:
709
+ raise ValueError("`noise_labels` is required and must have shape (batch, noise_coords).")
710
+ if hidden_states.ndim != 4:
711
+ raise ValueError(f"`hidden_states` must be BCHW, got {tuple(hidden_states.shape)}.")
712
+ hidden_bhwc = hidden_states.permute(0, 2, 3, 1).contiguous()
713
+ use_autocast = bool(self.config.use_bf16) and hidden_states.device.type == "cuda"
714
+ with torch.amp.autocast(device_type=hidden_states.device.type, dtype=torch.bfloat16, enabled=use_autocast):
715
+ cond = self.condition(class_labels, guidance_scale, noise_labels)
716
+ sample_bhwc = self.model(hidden_bhwc, cond)
717
+ sample = sample_bhwc.permute(0, 3, 1, 2).contiguous()
718
+ if not return_dict:
719
+ return (sample,)
720
+ return WFlowTransformer2DModelOutput(sample=sample)
W-Flow-XL/vae/config.json ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_class_name": "AutoencoderKL",
3
+ "_diffusers_version": "0.36.0",
4
+ "_name_or_path": "stabilityai/sd-vae-ft-mse",
5
+ "act_fn": "silu",
6
+ "block_out_channels": [
7
+ 128,
8
+ 256,
9
+ 512,
10
+ 512
11
+ ],
12
+ "down_block_types": [
13
+ "DownEncoderBlock2D",
14
+ "DownEncoderBlock2D",
15
+ "DownEncoderBlock2D",
16
+ "DownEncoderBlock2D"
17
+ ],
18
+ "force_upcast": true,
19
+ "in_channels": 3,
20
+ "latent_channels": 4,
21
+ "latents_mean": null,
22
+ "latents_std": null,
23
+ "layers_per_block": 2,
24
+ "mid_block_add_attention": true,
25
+ "norm_num_groups": 32,
26
+ "out_channels": 3,
27
+ "sample_size": 256,
28
+ "scaling_factor": 0.18215,
29
+ "shift_factor": null,
30
+ "up_block_types": [
31
+ "UpDecoderBlock2D",
32
+ "UpDecoderBlock2D",
33
+ "UpDecoderBlock2D",
34
+ "UpDecoderBlock2D"
35
+ ],
36
+ "use_post_quant_conv": true,
37
+ "use_quant_conv": true
38
+ }
W-Flow-XL/vae/diffusion_pytorch_model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:2aa1f43011b553a4cba7f37456465cdbd48aab7b54b9348b890e8058ea7683ec
3
+ size 334643268
demo-L.png ADDED
demo-XL.png ADDED
demo.png ADDED

Git LFS Details

  • SHA256: ce3795096ea6b53c0c3a3b758bee8736ba5498175f1be1aebf91ac6d59ca6713
  • Pointer size: 131 Bytes
  • Size of remote file: 126 kB