[diffusion] feat: support diffusers backend - run any model supported by diffusers (#14112)

This commit is contained in:
Adarsh Shirawalmath
2026-01-06 10:00:57 +05:30
committed by GitHub
parent 84d13c54bb
commit 7be1a8c70c
17 changed files with 1120 additions and 57 deletions

View File

@@ -143,13 +143,98 @@ def _sanitize_for_logging(obj: Any, key_hint: str | None = None) -> Any:
return "<unserializable>"
class ExecutionMode(str, Enum):
"""
Enumeration for different pipeline modes.
Inherits from str to allow string comparison for backward compatibility.
"""
INFERENCE = "inference"
@classmethod
def from_string(cls, value: str) -> "ExecutionMode":
"""Convert string to ExecutionMode enum."""
try:
return cls(value.lower())
except ValueError:
raise ValueError(
f"Invalid mode: {value}. Must be one of: {', '.join([m.value for m in cls])}"
) from None
@classmethod
def choices(cls) -> list[str]:
"""Get all available choices as strings for argparse."""
return [mode.value for mode in cls]
class WorkloadType(str, Enum):
"""
Enumeration for different workload types.
Inherits from str to allow string comparison for backward compatibility.
"""
I2V = "i2v" # Image to Video
T2V = "t2v" # Text to Video
T2I = "t2i" # Text to Image
I2I = "i2i" # Image to Image
@classmethod
def from_string(cls, value: str) -> "WorkloadType":
"""Convert string to WorkloadType enum."""
try:
return cls(value.lower())
except ValueError:
raise ValueError(
f"Invalid workload type: {value}. Must be one of: {', '.join([m.value for m in cls])}"
) from None
@classmethod
def choices(cls) -> list[str]:
"""Get all available choices as strings for argparse."""
return [workload.value for workload in cls]
class Backend(str, Enum):
"""
Enumeration for different model backends.
- AUTO: Automatically select backend (prefer sglang native, fallback to diffusers)
- SGLANG: Use sglang's native optimized implementation
- DIFFUSERS: Use vanilla diffusers pipeline (supports all diffusers models)
"""
AUTO = "auto"
SGLANG = "sglang"
DIFFUSERS = "diffusers"
@classmethod
def from_string(cls, value: str) -> "Backend":
"""Convert string to Backend enum."""
try:
return cls(value.lower())
except ValueError:
raise ValueError(
f"Invalid backend: {value}. Must be one of: {', '.join([m.value for m in cls])}"
) from None
@classmethod
def choices(cls) -> list[str]:
"""Get all available choices as strings for argparse."""
return [backend.value for backend in cls]
@dataclasses.dataclass
class ServerArgs:
# Model and path configuration (for convenience)
model_path: str
# Model backend (sglang native or diffusers)
backend: Backend = Backend.AUTO
# Attention
attention_backend: str = None
diffusers_attention_backend: str = None # for diffusers backend only
# Distributed executor backend
nccl_port: Optional[int] = None
@@ -355,6 +440,13 @@ class ServerArgs:
choices=[e.name.lower() for e in AttentionBackendEnum] + ["fa3", "fa4"],
help="The attention backend to use. If not specified, the backend is automatically selected based on hardware and installed packages.",
)
parser.add_argument(
"--diffusers-attention-backend",
type=str,
default=None,
help="Attention backend for diffusers pipelines (e.g., flash, _flash_3_hub, sage, xformers). "
"See: https://huggingface.co/docs/diffusers/main/en/optimization/attention_backends",
)
# HuggingFace specific parameters
parser.add_argument(
@@ -601,6 +693,14 @@ class ServerArgs:
default=ServerArgs.log_level,
help="The logging level of all loggers.",
)
parser.add_argument(
"--backend",
type=str,
choices=Backend.choices(),
default=ServerArgs.backend.value,
help="The model backend to use. 'auto' prefers sglang native and falls back to diffusers. "
"'sglang' uses native optimized implementation. 'diffusers' uses vanilla diffusers pipeline.",
)
return parser
def url(self):
@@ -718,6 +818,16 @@ class ServerArgs:
@classmethod
def from_kwargs(cls, **kwargs: Any) -> "ServerArgs":
# Convert mode string to enum if necessary
if "mode" in kwargs and isinstance(kwargs["mode"], str):
kwargs["mode"] = ExecutionMode.from_string(kwargs["mode"])
# Convert workload_type string to enum if necessary
if "workload_type" in kwargs and isinstance(kwargs["workload_type"], str):
kwargs["workload_type"] = WorkloadType.from_string(kwargs["workload_type"])
# Convert backend string to enum if necessary
if "backend" in kwargs and isinstance(kwargs["backend"], str):
kwargs["backend"] = Backend.from_string(kwargs["backend"])
kwargs["pipeline_config"] = PipelineConfig.from_kwargs(kwargs)
return cls(**kwargs)