Files

17 KiB
Raw Permalink Blame History

Model selection

Start without model arguments to select models in the web UI:

sd-server --model-dir ./models

From a source checkout, you can also use sh ./start-server.sh on Linux/macOS or .\start-server.bat on Windows. The launchers look for the server relative to the script: beside the script, then in bin/Release/, bin/, build/bin/Release/, and build/bin/, in that order. For a different build directory, set SD_SERVER_PATH to the executable path:

SD_SERVER_PATH="./build_vulkan/bin/sd-server" sh ./start-server.sh --listen-port 8080
$env:SD_SERVER_PATH = ".\build_vulkan\bin\Release\sd-server.exe"
.\start-server.bat --listen-port 8080

Binary release archives include both launchers. Keep the launchers under version control and put personal settings in a separate file beside them:

  • Windows batch: start-server.local.bat
  • Linux/macOS: start-server.local.sh

These local files are ignored by Git and excluded from release archives. They are loaded automatically after the launcher's defaults. They can override SD_SERVER_PATH, MODEL_DIR, and COMMANDLINE_ARGS; there is no need to edit the tracked launchers. For example:

@echo off
set "MODEL_DIR=D:\stable-diffusion-webui\models"
set "COMMANDLINE_ARGS=--listen-port 8080 --offload-to-cpu"
MODEL_DIR="/data/stable-diffusion-webui/models"
COMMANDLINE_ARGS="--listen-port 8080 --offload-to-cpu"

Each launcher prints the resolved command before execution and forwards the server's exit code.

SD_SERVER_PATH inherits the environment value by default; leave it empty for automatic discovery, or set it in the local file to select another executable. Settings are applied in this order: launcher defaults, local configuration, then invocation arguments. Repeated --model-dir arguments add roots, so they do not replace the MODEL_DIR root. Local configuration files are shell scripts and use the corresponding shell's syntax.

The launchers preserve the current working directory, so the default MODEL_DIR="./models" is relative to where you start the launcher. Arguments passed when invoking the launcher follow these defaults. Repeated --model-dir arguments add search roots rather than replacing MODEL_DIR; set MODEL_DIR in the local configuration to change the first root. Other single-value options can override the defaults. In the shell script, COMMANDLINE_ARGS is a whitespace-separated list; pass values containing spaces as quoted arguments when invoking the script. MODEL_DIR itself supports spaces in both scripts. A leading --version bypasses the configured defaults. An explicit SD_SERVER_PATH is used without falling back to another build if it is invalid.

Choose a recipe, select the required component files, and click Load models. Recipe and component selectors support searching by name or relative file ID. Use the arrow keys and Enter to select, or Escape to cancel a search. With Apply recipe defaults enabled, selecting a recipe immediately applies its declared generation defaults while preserving prompts, input images and fields not specified by the recipe. Disable it to keep your current parameters when switching recipes. This preference defaults to enabled and is saved locally. Model loading and server-info refreshes do not reapply defaults or reset the form. Recipes declaring video_frames also switch the form to Video Generation; other recipes switch to Image Generation. Generation is enabled after the selected recipe is loaded. Changing a selection does not reload the model until you click Load. The server can also start with the existing model arguments shown below; existing API clients then work without selecting a recipe. The UI automatically selects Command-line model (all features) and uses the startup generation defaults. This runtime-only recipe exposes all controls for the supported image/video mode. Selecting another recipe previews a model switch; selecting the command-line entry again restores its generation defaults. The entry is removed when the command-line context is unloaded or replaced.

