| # LocalAI Diffusers Backend | |
| This backend provides gRPC access to Hugging Face diffusers pipelines with dynamic pipeline loading. | |
| ## Creating a separate environment for the diffusers project | |
| ``` | |
| make diffusers | |
| ``` | |
| ## Dynamic Pipeline Loader | |
| The diffusers backend includes a dynamic pipeline loader (`diffusers_dynamic_loader.py`) that automatically discovers and loads diffusers pipelines at runtime. This eliminates the need for per-pipeline conditional statements - new pipelines added to diffusers become available automatically without code changes. | |
| ### How It Works | |
| 1. **Pipeline Discovery**: On first use, the loader scans the `diffusers` package to find all classes that inherit from `DiffusionPipeline`. | |
| 2. **Registry Caching**: Discovery results are cached for the lifetime of the process to avoid repeated scanning. | |
| 3. **Task Aliases**: The loader automatically derives task aliases from class names (e.g., "text-to-image", "image-to-image", "inpainting") without hardcoding. | |
| 4. **Multiple Resolution Methods**: Pipelines can be resolved by: | |
| - Exact class name (e.g., `StableDiffusionPipeline`) | |
| - Task alias (e.g., `text-to-image`, `img2img`) | |
| - Model ID (uses HuggingFace Hub to infer pipeline type) | |
| ### Usage Examples | |
| ```python | |
| from diffusers_dynamic_loader import ( | |
| load_diffusers_pipeline, | |
| get_available_pipelines, | |
| get_available_tasks, | |
| resolve_pipeline_class, | |
| discover_diffusers_classes, | |
| get_available_classes, | |
| ) | |
| # List all available pipelines | |
| pipelines = get_available_pipelines() | |
| print(f"Available pipelines: {pipelines[:10]}...") | |
| # List all task aliases | |
| tasks = get_available_tasks() | |
| print(f"Available tasks: {tasks}") | |
| # Resolve a pipeline class by name | |
| cls = resolve_pipeline_class(class_name="StableDiffusionPipeline") | |
| # Resolve by task alias | |
| cls = resolve_pipeline_class(task="stable-diffusion") | |
| # Load and instantiate a pipeline | |
| pipe = load_diffusers_pipeline( | |
| class_name="StableDiffusionPipeline", | |
| model_id="runwayml/stable-diffusion-v1-5", | |
| torch_dtype=torch.float16 | |
| ) | |
| # Load from single file | |
| pipe = load_diffusers_pipeline( | |
| class_name="StableDiffusionPipeline", | |
| model_id="/path/to/model.safetensors", | |
| from_single_file=True, | |
| torch_dtype=torch.float16 | |
| ) | |
| # Discover other diffusers classes (schedulers, models, etc.) | |
| schedulers = discover_diffusers_classes("SchedulerMixin") | |
| print(f"Available schedulers: {list(schedulers.keys())[:5]}...") | |
| # Get list of available scheduler classes | |
| scheduler_list = get_available_classes("SchedulerMixin") | |
| ``` | |
| ### Generic Class Discovery | |
| The dynamic loader can discover not just pipelines but any class type from diffusers: | |
| ```python | |
| # Discover all scheduler classes | |
| schedulers = discover_diffusers_classes("SchedulerMixin") | |
| # Discover all model classes | |
| models = discover_diffusers_classes("ModelMixin") | |
| # Get a sorted list of available classes | |
| scheduler_names = get_available_classes("SchedulerMixin") | |
| ``` | |
| ### Special Pipeline Handling | |
| Most pipelines are loaded dynamically through `load_diffusers_pipeline()`. Only pipelines requiring truly custom initialization logic are handled explicitly: | |
| - `FluxTransformer2DModel`: Requires quantization and custom transformer loading (cannot use dynamic loader) | |
| - `WanPipeline` / `WanImageToVideoPipeline`: Uses dynamic loader with special VAE (float32 dtype) | |
| - `SanaPipeline`: Uses dynamic loader with post-load dtype conversion for VAE/text encoder | |
| - `StableVideoDiffusionPipeline`: Uses dynamic loader with CPU offload handling | |
| - `VideoDiffusionPipeline`: Alias for DiffusionPipeline with video flags | |
| All other pipelines (StableDiffusionPipeline, StableDiffusionXLPipeline, FluxPipeline, etc.) are loaded purely through the dynamic loader. | |
| ### Error Handling | |
| When a pipeline cannot be resolved, the loader provides helpful error messages listing available pipelines and tasks: | |
| ``` | |
| ValueError: Unknown pipeline class 'NonExistentPipeline'. | |
| Available pipelines: AnimateDiffPipeline, AnimateDiffVideoToVideoPipeline, ... | |
| ``` | |
| ## Environment Variables | |
| | Variable | Default | Description | | |
| |----------|---------|-------------| | |
| | `COMPEL` | `0` | Enable Compel for prompt weighting | | |
| | `XPU` | `0` | Enable Intel XPU support | | |
| | `CLIPSKIP` | `1` | Enable CLIP skip support | | |
| | `SAFETENSORS` | `1` | Use safetensors format | | |
| | `CHUNK_SIZE` | `8` | Decode chunk size for video | | |
| | `FPS` | `7` | Video frames per second | | |
| | `DISABLE_CPU_OFFLOAD` | `0` | Disable CPU offload | | |
| | `FRAMES` | `64` | Number of video frames | | |
| | `BFL_REPO` | `ChuckMcSneed/FLUX.1-dev` | Flux base repo | | |
| | `PYTHON_GRPC_MAX_WORKERS` | `1` | Max gRPC workers | | |
| ## Running Tests | |
| ```bash | |
| ./test.sh | |
| ``` | |
| The test suite includes: | |
| - Unit tests for the dynamic loader (`test_dynamic_loader.py`) | |
| - Integration tests for the gRPC backend (`test.py`) |