diffusers-workflow 0.14.0__py3-none-any.whl → 0.15.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {diffusers_workflow-0.14.0.dist-info → diffusers_workflow-0.15.0.dist-info}/METADATA +2 -1
- {diffusers_workflow-0.14.0.dist-info → diffusers_workflow-0.15.0.dist-info}/RECORD +54 -51
- dw/acceleration_warnings.py +36 -0
- dw/docs/ACCELERATION.md +43 -5
- dw/docs/ARCHITECTURE.md +3 -0
- dw/docs/DEPENDENCIES.md +2 -0
- dw/docs/MCP.md +2 -2
- dw/docs/QUANTIZATION.md +2 -0
- dw/docs/RECIPES_24GB.md +1 -1
- dw/docs/RELEASING.md +61 -0
- dw/docs/SECURITY.md +26 -0
- dw/docs/TASKS.md +16 -1
- dw/docs/WORKFLOW_GUIDE.md +21 -4
- dw/pipeline_processors/components.py +33 -4
- dw/pipeline_processors/pipeline.py +15 -1
- dw/server/api_models.py +5 -0
- dw/server/routes/system.py +4 -1
- dw/server/ui/assets/{cssMode-BM_j_5VW.js → cssMode-D_BuRO9Y.js} +1 -1
- dw/server/ui/assets/{editor.api-CEPMtaHf.js → editor.api-B6pi6BSE.js} +1 -1
- dw/server/ui/assets/{freemarker2-BVTL0E_v.js → freemarker2-mPiw3NV_.js} +1 -1
- dw/server/ui/assets/{handlebars-DN1SqR7g.js → handlebars-BfGb596Y.js} +1 -1
- dw/server/ui/assets/{html-BYdDV855.js → html-xXIqw-JZ.js} +1 -1
- dw/server/ui/assets/{htmlMode-CktrpppH.js → htmlMode-B3FC_H4q.js} +1 -1
- dw/server/ui/assets/{index-Dd1gXnAH.js → index-Civ6zDZP.js} +44 -44
- dw/server/ui/assets/{javascript-DvSbrt_n.js → javascript-B-FFcgST.js} +1 -1
- dw/server/ui/assets/{jsonMode-CXzErKKD.js → jsonMode-BELbxUQD.js} +1 -1
- dw/server/ui/assets/{liquid-BRCKFwoi.js → liquid-CxXhb7_e.js} +1 -1
- dw/server/ui/assets/{lspLanguageFeatures-njtWwPtu.js → lspLanguageFeatures-sXyBqSzn.js} +1 -1
- dw/server/ui/assets/{mdx-BUaukvEP.js → mdx-4jPGQ4yb.js} +1 -1
- dw/server/ui/assets/{monaco-gga5ZcVz.js → monaco-ByFdQnrs.js} +4 -4
- dw/server/ui/assets/{python-BlUYF5iw.js → python-D3CL9Y6O.js} +1 -1
- dw/server/ui/assets/{razor-C_60BEWv.js → razor-F_hjmtqk.js} +1 -1
- dw/server/ui/assets/{tsMode-DZ39FkiR.js → tsMode-BiyDvHYY.js} +1 -1
- dw/server/ui/assets/{typescript-DRuDz-v_.js → typescript-DBE1Uz0U.js} +1 -1
- dw/server/ui/assets/{workers-BWXmwymL.js → workers-Ci7sZ35J.js} +1 -1
- dw/server/ui/assets/{xml-CBshcw4i.js → xml-Eqpmo6a1.js} +1 -1
- dw/server/ui/assets/{yaml-D1ZImLMB.js → yaml-BNP_JiwW.js} +1 -1
- dw/server/ui/index.html +1 -1
- dw/sparse_attention.py +669 -0
- dw/step_cache.py +24 -2
- dw/tasks/speech_generation.py +46 -18
- dw/tasks/text_generation.py +317 -21
- dw/trust.py +33 -0
- dw/workflow_schema.json +28 -2
- dw/workflows/flux3_klein_upsample.json +33 -0
- dw/workflows/flux3_klein_upsample_edit.json +51 -0
- dw_mcp/assets.py +7 -4
- dw_mcp/tools_authoring.py +1 -1
- dw_mcp/tools_media.py +3 -3
- dw_mcp/workspaces.py +5 -4
- {diffusers_workflow-0.14.0.dist-info → diffusers_workflow-0.15.0.dist-info}/WHEEL +0 -0
- {diffusers_workflow-0.14.0.dist-info → diffusers_workflow-0.15.0.dist-info}/entry_points.txt +0 -0
- {diffusers_workflow-0.14.0.dist-info → diffusers_workflow-0.15.0.dist-info}/licenses/LICENSE +0 -0
- {diffusers_workflow-0.14.0.dist-info → diffusers_workflow-0.15.0.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: diffusers-workflow
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.15.0
|
|
4
4
|
Summary: Declarative workflow engine and web UI for Hugging Face Diffusers
|
|
5
5
|
Author: dkackman
|
|
6
6
|
License: Apache-2.0
|
|
@@ -37,6 +37,7 @@ Requires-Dist: controlnet-aux>=0.0.10
|
|
|
37
37
|
Requires-Dist: opencv-python-headless>=5.0.0.93
|
|
38
38
|
Requires-Dist: kornia>=0.8.3
|
|
39
39
|
Requires-Dist: kernels>=0.17.2
|
|
40
|
+
Requires-Dist: comfy-kitchen<0.3,>=0.2.38
|
|
40
41
|
Requires-Dist: spandrel>=0.4.2
|
|
41
42
|
Requires-Dist: facexlib>=0.3.0
|
|
42
43
|
Requires-Dist: numpy>=2.5.4
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
diffusers_workflow-0.
|
|
1
|
+
diffusers_workflow-0.15.0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
2
2
|
dw/__init__.py,sha256=YKwvXdngbW8iY6xFcfVwDCeiD_oFyCdWb-rRVUogp0Y,19969
|
|
3
|
-
dw/acceleration_warnings.py,sha256=
|
|
3
|
+
dw/acceleration_warnings.py,sha256=gvTXl7J-iARkl1QReaG1UT0ntd_lm7CUvdRy3tDDxbg,12836
|
|
4
4
|
dw/adapter_compatibility.py,sha256=rNs63QXONXqr5ZJaY8h6Ur9FcNGLeAOo18it__IOwE4,15890
|
|
5
5
|
dw/argument_media.py,sha256=fIsvlDRCuTz_DPH4MXFxBZiKTQfgR1vY0-wTU5P9p-I,15145
|
|
6
6
|
dw/argument_warnings.py,sha256=Kwy-gicCXOnsAEs_08p7X7g-HEjfzukVkP6qQFRHSak,10457
|
|
@@ -66,14 +66,15 @@ dw/settings.py,sha256=lqIuoiwqfVzbiCvu0YC5zBWNfT3ojwVfx2XfR23fkyI,4457
|
|
|
66
66
|
dw/shot_span_preflight.py,sha256=Vsb9OKB3a8Wav4Y-orfgAB6Y5JIrCO3RBHfzLmadhp4,6135
|
|
67
67
|
dw/shots.py,sha256=O3JcJgkRhSKbR3WeMh1vDO_gw-zjE9MXbUJwfoGqIqg,22760
|
|
68
68
|
dw/slice_preflight.py,sha256=IJ1NWZPfFBgz_YKU8CvHilasAa6nEIUGu3XW8Vf4gHY,7492
|
|
69
|
+
dw/sparse_attention.py,sha256=Yb2eeNPj6Wh8sgL77K0ZcDiBZImGoPYdzuF4IXwgkV4,25569
|
|
69
70
|
dw/step.py,sha256=ReYYvfQUKDVtSJ2bcShHDJEmga0YunRIYQV0k1ySSKc,10259
|
|
70
|
-
dw/step_cache.py,sha256=
|
|
71
|
+
dw/step_cache.py,sha256=knS_FgaYolQBRRUD7bgjAEPoFoH6djkBsZXEHSmJu4o,35413
|
|
71
72
|
dw/step_value_checks.py,sha256=mgbz3dlNl-UDzSkozTrHO7novtRkf9Zi6Uovd7rL434,17399
|
|
72
73
|
dw/subfolders.py,sha256=ZRRxMhHk1Yha9yt_5C_kJfe1YBWJYRba5n2w6Nx30xw,3738
|
|
73
74
|
dw/task_domains.py,sha256=cxfTaECzTOCrFNZQdzgVme6yYk5Hr-P-nHnO8n_zTBo,35379
|
|
74
75
|
dw/task_problems.py,sha256=A1nTz_CLstykPLJgq2GWyEb7XhEFeEDHq_DhqB-aMMU,24564
|
|
75
76
|
dw/test.py,sha256=P6JkCw1OjVh-xY_kS-STGlkEHpN9riToXV7A20WX5MA,582
|
|
76
|
-
dw/trust.py,sha256=
|
|
77
|
+
dw/trust.py,sha256=Uwa4XsPOZ6NcAF2E-8mDYBfA0IHK-AeIfQocPtQMqoY,13298
|
|
77
78
|
dw/type_helpers.py,sha256=u9r60J-Sc_X18nS_IZadSyOQGk3NmmSYM4FgYkpMaTY,10036
|
|
78
79
|
dw/type_references.py,sha256=h8E7rqzD-b6fOcFo-OADu1pv7zO4K7qPQ2x-pFQhjYI,11769
|
|
79
80
|
dw/validate.py,sha256=qZO_j0Uah8CXNdO5BjTii6am3LbMn1hlgPACivm1Sz8,2223
|
|
@@ -90,49 +91,49 @@ dw/worker_manager.py,sha256=xW0VR0ceU43bAnmaZTkW7uhislKTdawbJEt2aSTb6jg,13813
|
|
|
90
91
|
dw/worker_protocol.py,sha256=xtRMJF9MSKyNUiJeD2uI9TE5Wq8k-3vB9v7APlAbJWA,7160
|
|
91
92
|
dw/workflow.py,sha256=Wt1V62b0s2-5VeysELIII_g4LQ61Mz_YlLs4fBkF-VM,40800
|
|
92
93
|
dw/workflow_run.py,sha256=T2NI6q7wMdegnLgIFQGjujg2RcWsahFrn76EXsS7xUo,45791
|
|
93
|
-
dw/workflow_schema.json,sha256=
|
|
94
|
+
dw/workflow_schema.json,sha256=AVw1gzLWWZnaaIhJuU2Y318_n2VitriGIPNcTbbUnUg,76928
|
|
94
95
|
dw/workspace.py,sha256=D-xjweJvVknLBJyIeE6IRqeVCXTOnReCyZQwjqWhqi0,26072
|
|
95
96
|
dw/workspace_copy.py,sha256=SVxDZjCKgZKXedzlc6n-jfggtC9Asr0e7ZL0qe-eqUs,22988
|
|
96
97
|
dw/writers.py,sha256=S2-c1zitCHrH7UY8r_O5AmpNFc1eB2IErbAOeSNeWI0,15427
|
|
97
98
|
dw/community_pipelines/pipeline_flux_rf_inversion.py,sha256=XjLO58h5wQn16qP8wEIZKg2Y46mxzQ8qkUu29iQnrrA,50587
|
|
98
99
|
dw/community_pipelines/pipeline_ltx2_refine.py,sha256=kvDBeiaDvt_BX2AjbN6nnYN0EZsEvMzvSC6WzorA_48,6619
|
|
99
|
-
dw/docs/ACCELERATION.md,sha256=
|
|
100
|
+
dw/docs/ACCELERATION.md,sha256=HWKoOwbMBcdCUQG1XHzRKHBD-0BVrMpy6_msW15wirg,34544
|
|
100
101
|
dw/docs/AGENT_LOOP.md,sha256=rMb_c_r2ucsB7djwtQdp9_VVRagvhevWo-Iep7emmS8,4729
|
|
101
|
-
dw/docs/ARCHITECTURE.md,sha256=
|
|
102
|
-
dw/docs/DEPENDENCIES.md,sha256=
|
|
102
|
+
dw/docs/ARCHITECTURE.md,sha256=er-8uJXsCmpV36TXuG6C2QCWJxwi2jXJKzpwfuGXYTM,81580
|
|
103
|
+
dw/docs/DEPENDENCIES.md,sha256=rCEdlxxM_ENwWVkErKCBhGZYObRIMvIsC3tjNy2e0zw,4666
|
|
103
104
|
dw/docs/IP_ADAPTER.md,sha256=AAHaUIfbnOojHfT0noIeypbhdYPluR7sbZeVn5FpbjU,3730
|
|
104
105
|
dw/docs/LORAS.md,sha256=3Kh71Zig2TdNq9VnuYCkyZLhfAa4grfcyU6ikXzhWC0,7465
|
|
105
|
-
dw/docs/MCP.md,sha256=
|
|
106
|
+
dw/docs/MCP.md,sha256=rhW9w4mZ5HUmLVCJbZiTAERlTSwBH1_vj_anHH0HwsU,64729
|
|
106
107
|
dw/docs/PROMPT_WEIGHTING.md,sha256=Pvr25d3yvS8SlnYwX9qc61VvTa8yFMxK_1zMLvrEigI,3031
|
|
107
|
-
dw/docs/QUANTIZATION.md,sha256=
|
|
108
|
-
dw/docs/RECIPES_24GB.md,sha256=
|
|
109
|
-
dw/docs/RELEASING.md,sha256=
|
|
108
|
+
dw/docs/QUANTIZATION.md,sha256=aKohw0jZ28fOzrM_Q50QQ2klp-AdC_mKikz6u75yHN8,12103
|
|
109
|
+
dw/docs/RECIPES_24GB.md,sha256=nHCO8Go1mX_Ogm50z0hBn4ajGqeSlqRygBRiSiFeKGY,19219
|
|
110
|
+
dw/docs/RELEASING.md,sha256=rm2Ie40wN1F7Y13FrD8XaKFa9TsU08yW4JTNyCTeAtc,70760
|
|
110
111
|
dw/docs/REMOTE.md,sha256=rlqqi10Hm6LVwwu106_LTVlN2oBU0jKdnjupNffrGSE,6793
|
|
111
|
-
dw/docs/SECURITY.md,sha256=
|
|
112
|
+
dw/docs/SECURITY.md,sha256=qVxJjSwbyjzBySLrdtO3VSXAwm1xTsR8A6U_IYzVprY,22862
|
|
112
113
|
dw/docs/SECURITY_QUICKREF.md,sha256=-xZNIV6j1oWcoy5B-oHKqh3ko2zJgB2fuNMiDV4f1zY,3537
|
|
113
114
|
dw/docs/SERVER.md,sha256=byJ9VZDRqsinJUqAQvHjmDbDr_5qf3Jc7iTbN8SShaQ,73365
|
|
114
|
-
dw/docs/TASKS.md,sha256=
|
|
115
|
+
dw/docs/TASKS.md,sha256=VmwB8X7Sc4MSIhqLNUyJzbTCnMTljP11m2lBsz_EPAA,181619
|
|
115
116
|
dw/docs/TESTING.md,sha256=D4zmQp0iVmREM9J1tq4RxTmmIxvxsp5dRtuRGovP96s,3973
|
|
116
117
|
dw/docs/WORKER_GUIDE.md,sha256=t-RjdZ-7reBUfQypxfk_Qm4aPESMAGi7Wn-0Ri5S3Z8,2814
|
|
117
|
-
dw/docs/WORKFLOW_GUIDE.md,sha256=
|
|
118
|
+
dw/docs/WORKFLOW_GUIDE.md,sha256=ntzozyfFlGg8B_uS0m8siEo_Sa_hqVP608f3TWF0aT0,155511
|
|
118
119
|
dw/docs/WORKSPACES.md,sha256=fB7jbkB9ketnE9YxHlnAJZvNiHvke_SZl-_4yswjLSA,28206
|
|
119
120
|
dw/pipeline_processors/adapters.py,sha256=2i9XIbxeDfHWsB5RD4oUbExdg9WJnLTy4VFO8s8lcPE,9705
|
|
120
121
|
dw/pipeline_processors/chain.py,sha256=2KscX3jQttJL6NmEfiQquPGmBjYIGPOaueHbDv0OUHw,41721
|
|
121
|
-
dw/pipeline_processors/components.py,sha256=
|
|
122
|
+
dw/pipeline_processors/components.py,sha256=cFORltqkBukRhtENnoDOHQOFGnHfJCPbZekyU_N-cr0,47116
|
|
122
123
|
dw/pipeline_processors/config_objects.py,sha256=rVxhRSJiKz9tK-HeWiplPn3iYFCqd-02UcO_auUY6cY,11148
|
|
123
124
|
dw/pipeline_processors/h3_guide_steps.py,sha256=wsaV7jFqcoZAEfjjyKYAMust3XgotqMkftlA-Ov5WrE,21580
|
|
124
125
|
dw/pipeline_processors/h3_guides.py,sha256=dgz2hYyoMTZL7ppMcdIPyZ7JXfYzrI61GFiznIGdtDU,14918
|
|
125
126
|
dw/pipeline_processors/h3_hold.py,sha256=dwpUuT8NuAVo77_4YVBAvn3G5oBW32e6M6i-cds66oU,9912
|
|
126
127
|
dw/pipeline_processors/h3_hold_steps.py,sha256=mjoWAYHrVhQbpcXCzDVHhOXtCH50wXSUJjTmRhAGfzw,16437
|
|
127
128
|
dw/pipeline_processors/h3_rules.py,sha256=Kpm4xeO7oiM2hdECjvnPg_NZTgCO-vBxs2jHtNW08iA,9244
|
|
128
|
-
dw/pipeline_processors/pipeline.py,sha256=
|
|
129
|
+
dw/pipeline_processors/pipeline.py,sha256=gda9a3CQ36niVI-RZE5EXnH11HHG4dJiiAPib3HHeRk,46477
|
|
129
130
|
dw/pipeline_processors/placement.py,sha256=D-7ZMNs2P8t81CTtwc_APVrlk_8bz7Ek0M-Hb8wFhV4,16342
|
|
130
131
|
dw/pipeline_processors/progress.py,sha256=RUv2ftKo18zqiDI0tUV6aPkFAVIMhfBPxEBpylPXflI,9431
|
|
131
132
|
dw/pipeline_processors/remote.py,sha256=eZl6fPEKUrd1ieFgX94QNKAR4ziPH9JXTV_Hse4VsqY,2450
|
|
132
133
|
dw/pipeline_processors/timing.py,sha256=mkFj49TJKxZVVoi3dCJ3s8EybCPpS3TNWtQfuvBR2c8,19561
|
|
133
134
|
dw/server/__init__.py,sha256=NGXV8LM6oYUZhEwWSDo3ihBvmzrC71az3Wc2gkGodcM,153
|
|
134
135
|
dw/server/admission.py,sha256=9Sx-L11cvNHIl7ojQowIL3uuCRdDODNFbhRmrdwDy6Q,24581
|
|
135
|
-
dw/server/api_models.py,sha256
|
|
136
|
+
dw/server/api_models.py,sha256=-Dtk7sef0E1Qi25X7c5T1BQUGeeAtX-XF9NGZl9z7N8,30303
|
|
136
137
|
dw/server/api_models_base.py,sha256=qBcRTjW0zyAy4G2kCzOdRzXy6p0bMLFauTCndyftgFI,1977
|
|
137
138
|
dw/server/api_models_library.py,sha256=9Gsoy_inDv_dBvE0qZ0w3PFXHIkit7g298yNxqQ8pfE,5748
|
|
138
139
|
dw/server/app.py,sha256=ruqhEDErxuzUr_9FVfIJ4vdgCalK4MU6vtFzhE2pLgE,10670
|
|
@@ -167,8 +168,8 @@ dw/server/routes/jobs.py,sha256=MIChTh_VgWcl7tGBVaPIy41gpO5AGReJHdHWCaHTKjQ,4007
|
|
|
167
168
|
dw/server/routes/library.py,sha256=yjHhpQIMS-kMRRZqpbcXzTsNVyzKpS60qlU6XUU5n3I,34611
|
|
168
169
|
dw/server/routes/loras.py,sha256=Hai7GIt7nXPiFa-zWWxEtCCrjPfJz3JzmIlBm2tS7ck,8270
|
|
169
170
|
dw/server/routes/media.py,sha256=FAt1HPPk28j3-5qBvcH7uX1u6aWiRm9pzZlfBglT2Yw,41875
|
|
170
|
-
dw/server/routes/system.py,sha256=
|
|
171
|
-
dw/server/ui/index.html,sha256=
|
|
171
|
+
dw/server/routes/system.py,sha256=RMmcOpmdzsyLjALGH99OHLlAJrkj_oyKQEpCYb2yGAg,21600
|
|
172
|
+
dw/server/ui/index.html,sha256=jPVBhTuVhMfijVe8GYcpr43aa2vAJTvE7aL6TafEjuo,826
|
|
172
173
|
dw/server/ui/assets/abap-08VXUWAP.js,sha256=v_s2iGszAEBUjgmnxo-oLx1BQTQAjswxiNzZ24fNZ3o,11690
|
|
173
174
|
dw/server/ui/assets/apex-BWPQTe0t.js,sha256=eUu2JicJ0pjmMYETgWVVuzFEJeyxEfievljL436Mt3Q,3469
|
|
174
175
|
dw/server/ui/assets/azcli-Bc_sGQ0U.js,sha256=LDRk2Ih2wJsTBkEl5yiESmbLMeMCGuNGu5aDZxaZzRA,707
|
|
@@ -183,44 +184,44 @@ dw/server/ui/assets/csharp-BKxtCVv1.js,sha256=tcK0xVr_gQziNy8CVDw-kMQEwehIe9ND34
|
|
|
183
184
|
dw/server/ui/assets/csp-bTuwJoIa.js,sha256=pUYDwODPsXKr4shrxhfRg0_WRY3TLT8f5omX7nYPw7Y,1278
|
|
184
185
|
dw/server/ui/assets/css-DIMkf-bt.js,sha256=Nhs17Txzlhf5DumZtrz-bnBHwdMMUt9YQBxQSG9f2OQ,4361
|
|
185
186
|
dw/server/ui/assets/css.worker-C6lDtRpF.js,sha256=ft-SA2IfNjCmj4OcQzAbBRB2HdcczVU36dvuGSI_uaA,1078254
|
|
186
|
-
dw/server/ui/assets/cssMode-
|
|
187
|
+
dw/server/ui/assets/cssMode-D_BuRO9Y.js,sha256=35oGAZwX6LWoxVDe4hfdwnCrWYSTUkME3_xUfZ2rZ-4,2952
|
|
187
188
|
dw/server/ui/assets/cypher-CVaqCwHa.js,sha256=AYGtVhyMHJdRbOwpGLEfAPAyHAdwXc3J0D_mjN4oLVg,3048
|
|
188
189
|
dw/server/ui/assets/dart-onAF5SnQ.js,sha256=QWSf47NMFu2yUd9XFSGEuisDrfcp-gvscx9WznuMY2w,3931
|
|
189
190
|
dw/server/ui/assets/dockerfile-DZFCIeNp.js,sha256=hIFKl4QSK6zsn49CP3KacmKpiovwWnTZleepql5VAHo,1728
|
|
190
191
|
dw/server/ui/assets/ecl-D05T4iGw.js,sha256=8dy8B-9clhaDibzPszzXjx7c9Zj0t2pUw19rgIOlAkM,4623
|
|
191
192
|
dw/server/ui/assets/editor-DjpsE8to.css,sha256=eXqoXVVwoOu7BHCT9Y6a3BOUUHhJVCWycTMHPlsVqdo,99095
|
|
192
|
-
dw/server/ui/assets/editor.api-
|
|
193
|
+
dw/server/ui/assets/editor.api-B6pi6BSE.js,sha256=NLbZE7WaUbI639gmacUm3FHlBt7eKAPRyZV8d-zkouw,2735707
|
|
193
194
|
dw/server/ui/assets/editor.worker-BmdWdrHZ.js,sha256=Ih2vJ17lgC5GJ1KP9ltE1UyLran3eG7m51K9mfkfofE,303777
|
|
194
195
|
dw/server/ui/assets/elixir-6RTg0lbw.js,sha256=_AM20WhJvweAHmfSKZJwEaIeLg71t8jkSUJgRVz5P0w,10116
|
|
195
196
|
dw/server/ui/assets/flow9-C5_-GSwl.js,sha256=kUYiOodGRTZ6qJ5xielY8Ku5yBXlsEOb9kxSY4Fajb0,1669
|
|
196
|
-
dw/server/ui/assets/freemarker2-
|
|
197
|
+
dw/server/ui/assets/freemarker2-mPiw3NV_.js,sha256=Y3fqlMuVPGuyUlGCcH-RI_tWOSxd8BVdNKyBW3axIHU,15548
|
|
197
198
|
dw/server/ui/assets/fsharp-C8Ef5oNN.js,sha256=UTeoJ7rvyxEcL_h0e74Hkkyfnqjz1KegentufCX2nkU,2651
|
|
198
199
|
dw/server/ui/assets/go-C-y9NEjX.js,sha256=yiNuAvOl-CJdg1l7tlsDbqjKrl95VJ6jchO7KXm8sIU,2350
|
|
199
200
|
dw/server/ui/assets/graphql-fmXr3nnJ.js,sha256=pm47jqz4rUAXQDgl98x5ePvvxf0fgOpsBE-AWYSMUYY,2119
|
|
200
|
-
dw/server/ui/assets/handlebars-
|
|
201
|
+
dw/server/ui/assets/handlebars-BfGb596Y.js,sha256=hBX4doUFAKBHQWaz6_b3hOOODlQr4t48_1yJjFZANuc,6284
|
|
201
202
|
dw/server/ui/assets/hcl-CpzslTdj.js,sha256=FTELtvUdJnCIa6x3jYwjNRaXvSqDk7_x4SlTYehMmdI,3449
|
|
202
|
-
dw/server/ui/assets/html-
|
|
203
|
+
dw/server/ui/assets/html-xXIqw-JZ.js,sha256=upLQkkiS1RR-4__b4uFLCYb76mmcAcpUK8OBjSGk1T8,4516
|
|
203
204
|
dw/server/ui/assets/html.worker-C5yZDBHz.js,sha256=4Kkoa_A4TNCicFnuUnxjWUnhuTl1Mn4XhuWx5B3E4w4,743387
|
|
204
|
-
dw/server/ui/assets/htmlMode-
|
|
205
|
-
dw/server/ui/assets/index-
|
|
205
|
+
dw/server/ui/assets/htmlMode-B3FC_H4q.js,sha256=ivIlqsKHf-NBcqyOuJ5vY2zHXF09EU2tslueIA_vPj8,3406
|
|
206
|
+
dw/server/ui/assets/index-Civ6zDZP.js,sha256=TTSWZ_amx-kQVf-oJDt6dWqSQT0FkC9ZZD-lliVQWq0,517581
|
|
206
207
|
dw/server/ui/assets/index-PRSQwOeN.css,sha256=L7SSBB84P-wyX2iqJyZG17UWTYxsLIMV6O4o7PeH7GU,83464
|
|
207
208
|
dw/server/ui/assets/ini-sBoK_t0W.js,sha256=6QF6Fp68pxwu26PuYuAa5XlpwDMMopXB8gHj4XgppU4,960
|
|
208
209
|
dw/server/ui/assets/java-BEtHBSE6.js,sha256=d9OpHur1TgBPjsMh5iCK_s6-JDUjIUa0H2gTU3OACVM,2906
|
|
209
|
-
dw/server/ui/assets/javascript-
|
|
210
|
+
dw/server/ui/assets/javascript-B-FFcgST.js,sha256=aumDzX_ILAyGp03_BHO0_cQa98NA-AGKq-H6a9xsRC0,688
|
|
210
211
|
dw/server/ui/assets/json.worker-DdeUAmHa.js,sha256=Gihf5S5n4Xv_Ipc_FoW6p492ZrLcyFk22r-RcK-GTlA,433137
|
|
211
|
-
dw/server/ui/assets/jsonMode-
|
|
212
|
+
dw/server/ui/assets/jsonMode-BELbxUQD.js,sha256=xOVW3sMt8cF8vSAf4kzX6GWBcXfNgHyh2T5PkXBJ9CE,12178
|
|
212
213
|
dw/server/ui/assets/julia-Bri6UV-V.js,sha256=GgHfKwkibx83YYASauJxey9COaeCnDC0-FO9DI5h1ww,6505
|
|
213
214
|
dw/server/ui/assets/kotlin-BOotOW0E.js,sha256=y9kKjKTUCkkgIf0XZrn0aW0M28yZaabvrArNjMhi9kM,3041
|
|
214
215
|
dw/server/ui/assets/less-B9JPFI3C.js,sha256=RK-lDgNqYLUdnolGcFtj5W5Nhdj2rhAQjegLMStkLbw,3749
|
|
215
216
|
dw/server/ui/assets/lexon-CfSJPG6W.js,sha256=3wceYal1Tl_3oIKlurT29e46CCwlH0DYXRxHyki6aAc,2288
|
|
216
|
-
dw/server/ui/assets/liquid-
|
|
217
|
-
dw/server/ui/assets/lspLanguageFeatures-
|
|
217
|
+
dw/server/ui/assets/liquid-CxXhb7_e.js,sha256=aSrVlMKrhUaXmu4_Nd7fUmGjpBc17YzMK_l0yHkDJGM,3344
|
|
218
|
+
dw/server/ui/assets/lspLanguageFeatures-sXyBqSzn.js,sha256=wDjyFsBkcOCWEYy5-TyBfjzzamxN3SM7WE0lG83Oq4o,28224
|
|
218
219
|
dw/server/ui/assets/lua-CsQS60Ue.js,sha256=T68zBfv8YbWQOUMOoKDHlS6ZLXQbvUoVzIqjfdKaN80,1982
|
|
219
220
|
dw/server/ui/assets/m3-D-oSqn_W.js,sha256=wiQpsc-ejuU-Nd_N1EEku70GvFxCKR2enx_4FMaLERU,2520
|
|
220
221
|
dw/server/ui/assets/markdown-Cimd5fb3.js,sha256=Yh5RI0xP6paio6bg3VkVHxwCFtfLSpYzYe4pqjAseXc,3639
|
|
221
|
-
dw/server/ui/assets/mdx-
|
|
222
|
+
dw/server/ui/assets/mdx-4jPGQ4yb.js,sha256=55LE1FjakLcAu4i0NQqu7mHAnbdnNfEaFXAIZaeo3bw,4319
|
|
222
223
|
dw/server/ui/assets/mips-CIPQ_RoX.js,sha256=Mf9nhH4UiNv4cOxx9GbzZEwcanALyeX1nqZyeDVwn-8,2325
|
|
223
|
-
dw/server/ui/assets/monaco-
|
|
224
|
+
dw/server/ui/assets/monaco-ByFdQnrs.js,sha256=T_ewK8nqay68-sIGZOtbeucUS4HcLGTrJejtN9u9LD8,1296590
|
|
224
225
|
dw/server/ui/assets/monaco-n7clI0si.css,sha256=_s5n5INJJjzoqAk04ZYXP99EFmWEMeL6k0BatkMtehw,86925
|
|
225
226
|
dw/server/ui/assets/msdax-DauUninz.js,sha256=x-Ec1FvZQfNyIBufG3aF-nbhjtWWCb4trNEl2w7mORU,4270
|
|
226
227
|
dw/server/ui/assets/mysql-SOo6toE5.js,sha256=s0175vipA9oId7yWxl-u4jDQp6cAD1LlzIlQ94knUzE,9659
|
|
@@ -236,10 +237,10 @@ dw/server/ui/assets/powerquery-D3hlyOfw.js,sha256=h7-yZyeDYpf8Vz7I-o-AdOXL673EDo
|
|
|
236
237
|
dw/server/ui/assets/powershell-DmHpPYUd.js,sha256=fS-k4myYtbJ7I-nT4AOE2xWBU6BC4yBTsO8utRI2kYA,3057
|
|
237
238
|
dw/server/ui/assets/protobuf-C531GsRP.js,sha256=CE2QZMYH5tuK5qacJhFCN5Egq0ldACCn8ZMy7drCA_A,8897
|
|
238
239
|
dw/server/ui/assets/pug-Z5eAx3Zn.js,sha256=3W_Q5pw42PShvXTeZmdid5YpzS29ZEKItG3NbMZkZIY,4468
|
|
239
|
-
dw/server/ui/assets/python-
|
|
240
|
+
dw/server/ui/assets/python-D3CL9Y6O.js,sha256=uFvkqpg1C7Q60smwi_nsHIpUv5DeM1ljCwFTsBsEfzw,3455
|
|
240
241
|
dw/server/ui/assets/qsharp-DkqhCAOL.js,sha256=72cTeKiuU6qRxzI9j4KVb-r2y5u7Yj9O-DppqJMrsw8,2722
|
|
241
242
|
dw/server/ui/assets/r-BwWrilGY.js,sha256=kjvwR-197La6WrPfRntvc5VS4GcVs7SVUIcq5brgDh4,2836
|
|
242
|
-
dw/server/ui/assets/razor-
|
|
243
|
+
dw/server/ui/assets/razor-F_hjmtqk.js,sha256=Ce12v52aQOQrmZcSd56LbN01B6kOW-L_vOalU2JFS-Y,8113
|
|
243
244
|
dw/server/ui/assets/redis-ClamHrr6.js,sha256=P6KIG5bJRWvmyPzG14QO5RZJlmj49pzn-p4hDqSFQ5M,3032
|
|
244
245
|
dw/server/ui/assets/redshift-DT7zqm-g.js,sha256=PmLS8mPeeCIWu-NLw1SMU7nZp94WvW7aqKAG7TbJv3c,10331
|
|
245
246
|
dw/server/ui/assets/restructuredtext-BYgofb2h.js,sha256=UmiK7-mgglvXYqrOt4NCdx4oKNNoHilj1XfmVkRw7mA,3744
|
|
@@ -259,15 +260,15 @@ dw/server/ui/assets/swift-Bxkupp3x.js,sha256=PAoUaoj9w0C1Q8tOfBsDefytIxzaJLYxXo8
|
|
|
259
260
|
dw/server/ui/assets/systemverilog-Bz4Y3fRF.js,sha256=N8BJdmDPdAS3YSLf9-c6WjpeHiC8AUiPFC0b83QRu84,6850
|
|
260
261
|
dw/server/ui/assets/tcl-DISqw1ZD.js,sha256=tGDwrjRxtiwzHBQVX4aYHPx2tvnzyCbsk3MouRN8nGI,3271
|
|
261
262
|
dw/server/ui/assets/ts.worker-DGGa2mF8.js,sha256=Eo0Wf0gtl2BDSbqkCqvF4LtrJA8iMe9U-cKzQ3RM8kY,6928036
|
|
262
|
-
dw/server/ui/assets/tsMode-
|
|
263
|
+
dw/server/ui/assets/tsMode-BiyDvHYY.js,sha256=Ca-0GBGSaciuRPPUZghR3qKcQOp7d0RJ6suZUrGhiDg,21847
|
|
263
264
|
dw/server/ui/assets/twig-De2hgUGE.js,sha256=7UK-mZY0t2AOG2upJFdhUfk_hN4jQxNO37xW_pXsYRk,5781
|
|
264
|
-
dw/server/ui/assets/typescript-
|
|
265
|
+
dw/server/ui/assets/typescript-DBE1Uz0U.js,sha256=wpw7vVkVIjjlFwaqrO04e6awRMhkWDxAi7jrmxpR8_w,4675
|
|
265
266
|
dw/server/ui/assets/typespec-B8J7ngcE.js,sha256=4SiWGtYCn-n7DAFoQw3hFbXpXOEzUIVgPrFnMxeDL0A,2625
|
|
266
267
|
dw/server/ui/assets/vb-DV3o63ZY.js,sha256=g6FxShoSupLTGxKrGHUt31pO6FoCrY9npMMQpnSqtsM,5300
|
|
267
268
|
dw/server/ui/assets/wgsl-DpFanUEy.js,sha256=M1uSecn4lmt1G3mQyTCdxT4mfHC4g3AjJAw7cuUwAg4,7182
|
|
268
|
-
dw/server/ui/assets/workers-
|
|
269
|
-
dw/server/ui/assets/xml-
|
|
270
|
-
dw/server/ui/assets/yaml-
|
|
269
|
+
dw/server/ui/assets/workers-Ci7sZ35J.js,sha256=SPZgma5rj251uDHUfU8S3c961xkMEK8tUweIbqRG-c0,1249
|
|
270
|
+
dw/server/ui/assets/xml-Eqpmo6a1.js,sha256=9m7_keGrw_IAsVG8dxe-e4P04O5QOqoDpe9adZ9P4uk,1923
|
|
271
|
+
dw/server/ui/assets/yaml-BNP_JiwW.js,sha256=cHR32zoyBcp4r0b5IGVOgUEA_hExSz62X3PphQCeS54,3543
|
|
271
272
|
dw/tasks/assess.py,sha256=fgz2x3P6-9z9gusMgfws9kWqeVF9XkeabEwTzifSBQY,33654
|
|
272
273
|
dw/tasks/audio_dynamics.py,sha256=-dhNkBM3CkWGLbbd5fUExbWCb4FyLJp3mYkqIO4OeIg,18060
|
|
273
274
|
dw/tasks/audio_handlers.py,sha256=0hLa6olH2x01mQO5ev9yUBDd5BZbeHoZWGzkac_ut8c,8799
|
|
@@ -311,11 +312,11 @@ dw/tasks/rife_model.py,sha256=eO77oSH4OGY5pXBp6UDaXIDbGPlOHPIiXMrf1RMzYjo,6387
|
|
|
311
312
|
dw/tasks/script_check.py,sha256=4YJkN-6jdJJPTPld9EEFQZOUfKDjbyLxpOlLh5qIBRk,33198
|
|
312
313
|
dw/tasks/segment.py,sha256=2g-jndKDlIcVMH4OApWNlWzt-8DzQvhK82_TNMSXoTI,4267
|
|
313
314
|
dw/tasks/select.py,sha256=kDNxiVLN2_rN0LlQ6ORQe4mjn6s-iHpBzgyNLUd0_ss,3484
|
|
314
|
-
dw/tasks/speech_generation.py,sha256=
|
|
315
|
+
dw/tasks/speech_generation.py,sha256=tVPYzv7_8kg5oy41tntPSKyYuxc8cH4ptkInUwhbsJw,11744
|
|
315
316
|
dw/tasks/stabilize.py,sha256=XtVCV87gmsd0Q24U4Do6CqXEt54zxe7Vg6AED6UDsNo,5018
|
|
316
317
|
dw/tasks/task.py,sha256=QYDCPfik-Oc9D6aBeLXF1eDFj9B3nvLHZbMt3CD9fIs,14406
|
|
317
318
|
dw/tasks/tensor_image.py,sha256=xJDo5-Bi7drP4LqXgg_qGeEbC8q9-KA84iVJolQURhE,2083
|
|
318
|
-
dw/tasks/text_generation.py,sha256=
|
|
319
|
+
dw/tasks/text_generation.py,sha256=u8NbHYRmRrFNtX3tmmRYb94cuDqXYWGSZkpEymJ_rYg,18738
|
|
319
320
|
dw/tasks/text_sections.py,sha256=0eE7O0eLQCgxEooO3-RLuQSRwmeFwHttLqwhp71q3Lw,3260
|
|
320
321
|
dw/tasks/trim.py,sha256=wXKBjSdYTZQXlMIJpBwTGxJoun_SBzqw0kkPgF3-Nhg,5253
|
|
321
322
|
dw/tasks/upscale.py,sha256=4GIMgDEPtA39ecSMUD0PKaXEB2UaBCnEpO0XK3ojtb0,6852
|
|
@@ -324,11 +325,13 @@ dw/tasks/video_utils.py,sha256=4y08HWu99BZZZV4bFI9qeSFeEGuKMKqUmfvMXNuLrW0,19873
|
|
|
324
325
|
dw/tasks/voice_attribution.py,sha256=ZdCJcYbaEFQuMyCdKSs-qwrcGN3xjUPR2ePqPNcILis,36288
|
|
325
326
|
dw/tasks/windows.py,sha256=6Eho44yC0-nIY51yvsA0qBfQx9v5VXDWhxBftDkWLvU,21955
|
|
326
327
|
dw/tasks/zoe_depth.py,sha256=s-otGgDA_wIfawzGWhHd9eDtHBiNsNosjCUH3qIr03c,1817
|
|
328
|
+
dw/workflows/flux3_klein_upsample.json,sha256=3WkE2emSKGbsR03YJPlIsi_F5HAdgpC_Nzvm0WwCOUU,1800
|
|
329
|
+
dw/workflows/flux3_klein_upsample_edit.json,sha256=nU-gUblLrbT9UD_HZuovaQfg-vjJFb82hLQTV0_or1c,2932
|
|
327
330
|
dw/workflows/h3_context_ir.json,sha256=nasb5JKFs6bkqYXuTvCyyiGAROBo8N0vDw_X-ec8SYM,13653
|
|
328
331
|
dw/workflows/test.json,sha256=XFvEH7_8F8MGoX5b1j0FnT8dJghYiuyukj2q0JSEfkU,937
|
|
329
332
|
dw_mcp/__init__.py,sha256=v6ezMWrVwQmdKO_ze1xrqVF10NhjdnoE-ikK-NbXaus,435
|
|
330
333
|
dw_mcp/__main__.py,sha256=xiH0reOcZksZivZdK-PWD4A4HQSngiOLq4_D93wIqvg,4364
|
|
331
|
-
dw_mcp/assets.py,sha256=
|
|
334
|
+
dw_mcp/assets.py,sha256=5tjVS3rcx505RN-7vQ1sNgGJf_bD9BuvrjtAnzIFxm0,17838
|
|
332
335
|
dw_mcp/authoring.py,sha256=dNqhY5JnACSgfK9g1rDIURSLupWEn2h82bqd-iy43yM,5027
|
|
333
336
|
dw_mcp/catalog.py,sha256=qrmh9Gz3_g8Adm2rFQj5xqR_PTI37nci3VasiScAyH4,17477
|
|
334
337
|
dw_mcp/client.py,sha256=nqT5ClROP_Sza4WWbqtGHpxiQMGIRLh6Lb7LjzlrMHo,22855
|
|
@@ -341,13 +344,13 @@ dw_mcp/media.py,sha256=4MeRDi22JH4yhhnsQA4iCNSjhno3ZW6sZBTRrHgQHYY,23552
|
|
|
341
344
|
dw_mcp/models.py,sha256=uzsUY-CgiaP1LZLbdLnVRVXFSK2kcXs_tNquRKM6d9w,4220
|
|
342
345
|
dw_mcp/prompts.py,sha256=6gVgr6PJKwqvMDEXhMqMkZ5Y2EQ2YxESZFSdS-boCvA,4156
|
|
343
346
|
dw_mcp/server.py,sha256=aZEchCRpT2AMtWpM8bDcz6bKkgq9ORWpCCnb3UExrW8,7817
|
|
344
|
-
dw_mcp/tools_authoring.py,sha256=
|
|
347
|
+
dw_mcp/tools_authoring.py,sha256=0lvVU1NS5HDijLKMcUhuMSb1MNyK7dKj2-YcXNl2wq0,13369
|
|
345
348
|
dw_mcp/tools_catalog.py,sha256=Mt64C00eV2AAGT5XmmfsyfmiP86qVEQ5YXWhsTZc7J4,21485
|
|
346
349
|
dw_mcp/tools_jobs.py,sha256=IEErwMReZGBVVtbIpJFypNLB60q5gB87zZaSYDD-0hE,12403
|
|
347
|
-
dw_mcp/tools_media.py,sha256=
|
|
348
|
-
dw_mcp/workspaces.py,sha256=
|
|
349
|
-
diffusers_workflow-0.
|
|
350
|
-
diffusers_workflow-0.
|
|
351
|
-
diffusers_workflow-0.
|
|
352
|
-
diffusers_workflow-0.
|
|
353
|
-
diffusers_workflow-0.
|
|
350
|
+
dw_mcp/tools_media.py,sha256=1XwB3sBIxzXEIbPLF4s16SjLyxzlrI2fF4uZW0xe7JM,18755
|
|
351
|
+
dw_mcp/workspaces.py,sha256=wuFRa5fv4lQ5rFYJ01dm6LRBDBlajPxpwLZ-qh6JpAU,10976
|
|
352
|
+
diffusers_workflow-0.15.0.dist-info/METADATA,sha256=u-0bP72qu9p8ORnV2-hXrVGKsso85l_vDts6bpJHs9s,14967
|
|
353
|
+
diffusers_workflow-0.15.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
|
|
354
|
+
diffusers_workflow-0.15.0.dist-info/entry_points.txt,sha256=Dem_AOzV-Kcpr9AASlSvJ-S5sn3f6TQu6ABb6BbApho,148
|
|
355
|
+
diffusers_workflow-0.15.0.dist-info/top_level.txt,sha256=o-uFAN_oUOrhXfMKO39HsMs2r19L9LykxoVKj2S9q7U,10
|
|
356
|
+
diffusers_workflow-0.15.0.dist-info/RECORD,,
|
dw/acceleration_warnings.py
CHANGED
|
@@ -27,6 +27,9 @@ Each of these cost a render to find out in Don's `h3-quality` matrix:
|
|
|
27
27
|
cache's skip decision needs (`docs/ACCELERATION.md`).
|
|
28
28
|
- `attention_backend_unavailable`: a CUDA-only attention backend on a device
|
|
29
29
|
that isn't CUDA passes validate and fails at load.
|
|
30
|
+
- `sparse_attention_fallback`: the `sparse` attention backend on a device that
|
|
31
|
+
isn't CUDA. It never fails a run: it falls back to dense attention, so this
|
|
32
|
+
says the speedup is not coming, not that the job will break.
|
|
30
33
|
|
|
31
34
|
Every one is a warning and never a refusal. A value that cannot be resolved
|
|
32
35
|
before the run (a null variable, an unknown device) leaves its warning
|
|
@@ -39,6 +42,8 @@ import typing
|
|
|
39
42
|
from . import get_device_type
|
|
40
43
|
from .introspection import load_pipeline_class
|
|
41
44
|
from .references import iter_steps, render_path
|
|
45
|
+
from . import sparse_attention
|
|
46
|
+
from .sparse_attention import SPARSE_BACKEND
|
|
42
47
|
from .vram_estimate import required_vram_gb
|
|
43
48
|
|
|
44
49
|
# The fewest denoise steps a threshold cache is expected to skip any of. A
|
|
@@ -82,6 +87,7 @@ SHORT_SCHEDULE = "cache_short_schedule"
|
|
|
82
87
|
TAYLORSEER_STATE = "taylorseer_state_unestimated"
|
|
83
88
|
FULLGRAPH_WITH_CACHE = "compile_fullgraph_with_cache"
|
|
84
89
|
BACKEND_UNAVAILABLE = "attention_backend_unavailable"
|
|
90
|
+
SPARSE_FALLBACK = "sparse_attention_fallback"
|
|
85
91
|
CACHE_UNSUPPORTED = "cache_unsupported"
|
|
86
92
|
|
|
87
93
|
# The component names a cache hook attaches to, as in
|
|
@@ -258,6 +264,13 @@ def acceleration_warnings(context):
|
|
|
258
264
|
continue
|
|
259
265
|
for path, block in backends:
|
|
260
266
|
name = block.get("attention_backend")
|
|
267
|
+
if name == SPARSE_BACKEND:
|
|
268
|
+
warnings.append(
|
|
269
|
+
f"{render_path(path)}: {SPARSE_FALLBACK}: sparse attention "
|
|
270
|
+
f"needs CUDA; this server is '{context.device_type}', so "
|
|
271
|
+
f"the run uses dense attention{where}"
|
|
272
|
+
)
|
|
273
|
+
continue
|
|
261
274
|
if name not in CUDA_ONLY_ATTENTION_BACKENDS:
|
|
262
275
|
continue
|
|
263
276
|
warnings.append(
|
|
@@ -273,3 +286,26 @@ def acceleration_warnings(context):
|
|
|
273
286
|
path, _, rest = warning.partition(": ")
|
|
274
287
|
said.setdefault((path, rest.partition(": ")[0]), warning)
|
|
275
288
|
return list(said.values())
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
def available_attention_backends(device_type: str) -> list[str]:
|
|
292
|
+
"""The attention backends a server on `device_type` can run, in menu order.
|
|
293
|
+
|
|
294
|
+
`native` first, then the other `native`-family names; on CUDA, `sparse`
|
|
295
|
+
(only where the compiled kernels loaded) and the CUDA-only names. A name
|
|
296
|
+
diffusers' `AttentionBackendName` lacks is dropped, so the menu never
|
|
297
|
+
offers one the pipeline would refuse.
|
|
298
|
+
"""
|
|
299
|
+
from diffusers.models.attention_dispatch import AttentionBackendName
|
|
300
|
+
|
|
301
|
+
known = {backend.value for backend in AttentionBackendName}
|
|
302
|
+
cuda = device_type == "cuda"
|
|
303
|
+
names = ["native", "_native_flash", "_native_efficient", "_native_math"]
|
|
304
|
+
if cuda:
|
|
305
|
+
names.append("_native_cudnn")
|
|
306
|
+
names.append("flex")
|
|
307
|
+
if cuda:
|
|
308
|
+
if sparse_attention._kernels_importable():
|
|
309
|
+
names.append(SPARSE_BACKEND)
|
|
310
|
+
names.extend(sorted(CUDA_ONLY_ATTENTION_BACKENDS))
|
|
311
|
+
return [name for name in names if name == SPARSE_BACKEND or name in known]
|
dw/docs/ACCELERATION.md
CHANGED
|
@@ -159,20 +159,58 @@ Select the attention implementation diffusers uses for the duration of each pipe
|
|
|
159
159
|
}
|
|
160
160
|
```
|
|
161
161
|
|
|
162
|
-
Common values: `"flash"`, `"flash_hub"`, `"sage"`, `"sage_hub"`, `"native"`, `"flex"`. The full set is diffusers' `AttentionBackendName` enum - availability depends on what's installed (`flash-attn`, `sageattention`, etc.) and the platform. `_hub`-suffixed backends are fetched from the Hugging Face Hub kernel registry on first use, which needs the `kernels` package installed (`pip install kernels`) - it is not a dw dependency
|
|
162
|
+
Common values: `"flash"`, `"flash_hub"`, `"sage"`, `"sage_hub"`, `"native"`, `"flex"`. The full set is diffusers' `AttentionBackendName` enum - availability depends on what's installed (`flash-attn`, `sageattention`, etc.) and the platform. `_hub`-suffixed backends are fetched from the Hugging Face Hub kernel registry on first use, which needs the `kernels` package installed (`pip install kernels`) - it is not a dw dependency. The only backend a bundled workflow sets is `sparse`, the default on every MiniMax-H3 template, and it needs no `kernels` install (comfy-kitchen is a core dependency), so each bundled workflow runs on a plain install. diffusers also refuses a Hub kernel whose publisher it does not list as trusted - `sage_hub` among them, since SageAttention 2 comes from `SageAttention/sage-attention` - until `DIFFUSERS_TRUST_REMOTE_KERNELS=true`, which allows remote code from any such publisher. On an RTX 3090 `sage_hub` measured about 30% faster per MiniMax-H3 step (13.8 s against 19.2 s at 960x544x124, 54.7 s against 81.2 s at 345 frames); the local `sage` backend needs `sageattention>=2.1.1`, which PyPI does not carry.
|
|
163
163
|
|
|
164
164
|
Every MiniMax-H3 template in [templates/minimax/](../workflows/templates/minimax/)
|
|
165
165
|
exposes this as a variable: `attention_backend`, pinned on the H3 step's transformer
|
|
166
166
|
(`components.transformer`, or `components.transformer_ref` for a ref2va workflow) and
|
|
167
|
-
`
|
|
167
|
+
`"sparse"` by default (with `sparse_tau`, below). That covers the shots, chains and episodes - `dialogue-short`,
|
|
168
168
|
`shots-batch`, `music-video` and `storyboard` among them - and only their H3 steps: a
|
|
169
169
|
Z-Image still or Music3 song beside an H3 shot keeps the process default. Pass
|
|
170
|
-
`attention_backend=sage_hub` to a box with the `kernels` package and
|
|
171
|
-
`DIFFUSERS_TRUST_REMOTE_KERNELS=true` in its `.env`; on MPS
|
|
172
|
-
CUDA-only kernel fails there at load (validation warns, below). LTX-2.5 cannot use it: its transformer
|
|
170
|
+
`attention_backend=sage_hub` (or `native`) to override the default; `sage_hub` needs a box with the `kernels` package and
|
|
171
|
+
`DIFFUSERS_TRUST_REMOTE_KERNELS=true` in its `.env`; on MPS the default falls back to dense, but a CUDA-only kernel such as `sage_hub` fails there at load (validation warns, below). LTX-2.5 cannot use it: its transformer
|
|
173
172
|
passes an attention mask, and sage attention refuses one ("`attn_mask` is not supported
|
|
174
173
|
for sage attention", measured 2026-10-10), so the LTX templates expose no backend.
|
|
175
174
|
|
|
175
|
+
### `sparse` (MiniMax-H3)
|
|
176
|
+
|
|
177
|
+
`attention_backend: "sparse"` runs H3's attention through comfy-kitchen's block-sparse kernel: each query tile attends only to the key tiles that matter, so the cost of the long video-token sequence falls. It applies to the H3 transformer only, at pipeline or component level, and is the default on every H3 template (#931). Set at both levels, the component's own `attention_backend` wins, as it does for every backend: a pipeline-level `sparse` skips a component pinned to `sage_hub` (or anything else) and warns `attention_backend 'sparse' at pipeline level skips '<component>', which pins '<backend>'`. When it does install, the run logs `Using attention backend: sparse (tau <tau>) on <components>`, or `(topk <k>)` with top-k routing. `sparse_tau` (number, minimum 0, default 0.5; anything else, such as a `variable:` that resolves to a string or a bool, fails the step rather than running dense) sets how much of the attention mass a tile may drop; 0 keeps the most. Observed at Ref2VA 1344x768, seed 42: tau 1.0 ran 42.1 s/forward against 44.8 s at 0.5, and by Don's eye 1.0 gave smoother skin while 0.5 matched dense (the table below). That is one shape and one seed, not a rule that higher is always faster or smoother.
|
|
178
|
+
|
|
179
|
+
`sparse_topk` (a number strictly between 0 and 1; the H3 templates set 0.15, and a workflow that sets none routes by `sparse_tau`) switches the kernel to top-k routing: each query tile keeps that fraction of key tiles and drops the rest outright, with `sparse_tau` ignored. It is the selection lightx2v's Turbo-SLA LoRAs were trained against (85% sparsity, so `0.15`). Measured on `video-with-audio-768p`, seed 42 (#932): top-k 0.15 ran 21.1 s/forward against 23.6 s at tau 0.5, about 11% faster, and Don saw no difference on that clip, with either the Turbo-SLA LoRA or the default v1.2 turbo (so dw does not adopt the SLA LoRA). That clip has no faces, so it was checked on the H3 quality ramp's 4-reference sitcom shot at seeds 42, 7 and 1234 against tau 0.5. Don judged top-k equal or better: on the turbo L7 rung tau showed blue ghosting at seed 7 and slight smearing at all three, and on the 30-step base-model L5 rung the skin held. Top-k 0.15 is therefore the H3 templates' default; pass `sparse_topk=null` to route by `sparse_tau` instead.
|
|
180
|
+
|
|
181
|
+
| rung (minutes per job, seeds 42 / 7 / 1234) | tau 0.5 | top-k 0.15 |
|
|
182
|
+
|---|---|---|
|
|
183
|
+
| L7: ref2v 4-step turbo, int8 | 6.5 / 6.5 / 6.5 | 6.1 / 6.2 / 5.8 |
|
|
184
|
+
| L5: base model, int8, 30 steps | 26.8 / 26.6 / 26.4 | 23.9 / 25.5 / 23.9 |
|
|
185
|
+
|
|
186
|
+
**What the default buys depends on what it replaces.** Against `native` attention, which is what an H3 template ran before #931 unless `attention_backend` was set, sparse is 2.2-4.4x faster per step. Against `sage_hub`, the gain is much smaller: 6-16% depending on the shape (the second table). So sparse's main win is for a run that set no backend, and it needs no `kernels` package or `DIFFUSERS_TRUST_REMOTE_KERNELS`. A box already on `sage_hub` gains a little, at equal quality: on the H3 skill's quality-ramp rungs, Don judged faces, skin and draft-to-final staging equal under both backends across three seeds (#931 stage 3).
|
|
187
|
+
|
|
188
|
+
Measured on an RTX 3090, seed 42, s per transformer forward (one per denoise step), lower is faster:
|
|
189
|
+
|
|
190
|
+
| shape | native | `sage_hub` | sparse | sparse vs native | sparse vs `sage_hub` |
|
|
191
|
+
|---|---|---|---|---|---|
|
|
192
|
+
| T2VA 960x544, 4-step turbo, tau 1.0 | 24.3 | - | 10.8 | 2.25x | - |
|
|
193
|
+
| T2VA 1344x768, 4-step turbo, tau 1.0 | 96.1 | - | 21.9 | 4.38x | - |
|
|
194
|
+
| Ref2VA 1344x768, 8-step ref2v turbo, tau 1.0 | 108.4 | - | 42.1 | 2.58x | - |
|
|
195
|
+
| Ref2VA 1344x768, 8-step ref2v turbo, tau 0.5 (the default) | 108.4 | 51.0 | 44.1-44.8 | 2.42x | 1.16x |
|
|
196
|
+
|
|
197
|
+
Wall time, same order: 150 -> 95 s, 457 -> 158 s, 965 -> 430 s, and for the last row 965 s native, 489 s `sage_hub`, 442-450 s sparse.
|
|
198
|
+
|
|
199
|
+
Against `sage_hub` on the H3 skill's quality-ramp rungs (ep 6 cold open, 4 references, 1344x768, 124 frames; minutes per job, seeds 42 / 7 / 1234, all on the same diffusers):
|
|
200
|
+
|
|
201
|
+
| rung | `sage_hub` | sparse | sparse vs `sage_hub` |
|
|
202
|
+
|---|---|---|---|
|
|
203
|
+
| L1: ref2v 4-step turbo, int4, 5 steps | 5.5 / 5.5 / 5.5 | 5.2 / 5.2 / 5.1 | 1.06-1.08x |
|
|
204
|
+
| L7: ref2v 4-step turbo, int8, 5 steps | 7.1 / 6.9 / 7.1 | 6.5 / 6.5 / 6.5 | 1.06-1.09x |
|
|
205
|
+
| B3: base model, int8, 12 steps | 13.0 / 12.9 / 12.9 | 12.3 / 12.0 / 12.1 | 1.06-1.07x |
|
|
206
|
+
| L5: base model, int8, 30 steps | 29.7 / 29.7 / 29.7 | 26.8 / 26.6 / 26.4 | 1.11-1.12x |
|
|
207
|
+
|
|
208
|
+
The `first_block` cache on `sage_hub` (23.1 min at L5's settings) is still faster than sparse alone there; sparse with that cache is not measured. The native and tau 1.0 figures come from the #931 prototype. The `sage_hub` figure and the 44.1 s come from the engine on lem after the deploy, with a newer diffusers (jobs 94c04976d21d and 593131ca713f), so the sage comparison is between those two jobs only. The T2VA rows have no `sage_hub` run. Peak VRAM did not change. Judged by eye, tau 0.5 matched dense; tau 1.0 was smoother in skin.
|
|
209
|
+
|
|
210
|
+
It needs CUDA with compute capability 8.0 or higher. Anywhere else (MPS, CPU, an older card, an unsupported dtype or head size) the run goes dense instead of failing, and says so twice: `validate_workflow` warns `sparse_attention_fallback` when the server's device is not CUDA, and the run reports `<label>: sparse attention ran dense - <reason>` once per pipeline call. A job of one call warns once; a chained, `shots-batch` or `dialogue-short` job calls the pipeline once per segment or shot, so it warns once for each, under that segment's or shot's label. A comfy-kitchen kernel that fails on its first invocation in a call also runs that call dense, with `sparse kernel failed: <error>` as the reason; one that fails after it has run in the call fails the run, since some blocks have already run sparse.
|
|
211
|
+
|
|
212
|
+
Unlike sage, sparse **moves composition** relative to dense: the same subject, story and cuts, but different framing and set dressing. A draft and its final must therefore use the same backend; mixing `sparse` and `sage_hub` between tiers means the draft no longer predicts the final.
|
|
213
|
+
|
|
176
214
|
A component can also pin its backend persistently instead, via `set_attention_backend`:
|
|
177
215
|
|
|
178
216
|
```json
|
dw/docs/ARCHITECTURE.md
CHANGED
|
@@ -106,6 +106,7 @@ one to open.
|
|
|
106
106
|
| Inherited cost | `dw/server/deps.py`: `inherited_observed`, `dw/vram_inheritance.py`: `inherited_differences`, `dw/plan.py`: `_observed` (basis `inherited`), `dw/server/routes/jobs.py`: `_inherited_cost_warnings` | An inline workflow (no catalog name) is priced from the observed runs of the catalog template with the same `component_type` + `model_name` + `workflow` key as `vram_inheritance`; the template with the most cold runs wins, then name. `differs` lists offload, quantization, frame count, attention backend, cache, LoRA and reference count (the `references` list lengths, per-entry `item:` ones read off the `for_each` list; named, not scaled, #915) set differently from the template, and sets `low_confidence` when it lists any (#866). More pipeline steps than the template run (a `for_each` counted per member, against the list the bucket ran, so a fallback to the default bucket re-prices a longer list) re-price its minutes linearly, and the mean frames, inference steps, width and height per pipeline step are scaled by `scale_curated` itself - the one rule the catalog figure uses, so an inline copy and its template quote one request alike - with `scaled` naming why and `low_confidence` set (#851, #866). It is warned, never refused. | `tests/test_inherited_cost.py::TestPricedByPipelineIdentity::test_an_inline_copy_inherits_the_templates_runs`, `tests/test_inherited_cost.py::TestDifferences::test_offload_quantization_and_frames_are_named`, `tests/test_inherited_cost.py::TestDifferences::test_a_reference_count_other_than_the_templates_is_named`, `tests/test_inherited_cost.py::TestThePlanReportsIt::test_the_estimate_is_inherited_and_the_validate_answer_warns`, `tests/test_inherited_cost.py::TestTheTemplateAndAnInlineCopyAgree::test_the_same_minutes_within_rounding`, `tests/test_inherited_cost.py::TestAListLongerThanTheFallbackBucket::test_an_inline_six_shot_copy_scales_by_members` |
|
|
107
107
|
| Projected host-RAM peak | `dw/server/host_ram_need.py`: `memory_key`, `projected_peak`, `host_memory_block`; the fit is `dw/host_memory_projection.py`: `projected_mb`; history by key is `dw/server/job_history.py`: `peaks_for_key` | A run's memory key is the sorted pipeline identity of its pipeline steps plus every `quantization_config` / `offload` / `group_offload` value, with arguments substituted through `replace_variables`; never the workflow's name, so a renamed or inline copy shares the template's history. `observed` is the max peak over this machine's successful same-key runs and comes ahead of the list-run fit, unless the shape holds its pipeline across the list and the fit is the larger (the key leaves list length out, #910); with neither there is no figure. It never refuses; dispatch may delay a start on it (`dw/server/dispatch.py`: `Dispatcher._next_dispatch`, #869) (`Admission.host_ram_need`, validate's `plan.host_memory`). | `tests/test_host_ram_need.py::TestMemoryKey::test_an_inline_copy_without_its_metadata_has_the_same_key`, `tests/test_host_ram_need.py::TestMemoryKey::test_a_different_weights_dtype_is_a_different_key`, `tests/test_host_ram_need.py::TestProjectedPeak::test_an_observed_peak_beats_the_fit`, `tests/test_host_ram_need.py::TestALongerListThanObserved::test_an_accumulating_list_takes_the_larger_fit`, `tests/test_host_ram_need.py::TestProjectedPeak::test_a_failed_run_is_not_observed`, `tests/test_host_ram_need.py::TestValidateRoute::test_an_observed_run_is_the_plans_host_memory` |
|
|
108
108
|
| Acceleration warnings | `dw/acceleration_warnings.py`: `acceleration_warnings`, `CACHE_MIN_USEFUL_STEPS`, `CUDA_ONLY_ATTENTION_BACKENDS` (the last entry of `WARNING_CHECKS`) | An acceleration setting that can't pay off (a `first_block`/`mag` cache under `CACHE_MIN_USEFUL_STEPS`, any `taylorseer` cache, `compile.fullgraph` with a cache, a cache on a pipeline class with no transformer or whose transformer lacks `enable_cache()`, a CUDA-only `attention_backend` on a non-CUDA device) is a warning and never a refusal, and an unresolvable value (steps, backend, device) leaves it silent. | `tests/test_validation.py::TestAccelerationWarnings::test_warnings_never_refuse`, `tests/test_validation.py::TestAccelerationWarnings::test_steps_that_resolve_to_nothing_are_silent`, `tests/test_validation.py::TestAccelerationWarnings::test_an_unknown_device_is_silent`, `tests/test_validation.py::TestAccelerationWarnings::test_an_unresolvable_backend_is_silent_on_mps` |
|
|
109
|
+
| H3 sparse attention | `dw/sparse_attention.py`: `sparse_call`, `install_sparse`, `install_sparse_for_call`, `apply_sparse_settings`, `SparseH3AttnProcessor`; wired from `dw/pipeline_processors/components.py`: `configure_components` and `dw/pipeline_processors/pipeline.py`: `apply_runtime_settings` | Whether a pipeline call runs sparse is decided once per call, all or nothing (the call's first kernel invocation included); it never changes diffusers' process-wide backend and never reaches `AttentionBackendName`; it installs by a processor swap plus forward hooks, never a `forward` wrapper; and `sparse_tau` is a runtime setting, not part of the weights identity (#931). | `tests/test_sparse_attention_processor.py`, `tests/test_sparse_attention_wiring.py`, `tests/test_sparse_attention_tiles.py`, `tests/test_sparse_attention_backends.py` |
|
|
109
110
|
| H3 adapter partition | `dw/adapter_compatibility.py`; the server's index is `dw/server/deps.py` `lora_index` | The LoRA catalog decides first, on the server only: a `proven` entry's `workflow` refuses a step in the other partition, a `trial`/`rejected` entry's only warns. A file no entry places falls to its name: an FL2VA LoRA on a reference step is refused, and one whose name says neither `ref2v` nor `fl2v` is warned. | `tests/test_h3_adapters.py::TestWhatIsRefused::test_a_keyframe_adapter_on_the_reference_path`, `tests/test_h3_adapters.py::TestWhatIsRefused::test_an_unrecognised_name_is_a_warning_not_a_refusal`, `tests/test_h3_adapters.py::TestTheCatalogDecidesFirst::test_a_proven_entry_refuses_the_other_partition`, `tests/test_h3_adapters.py::TestTheCatalogDecidesFirst::test_a_weaker_entry_only_warns`, `tests/test_server_loras.py::TestTheCatalogPlacesAnAdapter::test_a_trial_entry_warns_and_promoting_it_refuses` |
|
|
110
111
|
| H3 audio hold, refine and guide layout | Five modules, imported one way: `dw/pipeline_processors/h3_rules.py` holds the names and rules, torch- and diffusers-free (`refine_problems`, the per-argument refine rules asked before validation and before the call; `not_h3`, the step rule; `snap_guide_length`, `guide_frame_problem`, `guide_chain_problems`, `guide_end_problem`; `CHAIN_CONTINUITY_MODES`; the chunk constants), `dw/pipeline_processors/h3_hold.py` puts the hold and refine blocks in (`insert_audio_hold`, `core_denoise_sequences`, `refines`), and `dw/pipeline_processors/h3_guides.py` the guide layout (`LAYOUT_ANCHORS`, `insert_guides`), which imports `h3_hold` and never the reverse; the blocks themselves, and the arithmetic they run, are `dw/pipeline_processors/h3_hold_steps.py` (`encode_audio_span`, `refine_sigmas`) and `dw/pipeline_processors/h3_guide_steps.py` (`splice_guide_rows`), which import diffusers when they load, so the two owners import them only inside `blocks()` and `guide_blocks()` (#790), and `h3_guide_steps` imports `h3_hold_steps` and never the reverse (`_with_guides` in `dw/pipeline_processors/pipeline.py` adds its blocks for a `guides` call), `dw/guides.py`: the `guides` validation check and the chain `continuity: "guide"` check, `guide_chain_errors`, which asks the `guides` check's own step rule (`_takes_guides_problem`, built on `h3_rules.not_h3` and `REFERENCE_WORKFLOWS`) and reads the mode names from `h3_rules.CHAIN_CONTINUITY_MODES`, the names `chain.py`'s `CONTINUITY_MODES` is zipped against (both registered in `dw/validation.py`; a `previous_result:` guide is checked at run time), `dw/hold_audio.py`: `hold_audio_errors`, `refine_strength_errors` | The one place dw modifies a diffusers modular pipeline's block graph: three blocks go in, before `set_timesteps`, `denoise` and `after_denoise`, in every H3 core-denoise sequence (the whole graph and the `workflow=`-pruned flat graph), and they are no-ops without `hold_audio` / `refine_strength`. A `hold_audio` path is opened only after `locations.validate_media_path` against the step's workflow directory. `dw/introspection.py` builds the same graph without weights, hold included, so `get_pipeline_signature` lists a modular pipeline's block inputs. The copies of diffusers behaviour are pinned to the installed diffusers: `shifted_sigma_grid` (the spacing `refine_sigmas` rests on) to stock `set_timesteps`, `GUIDE_FRAMES_PER_CHUNK`/`GUIDE_LATENTS_PER_CHUNK` to the H3 video VAE's `clip_length` and latents per clip, and every name in `LAYOUT_ANCHORS` (`_fill_audio_positions` among them) to `before_denoise`. | `tests/test_h3_hold_audio.py::TestAnchors::test_inserted_next_to_the_anchors_in_every_shape`, `tests/test_h3_hold_audio.py::TestHoldAudioLocation::test_a_path_outside_the_roots_is_refused_at_the_call`, `tests/test_h3_hold_audio.py::TestRefusals::test_a_non_h3_step_is_refused`, `tests/test_h3_hold_audio.py::TestSignature::test_the_h3_signature_shows_hold_audio`, `tests/test_h3_refine.py::TestAnchors::test_inserted_before_denoise_in_every_shape`, `tests/test_h3_refine.py::TestSigmaGridDrift::test_the_full_grid_is_stock_set_timesteps`, `tests/test_h3_guides.py::TestChunkDrift::test_frames_per_chunk_is_the_vae_clip_length`, `tests/test_h3_guides.py::TestChunkDrift::test_latents_per_chunk_is_the_vae_tokens_per_clip`, `tests/test_h3_guides.py::TestAnchors::test_installed_diffusers_has_every_anchor`, `tests/test_guide_chain_validation.py::TestRefused::test_the_step_rule_is_the_guides_rule`, `tests/test_guide_chain_validation.py::TestRefused::test_every_run_mode_is_known_to_validate`, `tests/test_h3_rules.py::test_h3_rules_imports_neither_torch_nor_diffusers`, `tests/test_h3_rules.py::test_the_block_owners_import_no_diffusers` |
|
|
111
112
|
| IC-LoRA reference scale | `workflows/templates/ltx2/` | The three conditioning templates run at `reference_downscale_factor: 1`, and the two upscalers at 2. | `tests/test_ltx2_ic_loras.py::TestEachTemplateMatchesItsCard::test_the_reference_is_encoded_at_the_output_resolution`, `tests/test_ltx2_ic_loras.py::TestTheGenerativeUpscaleMatchesTheSameCard::test_it_loads_the_upscaler_at_factor_two` |
|
|
@@ -147,6 +148,8 @@ one to open.
|
|
|
147
148
|
| Locations from a workflow | `dw/locations.py` | A local path in a workflow's media arguments (named like their media, or declared by the task's `@register_command(media_arguments=...)`, read through `TASK_MEDIA_ARGUMENTS`) is confined to a known root, a location written as a URL is one `security.validate_url` accepts, and a URL must not name a host inside the deployment. A host that does not resolve is refused. The requests themselves are `dw/outbound.py`'s. | `tests/test_locations.py::TestMediaPathContainment::test_absolute_path_outside_every_root_is_refused`, `tests/test_locations.py::TestMediaPathContainment::test_a_url_that_is_not_http_is_refused`, `tests/test_locations.py::TestMediaPathContainment::test_an_upper_case_https_url_is_not_refused_as_another_scheme`, `tests/test_security_ssrf.py::TestInternalAddressSpellings::test_a_name_that_resolves_inside`, `tests/test_locations.py::TestTaskMediaArguments::test_an_unreadable_source_is_an_error_at_its_path` |
|
|
148
149
|
| Outbound requests | `dw/outbound.py`: `safe_get`, `safe_post` | Every outbound request is validated per hop against `dw/locations.py`'s policy, resolved once and dialed at the address the policy checked, capped and timed. No other module under `dw/` makes an HTTP request or builds a session or adapter. | `tests/test_outbound.py::TestSafeRequest::test_one_lookup_per_hop_and_the_dial_is_the_checked_address` |
|
|
149
150
|
| Trust gate | `dw/trust.py`: `require_trusted_dotted_name` | In an untrusted workflow (the default), a dotted type outside the allowlist is a validation error before anything is imported. | `tests/test_security_trust_gate.py::TestValidationRefusesBeforeImport::test_a_dotted_type_is_a_validation_error` |
|
|
151
|
+
| Remote generate code | `dw/trust.py`: `require_trusted_generate_arguments`; `dw/tasks/text_generation.py`: `_validated_generate_kwargs`, `_validated_chat_template_kwargs` | Untrusted, `generate_kwargs` may not set `custom_generate` or `trust_remote_code` (transformers would download and run a repo's `custom_generate/generate.py`); both it and `chat_template_kwargs` hold only scalars (or, for `generate_kwargs`, lists of them) and none of the pipeline call's own keys. All checked before the model loads. | `tests/test_security_trust_gate.py::TestRemoteGenerateCodeUntrusted::test_refused_before_the_model_loads`, `tests/test_text_generation.py::TestGenerateKwargsAreFiltered::test_a_structural_key_is_refused_before_any_load`, `tests/test_text_generation.py::TestGenerateKwargsAreFiltered::test_a_nested_value_is_refused` |
|
|
152
|
+
| Hub-file system prompts | `dw/tasks/text_generation.py`: `resolve_system_prompt` | A `system_prompt.from_hub` file is pinned to a full commit, asked of the Hub anonymously before every use (failing closed on any error, offline or under `HF_HUB_OFFLINE`), downloaded with `token=False`, and refused over 1 MiB or when the Hub reports no size. | `tests/test_text_generation.py::TestSystemPromptFromHub::test_a_file_the_hub_will_not_serve_publicly_is_refused`, `tests/test_text_generation.py::TestSystemPromptFromHub::test_the_download_never_carries_the_server_token`, `tests/test_text_generation.py::TestSystemPromptFromHub::test_a_file_of_unknown_size_is_refused_before_downloading` |
|
|
150
153
|
| CodeQL path-injection model | `.github/codeql/dw-security/DwPathSanitizers.qll`, `.github/workflows/codeql.yml` | The local pack models the `dw/security.py` validators (and `dw/locations.py`'s `validate_media_path`) as sanitizers, so a validator that moves is re-modelled in the same commit. | `.github/codeql/dw-security/DwPathInjection.ql` |
|
|
151
154
|
| Archives never follow links | `dw/server/outputs.py`: `zip_download` | A gallery listing drops a symlink that leaves its root, and an archive skips one. | `tests/test_security_symlinks.py::TestOutputs::test_the_archive_route_does_not_follow_the_link`, `tests/test_security_symlinks.py::TestOutputs::test_the_gallery_listing_does_not_enumerate_the_link` |
|
|
152
155
|
| Engine/server import direction | `dw/workspace.py`: `EXPORTS_SUBDIR` | No engine module imports `dw.server` except the entry point `dw/serve.py`, and a constant both sides need lives engine-side. | `docs/stabilization/baseline.json`: `import_cycles` ratchet (indirect: it fails only on an import that closes a cycle) |
|
dw/docs/DEPENDENCIES.md
CHANGED
|
@@ -49,6 +49,8 @@ pyproject; install.ps1 installs it explicitly on Windows.
|
|
|
49
49
|
|
|
50
50
|
**All platforms (core ML):** peft, transformers, accelerate, safetensors, controlnet_aux, sentencepiece, torchsde, torchao, optimum-quanto, gguf, kornia, ftfy, sdnq, spandrel, facexlib (spandrel + facexlib back the `upscale` and `restore_faces` tasks). On first use, `restore_faces` has facexlib download its face detection and parsing weights (about 110 MB) from facexlib's own GitHub releases into the facexlib package directory. It is the one model download that bypasses the Hugging Face cache, dw's download manager and the `plan.downloads_required` estimate.
|
|
51
51
|
|
|
52
|
+
**All platforms (sparse attention):** comfy-kitchen (Sol-Attn sparse attention for MiniMax H3's generated-video rows, #931). Its compiled CUDA/HIP kernels ship for Linux and Windows; elsewhere it installs an eager-only build.
|
|
53
|
+
|
|
52
54
|
**All platforms (utilities):** fastapi, uvicorn (the `dw.serve` HTTP server and web UI), av, aiohttp, matplotlib, opencv-python-headless, concurrent-log-handler, qrcode, protobuf, imageio, imageio-ffmpeg, beautifulsoup4, soundfile, jsonschema, black, python-dotenv
|
|
53
55
|
|
|
54
56
|
**Linux (CUDA):** bitsandbytes
|
dw/docs/MCP.md
CHANGED
|
@@ -278,12 +278,12 @@ tools) rather than relying on the session pin.
|
|
|
278
278
|
| Tool | Arguments | Purpose |
|
|
279
279
|
| --- | --- | --- |
|
|
280
280
|
| `validate_workflow(workflow=None, name=None, workspace=None, arguments=None)` | exactly one of `workflow` (inline definition) or `name` (a stored workflow, as `list_workflows` reports it), optional `workspace`, optional `arguments` | Check a workflow against the schema and against real pipeline signatures. Free and instant. Validating by name uses the workflow file's own directory as the base directory, so it sees what a run would. Returns every schema violation in `errors`, each with the JSON path it sits at, so a draft is fixed in one pass, and a `previous_result:` that names no earlier step is one of them. `warnings` covers what still runs but is probably wrong - a signature mismatch, and, for a list-driven variable, an entry key no step reads, at the entry's path. `workspace` names the workspace for this one call without switching the session to it - use it to pin a job whose `output:` or `asset:` references live in a workspace other than the session's. Pass the same `arguments` you will pass to `run_workflow` and they are checked too - an undeclared or renamed variable name, a value that will not coerce to the declared type, and an `asset:`, `prompt:` or `output:` reference that names nothing this workspace can reach, each reported at `arguments.<name>`. `checked_arguments` lists what was covered, so a `valid: true` about the stored defaults cannot be mistaken for one about your values. A reference set the model would refuse - too many images, videos or audio clips, or, for MiniMax-H3, audio as the only reference - is an error here too, rather than a failure minutes into a run you acknowledged. `run_workflow` makes the same check and refuses a bad argument rather than queuing a job that fails on its first step. A valid answer carries `plan` - the fingerprint, step count, list lengths, `downloads_required`, `estimate` (with `basis`), `host_memory` (`{projected_mb, basis, runs}`, the projected host-RAM peak; `basis` is `observed` from same-key successful runs on this machine or `fit`; absent when there is no figure) and `elided_steps` for the arguments given; quote from it. `steps` counts what will run: a step nothing reads and which saves no file does not run, and is named in `elided_steps` instead |
|
|
281
|
-
| `list_workspaces()` | — | The server's workspaces and which one this session is using. Each has its own workflows, assets and outputs; the prompt library is shared by all of them |
|
|
281
|
+
| `list_workspaces()` | — | The server's workspaces and which one this session is using. Each has its own workflows, assets and outputs; the prompt library is shared by all of them. Compact entries are `name`/`default`/`usage` plus any `note` (clipped, `note_truncated` when cut); `detail=true` adds each entry's folder paths |
|
|
282
282
|
| `use_workspace(name)` | `name` | Work in that workspace for the rest of the session - every later call reads and writes there. This is how to keep your work out of another agent's namespace rather than sharing the default one. Checked against the server, so a typo fails here rather than scoping every later call to nothing. On a `dw.serve --mcp` endpoint the pin is shared by every connected client (#298, see the note above the table) - a `warning` field appears when this call overwrote a pin already pointed away from `default` |
|
|
283
283
|
| `create_workspace(name, use=False)` | `name`, `use` | Create a workspace. Pass use=true to switch this session to it as well; otherwise the session stays where it was and the result says so. The result names the workspace (`name`, `default`, `current`, `next`), not its folders - `list_workspaces(detail=true)` is the opt-in for those. `use=true` carries the same mounted-server caveat and `warning` field as `use_workspace` |
|
|
284
284
|
| `copy_to_workspace(destination, runs=None, assets=None, source=None)` | `destination`, `runs`, `assets`, `source` | Copy runs and assets from one workspace into another. Each `runs` entry is `<workflow>/<run id>` as `list_gallery` names it, or a bare `<workflow>` for all its runs; each `assets` entry is a path as after `asset:`, or a folder (`proj/`) for every file under it, keeping its path, note and kept shots. `source` defaults to this session's workspace. Free: no `acknowledged_cost`. Media is hard-linked (a copy across devices falls back to a real copy) and JSON sidecars are always copied, so an edit in one workspace never reaches the other. All or nothing; a run or identical asset the destination already has is skipped as `already_present`, a different file at an asset's path refuses the whole request, so a repeat is idempotent, and a `vN` it already uses is renumbered after its highest and reported in `renumbered`. Warnings: `unresolved_output_refs`, `absolute_paths`, `no_jobs`. A copied run has no job record - it shows in `list_gallery` and resolves as an `output:` reference, not in `list_jobs`. A run whose job is still queued or running is refused. To move, copy then `delete_output` the source runs and `delete_asset` the source assets. See [Workspaces](WORKSPACES.md#copying-between-workspaces) |
|
|
285
285
|
| `delete_workspace(name, acknowledged_cost=False)` | `name`, `acknowledged_cost` | Permanently delete a workspace and everything in it. Refuses without the acknowledgement, reporting what it would remove |
|
|
286
|
-
| `list_assets(limit=50, prefix)` | `limit`, `prefix` | The input media on the server, each with the `asset:` reference a workflow argument carries. Look here before asking for a file - what a workflow needs may already be there. `libraries` names the roots searched and which are writable; `shadowed` lists names a nearer library hides. Newest first; `prefix` keeps names starting with it (e.g. `cast/`), `limit` bounds the answer, `total` is the count matched before the cut |
|
|
286
|
+
| `list_assets(limit=50, prefix)` | `limit`, `prefix` | The input media on the server, each with the `asset:` reference a workflow argument carries. Look here before asking for a file - what a workflow needs may already be there. `libraries` names the roots searched and which are writable; `shadowed` lists names a nearer library hides. Compact entries are `name`/`reference`/`kind`/`size`/`origin` plus any `note` (clipped, `note_truncated` when cut); `detail=true` adds `folder`, `mtime`, `url`, `writable`, and `absolute_url`/`used_by` when set. Newest first; `prefix` keeps names starting with it (e.g. `cast/`), `limit` bounds the answer, `total` is the count matched before the cut |
|
|
287
287
|
| `keep_output(name, asset_name=None, overwrite=False, shared=False, workspace=None, note=None)` | `name`, optional `asset_name`, `overwrite`, `shared`, `workspace`, `note` | Keep a generated file as an input asset under a stable `asset:` name, so a later workflow can rely on it. The copy happens on the server: nothing is downloaded or re-uploaded. `note` is kept with the asset; left out, the source file's note is copied. `asset_name` may name a folder and takes the kept file's extension when it has none; `shared=true` keeps it in the library every workspace shares, which is where a recurring cast belongs. `workspace` names the workspace for this one call without switching the session to it - the same pin `run_workflow` takes, so a job run into another workspace stays reachable from the session that queued it |
|
|
288
288
|
| `set_note(target, note=None, workspace=None)` | `target` (a run `<workflow>/<run id>`, a gallery file name, `asset:<name>` or `workspace:<name>`), `note`, `workspace` | Set the note on a run, an output file, an asset or a workspace; null or `""` clears it. Plain text up to 4000 characters saying what the thing is for - what a run tested, why a file is the keeper. Free: no `acknowledged_cost`. Returns `{target, note, note_source}`. `run_workflow(note=...)` sets a run's note at submission and it shows on every file the run wrote; `list_gallery`, `list_assets`, `list_workspaces` and `list_jobs` carry each note clipped to 200 characters (`note_truncated: true` when cut), while `get_job` and `get_gallery_metadata` return it whole. `get_job` shows the run's current note, so one set here after submission replaces the submitted one. `workspace` names the workspace a run or file name is read in for this one call without switching the session to it - the same pin `run_workflow` takes |
|
|
289
289
|
| `upload_asset(file_path=None, content=None, asset_name=None, shared=False, note=None)` | exactly one of `file_path` or `content` (base64), optional `asset_name`, `shared`, `note` (kept with the asset) | Push an image, video or audio file, or a `.cube` 3D LUT for `apply_lut`, into the server's asset library and get back its `asset:` reference. `file_path` is read from the machine the MCP server runs on, so this is how an input reaches a dw.serve running somewhere else - but only when the caller shares a filesystem with that machine. `content` is the alternative for an agent that does not: the bytes travel inline, base64-encoded, in the tool call itself, capped at 4MB (well under `file_path`'s 200MB) because inline bytes compete with the calling agent's own context budget rather than being a bulk-transfer path (#203). `asset_name` is required with `content` (there is no file name to infer one from) and, either way, stores it under a readable name (`cast/priya-voice.wav`) instead of a random one; `shared=true` puts it in the library every workspace shares |
|
dw/docs/QUANTIZATION.md
CHANGED
|
@@ -151,6 +151,8 @@ examples use for their large transformers and text encoders:
|
|
|
151
151
|
|
|
152
152
|
**Examples:** [text-to-video.json](../workflows/templates/ltx2/text-to-video.json), [video-with-audio.json](../workflows/templates/minimax/video-with-audio.json)
|
|
153
153
|
|
|
154
|
+
The H3 templates also default to `attention_backend: "sparse"`; the quantization is independent of it ([Attention Backends](ACCELERATION.md#sparse-minimax-h3)).
|
|
155
|
+
|
|
154
156
|
### Cached on-the-fly (`DW_QUANTIZED_CACHE`)
|
|
155
157
|
|
|
156
158
|
An on-the-fly load reads the bf16 weights and quantizes them on every cold load. With `DW_QUANTIZED_CACHE=1` the server keeps the result: the first cold load saves each quantized component to disk with sdnq's `save_sdnq_model` (safetensors plus JSON, no pickle), and a later load of the same key reads it back with `load_sdnq_model`, skipping the bf16 read and the quantize. Any other value leaves it off, with no events. It covers both ways a component is quantized with a `sdnq.SDNQConfig` `quantization_config`: a modular pipeline's `load_components`, one config per component (MiniMax H3), and a component loaded on its own through its class's `from_pretrained` (LTX-2.5's transformer and Gemma text encoder). A hit is placed on the config's `return_device` (LTX's transformer goes straight to `cuda`) and loads with no download.
|
dw/docs/RECIPES_24GB.md
CHANGED
|
@@ -116,7 +116,7 @@ pipeline-level `offload`. The working 24GB configuration at 960x544:
|
|
|
116
116
|
| `text_encoder` | `remove_modules: ["lm_head"]` - the encoder path never calls it |
|
|
117
117
|
| `text_encoder.model` | SDNQ int4, `truncate_layers: {"language_model.layers": 51}`, `group_offload` `leaf_level` |
|
|
118
118
|
| `vae`, `audio_vae` | SDNQ int8, `device: "cuda"`, `residency: "on_demand"` |
|
|
119
|
-
| pipeline | `cache: first_block` (`threshold: 0.05`) only on a ~30-step base-model run (`lora_model_name: null`): -22% denoise there, identical staging and faces. It skips nothing at 12 steps or on a turbo schedule (consecutive distilled steps differ too much), and every H3 template takes it as a `cache` argument (null by default): `{"type": "first_block", "threshold": 0.05}`. Measured on a 3090 with `sage_hub`;
|
|
119
|
+
| pipeline | `cache: first_block` (`threshold: 0.05`) only on a ~30-step base-model run (`lora_model_name: null`): -22% denoise there, identical staging and faces. It skips nothing at 12 steps or on a turbo schedule (consecutive distilled steps differ too much), and every H3 template takes it as a `cache` argument (null by default): `{"type": "first_block", "threshold": 0.05}`. Measured on a 3090 with `sage_hub`; every H3 template now defaults to `attention_backend: "sparse"` ([Attention Backends](ACCELERATION.md#sparse-minimax-h3)), which needs no extra install. See the `minimax-h3` skill's `references/quality-and-speed.md` |
|
|
120
120
|
|
|
121
121
|
The VAEs are the piece worth calling out. They hold roughly 3GiB, are used only to
|
|
122
122
|
encode references and decode the result, and group offloading them is worse than useless
|
dw/docs/RELEASING.md
CHANGED
|
@@ -7,6 +7,67 @@ notes from commits at tag time (see below). This section is a scratch pad
|
|
|
7
7
|
for items a branch's author wants the next release note to name; clear it
|
|
8
8
|
when a release ships.
|
|
9
9
|
|
|
10
|
+
### 0.15.0
|
|
11
|
+
|
|
12
|
+
<!-- Drafted from v0.14.0..develop (0c4ed5ea). Paste into the GitHub release body once the tag has published: gh release edit v0.15.0 --notes-file ... -->
|
|
13
|
+
|
|
14
|
+
A release about speed for MiniMax H3 and a new image family. H3 now runs
|
|
15
|
+
sparse attention by default, 2-4x faster per step than plain attention and
|
|
16
|
+
6-20% faster than `sage_hub`, with no extra install and equal quality on
|
|
17
|
+
Don's judging. FLUX 3 Image Klein joins the catalog with its own templates
|
|
18
|
+
and skill. It also closes a remote-code hole in `speech_generation`.
|
|
19
|
+
|
|
20
|
+
**Sparse attention for MiniMax H3** (#931, #932)
|
|
21
|
+
|
|
22
|
+
- A new `attention_backend: "sparse"` runs H3's generated-video attention
|
|
23
|
+
through comfy-kitchen's Sol-Attn kernel. Text, references and audio stay
|
|
24
|
+
exact. It is the default on every H3 template, routed by top-k 0.15
|
|
25
|
+
(`sparse_topk`), with `sparse_tau` as the alternative routing.
|
|
26
|
+
- Against plain attention it is 2.2-4.4x faster per step on an RTX 3090.
|
|
27
|
+
- Against `sage_hub`, on the H3 quality-ramp rungs, it is 6-20% faster.
|
|
28
|
+
The L5 cinema final runs in 23.9-25.5 min, against 29.7 on sage.
|
|
29
|
+
- Don judged faces, skin and draft-to-final staging equal or better on
|
|
30
|
+
three seeds.
|
|
31
|
+
- It needs CUDA with compute capability 8.0+. Anywhere else (mps, cpu, an
|
|
32
|
+
older card) H3 runs dense instead of failing. On mps and cpu
|
|
33
|
+
`validate_workflow` warns `sparse_attention_fallback`; on an older card
|
|
34
|
+
or a CUDA box missing the kernels, the run says why it went dense.
|
|
35
|
+
- Sparse moves details against dense and sage (same shot, different set
|
|
36
|
+
dressing), so the `minimax-h3` skill's quality ramp keeps a draft and its
|
|
37
|
+
final on one backend. The ramp's TV and cinema paths now run sparse; the
|
|
38
|
+
sage B3 -> P1 pair stays as the fastest cached cinema final.
|
|
39
|
+
- `/api/health` lists the attention backends the server can run, and the
|
|
40
|
+
web UI's `attention_backend` fields are dropdowns of that list.
|
|
41
|
+
- A component that pins a backend keeps it under a pipeline-level
|
|
42
|
+
`sparse`, with a warning, and the run log names sparse's routing.
|
|
43
|
+
- lightx2v's Turbo-SLA LoRA was evaluated and not adopted: top-k routing
|
|
44
|
+
gives the same result on the existing turbo LoRA (#932).
|
|
45
|
+
|
|
46
|
+
**FLUX 3 Image Klein** (#930)
|
|
47
|
+
|
|
48
|
+
- Templates for text-to-image, upsample-then-generate, image edit,
|
|
49
|
+
multi-reference and layout-with-boxes, plus the model entry and a
|
|
50
|
+
`flux3-klein` composition skill.
|
|
51
|
+
- `text_generation` gains `chat_template_kwargs`, a `revision`, a list of
|
|
52
|
+
images, and a `system_prompt` read from a Hub repo file at a pinned
|
|
53
|
+
commit (anonymous, public files only, size-capped). Its `generate_kwargs`
|
|
54
|
+
are filtered, and `custom_generate` / `trust_remote_code` need trusted
|
|
55
|
+
workflows.
|
|
56
|
+
|
|
57
|
+
**Security**
|
|
58
|
+
|
|
59
|
+
- `speech_generation` passed a workflow's `generate_kwargs` and
|
|
60
|
+
`forward_params` to the model's `generate()` unfiltered, so an untrusted
|
|
61
|
+
workflow could set `custom_generate` / `trust_remote_code` and run code
|
|
62
|
+
from the Hub. Both are now refused unless workflows are trusted, before
|
|
63
|
+
the model loads. Every release through 0.14.0 is affected.
|
|
64
|
+
|
|
65
|
+
**Dependencies and deploy**
|
|
66
|
+
|
|
67
|
+
- New core dependency: `comfy-kitchen>=0.2.38,<0.3` (Apache-2.0). Linux and
|
|
68
|
+
Windows get the compiled CUDA/HIP kernels; macOS gets a pure-Python wheel
|
|
69
|
+
and runs H3 dense. `scripts/deploy.sh` reinstalls on the pyproject change.
|
|
70
|
+
|
|
10
71
|
### 0.14.0
|
|
11
72
|
|
|
12
73
|
<!-- Drafted from v0.13.0..develop (7b72a7de). Paste into the GitHub release body once the tag has published: gh release edit v0.14.0 --notes-file ... -->
|