ComfyUI Workflow Engineering Skill
Engineering ComfyUI workflows on the user's Windows ComfyUI Desktop (KingComfy) setup: locating installs and model files, lifting official template subgraphs into flat-packs, inserting speedup patches (EasyCache), and structurally validating workflow JSON. Includes GPU-architecture gating so unsupported optimizations are never recommended on the user's Pascal card.
When to Use
- User asks to make ComfyUI video/image generation faster or better quality.
- Need to add/remove nodes in a workflow, build a flat-pack, or fix a workflow that errors on load.
- Need to locate ComfyUI install, venv, models, custom nodes, or official templates.
- A new model release (e.g., MiniMax H4) needs a workflow adapted from official templates.
Prerequisites
- User's install: ComfyUI Desktop (Electron app) at
E:\Comfy\Comfy Desktop; managed install "KingComfy" atE:\Comfy-Desktop\ComfyUI-Installs\KingComfy. Standalone env:standalone-env\python.exe, venv atComfyUI\.venv(python 3.13, torch 2.6.0+cu124 — cu124 kept because 1080Ti is Pascal; cu130 envs don't run it). - Install registry:
%APPDATA%\Comfy Desktop\installations.json— JSON array withname,installPath,comfyVersion,launchArgs, per-install torch stack. - Shared dirs:
E:\Comfy-Desktop\ComfyUI-Shared\modelsis a mostly-EMPTY separate tree; real models live atKingComfy\ComfyUI\models\{diffusion_models,text_encoders,vae,...}. Workflows/output also underComfyUI-Shared\. - Official workflow templates ship as a pip package in the venv:
ComfyUI\.venv\Lib\site-packages\comfyui_workflow_templates_json\templates\*.json. Mega-node workflows there aredefinitions.subgraphs[0]containing the REAL flat-pack wiring — the visible UUID-type node is just the subgraph wrapper.
How to Run
- Find install: read
%APPDATA%\Comfy Desktop\installations.json. - Inspect workflow JSON: v0.4 format — nodes have
id/type/inputs/outputs/widgets_values; links are[id, origin_id, origin_slot, target_id, target_slot, type]. - Validate any workflow with
scripts/validate_comfyui_workflow.py <file.json>before handing it to the user. - Rebuild the H3 EasyCache flat-pack with
scripts/build_h3_flatpack.py(regenerates from the official template + user's last workflow values). Seereferences/minimax-h3-flatpack.mdfor the full recipe.
Quick Reference
- GPU capability gating (durable): 1080Ti = Pascal sm_61.
- ✅ Pure-PyTorch patches: EasyCache (native, ~20–25% on ≥100 frames), steps cuts, low-res + upscale.
- ❌ Triton/Ampere+ only (sm80+): SageAttention (~30% on RTX30+), NVIDIA Sol-Attn ("Patch Sol Attn", SM89+). Triton itself is sm70+. Never recommend these on this card.
- EasyCache node: native in ComfyUI ≥0.30 (
comfy_extras/nodes_easycache.py, registered innodes.py). KJNodes' own EasyCache is deprecated. Widgets:reuse_threshold0.2 (speed/quality dial — 0.1 ≈ near-lossless, 0.3+ faster),start_percent0.15,end_percent0.95,verbosefalse. - ⚠️ USER-VERIFIED: EasyCache corrupts MiniMax H3 output (joint video+audio latent): live test (turbo LoRA, 10 steps, 0.2 MP) produced red flickering speckles on the video + broken audio. Disable with
reuse_threshold= 0.0 (never skips; node stays in the graph for re-enable). Community corroborates quality loss even at 0.10 (HN item 49155629). Use EasyCache only for image models / non-joint-latent models; the H3 speed path is the Turbo LoRA. Insert between UNETLoader → BasicGuider. Scheduler rule: if the chain includes a sigma-shift node, feed BOTH BasicGuider and BasicScheduler from the chain END (shifted model) — the scheduler's sigmas must reflect the shift; without a shift node, the scheduler may stay on the raw model. - MiniMax H3 Turbo LoRA (4-step distill, 2026-08): original
larryvrh/MiniMax-H3-Turbo-Lorais NOT compatible with pruned models (AdaLN proj dim 2688 vs pruned's 8; larryvrh requires bf16 or full int8_convrot). Use the pruned conversiondrbaph/MiniMax-H3-Turbo-Lora-ComfyUI(removed 51 AdaLN pairs, 208/259 kept;minimax_h3_turbo_4step_pruned_comfyui.safetensors≈ 620 MB →models/loras/h3/). Apply withLoraLoaderModelOnly+MiniMaxH3SigmaShift[12, 6] (audio shift 6 — prevents broken audio) + steps 8–12 (drbaph example = 10, KSamplerSelectres_multistep+ BasicSchedulersimple). 4 steps is ONLY for larryvrh's custom turbo sampler; a stock sampler over-steps audio at 4 and breaks it. Chain: UNETLoader → LoRA → SigmaShift → EasyCache → BasicGuider + BasicScheduler. Does NOT stack with EasyCache on H3 — EasyCache is disabled there (user-verified artifacts). - MiniMax H3 flat-pack building blocks (all standard nodes): UNETLoader, CLIPLoader type=
minimax(NVFP4 AWQ encoder), VAELoader ×2 (video fp16 + audio fp32),MiniMaxH3ImageToVideo(COND + LATENT out),EmptyMiniMaxH3LatentAV,MiniMaxH3SigmaShift(shift_video 12, shift_audio 3), BasicGuider, KSamplerSelectres_multistep, BasicSchedulersimple/20 steps, RandomNoise, SamplerCustomAdvanced, VAEDecode + VAEDecodeAudio, CreateVideo (24 fps), SaveVideo. - T2V = same node, no keyframes: v0.30.2 has NO
MiniMaxH3TextToVideonode —MiniMaxH3ImageToVideoimplements BOTH t2va and fl2va (docstring: "t2va and fl2va: prompt (+ optional first/last keyframes)"). Leavefirst_frame/last_frameunconnected → pure text-to-video. T2V workflow deployed asworkflows/minimax_h3_t2v_turbo.json(copy of the I2V flat-pack minus LoadImage, with a T2V example prompt). - ComfyUI-MiniMaxH3-Easy (nkxx188, v1.0.3) — INSTALLED at
custom_nodes/ComfyUI-MiniMaxH3-Easy(zero deps, classic NODE_CLASS_MAPPINGS style, usescomfy_extras.nodes_minimax_h3internals so it works on v0.30.2). Nodes:MiniMaxH3EasyLoader(4-in-1: fl2va/ref2va/text_encoder/video_vae/audio_vae; auto-detects user's official filenames; ref2va combo = ["None","无"] when no ref2va file → falls back to fl2va),MiniMaxH3Easy(mode image/reference; media wildcard port for virtual wires; no media = T2V, 1 image = I2V, 2 = first/last; seconds 4–20 snapped to 17k+5; resolution presets 360P=0.2MP … 1080P=2.0MP),MiniMaxH3EasyOutput(unpacks positive/latent/video_vae/audio_vae/fps). Easymodeloutput is RAW (no LoRA/shift) → TurboLoRA +MiniMaxH3SigmaShiftconnect AFTER it. Combined workflowworkflows/minimax_h3_easy_turbo.json: EasyLoader → Easy → EasyOutput + model chain Easy→LoraLoaderModelOnly→SigmaShift[12,6]→EasyCache(0.0)→BasicGuider/BasicScheduler(10 steps), LoadImage left disconnected for I2V. Repo's shipped example workflow referencesMiniMaxH3MemoryEfficientSageAttentionPatch(foreign pack, useless on Pascal) — omit it. Reference-video mode needs VHS/KJNodes for video/audio loading (not installed). - MiniMax H3 FirstBlockCache (duckyshell, v1.0.0) — INSTALLED at
custom_nodes/ComfyUI-MiniMaxH3-FirstBlockCache. Pure-PyTorch model patch (no CUDA/Triton → works on Pascal): runs transformer block 0 every step, reuses cached residual of remaining blocks when first-block residual delta ≤ threshold (presets Safe 0.08 / Fast 0.10 / Aggressive 0.12; max 2 consecutive hits; 10–95% window; optional temporal guard on video frames). HARD-CONFLICTS with EasyCache: the native EasyCache node ALWAYS setstransformer_options["easycache"](even at reuse_threshold 0.0 — verified innodes_easycache.py), and FBCache raises ValueError on that key → EasyCache node must be REMOVED from the chain, not just disabled. Also conflicts with LazyCache/CacheDiT/T8 Block Cache/any dit double_block patch. Placement: directly after the diffusion model loader (Easy.model → FBCache → LoraLoaderModelOnly → SigmaShift → Guider/Scheduler). 5090 benchmark: 1.44–1.49× cache-only at 20 steps; expect less at turbo 10 steps. Same artifact risk class as EasyCache (joint video+audio latent) — test Safe preset first; author tested 5090 only. Test workflow:workflows/minimax_h3_easy_turbo_fbcache.json(EasyCache removed, FBCache Safe preset, saves tovideo/MiniMax_H3_FBC). - Frame grid: length snaps to 17k+5 @ 24 fps. Seconds→frames:
max(5, round(a*24)) + (5 - (max(5, round(a*24)) % 17)) % 17(5 s → 124 f). - v0.4 JSON rules: node input entries carry
linkids that MUST exist in thelinksarray (and vice-versa for outputlinks); widget-only inputs need NO input entry (BasicScheduler's 3 widgets have none) but combo/model-name widgets (VAELoader, UNETLoader) do; link ids and node ids are independent namespaces; subgraph ports are -10 (inputs) / -20 (outputs).
Procedure
Find install / files
cat "$APPDATA/Comfy Desktop/installations.json"→ per-installinstallPath.- Models:
installPath/ComfyUI/models/<type>/. Check BOTH the install tree andComfyUI-Shared\models(shared is often empty). - Custom nodes:
installPath/ComfyUI/custom_nodes/(user's KingComfy currently has almost none). - Templates:
.venv/Lib/site-packages/comfyui_workflow_templates_json/templates/.
Lift a subgraph into a flat-pack (H3 recipe)
- Load template json; take
definitions.subgraphs[0]. - Copy its
nodeswith id offset (+1000), remap sub links (link id +2000, node refs +OFF); drop all links touching ports -10/-20. - Replace subgraph-port links with top-level wiring: LoadImage →
first_frame, ResolutionSelector → width/height, CreateVideo → SaveVideo. - Set widgets from the user's existing workflow (prompt/seed/duration/model names preserved).
- Insert EasyCache between UNETLoader and BasicGuider: new link UNET→EasyCache, EasyCache→Guider; DELETE the original UNET→BasicGuider link (else duplicate target slot); update BasicGuider's input entry
linkto the new id. - Validate (scripts/validate_comfyui_workflow.py) — it catches dangling links AND duplicate target slots (the first build missed this and had a silent double-wire into BasicGuider).
Speed recommendations for this user (1080Ti 11 GB) — as deployed 2026-08
- MiniMax H3 Turbo LoRA (pruned conversion) — DEPLOYED:
LoraLoaderModelOnly+MiniMaxH3SigmaShift [12,6]+ steps 10 ≈ 2× sampling cut. This is the H3 speed path. - EasyCache — OFF for H3 (user-verified artifacts;
reuse_threshold0.0 in the workflow). Re-enable only for non-H3 models. - Steps 8–12 (BasicScheduler) — tuning knob around 10.
- Iterate with seed-only changes: prompt encode is cached by ComfyUI; the 32B Qwen3-VL encoder is the dominant cost on 11 GB (offload).
- Do NOT recommend SageAttention / Sol-Attn / Spectrum on this GPU (Triton sm80+; Spectrum redundant with EasyCache and reported quality issues).
- Resolution: H3 minimum 384p (≈0.15 MP square); 0.1 MP (320×320) is BELOW the floor — degraded quality/motion. Sampling time ≈ linear in megapixels + fixed overhead (model load + 32B encode): measured on this machine (turbo 10 steps) — 0.1 MP ≈ 14 min, 0.2 MP ≈ 25 min.
Pitfalls
- ComfyUI Desktop re-saves workflow files: the app writes the workflow JSON back to disk when the user opens/saves it (file mtime/size change). Always re-read the file right before editing, and after editing tell the user to REOPEN the workflow in the app — otherwise a stale in-app copy silently overwrites the patched file.
- LoadImage must reference a file that actually exists in
input/: official templates point at sample images (e.g.transparent_rgb_gaming_mouse.png) that may be missing on the user's machine. CheckComfyUI-Shared/input/first and point the widget at a real file. - Duplicate target slot: inserting a node into a chain leaves the old link; two links to the same (target_id, target_slot) silently breaks wiring. Delete the replaced link AND re-sync the target node's input entry.
- Input entries vs links array drift: after rewiring, node
inputs[].linkandoutputs[].linksmust be updated to match thelinksarray or the frontend shows disconnected inputs. - User rule: never leave build scripts/scratch in the home folder — write to
%TEMP%and delete after; deliverable files go in the ComfyUI workflows dir (or the user's NAS work folder). - Template subgraphs contain disconnected leftover nodes (e.g., ImageScaleToTotalPixels/GetImageSize) — drop them.
grep -rover the whole ComfyUI tree times out; scope searches tocomfy_extras,comfy_api_nodes,nodes.py.- Official mega-node workflows hide steps/sampler and do NOT accept EasyCache — a flat-pack is required for any model patch.
- Don't claim end-to-end success: structural validation only proves wiring; actual sampling needs the user to run ComfyUI Desktop. Ask them to run once and report errors.
- Experimental speedup nodes:
is_experimentalnodes (EasyCache) may look correct in code yet corrupt output in practice. Treat marketing/community numbers as untested until the USER runs it on their workload; if it fails, disable via widget (e.g.reuse_threshold0.0) rather than deleting the node — easier to re-enable after a fix. - Give time expectations before long runs: megapixel ≈ linear sampling scaling + fixed overhead. State the floor (H3 = 384p) and a time table up front so the user doesn't burn a 25-min run on below-minimum resolution.
GPU Upgrade Compatibility Checklist
When asked "can I put GPU X in this PC?", probe the machine first (wmic baseboard get Product, wmic cpu get Name, wmic bios get SMBIOSBIOSVersion, check C:\Windows\System32\winload.efi exists), then check:
- UEFI boot required for Blackwell (RTX 50xx / RTX PRO 6000) — legacy BIOS refuses to init the card.
winload.efipresent = OK. - PCIe: any x16 slot works; PCIe 3.0 boards (e.g. B460M-A + i5-10400F) run the card at 3.0 — fine for inference (model loads a few seconds slower).
- PSU: new-card TDP + ~150 W headroom (RTX PRO 6000 Blackwell = 350 W); 16-pin (12V-2x6) connector or adapter. Software cannot read PSU wattage — ask the user to read the sticker.
- CUDA/torch floor: Blackwell sm_120 needs CUDA 12.8+ / torch cu128+. If the env was downgraded for the old GPU (KingComfy: cu124 kept for Pascal), restore the stock env after the swap.
- Gain sanity check: RTX PRO 6000 runs H3 10 s @ 864p in ~140 s (≈105 s with SageAttention) vs ~25 min on the 1080Ti at 0.2 MP 5 s — expect 10–20×. SageAttention/Sol-Attn become available too (sm_120).
Local Inference Hardware Planning (multi-GPU / DGX Spark / big MoE)
When the user floats local-inference hardware ideas (SLI, multi-GPU pooling, DGX Spark, workstation GPUs), these are the durable facts:
- SLI never pools VRAM (mirrors frames for gaming; CUDA compute ignores it). Pooling only happens via software tensor parallelism (llama.cpp
--split, vLLM TP, accelerate) — and that needs a real x16 slot per GPU. The user's B460M-A has ONE x16 slot (rest are x1) → second GPU impractical. - ComfyUI is single-GPU: multi-GPU pooling does NOT apply to ComfyUI/H3 at all. 4×1080Ti cannot run H3.
- DeepSeek V4 Flash (284B MoE) local memory tiers: FP8 ≈ 167GB, Q4 ≈ 142GB, Q3 ≈ 107GB, Q2 ≈ 71GB, 1.58-bit ≈ 53GB. The 1080Ti (11GB VRAM + 48GB RAM) cannot load even the smallest tier — "slow but running" is impossible, not just slow.
- Verified community numbers (Aug 2026): DGX Spark 1× = Q2 at
13–15 tok/s (MTP ~30, 256K+ ctx); Spark 2× (256GB, TP=2, FP8) = 40–67 tok/s, 1M ctx; RTX PRO 6000 96GB = Q2 (30–50 tok/s) AND full H3 (42.5GB) — one card covers both. - DGX Spark eGPU: officially unsupported (USB ports are USB 3.2-class, no PCIe tunneling; no internal PCIe slot; NVIDIA staff confirmed on developer forums). Spark clustering (ConnectX) links Sparks, not GPUs.
- Break-even math: at DeepSeek API prices ($0.14/$0.28 per 1M;
$0.64 effective per 1M output with 5:1 input at 50% cache), even 24/7 generation on 2× Spark saves only ~$3–4/day → 5–7 yr payback excluding electricity ($2–3/day), effectively never with it. Local only makes sense for privacy / unlimited / ownership, never for cost recovery.
Verification
python scripts/validate_comfyui_workflow.py <workflow.json>→ node/link counts +ERRORS: none.- Check the model chain explicitly:
UNETLoader → EasyCache → BasicGuider(link origins/targets). - Confirm the patch node is registered in this install: grep
nodes.pyfor the node id (EasyCache).
Support Files
references/minimax-h3-flatpack.md— full H3 session detail: model files, exact node/widget table, speedup landscape & benchmarks, sources.scripts/validate_comfyui_workflow.py— general structural validator for v0.4 workflow JSON.scripts/build_h3_flatpack.py— regenerates the EasyCache flat-pack from the official template.