Skip to content

DIFFSYNTH_ATTENTION_IMPLEMENTATION is unvalidated: naming an uninstalled backend raises NameError at dispatch #12

Description

@rakhimovv

DIFFSYNTH_ATTENTION_IMPLEMENTATION is taken unvalidated, so naming an uninstalled backend crashes at dispatch — while its sibling WAM_ATTENTION_IMPL validates and falls back. This is the root cause behind the diagnostics fixes in #9 and #11; those made the report honest, but the underlying selection is still unchecked.

The asymmetry

get_attention_fn in openwam/model/action_backbone/components.py does both checks:

override = os.environ.get("WAM_ATTENTION_IMPL", "").strip().lower()
if override:
    if override not in _BACKEND_MAP:
        raise ValueError(f"Unknown WAM_ATTENTION_IMPL='{override}'. Choose from: {list(_BACKEND_MAP.keys())}")
    fn = _BACKEND_MAP[override]()
    if fn is None:
        logger.warning("WAM_ATTENTION_IMPL='%s' requested but not available, falling back to auto-detect", override)

initialize_attention_priority in openwam/model/video_backbone/wan/shared/core/attention/attention.py does neither — it lowercases and returns:

if os.environ.get("DIFFSYNTH_ATTENTION_IMPLEMENTATION") is not None:
    return os.environ.get("DIFFSYNTH_ATTENTION_IMPLEMENTATION").lower()

Three failure modes

All three run on Python 3.10.20, torch 2.7.1+cu128, flash_attn 2.8.3.post1, 4×H100, on main at c5b6b81 (which includes #11). FA3 and sage are not installed here, which is the ordinary case.

1. Naming an unavailable backend crashes at dispatch. The device/dtype guard from #9 admits CUDA+half, but nothing checks the library actually imported:

$ DIFFSYNTH_ATTENTION_IMPLEMENTATION=flash_attention_3
ATTENTION_IMPLEMENTATION = 'flash_attention_3'
FLASH_ATTN_3_AVAILABLE   = False
resolve_implementation   -> flash_attention_3
attention_forward: NameError: name 'flash_attn_interface' is not defined

This is the one I'd call a plain bug. WAM_ATTENTION_IMPL=flash3 on the same machine warns and falls back; this raises a NameError from inside the kernel wrapper.

2. An unrecognized value is accepted silently.

$ DIFFSYNTH_ATTENTION_IMPLEMENTATION=bogus
ATTENTION_IMPLEMENTATION = 'bogus'   -> attention_forward runs fine (plain SDPA)

attention_forward's else branch is doing the right thing, but a typo'd backend name is indistinguishable from a working one — the user asked for a fused kernel and silently got SDPA.

3. The empty string is reachable and behaves the same, because the lookup guards on is not None rather than truthiness:

$ DIFFSYNTH_ATTENTION_IMPLEMENTATION=
ATTENTION_IMPLEMENTATION = ''   -> resolve_implementation -> ''   -> SDPA

This is also why the deploy report currently logs a blank backend name for that case — @wayrise raised the cosmetic in #11 and I deliberately left it alone there, because annotating the symptom in the logger seemed worse than fixing the cause here.

Suggested fix

Mirror the sibling. In initialize_attention_priority, after reading the override: .strip().lower(), reject a name outside the known set, and check the corresponding *_AVAILABLE flag before returning it, falling back to auto-detection with a warning when the library is missing.

That closes all three modes and makes the two env vars behave the same way, which seems worth having on its own — right now WAM_ATTENTION_IMPL=nonsense raises immediately and DIFFSYNTH_ATTENTION_IMPLEMENTATION=nonsense runs a whole training job.

One genuine design question I did not want to decide for you: unrecognized value — raise or warn-and-fall-back? components.py raises for an unknown name but only warns for an unavailable one, and I can see the argument either way for an env var inherited from DiffSynth-Studio, where a stricter reading might break someone's existing invocation. Availability-checking (mode 1) seems unambiguous to me; the membership check is the part that's your call.

Happy to send the PR once you've picked the semantics — it's a contained change to one function plus tests, and I have the box to verify it on. Or say the word and I'll leave it with you.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions