Nodes/Causal Forcing for ComfyUI/Causal Forcing Doctor
ComfyUI Node

Causal Forcing Doctor

Run Causal Forcing Doctor before you blame the model

By hiroki-abe-58·Created 23 days ago·Updated 23 days ago· 2
Causal Forcing Doctor
    • report
    ◄runtime_id▾►
    ◄verify_sha256false►

    What it's for

    This pack doesn't run Causal Forcing inside ComfyUI. It shells out to a separate Linux/WSL2 environment with its own Python, its own torch, its own flash-attn build, its own pinned checkout of the upstream code and 17 GB of Wan weights plus a 5.7 GB checkpoint. Nine ways for that to be subtly wrong, and every one of them otherwise shows up three minutes into a generation job as a stack trace.

    The Doctor node is the cheap check. It runs the same way a generation job does - a job file, the runtime's Python, runtime/cf_doctor.py - but generates nothing. It's an output node, so it runs on its own: add it, pick your runtime, hit queue.

    What it actually checks

    Because it executes inside the runtime, it is testing the runtime's environment, not ComfyUI's. That's the entire value - ComfyUI's Python being healthy tells you nothing about this.

    • upstream_commit - the git HEAD of your Causal-Forcing checkout against the pinned da3ddf1a590f30c9edc568e11c2f77170995c31c. A mismatch is a warn, not a fail: you can probably still generate, you just can't claim the reference result.
    • upstream_files - sha256 of the upstream files that matter, with line endings normalised to LF first, so a Windows git with core.autocrlf=true doesn't produce a scary false failure. A modified or missing file is a hard fail, because the runner is going to import those files unmodified.
    • model_files - every Wan file it needs, by size (and by sha256 if you asked for it).
    • checkpoints - each profile you listed in causalforcing.runtimes.json, checked for existence and expected size. Per-profile, so you'll immediately see which model you've actually got.
    • cuda - device name, compute capability, free and total VRAM, straight from torch inside the runtime. This is where "WSL2 can't see the NVIDIA driver" surfaces, as a plain torch.cuda.is_available() is False.
    • flash_attn_kernel - it doesn't just import flash-attn, it runs a flash_attn_varlen_func call and checks the output is finite. That catches the classic wheel/torch/CUDA-ABI mismatch that an import alone sails through. It's a fail, and the detail line says why: upstream's cross-attention path requires flash-attn 2.
    • Imports for diffusers, transformers, omegaconf, av, einops, torchvision and PIL, each reported with a version.
    • The overall verdict is ok, warn or fail, and one warn is worth knowing about: under 40 GB of VRAM with offload_text_encoder: false, it tells you to switch it on - what upstream's inference.py does automatically.

    Inputs and output

    runtime_id is the same enum as everywhere else in the pack: choices come from causalforcing.runtimes.json, and if you haven't made that file the only option is (no runtime configured).

    verify_sha256 (default off) hashes every model and checkpoint file. On the reference setup that's about 17 GB of Wan plus 5.7 GB per checkpoint, so it's a disk-read pass, not a dropdown you flick casually. Run it once after downloading the weights - docs/SETUP.md recommends exactly that - then leave it off.

    The output is report, a JSON string you can send to Preview Any. The node also prints a readable summary in the UI (the overall status plus one line per check), which is usually all you need:

    wsl-causalforcing: ok
      ok  upstream_commit
      ok  checkpoints
     warn  vram
    

    Note the node returns time.time() from IS_CHANGED, so it re-runs on every queue instead of being cached - which is what you want from a diagnostic, and is the standard ComfyUI idiom for a node that must always fire (comfyui-node-plumbing.md).

    Setting it up

    There's no separate install; it comes with the pack.

    cd ComfyUI/custom_nodes
    git clone https://github.com/hiroki-abe-58/ComfyUI-CausalForcing
    

    Restart ComfyUI, create ComfyUI/user/causalforcing.runtimes.json from the pack's example (or point COMFYUI_CAUSALFORCING_CONFIG at your own file), and queue the Doctor. There's a ready-made graph at workflows/causalforcing_doctor.json. Only after it comes back clean would I bother queueing a video: every job pays 35-42 s of model load before you learn anything.

    Reading failures

    • overall: fail with an error and a configured list - the runtime id in the workflow doesn't exist in the config. Renamed a runtime? That's this.
    • config error in the report - the JSON itself is bad: wrong schema_version, an unknown key, a relative path where an absolute Linux path is required (all runtime paths must be absolute, and .. is rejected), or an env entry outside the allowlist. The file is validated strictly on purpose, so typos fail loudly instead of half-working.
    • checkpoints: {"cfpp_framewise_2step": "missing"} - the path in your config is wrong or the download didn't finish. Fix the config, not the model id.
    • flash_attn_kernel: fail - almost always the wheel: flash-attn 2.8.3 has to match torch 2.8 and the cxx11abiTRUE build. Reinstall from the wheel listed in runtime/requirements-reference.txt and check its sha256.
    • cuda: fail - run nvidia-smi inside the same WSL2 distro. If that's empty, nothing the Doctor does will help.
    CategoryCausalForcing

    Inputs (2)

    NameTypeDefaultDescription
    runtime_idCOMBO1 options: (no runtime configured)
    verify_sha256BOOLEANfalseHash every model and checkpoint file (tens of GB of reads).

    Outputs (1)

    NameTypeDescription
    reportSTRING—