(
query: torch.Tensor,
key: torch.Tensor,
value: torch.Tensor,
attn_mask: torch.Tensor | None = None,
dropout_p: float = 0.0,
is_causal: bool = False,
scale: float | None = None,
enable_gqa: bool = False,
attention_kwargs: dict[str, Any] | None = None,
*,
backend: AttentionBackendName | None = None,
parallel_config: "ParallelConfig" | None = None,
)
| 389 | |
| 390 | |
| 391 | def dispatch_attention_fn( |
| 392 | query: torch.Tensor, |
| 393 | key: torch.Tensor, |
| 394 | value: torch.Tensor, |
| 395 | attn_mask: torch.Tensor | None = None, |
| 396 | dropout_p: float = 0.0, |
| 397 | is_causal: bool = False, |
| 398 | scale: float | None = None, |
| 399 | enable_gqa: bool = False, |
| 400 | attention_kwargs: dict[str, Any] | None = None, |
| 401 | *, |
| 402 | backend: AttentionBackendName | None = None, |
| 403 | parallel_config: "ParallelConfig" | None = None, |
| 404 | ) -> torch.Tensor: |
| 405 | attention_kwargs = attention_kwargs or {} |
| 406 | |
| 407 | if backend is None: |
| 408 | # If no backend is specified, we either use the default backend (set via the DIFFUSERS_ATTN_BACKEND environment |
| 409 | # variable), or we use a custom backend based on whether user is using the `attention_backend` context manager |
| 410 | backend_name, backend_fn = _AttentionBackendRegistry.get_active_backend() |
| 411 | else: |
| 412 | backend_name = AttentionBackendName(backend) |
| 413 | backend_fn = _AttentionBackendRegistry._backends.get(backend_name) |
| 414 | |
| 415 | kwargs = { |
| 416 | "query": query, |
| 417 | "key": key, |
| 418 | "value": value, |
| 419 | "attn_mask": attn_mask, |
| 420 | "dropout_p": dropout_p, |
| 421 | "is_causal": is_causal, |
| 422 | "scale": scale, |
| 423 | **attention_kwargs, |
| 424 | "_parallel_config": parallel_config, |
| 425 | } |
| 426 | # Equivalent to `is_torch_version(">=", "2.5.0")` — use module-level constant to avoid |
| 427 | # Dynamo tracing into the lru_cache-wrapped `is_torch_version` during torch.compile. |
| 428 | if _CAN_USE_FLEX_ATTN: |
| 429 | kwargs["enable_gqa"] = enable_gqa |
| 430 | |
| 431 | if _AttentionBackendRegistry._checks_enabled: |
| 432 | removed_kwargs = set(kwargs) - set(_AttentionBackendRegistry._supported_arg_names[backend_name]) |
| 433 | if removed_kwargs: |
| 434 | logger.warning(f"Removing unsupported arguments for attention backend {backend_name}: {removed_kwargs}.") |
| 435 | for check in _AttentionBackendRegistry._constraints.get(backend_name): |
| 436 | check(**kwargs) |
| 437 | |
| 438 | kwargs = {k: v for k, v in kwargs.items() if k in _AttentionBackendRegistry._supported_arg_names[backend_name]} |
| 439 | |
| 440 | return backend_fn(**kwargs) |
| 441 | |
| 442 | |
| 443 | # ===== Checks ===== |
no test coverage detected
searching dependent graphs…