Repository navigation
Expand file tree
/
Copy pathworkflow_schema.json
More file actions
1390 lines (1390 loc) · 75.1 KB
/
Copy pathworkflow_schema.json
File metadata and controls
1390 lines (1390 loc) · 75.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
{
"$id": "https://github.com/dkackman/diffusers-helper/workflow",
"$schema": "https://json-schema.org/draft/2020-12/schema#",
"description": "The definition of the diffusers-workflow.",
"type": "object",
"properties": {
"id": {
"type": "string"
},
"description": {
"type": "string"
},
"configures": {
"type": "string",
"description": "For a workflow under models/: the templates/ workflow this is a tuned per-checkpoint configuration of, as a catalog name such as 'templates/text-to-image'."
},
"shape": {
"type": "string",
"enum": ["image", "image-set", "image-edit", "shot", "sequence", "audio", "text", "utility"],
"description": "What the workflow produces. Derived from the steps by the server; declare it only where the derivation is wrong. Closed vocabulary - adding a value is additive, renaming one breaks every client that filtered on it."
},
"traits": {
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"enum": ["has-audio", "chained", "image-conditioned", "identity-referenced", "needs-input-media", "composes-workflows"]
},
"description": "How the output is made or what it needs supplied. Derived by the server; declare only to override."
},
"summary": {
"type": "string",
"maxLength": 120,
"description": "One line saying what the workflow is for, carried in catalog listings. Defaults to the first sentence of 'description'."
},
"cost": {
"type": "array",
"description": "Measured runs, one per device the maintainer measured on, each measured at the workflow's variable defaults: a run that moves num_inference_steps, width/height or num_frames off them is quoted scaled in proportion (plan basis 'derived'), so a figure measured anywhere else must be re-priced to the defaults before it is written. Never invented without a run; absent means unknown. 'minutes' is the whole run's wall clock on a worker that has to load the models - what a consumer actually waits through, not the denoise loop alone; on a video template the two differ by minutes.",
"items": {
"type": "object",
"required": ["device", "vram_gb", "minutes"],
"properties": {
"device": {"type": "string", "enum": ["cuda", "mps", "cpu"]},
"name": {"type": "string", "description": "The accelerator, for a person: 'RTX 4090', 'M2 Ultra'"},
"vram_gb": {"type": "number", "minimum": 0},
"minutes": {"type": "number", "minimum": 0},
"per_entry": {
"type": "object",
"description": "For a list-driven workflow: the measured cost of one entry of 'variable' (every member it produces), and the length of the default list 'minutes' was measured with, so a run over N entries is (minutes - per_entry.minutes * entries) + per_entry.minutes * N.",
"required": ["variable", "minutes", "entries"],
"properties": {
"variable": {"type": "string"},
"minutes": {"type": "number", "minimum": 0},
"entries": {"type": "integer", "minimum": 1}
},
"additionalProperties": false
}
},
"additionalProperties": false
}
},
"cost_drivers": {
"description": "The variables that move this workflow's cost, by name - a frame count, a step count, a segment count, not a prompt or a seed. Runs of this workflow are bucketed by these values when the server reports what its own history observed, so a 141-frame run never informs a 124-frame figure. Each name must be a variable this workflow declares. Declaring none is not neutral: the observed figure then falls back to runs that overrode nothing at all, which most real runs do not.",
"type": "array",
"items": {"type": "string"},
"uniqueItems": true
},
"variables": {
"$ref": "#/$defs/arguments"
},
"vram_estimate": {
"description": "A declared VRAM ceiling over this workflow's cost_drivers, checked against each 'cost' entry's 'vram_gb' in validate_workflow and again before a run starts. Never derived from a profiler - a maintainer's own reading of what a stage needs, the same way 'cost' itself is. Projected per pipeline step of the definition as it will run - variables substituted and every for_each expanded, so each member is projected with its own values: required_gb = base_gb + bytes_per_voxel * (product of voxel_variables' values) / 2^30 + gb_per_reference * (the step's 'references' entries whose from_file/from_previous_result is not null) + bytes_per_guide_voxel * (sum over the step's guides of snapped guide frames) * (product of the voxel_variables other than num_frames) / 2^30; a step projecting above any cost entry's vram_gb for that entry's device is refused, not warned, since the failure this guards is an OOM partway through a run that already spent minutes loading. Only the largest step past the ceiling is reported - for a for_each member, at the list entry it came from. 'voxel_variables' names the cost_drivers whose product drives the estimate - typically width, height and num_frames for a video template.",
"type": "object",
"required": ["base_gb", "bytes_per_voxel", "voxel_variables"],
"properties": {
"base_gb": {"type": "number", "minimum": 0, "description": "What stays resident regardless of the voxel count - everything the pipeline keeps on the device throughout, measured or bounded by a real run."},
"bytes_per_voxel": {"type": "number", "minimum": 0, "description": "Bytes of additional VRAM per unit of the voxel_variables' product, calibrated from a real run's reported requirement at a known combination."},
"voxel_variables": {
"type": "array",
"items": {"type": "string"},
"minItems": 1,
"uniqueItems": true,
"description": "Names whose product is the voxel count the formula scales with. Each is read from the step's own pipeline arguments, else from the workflow's variables; a step where one is not a number is not projected."
},
"gb_per_reference": {"type": "number", "minimum": 0, "description": "GB of additional VRAM per reference the step passes - a reference-conditioned pipeline holds each one's encoding resident beside the latents. Every kind counts once; an entry whose media is null is dropped before the pipeline sees it and is not counted. Absent means references are not in the formula."},
"bytes_per_guide_voxel": {"type": "number", "minimum": 0, "description": "Bytes of additional VRAM per guide voxel - an H3 guide is encoded on the target canvas, so each one the step lays in (its own 'guides' whose video is not null, plus the one a continuity 'guide' chain appends) costs its snapped frame count times the product of the voxel_variables other than num_frames. A clip's frames are probed from its header; one that cannot be probed (a previous_result:, an unreadable file) is charged at the step's num_frames, the worst case. Absent means guides are not in the formula."},
"reason": {"type": "string"}
},
"additionalProperties": false
},
"variable_constraints": {
"description": "What each variable's value is allowed to be, by variable name. A rule the engine could only enforce after the weights were loaded costs minutes to discover; declared here it is a free refusal at validation time and a line in the catalog beside the default.",
"type": "object",
"additionalProperties": {
"$ref": "#/$defs/variable_constraint"
}
},
"seed": {
"description": "Default seed for the entire workflow. Accepts a 'variable:' reference.",
"type": [
"integer",
"string"
],
"pattern": "^variable:",
"format": "int64"
},
"argument_template": {
"description": "Engine-injected: the arguments a parent workflow hands this one when it runs it as a sub-workflow. At run time _sub_workflow_action holds them on the child workflow, and they are never written into the definition. A value authored here is read only when this workflow is not run as a sub-workflow.",
"type": "object"
},
"steps": {
"type": "array",
"minItems": 1,
"items": {
"$ref": "#/$defs/step"
}
}
},
"additionalProperties": false,
"required": [
"id",
"steps"
],
"$defs": {
"variable_constraint": {
"description": "A rule the author declares for one variable's value, in the same field names a chain step's 'frame_snap' uses, so a model's frame rule is written once. Checked before anything is queued and reported beside the variable's default, so a consumer reads the rule rather than guessing it (#96).",
"type": "object",
"properties": {
"modulus": {
"type": "integer",
"minimum": 1
},
"remainder": {
"type": "integer",
"minimum": 0
},
"min_frames": {
"type": "integer",
"minimum": 1
},
"max_frames": {
"type": "integer",
"minimum": 1
},
"snap": {
"description": "What to do with a value the rule refuses. 'up' rounds to the next value the rule accepts, and warns that it did; absent, the value is refused.",
"enum": [
"up"
]
},
"reason": {
"description": "Why the rule exists, in the author's words - quoted in the refusal and reported beside the default.",
"type": "string"
}
},
"dependentRequired": {
"modulus": [
"remainder"
],
"remainder": [
"modulus"
]
},
"additionalProperties": false
},
"image": {
"type": "object",
"properties": {
"location": {
"type": "string",
"format": "uri"
},
"size": {
"type": "object",
"properties": {
"width": {
"type": "integer",
"format": "int16"
},
"height": {
"type": "integer",
"format": "int16"
}
}
}
},
"required": [
"location"
]
},
"step": {
"type": "object",
"additionalProperties": false,
"$comment": "A step is closed: the engine reads only the properties above, so an invented control-flow key ('when', 'retry') or a mistyped real one ('relase_pipeline') is a hard error rather than a silent no-op.",
"properties": {
"name": {
"type": "string"
},
"for_each": {
"description": "Run this step once per entry of a list. A list, or a 'variable:' reference to one. Inside the step, 'item:' is the entry and 'item:field' one of its fields (or {\"item\": \"field\", \"default\": X}, the field with X for an entry that omits it); a later step reads every member's result with 'gather:<step name>'. Members are named '<step name>@<entry name>' (or '@<index>' for an entry without a name), so '@' is reserved in step names.",
"type": ["array", "string"],
"pattern": "^variable:",
"minItems": 1,
"maxItems": 32
},
"seed": {
"description": "Default seed for the entire step. Accepts a 'variable:' reference.",
"type": [
"integer",
"string"
],
"pattern": "^variable:",
"format": "int64"
},
"release_pipeline": {
"description": "Unload this step's pipeline once the step completes, freeing its memory for later steps. A later pipeline_reference to this step is an error, and the persistent worker's cross-run model cache will not retain it.",
"type": "boolean"
},
"release_models": {
"description": "Unload every cached task model once the step completes, freeing their memory for later steps. Task models otherwise stay loaded for the life of the process; set this on a task or sub-workflow step whose model is not needed again, such as a prompt expander running ahead of a generation step. A later step using the same model reloads it.",
"type": "boolean"
},
"task": {
"$ref": "#/$defs/task"
},
"pipeline": {
"$ref": "#/$defs/pipeline"
},
"pipeline_reference": {
"$ref": "#/$defs/pipeline_reference"
},
"workflow": {
"$ref": "#/$defs/workflow_reference"
},
"result": {
"$ref": "#/$defs/result"
}
},
"oneOf": [
{
"required": [
"name",
"task"
]
},
{
"required": [
"name",
"pipeline"
]
},
{
"required": [
"name",
"pipeline_reference"
]
},
{
"required": [
"name",
"workflow"
]
}
]
},
"arguments": {
"type": "object",
"additionalProperties": {
"description": "null declares an argument that is optional - a workflow can expose a variable a caller may pass without inventing a sentinel value for its absence. If a step feeds a required task argument from a variable whose value is null, the document itself still saves and validates - but a run (or a validate/save call that supplies its own arguments) that leaves the variable null fails, since the argument the step needs was never actually given a value.",
"type": [
"string",
"integer",
"number",
"object",
"array",
"boolean",
"null"
]
}
},
"pipeline_reference": {
"type": "object",
"additionalProperties": false,
"$comment": "Closed - see 'step'.",
"properties": {
"reference_name": {
"type": "string"
},
"chain": {
"$ref": "#/$defs/chain"
},
"arguments": {
"$ref": "#/$defs/arguments"
}
},
"required": [
"reference_name",
"arguments"
]
},
"chain": {
"description": "Run this pipeline repeatedly, carrying visual continuity from each segment into the next, and stitch the segments into one long video. Specify the length with exactly one of 'segments' or 'match_audio'.",
"type": "object",
"properties": {
"segments": {
"description": "Number of segments to generate and stitch. Accepts a 'variable:' reference.",
"type": [
"integer",
"string"
],
"minimum": 1
},
"match_audio": {
"description": "Derive the segment count from the duration of this step's hold_audio track, or else its one audio reference, slicing it into frame-aligned per-segment chunks (each segment's hold_audio, or its audio reference); the final video is muxed with the original, unsliced audio track.",
"type": "boolean"
},
"continuity": {
"description": "How continuity is carried from one segment into the next. 'last_frame' carries the segment's final frame as the next one's keyframe. 'last_segment' carries the segment itself - its frames and the soundtrack generated with them - as a video reference, which keeps motion, camera and voice across the seam instead of appearance alone; it needs a 'segment_argument' holding a references list. 'guide' (MiniMax-H3 t2va and fl2va only - guides stay off ref2va) lays the segment's last 'guide_frames' frames, with their audio when 'carry_audio', into the next at frame 0 as a guide, sets an fl2va keyframe to the guide's first frame, and trims the guide off again; 'trim_frames' and 'carry_frames' do not apply, and 'crossfade_ms' only when 'carry_audio' is false. Accepts a 'variable:' reference.",
"anyOf": [
{
"type": "string",
"enum": [
"last_frame",
"last_segment",
"guide"
]
},
{
"type": "string",
"pattern": "^variable:"
}
],
"default": "last_frame"
},
"guide_frames": {
"description": "'guide' only - frames of each segment's tail laid into the next as its frame-0 guide, and trimmed off it: 22 or 39 (whole-latent guide lengths), nothing else. Ignored by the other continuity modes. Accepts a 'variable:' reference.",
"type": [
"integer",
"string"
],
"default": 22
},
"segment_argument": {
"description": "The pipeline argument the carry-over lands in - e.g. 'image' for image-to-video pipelines, or 'references' for reference-conditioned modular pipelines, where the carry-over is appended as an image or video reference.",
"type": "string",
"default": "image"
},
"carry_frames": {
"description": "'last_segment' only - carry just this many frames from the tail of each segment rather than all of them, cutting the reference's soundtrack to the same span. A shorter carry costs less sequence length and memory (MiniMax H3 conditions on reference clips of 2 seconds and up, i.e. 48 frames at its 24 fps). Accepts a 'variable:' reference.",
"type": [
"integer",
"string"
],
"minimum": 1
},
"carry_audio": {
"description": "'last_segment' and 'guide' - whether the carry brings the soundtrack generated with it, which is what carries a voice across the seam (a guide holds it, so the seam is not crossfaded). Turn it off when the segments are already conditioned on a supplied audio track, as in a 'match_audio' chain.",
"type": "boolean",
"default": true
},
"trim_frames": {
"description": "Frames removed from the head of every segment after the first (an image-to-video segment reproduces its keyframe as frame 0). Also bounds the audio crossfade window to trim_frames / fps seconds. Accepts a 'variable:' reference.",
"type": [
"integer",
"string"
],
"minimum": 0,
"default": 1
},
"crossfade_ms": {
"description": "Equal-power crossfade applied to generated audio at segment boundaries, clamped to the trim_frames / fps window. Accepts a 'variable:' reference.",
"type": [
"number",
"string"
],
"minimum": 0,
"default": 75
},
"fps": {
"description": "Frame rate used for the chain's audio math - trimming, crossfading, and match_audio planning. Defaults to the pipeline's 'frame_rate' argument when present; pipelines with a fixed rate (MiniMax H3: 24) need it set here. Accepts a 'variable:' reference.",
"type": [
"number",
"string"
],
"exclusiveMinimum": 0
},
"frame_snap": {
"description": "Constraint the pipeline places on num_frames - counts must equal modulus * n + remainder within the bounds (MiniMax H3: modulus 17, remainder 5, min 124, max 345). Used to snap the final match_audio segment to a valid length. May instead be the string 'constraint:<variable>', naming an entry of the workflow's 'variable_constraints' - so the rule is stated once rather than twice in one file.",
"oneOf": [
{
"type": "object",
"properties": {
"modulus": {
"type": "integer",
"minimum": 1
},
"remainder": {
"type": "integer",
"minimum": 0
},
"min_frames": {
"type": "integer",
"minimum": 1
},
"max_frames": {
"type": "integer",
"minimum": 1
}
},
"required": [
"modulus",
"remainder"
],
"additionalProperties": false
},
{
"type": "string",
"pattern": "^constraint:[a-zA-Z_][a-zA-Z0-9_-]*$"
}
]
},
"prompts": {
"description": "Per-segment prompt overrides; segment i uses prompts[min(i, len(prompts) - 1)]. Accepts a 'variable:' reference; a variable left null leaves every segment on the step's own 'prompt'.",
"type": [
"array",
"string",
"null"
],
"items": {
"type": "string"
},
"minItems": 1
},
"save_segments": {
"description": "Write each completed segment to the output directory as a playable mp4 and free its frames, bounding memory to one segment - a crashed chain leaves the finished segments behind. The final video is streamed from the segment files. Requires PyAV and a frame rate.",
"type": "boolean",
"default": false
},
"keep_segments": {
"description": "Leave the segment files in place after the final video is written (default: they are removed once it saves successfully). Only meaningful with save_segments.",
"type": "boolean",
"default": false
}
},
"oneOf": [
{
"required": [
"segments"
]
},
{
"required": [
"match_audio"
]
}
],
"additionalProperties": false
},
"pipeline": {
"type": "object",
"properties": {
"configuration": {
"$ref": "#/$defs/pipeline_configuration"
},
"shared_components": {
"$ref": "#/$defs/shared_components"
},
"reused_components": {
"$ref": "#/$defs/reused_components"
},
"scheduler": {
"$ref": "#/$defs/scheduler"
},
"audio_scheduler": {
"$ref": "#/$defs/scheduler"
},
"model": {
"$ref": "#/$defs/pipeline_component"
},
"transformer": {
"$ref": "#/$defs/pipeline_component"
},
"transformer_2": {
"$ref": "#/$defs/pipeline_component"
},
"vae": {
"$ref": "#/$defs/pipeline_component"
},
"unet": {
"$ref": "#/$defs/pipeline_component"
},
"text_encoder": {
"$ref": "#/$defs/pipeline_component"
},
"text_encoder_2": {
"$ref": "#/$defs/pipeline_component"
},
"text_encoder_3": {
"$ref": "#/$defs/pipeline_component"
},
"tokenizer": {
"$ref": "#/$defs/pipeline_component"
},
"tokenizer_2": {
"$ref": "#/$defs/pipeline_component"
},
"tokenizer_3": {
"$ref": "#/$defs/pipeline_component"
},
"image_encoder": {
"$ref": "#/$defs/pipeline_component"
},
"feature_extractor": {
"$ref": "#/$defs/pipeline_component"
},
"prompt_enhancer_head": {
"$ref": "#/$defs/pipeline_component"
},
"controlnet": {
"$ref": "#/$defs/controlnet"
},
"loras": {
"type": "array",
"items": {
"$ref": "#/$defs/lora"
}
},
"ip_adapter": {
"$ref": "#/$defs/ip_adapter"
},
"from_pretrained_arguments": {
"$ref": "#/$defs/from_pretrained_arguments"
},
"remote_text_encoder": {
"description": "Encode prompts with a remote text-encoder service instead of loading the text encoder locally. The pipeline's text_encoder is set to None, the prompt is POSTed to the service (authenticated with the HuggingFace token), and the returned embeddings are passed to the pipeline as prompt_embeds. Mutually exclusive with prompt_weighting.",
"type": "object",
"properties": {
"url": {
"description": "URL of the remote text encoder endpoint, e.g. a HuggingFace inference endpoint.",
"type": "string"
}
},
"required": [
"url"
]
},
"seed": {
"description": "The seed for this pipeline. Accepts a 'variable:' reference.",
"type": [
"integer",
"string"
],
"pattern": "^variable:",
"format": "int64"
},
"chain": {
"$ref": "#/$defs/chain"
},
"arguments": {
"$ref": "#/$defs/arguments"
}
},
"additionalProperties": {
"description": "Any other key names a pipeline component to load. Diffusers grows component names faster than this schema does, so a key whose value is a component definition - an object carrying 'from_pretrained_arguments' - is loaded under that name. Anything else is a mistyped or misplaced key and is refused rather than ignored.",
"unknownPropertyMessage": "the engine reads the properties this object declares, plus any other key whose value is a component definition (an object carrying 'from_pretrained_arguments') - anything else would be silently ignored",
"type": "object",
"required": [
"from_pretrained_arguments"
],
"allOf": [
{
"$ref": "#/$defs/pipeline_component"
}
]
},
"required": [
"configuration",
"from_pretrained_arguments",
"arguments"
]
},
"pipeline_configuration": {
"type": "object",
"properties": {
"offload": {
"type": "string",
"enum": [
"model",
"sequential"
]
},
"exclude_from_cpu_offload": {
"description": "Component names (e.g. 'vae', 'text_encoder') to keep resident on the accelerator instead of offloading. Only applies when offload is 'sequential'.",
"type": "array",
"items": {
"type": "string"
}
},
"group_offload": {
"$ref": "#/$defs/group_offload"
},
"device": {
"description": "The device to run this pipeline on, e.g. 'cuda', 'cuda:1', 'mps' or 'cpu'. Defaults to the device dw is running on and becomes the default for this pipeline's components. A backend this machine does not have is translated to the one it does, with a warning, so a workflow written on a CUDA box runs on a Mac and back again - the index is dropped in that translation. A 'cpu' device is never translated.",
"type": "string"
},
"component_type": {
"description": "The python type of pipeline to use in the format 'module.typename' module defaults to diffusers",
"type": "string"
},
"no_generator": {
"description": "Whether to use a generator for the pipeline. Some pipelines do not support generators.",
"type": "boolean"
},
"enable_attention_slicing": {
"description": "Whether to enable attention slicing for the pipeline to reduce memory usage.",
"type": "boolean"
},
"disable_attention_slicing": {
"description": "Turn off the attention slicing MPS applies automatically. Worth setting for SDXL-family models on a Mac: MPS SDPA is fast at their head dim (64) and slicing made it 2.4x slower.",
"type": "boolean"
},
"attention_backend": {
"description": "The attention backend to use for the pipeline. 'sparse' is dw's own, not a diffusers backend: comfy-kitchen sparse attention on a MiniMax-H3 transformer's generated-video rows, installed for this call only, with everything else dense. It needs CUDA sm_80+ and bf16/fp16, and runs dense with a warning where it cannot run; on a pipeline with no MiniMax-H3 transformer it also runs dense with a warning (#931).",
"type": "string"
},
"sparse_tau": {
"description": "The sparsity threshold for attention_backend 'sparse': higher is sparser and faster, lower is closer to dense. Defaults to 0.5. A runtime setting like a LoRA scale - changing it reuses the loaded pipeline (#931). Accepts a 'variable:' reference.",
"type": ["number", "string"],
"pattern": "^variable:",
"minimum": 0
},
"sparse_topk": {
"description": "sol_attn's top-k routing for attention_backend 'sparse': keep this fraction of key tiles per query tile (strictly between 0 and 1) and drop the rest, the selection lightx2v's SLA LoRAs were trained against. When set, sparse_tau is ignored; unset (the default) routes by sparse_tau. A runtime setting like a LoRA scale - changing it reuses the loaded pipeline (#932). Accepts a 'variable:' reference.",
"type": ["number", "string"],
"pattern": "^variable:",
"exclusiveMinimum": 0,
"exclusiveMaximum": 1
},
"prompt_weighting": {
"description": "Enable A1111-style prompt weighting syntax: (word:1.5) for emphasis, [word] for de-emphasis, ((word)) for nested weighting. Also supports prompts longer than 77 tokens. Currently supports Flux pipelines. Mutually exclusive with remote_text_encoder.",
"type": "boolean"
},
"pre_load_modules": {
"description": "List of Python modules to import before loading the pipeline. Used for modules that register with diffusers on import (e.g., sdnq).",
"type": "array",
"items": {
"type": "string"
}
},
"load_components": {
"description": "Arguments passed to a modular pipeline's load_components() - modular pipelines load their component weights separately from their config. Use 'dtype' to set the component dtype and 'names' to load a subset of components.",
"type": "object",
"properties": {
"names": {
"description": "Names of the components to load. All components are loaded when omitted.",
"type": "array",
"items": {
"type": "string"
}
},
"dtype": {
"description": "The torch dtype to load components in, e.g. 'torch.bfloat16'",
"type": "string"
},
"quantization_config": {
"description": "Quantization configuration per component, keyed by component name (e.g. 'transformer', 'text_encoder'). A component not named here loads unquantized.",
"type": "object",
"additionalProperties": {
"$ref": "#/$defs/quantization_config"
}
}
}
},
"configs": {
"description": "Values a modular pipeline's blocks declare and read while they run - not components, and not call arguments. Keys are whatever the pipeline itself declares, so what may be set here depends on the model: MiniMax-H3 declares 'canvas_short_edge', 'canvas_max_pixels' and 'reference_image_short_edge'. A name the pipeline does not declare is an error rather than a setting that quietly did nothing.",
"type": "object",
"additionalProperties": {
"type": [
"string",
"integer",
"number",
"boolean",
"array",
"null"
]
}
},
"components": {
"description": "Configuration applied to components once the pipeline has loaded them. This is where a modular pipeline's components are placed, since it pulls their weights itself. Keys name a component, optionally as a dotted path into one, e.g. 'text_encoder.model'.",
"type": "object",
"additionalProperties": {
"type": "object",
"properties": {
"group_offload": {
"$ref": "#/$defs/group_offload"
},
"device": {
"description": "The device to move this component to, e.g. 'cuda'. Only for components small enough to stay resident - the offloaded ones are placed by their own hooks.",
"type": "string"
},
"residency": {
"description": "Whether the component stays on its device for the whole run ('resident', the default) or rests in system memory and is moved to the device only while one of its own calls runs ('on_demand'). Use on_demand for a component that is large but called a handful of times, like a VAE that only encodes references and decodes the result - it frees the device for the rest of the run and, unlike group_offload, moves the model whole, so a tiled decode costs one pair of transfers rather than one per tile. Not for a component called every step, and cannot be combined with group_offload.",
"type": "string",
"enum": [
"resident",
"on_demand"
]
},
"enable_tiling": {
"description": "Enable tiled decoding on this component, for a decoder that is not the one named 'vae' (which the pipeline-level 'vae' block covers) - LTX-2.5's 'diffusion_decoder', say, which otherwise decodes the whole video volume in one allocation. 'true' uses the model's own default tile size; an object passes tile and stride sizes through to enable_tiling(), which is what a card smaller than those defaults needs.",
"type": [
"boolean",
"object"
]
},
"attention_backend": {
"description": "Pin this component's attention backend persistently via set_attention_backend, e.g. 'flash', 'sage', '_flash_3_hub'. Use this instead of the pipeline-level attention_backend when the component is compiled - the per-call context manager forces recompiles. 'sparse' installs dw's comfy-kitchen sparse attention on a MiniMax-H3 transformer instead of calling set_attention_backend, and stays installed until the component is configured with another backend; on any other component it runs dense with a warning (#931).",
"type": "string"
},
"sparse_tau": {
"description": "The sparsity threshold for this component's attention_backend 'sparse': higher is sparser and faster, lower is closer to dense. Defaults to 0.5. A runtime setting like a LoRA scale - changing it reuses the loaded pipeline and is re-applied to it (#931). Accepts a 'variable:' reference.",
"type": ["number", "string"],
"pattern": "^variable:",
"minimum": 0
},
"sparse_topk": {
"description": "sol_attn's top-k routing for attention_backend 'sparse': keep this fraction of key tiles per query tile (strictly between 0 and 1) and drop the rest, the selection lightx2v's SLA LoRAs were trained against. When set, sparse_tau is ignored; unset (the default) routes by sparse_tau. A runtime setting like a LoRA scale - changing it reuses the loaded pipeline (#932). Accepts a 'variable:' reference.",
"type": ["number", "string"],
"pattern": "^variable:",
"exclusiveMinimum": 0,
"exclusiveMaximum": 1
},
"attn_processor_type": {
"description": "The attention processor this component runs, by type name, constructed with no arguments and handed to set_attn_processor(). The pipeline-level 'unet' and 'transformer' blocks cover those two components; this covers any other one that carries attention - LTX-2.5's 'diffusion_decoder', whose default processor is a portable FlexAttention fallback rather than the NATTEN path the decoder was built around.",
"type": "string"
},
"truncate_layers": {
"description": "Drop the tail of a ModuleList inside this component that the run never reads, before any offload hooks are installed. Keys are dotted paths relative to the component, values the number of entries to keep. For an encoder used for its hidden states: MiniMax-H3 conditions on hidden_states[50] of its 64-layer Qwen3-VL, so { 'language_model.layers': 51 } drops the 13 layers whose output nothing consumes while leaving hidden_states[50] bit-identical (keeping only 50 would hand back the final-norm output instead, a different tensor).",
"type": "object",
"additionalProperties": {
"type": "integer",
"minimum": 1
}
},
"remove_modules": {
"description": "Dotted paths to modules inside this component that the run never calls, each replaced with an Identity before any offload hooks are installed - a language-model head on a model used as an encoder, say. The attribute survives for anything that looks it up; the weights are freed rather than held (and, offloaded, pinned) for a call that never comes.",
"type": "array",
"items": {
"type": "string"
}
},
"compile": {
"$ref": "#/$defs/compile_config"
}
}
}
},
"preserve_device_placement": {
"description": "Whether to leave the component where it loaded rather than moving it to the device. Needed when the component is loaded already placed - by a 'device_map', or by a quantization that pins its tensors to one device. A 'components' block that group offloads already keeps the pipeline off the device on its own. Renamed from 'do_not_send_to_device', which is no longer recognized.",
"type": "boolean"
},
"components_manager": {
"description": "Attach a ComponentsManager to a modular pipeline. The manager tracks the pipeline's components and, with auto CPU offload enabled, keeps only the running ones on the device. It replaces 'offload', which modular pipelines do not support.",
"type": "object",
"properties": {
"enable_auto_cpu_offload": {
"description": "Move components between the device and system memory as the pipeline runs. Requires a device that reports free memory (CUDA). When enabled the manager owns device placement, so the pipeline is not moved to the device directly.",
"type": "boolean",
"default": false
},
"memory_reserve_margin": {
"description": "Device memory to keep free when deciding what to offload, e.g. '3GB'",
"type": "string",
"default": "3GB"
}
}
},
"sdnq_optimize": {
"description": "List of pipeline component names to apply SDNQ quantized matmul optimization to (e.g., ['transformer', 'text_encoder']). Requires sdnq package and CUDA/XPU hardware.",
"type": "array",
"items": {
"type": "string"
}
},
"cache": {
"description": "Enable diffusers built-in cache acceleration on the transformer. Hooks auto-reset between inference runs. Accepts a 'variable:' reference to a whole cache object; a variable that resolves to null means no cache, and the object it resolves to is checked against this shape at validate.",
"type": [
"object",
"string"
],
"pattern": "^variable:",
"properties": {
"type": {
"description": "Cache algorithm: first_block (simplest, broadest support), faster (video-oriented, experimental), mag (magnitude-based, needs num_inference_steps), taylorseer (Taylor series approximation), text_kv (text key-value cache).",
"type": "string",
"enum": [
"first_block",
"faster",
"mag",
"taylorseer",
"text_kv"
]
},
"threshold": {
"description": "Cache threshold for first_block and mag types. Higher = more speedup, more quality loss. first_block default: 0.05, mag default: 0.06. Accepts a 'variable:' reference.",
"type": [
"number",
"string"
]
},
"num_inference_steps": {
"description": "Required for mag cache type. The transformer forwards the call runs: the pipeline's num_inference_steps, except where the scheduler runs fewer (MiniMax-H3 runs one fewer, so a calibration reports one ratio fewer than the call's steps; set this to the count reported).",
"type": "integer"
},
"max_skip_steps": {
"description": "Max consecutive skippable steps for mag cache. Default: 3.",
"type": "integer"
},
"retention_ratio": {
"description": "Fraction of initial steps where skipping is disabled for mag cache. Default: 0.2.",
"type": "number"
},
"mag_ratios": {
"description": "Per-step magnitude ratios for mag cache. Required unless calibrate is true, and checkpoint-dependent. Either a preset name shipped by diffusers ('flux') or an explicit array of per-step ratios. Interpolated automatically when its length differs from num_inference_steps.",
"oneOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "number"
}
}
]
},
"calibrate": {
"description": "Run mag cache in calibration mode: skip nothing, and report the magnitude ratios for this model at the end of the run as a job warning and log event, so they can be pasted into mag_ratios. Under classifier-free guidance run as separate cond and uncond passes two lists are reported, labeled [cond] and [uncond]; use the cond one. A pipeline whose transformer does not support enable_cache() (a UNet such as SD 1.5, Z-Image) runs uncached with a job warning and reports nothing. Default: false.",
"type": "boolean"
},
"cache_interval": {
"description": "Full computation every N steps for taylorseer cache. Default: 5.",
"type": "integer"
},
"max_order": {
"description": "Taylor series order for taylorseer cache. Higher = better approximation, more memory. Default: 1.",
"type": "integer"
},
"is_guidance_distilled": {
"description": "For faster cache: set true when the model is guidance-distilled (FLUX.1-dev, FLUX.1-Krea-dev), where guidance_scale is an embedding and the transformer sees a batch of 1, not a cond/uncond pair. Without it faster fails at the first step with 'tuple index out of range'. Default: false.",
"type": "boolean"
}
},
"required": [
"type"
]
},
"vae": {
"type": "object",
"properties": {
"enable_slicing": {
"description": "Decode the latent batch one sample at a time rather than all at once - the answer to a decode that runs out of memory on a batch the denoise itself fitted. Costs nothing but the loss of batched decode parallelism.",
"type": "boolean"
},
"enable_tiling": {
"description": "Decode in tiles rather than in one allocation, for a single sample too large to decode whole - a long or high-resolution video, where the peak is the decode rather than the denoise. Combines with 'enable_slicing'.",
"type": "boolean"
},
"channels_last": {
"type": "boolean"
},
"torch_dtype": {
"type": "string"
}
}
},
"unet": {
"type": "object",
"properties": {
"enable_forward_chunking": {
"type": "boolean"
},
"channels_last": {
"type": "boolean"
},
"torch_dtype": {
"type": "string"
},
"attn_processor_type": {
"type": "string"
}
}
},
"transformer": {
"type": "object",
"properties": {
"attn_processor_type": {
"description": "The type name of an attention processor",
"type": "string"
}
}
},
"text_encoder": {
"type": "object",
"properties": {
"torch_dtype": {
"type": "string"
}
}
},
"shared_components": {
"$ref": "#/$defs/shared_components"
},
"reused_components": {
"$ref": "#/$defs/reused_components"
},
"enable_layerwise_casting": {
"$ref": "#/$defs/enable_layerwise_casting"
},
"inversion": {
"description": "Run the pipeline's invert() rather than the pipeline itself, returning the inverted latents. Only for pipelines that have one.",
"type": "boolean"
},
"generate": {
"description": "Run the pipeline's generate() rather than the pipeline itself, returning the generated ids. Only for pipelines that have one, such as a conditioner used on its own.",
"type": "boolean"
}
},
"additionalProperties": false,
"required": [
"component_type"
]
},
"shared_components": {
"description": "The names of components this step loads and later steps may reuse. A modular pipeline is given them after it is built, so the components it shares are the ones it actually loaded.",
"type": "array",
"items": {
"type": "string"
}
},
"reused_components": {
"description": "The names of components an earlier step shared, reused here instead of being loaded again. A reused component keeps the device placement the step that shared it gave it.",
"type": "array",
"items": {
"type": "string"
}
},
"scheduler": {
"type": "object",
"properties": {
"configuration": {
"type": "object",
"properties": {
"scheduler_type": {
"type": "string"
}
},
"required": [
"scheduler_type"
]
},
"from_config_args": {
"$ref": "#/$defs/arguments"
},
"shift": {
"description": "Exponential sigma shift applied to this scheduler's schedule, for schedulers that take one (MiniMax H3: 12.0 for video, 3.0 for audio in the released checkpoint). Lower it when running few steps - a high shift packs the whole grid near sigma 1 and leaves one enormous final step, which a short schedule cannot absorb. Accepts a 'variable:' reference.",
"type": [
"number",
"string"
],
"exclusiveMinimum": 0
}
},
"anyOf": [
{
"required": [
"configuration"
]
},
{
"required": [
"shift"
]
}
]
},
"pipeline_component": {
"type": "object",
"properties": {
"configuration": {
"type": "object",
"properties": {
"device": {
"description": "The device to load this component onto, e.g. 'cuda', 'cuda:1', 'mps' or 'cpu'. Defaults to the device its pipeline runs on. A backend this machine does not have is translated to the one it does, with a warning.",
"type": "string"
},
"component_type": {
"description": "The python type of pipeline component to use in the format 'module.typename' module defaults to diffusers",
"type": "string"
}