Built-in recipes cover SD 1/2/3/3.5, SDXL and distilled checkpoints; FLUX 1/2/3, Chroma, Qwen Image and editing variants; Z-Image, Anima, ERNIE, LENS, PiD and other supported image families; AnimateDiff, Wan, LTX, HunyuanVideo, LingBot Video and MiniMax-H3. Model-specific text encoder labels identify the expected encoder family and size. Loading a video model enables Video Generation; I2V also requires a start image. The Models panel can be collapsed and remembers its open state. Its header shows elapsed loading time from the status API and keeps the final time after success or failure, including after a page refresh. Built-ins are embedded in the binary from recipes/, with one JSON file per recipe. Adding or editing a built-in requires rebuilding the server. User recipes are read from <model-dir>/recipes/*.json. A valid user recipe with the same ID replaces the entire built-in recipe. Across roots, the first valid user recipe wins; overrides are logged. Duplicate user IDs within one root are rejected; invalid recipes are reported without removing a valid recipe from another root or the built-in version. Slots need only id and required; the server supplies labels and search directories. Use label only when a recipe needs a more specific display name.

Recipes use features to enable specialized controls and disabled_features to turn off shared defaults. Disabled features take precedence. The UI hides unsupported fields, empty sections and irrelevant sampler/cache options, and omits hidden values from generation requests. See the feature declarations for the defaults and complete list of supported names.

Built-in additions and changes must follow the recipe policy. Split recipes by task weights or added capabilities, not by style or acceleration LoRAs. Quantizations, file formats and compatible layer-count variants share a recipe. Native encoders, projectors and connectors stay in the model's recipe. Community editing recipes require selecting the matching LoRA separately; a recipe does not enable it automatically.

See generation defaults and sources for the selected publisher recommendations and reference-code defaults, with step defaults capped at 20. Recipes link to the original publisher's Hugging Face repository where one is available. DiT recipes default to Euler, except for models requiring a specialized sampler.

Compatible recipes offer a TAE slot alongside VAE. When the checkpoint does not bundle a VAE, select at least one of VAE or TAE. The Models panel shows a reminder below the model selectors until this requirement is met. A selected TAE is used for encoding and decoding, including when a full VAE is also selected; use complete, model-compatible TAE weights rather than decoder-only preview weights. Qwen Image 2.1 uses the same recipe for its full VAE and TAEQI2.1 alternatives.

The following variants have dedicated recipes:

Model Recipe IDs / notes
Z-Image L2P z-image-l2p; no VAE
LLaDA-Image llada-image (base) and llada-image-turbo; use matching encoders and connectors
PixArt Alpha pixart-alpha-512, pixart-alpha-1024; Alpha VAE scale and positional settings
PiD / PiD 1.5 pid / pid-15 for Flux or Z-Image VAE; append -sd3, -flux2, or -qwen-image for other latent formats
SDXL adapters sdxl-ip-adapter supports classic and Plus ViT-H adapters; sdxl-controlnet requires compatible SDXL weights
FLUX.1 Fill / Depth flux1-fill uses Init Image and Mask Image; flux1-depth uses a precomputed depth map in Control Image
SD2 / SDXL inpainting sd2-inpainting, sdxl-inpainting
SD-Turbo sd-turbo; single-file SD2.1-derived checkpoint
Community editing LoRAs anima-edit, krea2-raw-edit, krea2-turbo-edit; apply a matching LoRA after loading
HunyuanVideo 1.5 hunyuan-video-15-t2v, hunyuan-video-15-i2v; choose the task's checkpoint
Wan 2.1 / compatible single Wan 2.2 experts wan21-t2v, wan21-i2v; the I2V recipe also accepts compatible SkyReels V2 weights
Qwen Image 2.1 Turbo qwen-image-21-turbo; standalone Turbo weights with the fixed 8-step schedule, Euler and CFG 1
MOSS Image moss-image-base, moss-image-sft; choose the corresponding checkpoint

PiD always requires a reference image and uses the first one. Its recipes expose reference inputs rather than ordinary image-to-image inputs. IP-Adapter recipes expose a separate IP-Adapter image and strength. FLUX Canny/Depth consume Control Image directly without a separate ControlNet; the UI does not calculate edge or depth maps. Their strength is controlled by guidance, not ControlNet strength. Krea2 edit recipes use the default krea2_ostris_edit reference preset, so the editing LoRA must match that convention. Ordinary Anima and Krea2 recipes do not expose reference-image editing inputs.

Fill/Depth guidance defaults follow the Diffusers FLUX documentation. SD-Turbo uses the model card's one-step configuration, with CFG disabled using scale 1 in sd.cpp.

SVD is not included: legacy model recognition and UNet branches remain, but the current runner/conditioning setup does not provide a dedicated SVD image-conditioning path. Adding a recipe alone would not establish a working SVD pipeline.

Reference images, masks, audio, first/last video frames, and generation options such as upscaling remain generation inputs. Hardware and memory options remain startup arguments. Tiny SD/Tiny SD2 and Diffusers LCM directories must first be converted into single-file checkpoints for the file catalog. LCM checkpoints and LoRAs use the matching SD family recipe; select LCM sampling and adjust steps/CFG for the chosen weights. Metadata inspection, conversion, standalone upscaling and ADetailer are CLI workflows rather than model-loading recipes. ESRGAN and LTX latent upscalers are selected through generation upscaling settings with --hires-upscalers-dir; textual inversion uses the startup --embd-dir option.

Repeat --model-dir to share multiple model directories, including an existing SD WebUI model directory:

sd-server --model-dir ./models --model-dir /data/stable-diffusion-webui/models

With no --model-dir, the server uses ./models. Explicit roots replace that default and are scanned in argument order. Duplicate canonical roots and file paths are scanned once. Every root can contain a recipes/ directory. Directory names are matched case-insensitively on all platforms:

Category Directory names
Checkpoints checkpoints, Stable-diffusion
VAE vae, VAE
LoRA loras, Lora
ControlNet controlnet, ControlNet

Other categories keep their existing directory names. Classification uses only the containing directory: *.vae.safetensors, *.vae.ckpt, and similar names inside checkpoints/ or Stable-diffusion/ remain checkpoints.

Place model files in category directories, for example:

models/
  checkpoints/
  diffusion_models/
  text_encoders/
  vae/
  clip_vision/
  loras/
  recipes/
    my-flux.json

Subdirectories within a model category are supported. Use Refresh files & recipes after adding files or changing recipes. Scanning lists file names without loading model weights. Category membership does not guarantee compatibility; the model loader performs the final compatibility check. Symlinks resolving outside the model directory are rejected. Dropdown labels omit the category prefix while retaining subdirectory names. Identical display paths are displayed as full file paths, with source directories before the filename instead of a hash suffix. The same applies to duplicate LoRA paths. File IDs include a root qualifier for additional roots; clients should use the returned IDs. Empty optional categories do not display missing-file hints.

Place Tiny AutoEncoder (TAE) files in vae/ and select them in the TAE slot. The legacy vae_approx/ directory is also scanned for TAE selections.

LoRAs are discovered automatically in both loras/ and Lora/ under every model root. Use --lora-model-dir to replace automatic discovery with one explicit LoRA directory. Duplicate names remain separate selectable entries. The LoRA selectors support searching by name or path with the same keyboard controls as model selectors.

The server keeps one model context loaded. Loading or unloading is rejected while generation requests or queued jobs are pending. A switch validates the selection before unloading the old context, then loads the replacement. If loading fails, the service stays online with no active model and reports the error. Backend and memory options supplied at startup apply to subsequent loads. Recipe defaults apply to new loads; explicitly supplied generation request parameters take precedence.

See the API reference for recipe fields, supported slots, management endpoints, and compatibility behavior.

Example

The following example starts sd-server with a standalone diffusion model, VAE, and LLM text encoder:

.\bin\Release\sd-server.exe --diffusion-model  ..\models\diffusion_models\z_image_turbo_bf16.safetensors --vae ..\models\vae\ae.sft  --llm ..\models\text_encoders\qwen_3_4b.safetensors --offload-to-cpu -v --cfg-scale 1.0

What this example does:

  • --diffusion-model selects the standalone diffusion model
  • --vae selects the VAE decoder
  • --llm selects the text encoder / language model used by this pipeline
  • --offload-to-cpu reduces VRAM pressure by keeping weights in RAM when possible
  • -v enables verbose logging (equivalent to --log-level verbose)
  • --cfg-scale 1.0 sets the default CFG scale for generation

Logging defaults to info. Use --log-level <level> to select debug, verbose, info, warn, or error (from most to least detailed). Each level includes messages at that level and all less detailed levels. -v and --verbose are equivalent to --log-level verbose. If repeated, the last logging option wins.

After the server starts successfully:

  • the web UI is available at http://127.0.0.1:1234/
  • the native async API is available under /sdcpp/v1/...
  • the compatibility APIs are available under /v1/... and /sdapi/v1/...

If you want to use a different host or port, pass:

--listen-ip <ip> --listen-port <port>

Frontend

Build with Frontend

The server can optionally build the web frontend and embed it into the binary as gen_index_html.h.

Requirements

Install the following tools:

npm install -g pnpm

Verify installation:

node -v
pnpm -v

Install frontend dependencies

Go to the frontend directory and install dependencies:

cd examples/server/frontend
pnpm install

Build the server with CMake

Enable the frontend build option when configuring CMake:

cmake -B build -DSD_SERVER_BUILD_FRONTEND=ON
cmake --build build --config Release

If pnpm is available, the build system will automatically run:

pnpm run build
pnpm run build:header

and embed the generated frontend into the server binary.

Frontend Repository

The web frontend is maintained in a separate repository, https://github.com/leejet/sdcpp-webui.

If you want to modify the UI or frontend logic, please submit pull requests to the frontend repository.

This repository (stable-diffusion.cpp) only vendors the frontend periodically. Changes from the frontend repo are synchronized:

  • approximately every 1–2 weeks, or
  • when there are major frontend updates

Because of this, frontend changes will not appear here immediately after being merged upstream.

Using an external frontend

By default, the server uses the embedded frontend generated during the build (gen_index_html.h).

You can also serve a custom frontend file instead of the embedded one by using:

--serve-html-path <path-to-index.html>

For example:

sd-server --serve-html-path ./index.html

In this case, the server will load and serve the specified index.html file instead of the embedded frontend. This is useful when:

  • developing or testing frontend changes
  • using a custom UI
  • avoiding rebuilding the binary after frontend modifications

Usage

For detailed command-line arguments, run:

./bin/sd-server -h

For completely black or white images or videos, NaNs, and the --linear-scale / --attn-scale startup options, see Troubleshooting.