Adding a New Model
This guide walks through adding a new diffusion model to the system, from creating the Python class to syncing configuration.
Prerequisites
Before starting, understand the model’s requirements:
Pipeline class — which
diffuserspipeline loads it (e.g.,FluxPipeline,StableDiffusionXLPipeline)Text encoder — CLIP-based (77-token limit, supports Compel) or non-CLIP
Default parameters — recommended steps, guidance scale, resolution
Special requirements — quantization, custom schedulers, prompt handling quirks
Step 1: Create the Model File
Create a new file in src/cw/lib/models/. For a simple model, this is ~20 lines:
# src/cw/lib/models/newmodel.py
from diffusers import YourPipeline
from .base import BaseModel
class NewModel(BaseModel):
def _create_pipeline(self):
return YourPipeline.from_pretrained(
self.model_path,
torch_dtype=self.dtype,
)
_create_pipeline() is the only required override. Everything else — device setup, generation loop, LoRA management, metadata, cache clearing — is inherited from BaseModel.
Step 2: Register in the Factory
Add the import and dispatch case to src/cw/lib/models/__init__.py:
from .newmodel import NewModel
class ModelFactory:
@staticmethod
def create_model(model_config: dict, model_path: str) -> BaseModel:
pipeline_name = model_config.get("pipeline", "")
# ... existing cases ...
elif pipeline_name == "YourPipeline":
return NewModel(model_config, model_path)
else:
raise ValueError(f"Unknown pipeline type: {pipeline_name}")
Also add NewModel to the __all__ list.
Step 3: Add to presets.json
Add a model entry to the models array in data/presets.json:
{
"slug": "new-model",
"label": "New Model",
"pipeline": "YourPipeline",
"path": "organization/model-name",
"base_architecture": "sdxl",
"settings": {
"steps": 20,
"guidance_scale": 7.0,
"resolution": 1024,
"dtype": "bfloat16",
"supports_negative_prompt": false
}
}
Key fields:
slug — unique identifier, used in the warm cache
pipeline — must match the
ModelFactorydispatch stringpath — HuggingFace repo ID (e.g.,
black-forest-labs/FLUX.1-dev) or local.safetensorspathbase_architecture — determines LoRA compatibility (
sdxl,sd15,flux1,qwen,zimage)settings — default generation parameters and behavior flags
Step 4: Sync to Database
Run the import command to sync presets.json to the Django database:
uv run manage.py import_presets
The model will appear in the Diffusion Models admin page and be available for DiffusionJob creation.
Adding Behavior with Hooks
For models that need custom behavior, override the optional hook methods:
from diffusers import SpecialPipeline
from .base import BaseModel
class SpecialModel(BaseModel):
def _create_pipeline(self):
return SpecialPipeline.from_pretrained(
self.model_path,
torch_dtype=self.dtype,
)
def _build_pipeline_kwargs(self, params, progress_callback):
"""Add model-specific generation parameters."""
kwargs = super()._build_pipeline_kwargs(params, progress_callback)
# Example: this model uses true_cfg_scale instead of guidance_scale
kwargs["true_cfg_scale"] = kwargs.pop("guidance_scale")
return kwargs
def _handle_special_prompt_requirements(self, params):
"""Handle model-specific prompt quirks."""
# Example: model requires non-empty negative prompt
if not params.get("negative_prompt"):
params["negative_prompt"] = " "
return params
Available hooks (see Diffusion Models for details):
_build_prompts(params)— customize prompt processing_build_pipeline_kwargs(params, callback)— add model-specific pipeline parameters_apply_device_optimizations()— custom device setup_handle_special_prompt_requirements(params)— model-specific prompt quirks
Adding Mixins
For CLIP-based models that need long prompt support or prompt weighting:
from diffusers import StableDiffusionXLPipeline
from .base import BaseModel
from .mixins import CompelPromptMixin
class MySDXLModel(CompelPromptMixin, BaseModel):
"""SDXL model with Compel prompt weighting."""
def _create_pipeline(self):
return StableDiffusionXLPipeline.from_pretrained(
self.model_path,
torch_dtype=self.dtype,
variant="fp16",
)
Mixins must be listed before BaseModel in the class definition for proper MRO.
Available mixins:
CompelPromptMixin— long prompts (>77 tokens) and(word:1.3)weighting for CLIP-based modelsDebugLoggingMixin— verbose debug output gated by theenable_debug_loggingflag
Configuration Flags
Control model behavior via flags in the settings block of presets.json:
Flag |
When to Use |
|---|---|
|
Turbo/distilled models that must use CFG 0.0 |
|
Models with non-CLIP text encoders (Flux, Flux 2 Klein) |
|
Large models that need quantization for memory |
|
Models that need aggressive memory optimization |
|
During development, for verbose output |
|
Models that accept negative prompts (needs CFG > 0) |
|
Override the default scheduler |