BiliSakura commited on
Commit
a0c1743
Β·
verified Β·
1 Parent(s): 29f56b7

Upload Priming-diffusers checkpoints

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

Git LFS Details

  • SHA256: b752110e72e731d308a57834b4835f25bfe798d8369f1b9b33278a25659fa0bf
  • Pointer size: 131 Bytes
  • Size of remote file: 119 kB
demo.png ADDED

Git LFS Details

  • SHA256: 8b0f34bbd320b2f03c941b73f48449f03827514f9aca868feb5e1e886bb40f6f
  • Pointer size: 131 Bytes
  • Size of remote file: 131 kB