mirror of
https://github.com/Comfy-Org/comfy-kitchen.git
synced 2026-11-04 23:37:42 +00:00
Labels
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Comfy-Org/comfy-kitchen#277
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/Comfy-Org/comfy-kitchen/pull/275
Author: @LXD-8
Created: 10/23/2026
Status: 🔄 Open
Base:
main← Head:mps-input-act📝 Commits (10+)
15dd533Add Metal RoPE and AdaLN kernels for Apple GPUs (mps backend)79e38b2mps: decline on a shader compile failure, and on a missing primary scale95f6f76tests: count the shader compile attempts in the fallback teste7f0778tests: cover adaln and split-half in the mps fallback regressions0152510README: list mps first in the backend priority order8a41306README: describe the backend order as runtime-dependent, mps first when available01df9fbREADME: add mps to the backend lista9a2f37Docs: paired rope entries launch one Metal kernel per tensore40980aREADME: the 1024 head-dim limit applies to RoPE onlybd62eccREADME: list every case the mps call rules send to eager📊 Changes
13 files changed (+1174 additions, -47 deletions)
View changed files
📝
README.md(+71 -47)📝
comfy_kitchen/__init__.py(+38 -0)📝
comfy_kitchen/backends/eager/__init__.py(+9 -0)➕
comfy_kitchen/backends/eager/input_act.py(+37 -0)➕
comfy_kitchen/backends/mps/__init__.py(+118 -0)➕
comfy_kitchen/backends/mps/activations.py(+27 -0)➕
comfy_kitchen/backends/mps/kernels.py(+377 -0)➕
comfy_kitchen/backends/mps/norm.py(+22 -0)➕
comfy_kitchen/backends/mps/rope.py(+142 -0)➕
tests/test_input_act.py(+32 -0)➕
tests/test_mps_adaln.py(+51 -0)➕
tests/test_mps_input_act.py(+57 -0)➕
tests/test_mps_rope.py(+193 -0)📄 Description
Based on
main@f8b7e97(v0.2.40). Depends on #270: this branch carries #270's commits, and only the last commit (Add ck.input_act ...) is new here. I'll rebase it once #270 lands.What
ck.input_act(x, input_act, act_weight=None, act_eps=0.0): the input activations the quantized linears take asinput_act(gelu_tanh,swiglu,situ,rms_norm), as a standalone, registry-dispatched op.apply_input_actunchanged, so results are bit-identical to what the quantized backends already use as their fallback.swiglu,situ) as one Metal kernel, in float32, float16 and bfloat16, with strided rows as long as the last dim is contiguous. Every other activation, dtype or layout is declined by the call rule and runs on eager.None/"none"returnsxitself without entering the custom op (a custom op may not return its input).torch.compile(fullgraph=True).Why
The quantized linears fuse these activations into their quantizer. An unquantized linear still has to apply
act(x)on its own, and today a host can only do that eagerly. In ComfyUI that iscomfy/ops.py'sINPUT_ACT_EAGER, which the fused MLPs (MOSS-Image'ssitu, Qwen-Image 2.1'sswiglu) go through whenever their weights are not quantized. On MPS,situin particular is a chain of about ten elementwise ops over the full[tokens, 2 * hidden]activation. A dispatched op lets a backend take that over, the same way the rope and norm entry points work.The ComfyUI side is a one-line change in
_eager_input_act(callck.input_actinstead ofINPUT_ACT_EAGERoutside training). I'll send it to ComfyUI once this is released, rather than as a version-probing branch now.Measurements
MacBook Pro M5 Max (40-core GPU), 128 GB, macOS 27.2. bf16, median ms per call, eager backend against this backend:
situ, x (1, 4141, 16384) (MOSS-Image)swiglu, x (1, 4139, 24576) (Qwen-Image 2.1)That is PyTorch 2.14.1; nightly 2.16.0.dev20261022 gives the same (7.5x, 1.6x).
swiglugains less because eager already does it in two ops.End to end in ComfyUI 0.42.0 (PyTorch nightly,
--use-pytorch-cross-attention), seconds per 1024x1024 image. Both columns run #270; the right one adds this PR plus the one-line ComfyUI change above:The MOSS gain is
situ; for Qwen the difference is within run-to-run noise.I have not measured M1 to M4.
Verification
tests/test_input_act.py(runs everywhere): the eager op equalsapply_input_actbit for bit for all four activations,None/"none"return the input, andtorch.compile(fullgraph=True)gives the right shape and values.tests/test_mps_input_act.py(skipped off MPS):swigluandsituacross four shapes and three dtypes, strided rows, and the calls that must stay on eager. Same criterion as #270: no further from an fp32 CPU reference than eager running on MPS. Swapping the two halves ofswigluin the kernel fails 15 of them.main: 770 / 3568 / 0).ruff checkclean on the changed files.🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.