mirror of
https://github.com/leejet/stable-diffusion.cpp.git
synced 2026-11-09 10:26:36 +00:00
feat(server): add recipe-based model management (#2176)
This commit is contained in:
1 parent
9b7da27374
commit
0518b34374
132 files changed
+6688
-147
No files matched your search
@@ -0,0 +1,2 @@
|
||||
/start-server.sh text eol=lf
|
||||
/start-server.bat text eol=crlf
|
||||
@@ -26,6 +26,8 @@ on:
|
||||
"ggml",
|
||||
"examples/server/frontend",
|
||||
"examples/server/frontend/**",
|
||||
"start-server.sh",
|
||||
"start-server.bat",
|
||||
]
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
@@ -44,6 +46,8 @@ on:
|
||||
"ggml",
|
||||
"examples/server/frontend",
|
||||
"examples/server/frontend/**",
|
||||
"start-server.sh",
|
||||
"start-server.bat",
|
||||
]
|
||||
|
||||
env:
|
||||
@@ -107,7 +111,8 @@ jobs:
|
||||
run: |
|
||||
cp ggml/LICENSE ./build/bin/ggml.txt
|
||||
cp LICENSE ./build/bin/stable-diffusion.cpp.txt
|
||||
zip -j sd-${{ env.BRANCH_NAME }}-${{ steps.commit.outputs.short }}-bin-${{ steps.system-info.outputs.OS_TYPE }}-${{ steps.system-info.outputs.OS_NAME }}-${{ steps.system-info.outputs.OS_VERSION }}-${{ steps.system-info.outputs.CPU_ARCH }}.zip ./build/bin/*
|
||||
chmod +x start-server.sh
|
||||
zip -j sd-${{ env.BRANCH_NAME }}-${{ steps.commit.outputs.short }}-bin-${{ steps.system-info.outputs.OS_TYPE }}-${{ steps.system-info.outputs.OS_NAME }}-${{ steps.system-info.outputs.OS_VERSION }}-${{ steps.system-info.outputs.CPU_ARCH }}.zip ./build/bin/* ./start-server.sh ./start-server.bat
|
||||
|
||||
- name: Upload artifacts
|
||||
if: ${{ ( github.event_name == 'push' && github.ref == 'refs/heads/master' ) || github.event.inputs.create_release == 'true' }}
|
||||
@@ -170,7 +175,8 @@ jobs:
|
||||
run: |
|
||||
cp ggml/LICENSE ./build/bin/ggml.txt
|
||||
cp LICENSE ./build/bin/stable-diffusion.cpp.txt
|
||||
zip -j sd-${{ env.BRANCH_NAME }}-${{ steps.commit.outputs.short }}-bin-${{ steps.system-info.outputs.OS_TYPE }}-${{ steps.system-info.outputs.OS_NAME }}-${{ steps.system-info.outputs.OS_VERSION }}-${{ steps.system-info.outputs.CPU_ARCH }}-vulkan.zip ./build/bin/*
|
||||
chmod +x start-server.sh
|
||||
zip -j sd-${{ env.BRANCH_NAME }}-${{ steps.commit.outputs.short }}-bin-${{ steps.system-info.outputs.OS_TYPE }}-${{ steps.system-info.outputs.OS_NAME }}-${{ steps.system-info.outputs.OS_VERSION }}-${{ steps.system-info.outputs.CPU_ARCH }}-vulkan.zip ./build/bin/* ./start-server.sh ./start-server.bat
|
||||
|
||||
- name: Upload artifacts
|
||||
if: ${{ ( github.event_name == 'push' && github.ref == 'refs/heads/master' ) || github.event.inputs.create_release == 'true' }}
|
||||
@@ -325,7 +331,8 @@ jobs:
|
||||
run: |
|
||||
cp ggml/LICENSE ./build/bin/ggml.txt
|
||||
cp LICENSE ./build/bin/stable-diffusion.cpp.txt
|
||||
zip -j sd-${{ env.BRANCH_NAME }}-${{ steps.commit.outputs.short }}-bin-${{ steps.system-info.outputs.OS_TYPE }}-${{ steps.system-info.outputs.OS_NAME }}-${{ steps.system-info.outputs.OS_VERSION }}-${{ steps.system-info.outputs.CPU_ARCH }}.zip ./build/bin/*
|
||||
chmod +x start-server.sh
|
||||
zip -j sd-${{ env.BRANCH_NAME }}-${{ steps.commit.outputs.short }}-bin-${{ steps.system-info.outputs.OS_TYPE }}-${{ steps.system-info.outputs.OS_NAME }}-${{ steps.system-info.outputs.OS_VERSION }}-${{ steps.system-info.outputs.CPU_ARCH }}.zip ./build/bin/* ./start-server.sh ./start-server.bat
|
||||
|
||||
- name: Upload artifacts
|
||||
if: ${{ ( github.event_name == 'push' && github.ref == 'refs/heads/master' ) || github.event.inputs.create_release == 'true' }}
|
||||
@@ -420,7 +427,7 @@ jobs:
|
||||
ls .\build\bin
|
||||
throw "Can't find stable-diffusion.dll"
|
||||
}
|
||||
7z a sd-${{ env.BRANCH_NAME }}-${{ steps.commit.outputs.short }}-bin-win-${{ matrix.build }}-x64.zip $filePath
|
||||
7z a sd-${{ env.BRANCH_NAME }}-${{ steps.commit.outputs.short }}-bin-win-${{ matrix.build }}-x64.zip $filePath .\start-server.sh .\start-server.bat
|
||||
|
||||
- name: Copy and pack Cuda runtime
|
||||
id: pack_cuda_runtime
|
||||
@@ -575,7 +582,7 @@ jobs:
|
||||
- name: Pack artifacts
|
||||
if: ${{ ( github.event_name == 'push' && github.ref == 'refs/heads/master' ) || github.event.inputs.create_release == 'true' }}
|
||||
run: |
|
||||
7z a sd-${{ env.BRANCH_NAME }}-${{ steps.commit.outputs.short }}-bin-win-rocm-${{ env.ROCM_VERSION }}-x64.zip .\build\bin\*
|
||||
7z a sd-${{ env.BRANCH_NAME }}-${{ steps.commit.outputs.short }}-bin-win-rocm-${{ env.ROCM_VERSION }}-x64.zip .\build\bin\* .\start-server.sh .\start-server.bat
|
||||
|
||||
- name: Upload artifacts
|
||||
if: ${{ ( github.event_name == 'push' && github.ref == 'refs/heads/master' ) || github.event.inputs.create_release == 'true' }}
|
||||
@@ -737,7 +744,8 @@ jobs:
|
||||
run: |
|
||||
cp ggml/LICENSE ./build/bin/ggml.txt
|
||||
cp LICENSE ./build/bin/stable-diffusion.cpp.txt
|
||||
zip -y -r sd-${{ env.BRANCH_NAME }}-${{ steps.commit.outputs.short }}-bin-${{ steps.system-info.outputs.OS_TYPE }}-Ubuntu-${{ env.UBUNTU_VERSION }}-${{ steps.system-info.outputs.CPU_ARCH }}-rocm-${{ matrix.ROCM_VERSION }}.zip ./build/bin
|
||||
chmod +x start-server.sh
|
||||
zip -y -r sd-${{ env.BRANCH_NAME }}-${{ steps.commit.outputs.short }}-bin-${{ steps.system-info.outputs.OS_TYPE }}-Ubuntu-${{ env.UBUNTU_VERSION }}-${{ steps.system-info.outputs.CPU_ARCH }}-rocm-${{ matrix.ROCM_VERSION }}.zip ./build/bin ./start-server.sh ./start-server.bat
|
||||
|
||||
- name: Upload artifacts
|
||||
if: ${{ ( github.event_name == 'push' && github.ref == 'refs/heads/master' ) || github.event.inputs.create_release == 'true' }}
|
||||
|
||||
@@ -7,6 +7,10 @@ tests/
|
||||
.cache/
|
||||
*.swp
|
||||
*.bat
|
||||
!/start-server.bat
|
||||
/start-server.local.sh
|
||||
/start-server.local.bat
|
||||
/start-server.local.ps1
|
||||
*.bin
|
||||
*.exe
|
||||
*.gguf
|
||||
|
||||
@@ -83,6 +83,8 @@ documentation.
|
||||
and debugging.
|
||||
* `examples/common/` - shared example support code.
|
||||
* `examples/server/` - server application built on top of the library.
|
||||
Before modifying built-in recipes, read and follow
|
||||
[the built-in recipe policy](examples/server/recipes/README.md).
|
||||
* `examples/server/frontend/` - git submodule containing independent frontend
|
||||
code. Avoid modifying it unless explicitly requested.
|
||||
|
||||
|
||||
@@ -33,6 +33,17 @@ PRs should include:
|
||||
|
||||
The [UIs list in the README](README.md#uis) only includes open-source projects that use `stable-diffusion.cpp` as a backend. Do not submit PRs to add closed-source UIs.
|
||||
|
||||
## Server Recipes
|
||||
|
||||
Before adding or changing a built-in server recipe, read and follow the
|
||||
[built-in recipe policy](examples/server/recipes/README.md). The policy governs
|
||||
native editing, community editing LoRAs, distinct task checkpoints, external
|
||||
adapters, native components and layer-count variants. Do not add recipes solely
|
||||
for style or acceleration LoRAs, separately stored native components, or added
|
||||
or removed model layers. Explain the task, component compatibility or capability
|
||||
difference that justifies a new recipe, and verify its required components,
|
||||
feature declarations and embedded API representation.
|
||||
|
||||
## Code Style
|
||||
|
||||
Format code according to the repository style before submitting changes.
|
||||
|
||||
@@ -68,6 +68,8 @@ add_executable(${TARGET}
|
||||
../common/media_io.cpp
|
||||
main.cpp
|
||||
runtime.cpp
|
||||
model_catalog.cpp
|
||||
routes_models.cpp
|
||||
async_jobs.cpp
|
||||
routes_index.cpp
|
||||
routes_openai.cpp
|
||||
@@ -88,6 +90,17 @@ else()
|
||||
message(STATUS "HAVE_INDEX_HTML disabled")
|
||||
endif()
|
||||
|
||||
file(GLOB BUILTIN_RECIPE_FILES CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/recipes/*.json")
|
||||
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${BUILTIN_RECIPE_FILES})
|
||||
# Keep recipes in separate literals to stay within MSVC's string size limit.
|
||||
set(SD_BUILTIN_RECIPES "")
|
||||
foreach(RECIPE_FILE IN LISTS BUILTIN_RECIPE_FILES)
|
||||
file(READ "${RECIPE_FILE}" RECIPE_JSON)
|
||||
string(APPEND SD_BUILTIN_RECIPES "R\"recipes(${RECIPE_JSON})recipes\",\n")
|
||||
endforeach()
|
||||
configure_file(recipes_builtin.h.in "${CMAKE_CURRENT_BINARY_DIR}/recipes_builtin.h" @ONLY)
|
||||
target_include_directories(${TARGET} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
|
||||
install(TARGETS ${TARGET} RUNTIME)
|
||||
target_link_libraries(${TARGET} PRIVATE stable-diffusion ${CMAKE_THREAD_LIBS_INIT})
|
||||
if(SD_WEBP)
|
||||
|
||||
@@ -1,3 +1,248 @@
|
||||
# Model selection
|
||||
|
||||
Start without model arguments to select models in the web UI:
|
||||
|
||||
```sh
|
||||
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:
|
||||
|
||||
```sh
|
||||
SD_SERVER_PATH="./build_vulkan/bin/sd-server" sh ./start-server.sh --listen-port 8080
|
||||
```
|
||||
|
||||
```powershell
|
||||
$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:
|
||||
|
||||
```bat
|
||||
@echo off
|
||||
set "MODEL_DIR=D:\stable-diffusion-webui\models"
|
||||
set "COMMANDLINE_ARGS=--listen-port 8080 --offload-to-cpu"
|
||||
```
|
||||
|
||||
```sh
|
||||
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/](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](api.md#recipe-feature-declarations) for the defaults
|
||||
and complete list of supported names.
|
||||
|
||||
Built-in additions and changes must follow the [recipe policy](recipes/README.md).
|
||||
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](recipes/defaults.md) 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](https://huggingface.co/docs/diffusers/api/pipelines/flux).
|
||||
SD-Turbo uses the [model card's one-step configuration](https://huggingface.co/stabilityai/sd-turbo),
|
||||
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:
|
||||
|
||||
```sh
|
||||
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:
|
||||
|
||||
```text
|
||||
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](api.md#model-management) 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:
|
||||
|
||||
+312
-19
@@ -59,6 +59,293 @@ Current endpoints include:
|
||||
- `POST /sdcpp/v1/vid_gen`
|
||||
- `POST /sdcpp/v1/upscale`
|
||||
|
||||
## Model management
|
||||
|
||||
Model management is additive: existing generation request bodies, successful
|
||||
responses, job polling and cancellation remain unchanged. All three API families
|
||||
use the current loaded context. Starting with the existing model arguments
|
||||
preserves command-line preloading and its generation defaults; it does not
|
||||
require a recipe.
|
||||
|
||||
Recipe defaults apply when a generation request omits the corresponding
|
||||
parameters. Image editing endpoints retain their existing input-image size
|
||||
inference when dimensions are omitted.
|
||||
|
||||
Without a loaded model, generation endpoints return HTTP 503 with
|
||||
`{"error":"No model is loaded","code":"model_not_loaded"}`.
|
||||
While loading/unloading, endpoints that access the context return HTTP 503
|
||||
with `code: "model_loading"`. These errors retain the existing string-valued
|
||||
`error` field. Job polling/cancellation, catalog queries and model status remain
|
||||
available during loading. Model lists are empty when no model is loaded;
|
||||
`/v1/models` retains the `sd-cpp-local` ID when ready.
|
||||
|
||||
| Method | Endpoint | Response / behavior |
|
||||
| --- | --- | --- |
|
||||
| GET | `/sdcpp/v1/recipes` | `{recipes: [...], errors: [...]}` |
|
||||
| GET | `/sdcpp/v1/model-files` | `{files: [{id, name, category, root, relative_path}], errors: [...]}` |
|
||||
| POST | `/sdcpp/v1/models/refresh` | Rescan recipes and files; return `{errors: [...]}` |
|
||||
| GET | `/sdcpp/v1/models/status` | Current state, recipe, selection, error, loading time and optional revision |
|
||||
| POST | `/sdcpp/v1/models/load` | Load the submitted recipe and selection; return status after completion |
|
||||
| POST | `/sdcpp/v1/models/unload` | Release the active context; return empty status |
|
||||
|
||||
Load request:
|
||||
|
||||
```json
|
||||
{
|
||||
"recipe": "flux1-dev",
|
||||
"models": {
|
||||
"diffusion_model": "diffusion_models/flux1-dev.gguf",
|
||||
"clip_l": "text_encoders/clip_l.safetensors",
|
||||
"t5xxl": "text_encoders/t5xxl.safetensors",
|
||||
"vae": "vae/ae.safetensors"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
File IDs are opaque strings returned by `model-files`. The first model root
|
||||
retains the existing relative IDs, such as `checkpoints/nested/model.gguf`.
|
||||
Additional roots use `@<root-id>/<relative-path>` so identical paths in different
|
||||
roots remain selectable. Root qualifiers derive from the canonical root path;
|
||||
adding unrelated roots or refreshing the catalog does not change them. Moving
|
||||
a root changes its qualifier. Do not construct IDs or use display names in load
|
||||
requests.
|
||||
|
||||
The display `name` omits the physical category directory (including aliases such
|
||||
as `Stable-diffusion`). Duplicate display paths use the full absolute file path,
|
||||
with the source directories before the filename and no hash suffix.
|
||||
`root` is an opaque source identifier, and
|
||||
`relative_path` is the file path beneath that root. Duplicate canonical files
|
||||
appear only once, using the first root that discovers them. Categories depend
|
||||
on directories, never on filename suffixes such as `.vae.safetensors`.
|
||||
|
||||
Repeated `--model-dir` arguments merge roots in order; absent arguments default
|
||||
to `./models`. User recipes override built-ins; the earliest root containing a
|
||||
valid user recipe wins across roots. Duplicate recipe IDs within one root are
|
||||
rejected. Directory aliases do not change recipe slot categories.
|
||||
|
||||
LoRA lists retain relative `path` IDs for `loras/` in the first model root and
|
||||
for an explicit `--lora-model-dir`, and qualify other directories. The additive `display_path` field provides a readable
|
||||
relative path, or the full absolute file path when needed to distinguish duplicates.
|
||||
Continue sending `path` in structured LoRA requests. `--lora-model-dir` overrides
|
||||
automatic discovery across all model roots.
|
||||
Absolute paths, unknown files, wrong categories and
|
||||
paths escaping the configured root are rejected. Optional slots can be omitted
|
||||
or set to an empty string. Load/unload returns HTTP 409 (`model_busy`) while
|
||||
requests or queued jobs are pending. Invalid configurations return HTTP 400
|
||||
(`invalid_model_config`) before unloading the current context. An initialization
|
||||
failure returns HTTP 422 (`model_load_failed`) and leaves no active context.
|
||||
The load HTTP request waits for completion; a separate client can poll status
|
||||
while it runs. Refreshing the catalog never modifies an already loaded context.
|
||||
|
||||
Status uses `state: empty | loading | ready | error`, `recipe` (ID or null),
|
||||
`models` (slot-to-file-ID mapping), and `error` (string or null). A monotonically
|
||||
increasing `revision` identifies runtime transitions within this server process.
|
||||
Command-line preloading keeps `origin: command_line` and `recipe: null` for
|
||||
compatibility, and adds `runtime_recipe`: a read-only `@command-line` recipe
|
||||
with all feature declarations enabled. It is only available while that context
|
||||
is loaded and cannot be submitted to `models/load`. The UI selects it by default
|
||||
and uses command-line generation defaults, not defaults from a catalog recipe.
|
||||
Capabilities also include this status as an additive `runtime` field.
|
||||
|
||||
`load_elapsed_seconds` is the server-measured duration in seconds (a number or
|
||||
null). It updates while a model is loading and freezes on success or failure.
|
||||
Timing starts after selection validation and includes releasing the previous
|
||||
model. It resets for each load and is null before any load and during/after
|
||||
unloading. Command-line preloading reports its completed initialization time.
|
||||
Poll `/sdcpp/v1/models/status` to display elapsed time, including while loading;
|
||||
timer updates alone do not change `revision`.
|
||||
|
||||
### Recipe feature declarations
|
||||
|
||||
Recipes may declare `features` and `disabled_features` arrays. The server starts
|
||||
with shared defaults, enables features declared by component slots and `features`,
|
||||
then applies `disabled_features` last. A disabled feature always wins. Unknown
|
||||
names, non-array values and duplicate names within an array are rejected.
|
||||
Both fields are optional; existing recipes remain valid.
|
||||
|
||||
```json
|
||||
{
|
||||
"features": ["flow_shift", "distilled_guidance"],
|
||||
"disabled_features": ["clip_skip", "lora"]
|
||||
}
|
||||
```
|
||||
|
||||
Default-enabled features are `img2img`, `mask_image`, `lora`, `vae_tiling`,
|
||||
`cache`, `cache_dit` and `preview`. All other features below default to false:
|
||||
|
||||
| Feature | Controls |
|
||||
| --- | --- |
|
||||
| `flow_shift` | Flow shift, where used by the selected scheduler |
|
||||
| `distilled_guidance` | Distilled guidance embedding |
|
||||
| `shifted_timestep` | SDXL timestep shifting |
|
||||
| `img_cfg` | Image CFG |
|
||||
| `slg` | Skip-layer guidance fields |
|
||||
| `clip_skip` | CLIP Skip |
|
||||
| `img2img`, `mask_image` | Image initialization/strength and masks |
|
||||
| `ref_images` | Reference image inputs |
|
||||
| `controlnet` | Control image and ControlNet strength |
|
||||
| `control_image` | Control image without a separate ControlNet (FLUX Canny/Depth) |
|
||||
| `ip_adapter` | IP-Adapter image and strength |
|
||||
| `init_image`, `end_image` | Video start/end frames |
|
||||
| `control_frames`, `vace` | Video control frames and VACE strength |
|
||||
| `high_noise` | High-noise pass, MoE boundary and high-noise LoRAs |
|
||||
| `lora`, `vae_tiling` | LoRA overrides and VAE tiling |
|
||||
| `cache`, `cache_unet`, `cache_dit` | Cache panel and architecture-specific algorithms |
|
||||
| `preview`, `preview_tae` | Preview panel and TAE preview option |
|
||||
|
||||
A `control_net` slot enables `controlnet`, `ip_adapter` enables `ip_adapter`,
|
||||
`high_noise_diffusion_model` enables `high_noise`, and `tae`/`taesd` enables `preview_tae`, unless explicitly disabled.
|
||||
ControlNet controls are shown when previewing a supporting recipe, even before
|
||||
a model file is selected. High-noise and TAE controls additionally require their
|
||||
component to be selected. Runtime capabilities require the component to be loaded.
|
||||
PuLID disables SLG while selected.
|
||||
Image-only and video-only inputs are filtered by the active generation mode.
|
||||
Eta depends on the selected sampler; SCM fields only apply to DBCache,
|
||||
TaylorSeer and Cache-DIT. Empty panels and advanced sections are hidden.
|
||||
|
||||
`GET /sdcpp/v1/recipes` adds a resolved boolean `effective_features` object to
|
||||
each recipe. This is response-only metadata, like `source` and slot `categories`;
|
||||
omit it when writing a user recipe file. The defaults are maintained by the
|
||||
server, not duplicated by the frontend.
|
||||
|
||||
`GET /sdcpp/v1/capabilities` adds `generation_features` for the loaded context,
|
||||
derived from the active recipe and component availability without inferring
|
||||
features from model-family names. When no model is loaded, every feature is
|
||||
present and false. The UI can still preview a selected recipe using its
|
||||
`effective_features` before loading.
|
||||
Existing `features` / `features_by_mode` keys are retained and their model-specific
|
||||
values reflect these declarations. A loaded recipe is snapshotted: refreshing
|
||||
recipe files does not change the active context's capabilities until reloading.
|
||||
Command-line preloading uses the runtime-only all-features recipe instead of model-family inference
|
||||
and component paths; variant-specific recipe declarations are more precise.
|
||||
|
||||
These declarations govern the Web UI and advertised capabilities, not API
|
||||
request validation. Existing generation APIs continue accepting their existing
|
||||
fields. The Web UI omits unsupported/hidden fields and ignores hidden image
|
||||
inputs when building requests, so switching recipes cannot submit stale options.
|
||||
|
||||
### User recipe format
|
||||
|
||||
Contributions to the built-in catalog must follow the
|
||||
[built-in recipe policy](recipes/README.md). Personal user recipes may define
|
||||
workflow-specific presets without adding them to the built-in catalog.
|
||||
|
||||
Each UTF-8 JSON file in `<model-dir>/recipes/` defines one complete recipe.
|
||||
The maximum recipe file size is 1 MiB. Unknown fields, invalid types and
|
||||
duplicate slots are errors. Built-ins in `examples/server/recipes/*.json` use
|
||||
the same one-recipe-per-file schema:
|
||||
|
||||
```json
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "my-flux",
|
||||
"name": "My FLUX",
|
||||
"description": "FLUX.1 dev",
|
||||
"model_url": "https://huggingface.co/black-forest-labs/FLUX.1-dev",
|
||||
"slots": [
|
||||
{"id": "diffusion_model", "required": true},
|
||||
{"id": "clip_l", "required": true},
|
||||
{"id": "t5xxl", "required": true},
|
||||
{"id": "vae", "required": false},
|
||||
{"id": "tae", "required": false}
|
||||
],
|
||||
"required_any": [["vae", "tae"]],
|
||||
"defaults": {"width": 1024, "height": 1024, "cfg_scale": 1.0, "distilled_guidance": 3.5, "sampling_method": "euler", "steps": 20}
|
||||
}
|
||||
```
|
||||
|
||||
IDs contain 1–128 ASCII letters, digits, dots, underscores or hyphens.
|
||||
`name`, `schema_version: 1` and `slots` are required; `description` and
|
||||
`model_url`, `required_any`, `defaults`, `context`, `features` and `disabled_features` are optional. Each slot requires only `id` and boolean `required`.
|
||||
The server supplies the default label and search directories for each slot.
|
||||
An optional nonempty `label` overrides the display name, for example
|
||||
`{"id": "diffusion_model", "label": "Low-noise diffusion model", "required": true}`.
|
||||
Legacy `category` fields remain accepted, but must match one of the slot's
|
||||
supported directories; they cannot redefine or restrict its search directories.
|
||||
At least one required `model` or `diffusion_model` slot is necessary.
|
||||
|
||||
`model_url` is an optional HTTPS Hugging Face model repository link, shown beside
|
||||
the recipe description. Built-ins link to the model's author/publisher, not repacks.
|
||||
`required_any` contains groups of declared slot IDs. At least one model in each
|
||||
group must be selected. For example, `"required_any": [["vae", "tae"]]` with both
|
||||
slots marked `required: false` allows either the full VAE or a compatible TAE.
|
||||
Selecting both is allowed; the current server uses TAE for encoding/decoding when
|
||||
TAE is selected. Checkpoint recipes with a bundled VAE do not need this group.
|
||||
Use complete, model-compatible TAE weights; decoder-only preview weights cannot
|
||||
replace a full VAE. Pixel-space models and unsupported latent formats have no
|
||||
TAE slot.
|
||||
|
||||
| Slot IDs | Search directories |
|
||||
| --- | --- |
|
||||
| `model` | `checkpoints` |
|
||||
| `diffusion_model`, `high_noise_diffusion_model`, `uncond_diffusion_model` | `diffusion_models` |
|
||||
| `clip_l`, `clip_g`, `t5xxl`, `llm`, `audio_encoder`, `embeddings_connectors` | `text_encoders` |
|
||||
| `clip_vision`, `llm_vision` | `clip_vision` |
|
||||
| `vae`, `audio_vae` | `vae` |
|
||||
| `tae` (legacy alias: `taesd`) | `vae` or `vae_approx` |
|
||||
| `tokenizer` | `tokenizers` |
|
||||
| `control_net` | `controlnet` |
|
||||
| `ip_adapter` | `ipadapter` |
|
||||
| `motion_module` | `motion_modules` |
|
||||
| `photo_maker` | `photomaker` |
|
||||
| `pulid_weights` | `pulid` |
|
||||
|
||||
Built-in recipes use `tae` for the Tiny AutoEncoder slot. TAE selections can use files from either `vae/` or the legacy
|
||||
`vae_approx/` directory. Existing recipes and load requests using `taesd`
|
||||
remain supported. Do not specify both `tae` and `taesd` in the same recipe
|
||||
or load request.
|
||||
|
||||
Model files can use `.gguf`, `.safetensors`, `.sft`, `.ckpt`, `.pt`, `.pth`
|
||||
or `.bin` extensions. The tokenizer category lists `.json` files only.
|
||||
Custom recipes compose components supported by the backend; they do not add
|
||||
new model architectures.
|
||||
|
||||
Optional `context` settings apply to each model load and override the matching
|
||||
startup setting. Supported fields are `vae_format` (`auto`, `flux`, `sd3`,
|
||||
`flux2`, or `wan`) and `model_args` (a string in the same format as
|
||||
`--model-args`; replaces the startup string). Other startup settings remain
|
||||
unchanged. Switching to a recipe that omits these fields restores the startup
|
||||
values. For example, PiD uses `{"vae_format": "flux"}` and Qwen Image Edit
|
||||
2511 uses `{"model_args": "qwen_image_zero_cond_t=true"}`.
|
||||
|
||||
Supported defaults:
|
||||
|
||||
- Integer `width`/`height` (64–4096), `steps` (1–1000), `video_frames`
|
||||
(1–4096), `fps` (1–240), `shifted_timestep` (0–1000), and
|
||||
`high_noise_steps` (1–1000 or -1 for automatic).
|
||||
- Numeric `cfg_scale`, `img_cfg_scale`, `distilled_guidance`, `flow_shift`,
|
||||
`high_noise_cfg_scale`, and `high_noise_flow_shift` (0–1000).
|
||||
- Numeric `strength` (0–1), used for image-to-image denoising, and
|
||||
`moe_boundary` (0–1), used for automatic Wan MoE expert switching.
|
||||
- `custom_sigmas`: an empty array or 2–1001 finite, nonnegative numbers.
|
||||
A nonempty array overrides the generated schedule; the sigma count minus one
|
||||
determines the actual step count. Include the final zero. An empty array uses
|
||||
the generated schedule. Loaded recipe sigmas apply to generation requests
|
||||
unless `sample_params.custom_sigmas` overrides them; switching recipes restores
|
||||
that recipe's schedule or the startup default.
|
||||
- Supported `sampling_method`/`scheduler` and
|
||||
`high_noise_sampling_method`/`high_noise_scheduler` names.
|
||||
|
||||
Other generation parameters continue to use startup defaults unless explicitly
|
||||
supplied by the generation request. Built-in Wan recipes provide video defaults;
|
||||
use `/sdcpp/v1/vid_gen` after loading a video model.
|
||||
LoRAs are merged from `loras/` and `Lora/` in every model root unless
|
||||
`--lora-model-dir` is supplied.
|
||||
|
||||
Recipe responses fill in each slot's `label`, `category` (the legacy value,
|
||||
if supplied, or the first search directory), and `categories` (the complete
|
||||
server-defined list of search directories). Clients should filter model files
|
||||
using `categories`; `category` remains available for older clients.
|
||||
For example, `{"id": "tae", "required": false}` expands to
|
||||
`{"id": "tae", "required": false, "label": "TAE", "category": "vae", "categories": ["vae", "vae_approx"]}`.
|
||||
|
||||
Recipe responses also add `source: builtin | user` and, for user recipes, `file`.
|
||||
Do not include `source`, `file`, or slot `categories` in a recipe file. A valid user recipe
|
||||
replaces a built-in with the same ID in full; inheritance/partial merging is
|
||||
not supported. Invalid recipes are skipped. Multiple valid user files sharing
|
||||
an ID are all skipped, preserving any built-in with that ID. Catalog errors
|
||||
are returned as `{file, message}` entries.
|
||||
|
||||
## `sd_cpp_extra_args`
|
||||
|
||||
`sd_cpp_extra_args` is an extension mechanism for the compatibility APIs.
|
||||
@@ -413,7 +700,7 @@ Common job shape:
|
||||
"id": "job_01HTXYZABC",
|
||||
"kind": "img_gen",
|
||||
"status": "queued",
|
||||
"created": 1775401200,
|
||||
"created": 1775401200000,
|
||||
"started": null,
|
||||
"completed": null,
|
||||
"queue_position": 2,
|
||||
@@ -437,6 +724,11 @@ Field types:
|
||||
| `error` | `object \| null` |
|
||||
| `preview` | `object \| null` |
|
||||
|
||||
`created`, `started`, and `completed` are integer Unix timestamps in
|
||||
**milliseconds**. Subtract `started` from `completed` and divide by 1000 to get
|
||||
the elapsed generation time in seconds, including output encoding and excluding
|
||||
queue time.
|
||||
|
||||
`preview` sub-fields:
|
||||
|
||||
| Field | Type | Notes |
|
||||
@@ -512,6 +804,7 @@ Shared nested fields:
|
||||
| --- | --- |
|
||||
| `loras[].name` | `string` |
|
||||
| `loras[].path` | `string` |
|
||||
| `loras[].display_path` | `string` (display only) |
|
||||
|
||||
`upscalers`
|
||||
|
||||
@@ -666,7 +959,7 @@ Example response:
|
||||
"id": "job_01HTXYZABC",
|
||||
"kind": "img_gen",
|
||||
"status": "queued",
|
||||
"created": 1775401200,
|
||||
"created": 1775401200000,
|
||||
"poll_url": "/sdcpp/v1/jobs/job_01HTXYZABC"
|
||||
}
|
||||
```
|
||||
@@ -994,9 +1287,9 @@ Example completed job:
|
||||
"id": "job_01HTXYZABC",
|
||||
"kind": "img_gen",
|
||||
"status": "completed",
|
||||
"created": 1775401200,
|
||||
"started": 1775401203,
|
||||
"completed": 1775401215,
|
||||
"created": 1775401200000,
|
||||
"started": 1775401203000,
|
||||
"completed": 1775401215237,
|
||||
"queue_position": 0,
|
||||
"result": {
|
||||
"output_format": "png",
|
||||
@@ -1020,9 +1313,9 @@ Example failed job:
|
||||
"id": "job_01HTXYZABC",
|
||||
"kind": "img_gen",
|
||||
"status": "failed",
|
||||
"created": 1775401200,
|
||||
"started": 1775401203,
|
||||
"completed": 1775401204,
|
||||
"created": 1775401200000,
|
||||
"started": 1775401203000,
|
||||
"completed": 1775401204000,
|
||||
"queue_position": 0,
|
||||
"result": null,
|
||||
"error": {
|
||||
@@ -1041,9 +1334,9 @@ Example cancelled job:
|
||||
"id": "job_01HTXYZABC",
|
||||
"kind": "img_gen",
|
||||
"status": "cancelled",
|
||||
"created": 1775401200,
|
||||
"created": 1775401200000,
|
||||
"started": null,
|
||||
"completed": 1775401202,
|
||||
"completed": 1775401202000,
|
||||
"queue_position": 0,
|
||||
"result": null,
|
||||
"error": {
|
||||
@@ -1079,7 +1372,7 @@ Example response:
|
||||
"id": "job_01HTXYZVID",
|
||||
"kind": "vid_gen",
|
||||
"status": "queued",
|
||||
"created": 1775401200,
|
||||
"created": 1775401200000,
|
||||
"poll_url": "/sdcpp/v1/jobs/job_01HTXYZVID"
|
||||
}
|
||||
```
|
||||
@@ -1407,9 +1700,9 @@ Example completed job:
|
||||
"id": "job_01HTXYZVID",
|
||||
"kind": "vid_gen",
|
||||
"status": "completed",
|
||||
"created": 1775401200,
|
||||
"started": 1775401203,
|
||||
"completed": 1775401215,
|
||||
"created": 1775401200000,
|
||||
"started": 1775401203000,
|
||||
"completed": 1775401215237,
|
||||
"queue_position": 0,
|
||||
"result": {
|
||||
"output_format": "webm",
|
||||
@@ -1433,9 +1726,9 @@ Example failed job:
|
||||
"id": "job_01HTXYZVID",
|
||||
"kind": "vid_gen",
|
||||
"status": "failed",
|
||||
"created": 1775401200,
|
||||
"started": 1775401203,
|
||||
"completed": 1775401204,
|
||||
"created": 1775401200000,
|
||||
"started": 1775401203000,
|
||||
"completed": 1775401204000,
|
||||
"queue_position": 0,
|
||||
"result": null,
|
||||
"error": {
|
||||
@@ -1454,9 +1747,9 @@ Example cancelled job:
|
||||
"id": "job_01HTXYZVID",
|
||||
"kind": "vid_gen",
|
||||
"status": "cancelled",
|
||||
"created": 1775401200,
|
||||
"created": 1775401200000,
|
||||
"started": null,
|
||||
"completed": 1775401202,
|
||||
"completed": 1775401202000,
|
||||
"queue_position": 0,
|
||||
"result": null,
|
||||
"error": {
|
||||
|
||||
@@ -88,7 +88,7 @@ const char* async_job_status_name(AsyncJobStatus status) {
|
||||
}
|
||||
|
||||
void purge_expired_jobs(AsyncJobManager& manager) {
|
||||
const int64_t now = unix_timestamp_now();
|
||||
const int64_t now = unix_timestamp_now_ms();
|
||||
|
||||
for (auto it = manager.expired_jobs.begin(); it != manager.expired_jobs.end();) {
|
||||
if (it->second <= now) {
|
||||
@@ -108,8 +108,8 @@ void purge_expired_jobs(AsyncJobManager& manager) {
|
||||
int64_t ttl_seconds = job->status == AsyncJobStatus::Completed
|
||||
? manager.completed_ttl_seconds
|
||||
: manager.failed_ttl_seconds;
|
||||
if (now - job->completed_at >= ttl_seconds) {
|
||||
manager.expired_jobs[job->id] = now + std::max<int64_t>(ttl_seconds, 60);
|
||||
if (now - job->completed_at >= ttl_seconds * 1000) {
|
||||
manager.expired_jobs[job->id] = now + std::max<int64_t>(ttl_seconds, 60) * 1000;
|
||||
it = manager.jobs.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
@@ -130,7 +130,7 @@ size_t count_pending_jobs(const AsyncJobManager& manager) {
|
||||
|
||||
std::string make_async_job_id(AsyncJobManager& manager) {
|
||||
std::ostringstream oss;
|
||||
oss << "job_" << std::hex << unix_timestamp_now() << "_" << std::setw(8)
|
||||
oss << "job_" << std::hex << unix_timestamp_now_ms() << "_" << std::setw(8)
|
||||
<< std::setfill('0') << manager.next_id++;
|
||||
return oss.str();
|
||||
}
|
||||
@@ -143,7 +143,7 @@ bool cancel_queued_job(AsyncJobManager& manager, AsyncGenerationJob& job) {
|
||||
|
||||
manager.queue.erase(new_end, manager.queue.end());
|
||||
job.status = AsyncJobStatus::Cancelled;
|
||||
job.completed_at = unix_timestamp_now();
|
||||
job.completed_at = unix_timestamp_now_ms();
|
||||
job.result_images_b64.clear();
|
||||
job.result_media_b64.clear();
|
||||
job.result_media_mime_type.clear();
|
||||
@@ -373,7 +373,7 @@ void async_job_worker(ServerRuntime& runtime) {
|
||||
|
||||
job = it->second;
|
||||
job->status = AsyncJobStatus::Generating;
|
||||
job->started_at = unix_timestamp_now();
|
||||
job->started_at = unix_timestamp_now_ms();
|
||||
}
|
||||
|
||||
std::vector<std::string> output_images;
|
||||
@@ -405,7 +405,7 @@ void async_job_worker(ServerRuntime& runtime) {
|
||||
continue;
|
||||
}
|
||||
|
||||
job->completed_at = unix_timestamp_now();
|
||||
job->completed_at = unix_timestamp_now_ms();
|
||||
if (ok) {
|
||||
job->status = AsyncJobStatus::Completed;
|
||||
job->result_images_b64 = std::move(output_images);
|
||||
|
||||
@@ -32,7 +32,7 @@ struct AsyncGenerationJob {
|
||||
std::string id;
|
||||
AsyncJobKind kind = AsyncJobKind::ImgGen;
|
||||
AsyncJobStatus status = AsyncJobStatus::Queued;
|
||||
int64_t created_at = unix_timestamp_now();
|
||||
int64_t created_at = unix_timestamp_now_ms();
|
||||
int64_t started_at = 0;
|
||||
int64_t completed_at = 0;
|
||||
ImgGenJobRequest img_gen;
|
||||
|
||||
+1
-1
Submodule examples/server/frontend updated: 8e7c115059...e36e34a2e2.
@@ -10,6 +10,7 @@
|
||||
#include "async_jobs.h"
|
||||
#include "common/common.h"
|
||||
#include "common/resource_owners.hpp"
|
||||
#include "model_catalog.h"
|
||||
#include "routes.h"
|
||||
#include "runtime.h"
|
||||
|
||||
@@ -50,7 +51,7 @@ static void parse_args(int argc,
|
||||
const bool random_seed_requested = default_gen_params.seed < 0;
|
||||
|
||||
if (!svr_params.resolve_and_validate() ||
|
||||
!ctx_params.resolve_and_validate(IMG_GEN) ||
|
||||
!ctx_params.resolve_and_validate(ctx_params.model_path.empty() && ctx_params.diffusion_model_path.empty() ? METADATA : IMG_GEN) ||
|
||||
!default_gen_params.resolve_and_validate(IMG_GEN,
|
||||
ctx_params.lora_model_dir,
|
||||
ctx_params.hires_upscalers_dir)) {
|
||||
@@ -84,14 +85,19 @@ int main(int argc, const char** argv) {
|
||||
|
||||
LOG_VERBOSE("version: %s", version_string().c_str());
|
||||
LOG_VERBOSE("%s", sd_get_system_info());
|
||||
LOG_VERBOSE("%s", svr_params.to_string().c_str());
|
||||
LOG_DEBUG("%s", svr_params.to_string().c_str());
|
||||
LOG_DEBUG("%s", ctx_params.to_string().c_str());
|
||||
LOG_DEBUG("%s", default_gen_params.to_string().c_str());
|
||||
|
||||
sd_ctx_params_t sd_ctx_params = ctx_params.to_sd_ctx_params_t(false);
|
||||
SDCtxPtr sd_ctx(new_sd_ctx(&sd_ctx_params));
|
||||
ServerModels models;
|
||||
if (!ctx_params.model_path.empty() || !ctx_params.diffusion_model_path.empty()) {
|
||||
const auto started = std::chrono::steady_clock::now();
|
||||
models.context.reset(new_sd_ctx(&sd_ctx_params));
|
||||
models.status["load_elapsed_seconds"] = std::chrono::duration<double>(std::chrono::steady_clock::now() - started).count();
|
||||
}
|
||||
|
||||
if (sd_ctx == nullptr) {
|
||||
if ((!ctx_params.model_path.empty() || !ctx_params.diffusion_model_path.empty()) && !models.context) {
|
||||
LOG_ERROR("new_sd_ctx_t failed");
|
||||
return 1;
|
||||
}
|
||||
@@ -104,7 +110,7 @@ int main(int argc, const char** argv) {
|
||||
std::mutex upscaler_mutex;
|
||||
AsyncJobManager async_job_manager;
|
||||
ServerRuntime runtime = {
|
||||
sd_ctx.get(),
|
||||
models.context.get(),
|
||||
&sd_ctx_mutex,
|
||||
&svr_params,
|
||||
&ctx_params,
|
||||
@@ -114,8 +120,16 @@ int main(int argc, const char** argv) {
|
||||
&upscaler_cache,
|
||||
&upscaler_mutex,
|
||||
&async_job_manager,
|
||||
&models,
|
||||
};
|
||||
|
||||
try {
|
||||
initialize_server_models(runtime);
|
||||
} catch (const std::exception& e) {
|
||||
LOG_ERROR("model catalog initialization failed: %s", e.what());
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::thread async_worker(async_job_worker, std::ref(runtime));
|
||||
|
||||
httplib::Server svr;
|
||||
@@ -147,6 +161,7 @@ int main(int argc, const char** argv) {
|
||||
register_openai_api_endpoints(svr, runtime);
|
||||
register_sdapi_endpoints(svr, runtime);
|
||||
register_sdcpp_api_endpoints(svr, runtime);
|
||||
register_model_endpoints(svr, runtime);
|
||||
|
||||
LOG_INFO("listening on: http://%s:%d\n", svr_params.listen_ip.c_str(), svr_params.listen_port);
|
||||
svr.listen(svr_params.listen_ip, svr_params.listen_port);
|
||||
|
||||
@@ -0,0 +1,664 @@
|
||||
#include "model_catalog.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <cmath>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
|
||||
#include "common/log.h"
|
||||
#include "recipes_builtin.h"
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
struct ModelSlot {
|
||||
const char* id;
|
||||
const char* label;
|
||||
std::vector<std::string> categories;
|
||||
std::string SDContextParams::*field;
|
||||
};
|
||||
|
||||
static const ModelSlot k_model_slots[] = {
|
||||
{"model", "Checkpoint", {"checkpoints"}, &SDContextParams::model_path},
|
||||
{"diffusion_model", "Diffusion model", {"diffusion_models"}, &SDContextParams::diffusion_model_path},
|
||||
{"high_noise_diffusion_model", "High-noise diffusion model", {"diffusion_models"}, &SDContextParams::high_noise_diffusion_model_path},
|
||||
{"uncond_diffusion_model", "Unconditional diffusion model", {"diffusion_models"}, &SDContextParams::uncond_diffusion_model_path},
|
||||
{"clip_l", "CLIP-L", {"text_encoders"}, &SDContextParams::clip_l_path},
|
||||
{"clip_g", "CLIP-G", {"text_encoders"}, &SDContextParams::clip_g_path},
|
||||
{"clip_vision", "CLIP Vision", {"clip_vision"}, &SDContextParams::clip_vision_path},
|
||||
{"t5xxl", "T5", {"text_encoders"}, &SDContextParams::t5xxl_path},
|
||||
{"llm", "LLM Text Encoder", {"text_encoders"}, &SDContextParams::llm_path},
|
||||
{"llm_vision", "LLM Vision Encoder", {"clip_vision"}, &SDContextParams::llm_vision_path},
|
||||
{"tokenizer", "Tokenizer", {"tokenizers"}, &SDContextParams::tokenizer},
|
||||
{"vae", "VAE", {"vae"}, &SDContextParams::vae_path},
|
||||
{"audio_vae", "Audio VAE", {"vae"}, &SDContextParams::audio_vae_path},
|
||||
{"audio_encoder", "Audio Encoder", {"text_encoders"}, &SDContextParams::audio_encoder_path},
|
||||
{"embeddings_connectors", "Embeddings Connectors", {"text_encoders"}, &SDContextParams::embeddings_connectors_path},
|
||||
{"tae", "TAE", {"vae", "vae_approx"}, &SDContextParams::taesd_path},
|
||||
{"taesd", "TAE", {"vae_approx", "vae"}, &SDContextParams::taesd_path},
|
||||
{"control_net", "ControlNet", {"controlnet"}, &SDContextParams::control_net_path},
|
||||
{"ip_adapter", "IP-Adapter", {"ipadapter"}, &SDContextParams::ip_adapter_path},
|
||||
{"motion_module", "Motion Module", {"motion_modules"}, &SDContextParams::motion_module_path},
|
||||
{"photo_maker", "PhotoMaker", {"photomaker"}, &SDContextParams::photo_maker_path},
|
||||
{"pulid_weights", "PuLID", {"pulid"}, &SDContextParams::pulid_weights_path},
|
||||
};
|
||||
|
||||
static const ModelSlot* find_model_slot(const std::string& id) {
|
||||
for (const auto& slot : k_model_slots) {
|
||||
if (id == slot.id) {
|
||||
return &slot;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static bool matches_model_category(const ModelSlot& slot, const std::string& category) {
|
||||
return std::find(slot.categories.begin(), slot.categories.end(), category) != slot.categories.end();
|
||||
}
|
||||
|
||||
static void clear_model_paths(SDContextParams& params) {
|
||||
for (const auto& slot : k_model_slots) {
|
||||
(params.*slot.field).clear();
|
||||
}
|
||||
}
|
||||
|
||||
std::string model_path_key(const fs::path& path) {
|
||||
#ifdef _WIN32
|
||||
const auto value = path.generic_wstring();
|
||||
const int length = LCMapStringEx(LOCALE_NAME_INVARIANT, LCMAP_LOWERCASE, value.data(),
|
||||
static_cast<int>(value.size()), nullptr, 0, nullptr, nullptr, 0);
|
||||
if (length > 0) {
|
||||
std::wstring folded(length, L'\0');
|
||||
LCMapStringEx(LOCALE_NAME_INVARIANT, LCMAP_LOWERCASE, value.data(),
|
||||
static_cast<int>(value.size()), &folded[0], length, nullptr, nullptr, 0);
|
||||
return fs::path(folded).generic_u8string();
|
||||
}
|
||||
#endif
|
||||
return path.generic_u8string();
|
||||
}
|
||||
|
||||
bool model_path_inside(const fs::path& root, const fs::path& path) {
|
||||
auto parent = root.begin();
|
||||
auto child = path.begin();
|
||||
for (; parent != root.end(); ++parent, ++child) {
|
||||
if (child == path.end() || model_path_key(*parent) != model_path_key(*child)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return child != path.end();
|
||||
}
|
||||
|
||||
ModelRoot make_model_root(const fs::path& path, bool primary) {
|
||||
ModelRoot root;
|
||||
const auto absolute = fs::absolute(path);
|
||||
std::error_code ec;
|
||||
root.path = fs::weakly_canonical(absolute, ec);
|
||||
if (ec)
|
||||
root.path = absolute.lexically_normal();
|
||||
root.primary = primary;
|
||||
uint64_t hash = 14695981039346656037ULL;
|
||||
for (unsigned char c : model_path_key(root.path)) {
|
||||
hash ^= c;
|
||||
hash *= 1099511628211ULL;
|
||||
}
|
||||
std::ostringstream id;
|
||||
id << '@' << std::hex << std::setfill('0') << std::setw(16) << hash;
|
||||
root.id = id.str();
|
||||
root.label = root.path.filename().u8string() + " [" + root.id.substr(1, 8) + "]";
|
||||
return root;
|
||||
}
|
||||
|
||||
std::vector<ModelRoot> get_model_roots(const SDSvrParams& params) {
|
||||
const auto directories = params.model_dirs.empty() ? std::vector<std::string>{"models"} : params.model_dirs;
|
||||
std::vector<ModelRoot> roots;
|
||||
std::set<std::string> seen;
|
||||
for (size_t i = 0; i < directories.size(); ++i) {
|
||||
auto root = make_model_root(fs::u8path(directories[i]), i == 0);
|
||||
if (seen.insert(model_path_key(root.path)).second)
|
||||
roots.push_back(std::move(root));
|
||||
}
|
||||
return roots;
|
||||
}
|
||||
|
||||
std::vector<fs::path> model_category_directories(const ModelRoot& root, const std::string& category) {
|
||||
std::vector<fs::path> directories;
|
||||
if (!fs::exists(root.path))
|
||||
return directories;
|
||||
for (const auto& entry : fs::directory_iterator(root.path)) {
|
||||
auto name = entry.path().filename().u8string();
|
||||
std::transform(name.begin(), name.end(), name.begin(), [](unsigned char c) { return std::tolower(c); });
|
||||
if (name == category || (category == "checkpoints" && name == "stable-diffusion") ||
|
||||
(category == "loras" && name == "lora")) {
|
||||
directories.push_back(entry.path());
|
||||
}
|
||||
}
|
||||
std::sort(directories.begin(), directories.end(), [&](const fs::path& a, const fs::path& b) {
|
||||
const bool a_standard = a.filename().u8string() == category;
|
||||
const bool b_standard = b.filename().u8string() == category;
|
||||
return a_standard != b_standard ? a_standard : a < b;
|
||||
});
|
||||
return directories;
|
||||
}
|
||||
|
||||
static bool valid_identifier(const std::string& id) {
|
||||
return !id.empty() && id.size() <= 128 &&
|
||||
std::all_of(id.begin(), id.end(), [](unsigned char c) {
|
||||
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
|
||||
(c >= '0' && c <= '9') || c == '-' || c == '_' || c == '.';
|
||||
});
|
||||
}
|
||||
|
||||
static void check_keys(const json& object, const std::set<std::string>& keys) {
|
||||
if (!object.is_object()) {
|
||||
throw std::runtime_error("expected an object");
|
||||
}
|
||||
for (auto it = object.begin(); it != object.end(); ++it) {
|
||||
if (!keys.count(it.key())) {
|
||||
throw std::runtime_error("unknown field: " + it.key());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void apply_recipe_defaults(const json& defaults, SDGenerationParams& params) {
|
||||
check_keys(defaults, {"width", "height", "steps", "cfg_scale", "strength", "distilled_guidance", "sampling_method", "scheduler", "custom_sigmas",
|
||||
"video_frames", "fps", "flow_shift", "moe_boundary", "high_noise_steps", "high_noise_cfg_scale",
|
||||
"high_noise_flow_shift", "high_noise_sampling_method", "high_noise_scheduler", "img_cfg_scale", "shifted_timestep"});
|
||||
for (const char* key : {"width", "height", "steps", "video_frames", "fps", "high_noise_steps", "shifted_timestep"}) {
|
||||
if (!defaults.contains(key)) {
|
||||
continue;
|
||||
}
|
||||
if (!defaults[key].is_number_integer()) {
|
||||
throw std::runtime_error(std::string(key) + " must be an integer");
|
||||
}
|
||||
const int64_t value = defaults[key].get<int64_t>();
|
||||
const std::string field = key;
|
||||
const bool dimension = field == "width" || field == "height";
|
||||
const int64_t maximum = dimension || field == "video_frames" ? 4096 : field == "fps" ? 240
|
||||
: 1000;
|
||||
const int64_t minimum = dimension ? 64 : field == "shifted_timestep" ? 0
|
||||
: 1;
|
||||
if ((value < minimum || value > maximum) && !(field == "high_noise_steps" && value == -1)) {
|
||||
throw std::runtime_error(std::string(key) + " is out of range");
|
||||
}
|
||||
if (std::string(key) == "width")
|
||||
params.width = static_cast<int>(value);
|
||||
if (std::string(key) == "height")
|
||||
params.height = static_cast<int>(value);
|
||||
if (std::string(key) == "steps")
|
||||
params.sample_params.sample_steps = static_cast<int>(value);
|
||||
if (field == "shifted_timestep")
|
||||
params.sample_params.shifted_timestep = static_cast<int>(value);
|
||||
if (field == "video_frames")
|
||||
params.video_frames = static_cast<int>(value);
|
||||
if (field == "fps")
|
||||
params.fps = static_cast<int>(value);
|
||||
if (field == "high_noise_steps")
|
||||
params.high_noise_sample_params.sample_steps = static_cast<int>(value);
|
||||
}
|
||||
for (const char* key : {"cfg_scale", "strength", "moe_boundary", "img_cfg_scale", "distilled_guidance", "flow_shift", "high_noise_cfg_scale", "high_noise_flow_shift"}) {
|
||||
if (!defaults.contains(key)) {
|
||||
continue;
|
||||
}
|
||||
if (!defaults[key].is_number()) {
|
||||
throw std::runtime_error(std::string(key) + " must be a number");
|
||||
}
|
||||
const float value = defaults[key].get<float>();
|
||||
if (!std::isfinite(value) || value < 0 || value > ((std::string(key) == "strength" || std::string(key) == "moe_boundary") ? 1.f : 1000.f)) {
|
||||
throw std::runtime_error(std::string(key) + " is out of range");
|
||||
}
|
||||
if (std::string(key) == "strength")
|
||||
params.strength = value;
|
||||
if (std::string(key) == "moe_boundary")
|
||||
params.moe_boundary = value;
|
||||
if (std::string(key) == "cfg_scale")
|
||||
params.sample_params.guidance.txt_cfg = value;
|
||||
if (std::string(key) == "img_cfg_scale")
|
||||
params.sample_params.guidance.img_cfg = value;
|
||||
if (std::string(key) == "distilled_guidance")
|
||||
params.sample_params.guidance.distilled_guidance = value;
|
||||
if (std::string(key) == "flow_shift")
|
||||
params.sample_params.flow_shift = value;
|
||||
if (std::string(key) == "high_noise_cfg_scale")
|
||||
params.high_noise_sample_params.guidance.txt_cfg = value;
|
||||
if (std::string(key) == "high_noise_flow_shift")
|
||||
params.high_noise_sample_params.flow_shift = value;
|
||||
}
|
||||
if (defaults.contains("custom_sigmas")) {
|
||||
const auto& sigmas = defaults.at("custom_sigmas");
|
||||
if (!sigmas.is_array() || sigmas.size() == 1 || sigmas.size() > 1001)
|
||||
throw std::runtime_error("custom_sigmas must be empty or contain 2-1001 values");
|
||||
for (const auto& sigma : sigmas) {
|
||||
if (!sigma.is_number() || !std::isfinite(sigma.get<float>()) || sigma.get<float>() < 0)
|
||||
throw std::runtime_error("custom_sigmas must contain finite nonnegative numbers");
|
||||
}
|
||||
params.custom_sigmas = sigmas.get<std::vector<float>>();
|
||||
}
|
||||
for (const char* key : {"sampling_method", "high_noise_sampling_method"}) {
|
||||
if (!defaults.contains(key))
|
||||
continue;
|
||||
auto& sample = std::string(key) == "sampling_method" ? params.sample_params : params.high_noise_sample_params;
|
||||
const auto name = defaults.at(key).get<std::string>();
|
||||
bool found = false;
|
||||
for (int i = 0; i < SAMPLE_METHOD_COUNT; ++i) {
|
||||
if (name == sd_sample_method_name(static_cast<sample_method_t>(i))) {
|
||||
sample.sample_method = static_cast<sample_method_t>(i);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
throw std::runtime_error(std::string("unknown ") + key);
|
||||
}
|
||||
for (const char* key : {"scheduler", "high_noise_scheduler"}) {
|
||||
if (!defaults.contains(key))
|
||||
continue;
|
||||
auto& sample = std::string(key) == "scheduler" ? params.sample_params : params.high_noise_sample_params;
|
||||
const auto name = defaults.at(key).get<std::string>();
|
||||
bool found = false;
|
||||
for (int i = 0; i < SCHEDULER_COUNT; ++i) {
|
||||
if (name == sd_scheduler_name(static_cast<scheduler_t>(i)) ||
|
||||
(name == "normal" && i == DISCRETE_SCHEDULER)) {
|
||||
sample.scheduler = static_cast<scheduler_t>(i);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
throw std::runtime_error(std::string("unknown ") + key);
|
||||
}
|
||||
}
|
||||
|
||||
static void apply_recipe_context(const json& settings, SDContextParams& params) {
|
||||
check_keys(settings, {"vae_format", "model_args"});
|
||||
if (settings.contains("vae_format")) {
|
||||
const auto format = settings.at("vae_format").get<std::string>();
|
||||
if (format != "auto" && format != "flux" && format != "sd3" && format != "flux2" && format != "wan")
|
||||
throw std::runtime_error("unknown vae_format");
|
||||
params.vae_format = format;
|
||||
}
|
||||
if (settings.contains("model_args")) {
|
||||
params.model_args = settings.at("model_args").get<std::string>();
|
||||
}
|
||||
}
|
||||
|
||||
static const std::map<std::string, bool> k_recipe_features = {
|
||||
{"img2img", true},
|
||||
{"mask_image", true},
|
||||
{"lora", true},
|
||||
{"vae_tiling", true},
|
||||
{"cache", true},
|
||||
{"cache_dit", true},
|
||||
{"preview", true},
|
||||
{"flow_shift", false},
|
||||
{"distilled_guidance", false},
|
||||
{"shifted_timestep", false},
|
||||
{"img_cfg", false},
|
||||
{"slg", false},
|
||||
{"clip_skip", false},
|
||||
{"ref_images", false},
|
||||
{"controlnet", false},
|
||||
{"control_image", false},
|
||||
{"ip_adapter", false},
|
||||
{"init_image", false},
|
||||
{"end_image", false},
|
||||
{"control_frames", false},
|
||||
{"vace", false},
|
||||
{"high_noise", false},
|
||||
{"cache_unet", false},
|
||||
{"preview_tae", false},
|
||||
};
|
||||
|
||||
static void validate_recipe_features(const json& recipe) {
|
||||
for (const char* key : {"features", "disabled_features"}) {
|
||||
if (!recipe.contains(key))
|
||||
continue;
|
||||
const auto& values = recipe.at(key);
|
||||
if (!values.is_array() || values.size() > k_recipe_features.size())
|
||||
throw std::runtime_error(std::string(key) + " must be an array of feature names");
|
||||
std::set<std::string> seen;
|
||||
for (const auto& value : values) {
|
||||
const auto name = value.get<std::string>();
|
||||
if (!k_recipe_features.count(name) || !seen.insert(name).second)
|
||||
throw std::runtime_error("unknown or duplicate feature: " + name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
json resolve_recipe_features(const json& recipe) {
|
||||
json features = k_recipe_features;
|
||||
for (const auto& slot : recipe.at("slots")) {
|
||||
const auto id = slot.at("id").get<std::string>();
|
||||
if (id == "ip_adapter")
|
||||
features["ip_adapter"] = true;
|
||||
if (id == "control_net")
|
||||
features["controlnet"] = true;
|
||||
if (id == "high_noise_diffusion_model")
|
||||
features["high_noise"] = true;
|
||||
if (id == "tae" || id == "taesd")
|
||||
features["preview_tae"] = true;
|
||||
}
|
||||
for (const auto& name : recipe.value("features", json::array()))
|
||||
features[name.get<std::string>()] = true;
|
||||
for (const auto& name : recipe.value("disabled_features", json::array()))
|
||||
features[name.get<std::string>()] = false;
|
||||
return features;
|
||||
}
|
||||
|
||||
json model_generation_features(const ServerRuntime& runtime) {
|
||||
if (!runtime.sd_ctx || runtime.models->active_recipe.is_null()) {
|
||||
json features = k_recipe_features;
|
||||
for (auto& feature : features)
|
||||
feature = false;
|
||||
return features;
|
||||
}
|
||||
json features = resolve_recipe_features(runtime.models->active_recipe);
|
||||
if (runtime.models->active_recipe.value("source", "") == "command_line")
|
||||
return features;
|
||||
// Optional components only become usable once selected and loaded.
|
||||
features["ip_adapter"] = features.value("ip_adapter", false) && !runtime.ctx_params->ip_adapter_path.empty();
|
||||
features["controlnet"] = features.value("controlnet", false) && !runtime.ctx_params->control_net_path.empty();
|
||||
features["high_noise"] = features.value("high_noise", false) && !runtime.ctx_params->high_noise_diffusion_model_path.empty();
|
||||
features["preview_tae"] = features.value("preview_tae", false) && !runtime.ctx_params->taesd_path.empty();
|
||||
if (!runtime.ctx_params->pulid_weights_path.empty())
|
||||
features["slg"] = false;
|
||||
return features;
|
||||
}
|
||||
|
||||
static void validate_recipe(const json& recipe) {
|
||||
check_keys(recipe, {"schema_version", "id", "name", "description", "model_url", "slots", "required_any", "defaults", "context", "features", "disabled_features"});
|
||||
if (!recipe.at("schema_version").is_number_integer() || recipe.at("schema_version") != 1 ||
|
||||
!valid_identifier(recipe.at("id").get<std::string>()) || recipe.at("name").get<std::string>().empty()) {
|
||||
throw std::runtime_error("invalid schema_version, id or name");
|
||||
}
|
||||
if (recipe.contains("description") && !recipe["description"].is_string()) {
|
||||
throw std::runtime_error("description must be a string");
|
||||
}
|
||||
if (recipe.contains("model_url")) {
|
||||
const auto url = recipe.at("model_url").get<std::string>();
|
||||
const std::string prefix = "https://huggingface.co/";
|
||||
if (url.size() <= prefix.size() || url.size() > 2048 || url.rfind(prefix, 0) != 0 ||
|
||||
std::any_of(url.begin(), url.end(), [](unsigned char c) { return std::isspace(c) || std::iscntrl(c); })) {
|
||||
throw std::runtime_error("model_url must be a Hugging Face HTTPS URL");
|
||||
}
|
||||
}
|
||||
const auto& slots = recipe.at("slots");
|
||||
if (!slots.is_array() || slots.empty() || slots.size() > 32) {
|
||||
throw std::runtime_error("slots must be a nonempty array of at most 32 entries");
|
||||
}
|
||||
std::set<std::string> ids;
|
||||
bool has_required_model = false;
|
||||
for (const auto& slot : slots) {
|
||||
check_keys(slot, {"id", "label", "category", "required"});
|
||||
const auto id = slot.at("id").get<std::string>();
|
||||
const auto* spec = find_model_slot(id);
|
||||
if (!spec || !ids.insert(id == "taesd" ? "tae" : id).second ||
|
||||
(slot.contains("category") && !matches_model_category(*spec, slot.at("category").get<std::string>())) ||
|
||||
(slot.contains("label") && slot.at("label").get<std::string>().empty()) || !slot.at("required").is_boolean()) {
|
||||
throw std::runtime_error("invalid or duplicate model slot: " + id);
|
||||
}
|
||||
has_required_model |= (id == "model" || id == "diffusion_model") && slot["required"].get<bool>();
|
||||
}
|
||||
if (!has_required_model) {
|
||||
throw std::runtime_error("a required model or diffusion_model slot is needed");
|
||||
}
|
||||
if (recipe.contains("required_any")) {
|
||||
const auto& groups = recipe.at("required_any");
|
||||
if (!groups.is_array() || groups.size() > 32)
|
||||
throw std::runtime_error("required_any must be an array of at most 32 slot groups");
|
||||
for (const auto& group : groups) {
|
||||
if (!group.is_array() || group.size() < 2 || group.size() > slots.size())
|
||||
throw std::runtime_error("required_any groups need at least two declared slots");
|
||||
std::set<std::string> seen;
|
||||
for (const auto& value : group) {
|
||||
const auto id = value.get<std::string>();
|
||||
if (!seen.insert(id).second || std::none_of(slots.begin(), slots.end(), [&](const json& slot) { return slot.at("id") == id; }))
|
||||
throw std::runtime_error("unknown or duplicate required_any slot: " + id);
|
||||
}
|
||||
}
|
||||
}
|
||||
validate_recipe_features(recipe);
|
||||
SDContextParams context;
|
||||
apply_recipe_context(recipe.value("context", json::object()), context);
|
||||
SDGenerationParams defaults;
|
||||
apply_recipe_defaults(recipe.value("defaults", json::object()), defaults);
|
||||
}
|
||||
|
||||
static json normalize_recipe(json recipe) {
|
||||
validate_recipe(recipe);
|
||||
recipe["effective_features"] = resolve_recipe_features(recipe);
|
||||
for (auto& slot : recipe.at("slots")) {
|
||||
const auto& spec = *find_model_slot(slot.at("id").get<std::string>());
|
||||
slot["label"] = slot.value("label", std::string(spec.label));
|
||||
slot["category"] = slot.value("category", spec.categories.front());
|
||||
slot["categories"] = spec.categories;
|
||||
}
|
||||
return recipe;
|
||||
}
|
||||
|
||||
static bool supported_model_file(const fs::path& path, const std::string& category) {
|
||||
std::string ext = path.extension().u8string();
|
||||
std::transform(ext.begin(), ext.end(), ext.begin(), [](unsigned char c) { return std::tolower(c); });
|
||||
if (category == "tokenizers") {
|
||||
return ext == ".json";
|
||||
}
|
||||
return ext == ".gguf" || ext == ".safetensors" || ext == ".sft" ||
|
||||
ext == ".ckpt" || ext == ".pt" || ext == ".pth" || ext == ".bin";
|
||||
}
|
||||
|
||||
void refresh_model_catalog(ServerRuntime& runtime) {
|
||||
auto& models = *runtime.models;
|
||||
std::lock_guard<std::mutex> lock(models.catalog_mutex);
|
||||
std::map<std::string, json> recipes;
|
||||
std::map<std::string, ModelFile> files;
|
||||
json errors = json::array();
|
||||
auto report = [&](const std::string& file, const std::string& message) {
|
||||
errors.push_back({{"file", file}, {"message", message}});
|
||||
};
|
||||
for (const char* builtin : k_builtin_recipes) {
|
||||
auto recipe = normalize_recipe(json::parse(builtin));
|
||||
const auto id = recipe.at("id").get<std::string>();
|
||||
recipe["source"] = "builtin";
|
||||
recipes[id] = std::move(recipe);
|
||||
}
|
||||
|
||||
std::set<std::string> seen_files;
|
||||
for (const auto& source : get_model_roots(*runtime.svr_params)) {
|
||||
const auto& root = source.path;
|
||||
auto display_path = [&](const fs::path& path) {
|
||||
return source.id + "/" + path.lexically_relative(root).generic_u8string();
|
||||
};
|
||||
const fs::path recipe_dir = root / "recipes";
|
||||
std::map<std::string, std::vector<json>> user_recipes;
|
||||
try {
|
||||
if (fs::exists(recipe_dir)) {
|
||||
if (!model_path_inside(root, fs::canonical(recipe_dir)))
|
||||
throw std::runtime_error("recipes directory escapes model directory");
|
||||
for (const auto& entry : fs::directory_iterator(recipe_dir)) {
|
||||
const std::string display = display_path(entry.path());
|
||||
if (entry.path().extension() != ".json")
|
||||
continue;
|
||||
try {
|
||||
if (!entry.is_regular_file() || !model_path_inside(root, fs::canonical(entry.path())))
|
||||
throw std::runtime_error("recipe must be a file inside the model directory");
|
||||
if (entry.file_size() > 1024 * 1024)
|
||||
throw std::runtime_error("recipe exceeds 1 MiB");
|
||||
std::ifstream input(entry.path(), std::ios::binary);
|
||||
json recipe;
|
||||
input >> recipe;
|
||||
recipe = normalize_recipe(std::move(recipe));
|
||||
recipe["source"] = "user";
|
||||
recipe["file"] = entry.path().filename().u8string();
|
||||
recipe["root"] = source.id;
|
||||
const auto id = recipe.at("id").get<std::string>();
|
||||
user_recipes[id].push_back(std::move(recipe));
|
||||
} catch (const std::exception& e) {
|
||||
report(display, e.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
report(display_path(recipe_dir), e.what());
|
||||
}
|
||||
for (auto& item : user_recipes) {
|
||||
if (item.second.size() != 1) {
|
||||
for (const auto& recipe : item.second)
|
||||
report(source.id + "/recipes/" + recipe["file"].get<std::string>(), "duplicate user recipe id: " + item.first);
|
||||
continue;
|
||||
}
|
||||
const auto existing = recipes.find(item.first);
|
||||
if (existing != recipes.end()) {
|
||||
if (existing->second["source"] == "user") {
|
||||
LOG_WARN("recipe '%s' from %s is shadowed by an earlier model directory", item.first.c_str(), source.label.c_str());
|
||||
continue;
|
||||
}
|
||||
LOG_INFO("user recipe '%s' from %s overrides the builtin", item.first.c_str(), source.label.c_str());
|
||||
}
|
||||
recipes[item.first] = std::move(item.second.front());
|
||||
}
|
||||
|
||||
std::set<std::string> categories;
|
||||
for (const auto& slot : k_model_slots)
|
||||
categories.insert(slot.categories.begin(), slot.categories.end());
|
||||
for (const auto& category : categories) {
|
||||
try {
|
||||
for (const auto& directory : model_category_directories(source, category)) {
|
||||
if (!model_path_inside(root, fs::canonical(directory))) {
|
||||
report(display_path(directory), "category directory escapes model directory");
|
||||
continue;
|
||||
}
|
||||
for (fs::recursive_directory_iterator it(directory), end; it != end; ++it) {
|
||||
std::error_code path_error;
|
||||
const fs::path canonical = fs::canonical(it->path(), path_error);
|
||||
if (path_error || !model_path_inside(root, canonical)) {
|
||||
it.disable_recursion_pending();
|
||||
report(display_path(it->path()), path_error ? path_error.message() : "path escapes model directory");
|
||||
continue;
|
||||
}
|
||||
if (!it->is_regular_file() || !supported_model_file(it->path(), category) ||
|
||||
!seen_files.insert(model_path_key(canonical)).second)
|
||||
continue;
|
||||
const auto relative = it->path().lexically_relative(root).generic_u8string();
|
||||
const auto id = source.primary ? relative : source.id + "/" + relative;
|
||||
files[id] = {category, it->path().lexically_relative(directory).generic_u8string(), relative, source};
|
||||
}
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
report(source.id + "/" + category, e.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
std::map<std::pair<std::string, std::string>, size_t> names;
|
||||
for (const auto& entry : files)
|
||||
++names[{entry.second.category, entry.second.name}];
|
||||
for (auto& entry : files) {
|
||||
auto& file = entry.second;
|
||||
if (names[{file.category, file.name}] > 1)
|
||||
file.name = (file.root.path / fs::u8path(file.relative_path)).generic_u8string();
|
||||
}
|
||||
models.recipes = std::move(recipes);
|
||||
models.files = std::move(files);
|
||||
models.catalog_errors = std::move(errors);
|
||||
}
|
||||
|
||||
json model_status(ServerRuntime& runtime) {
|
||||
std::lock_guard<std::mutex> lock(runtime.models->status_mutex);
|
||||
auto& models = *runtime.models;
|
||||
json status = models.status;
|
||||
if (status["state"] == "loading" && !status["load_elapsed_seconds"].is_null()) {
|
||||
status["load_elapsed_seconds"] = std::chrono::duration<double>(std::chrono::steady_clock::now() - models.load_started_at).count();
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
void initialize_server_models(ServerRuntime& runtime) {
|
||||
auto& models = *runtime.models;
|
||||
models.base_context = *runtime.ctx_params;
|
||||
clear_model_paths(models.base_context);
|
||||
models.base_defaults = *runtime.default_gen_params;
|
||||
if (runtime.sd_ctx) {
|
||||
models.status["state"] = "ready";
|
||||
models.status["origin"] = "command_line";
|
||||
json features = json::array();
|
||||
for (const auto& feature : k_recipe_features)
|
||||
features.push_back(feature.first);
|
||||
models.active_recipe = {
|
||||
{"id", "@command-line"},
|
||||
{"name", "Command-line model (all features)"},
|
||||
{"source", "command_line"},
|
||||
{"description", "Uses the loaded command-line model and its generation defaults."},
|
||||
{"slots", json::array()},
|
||||
{"defaults", json::object()},
|
||||
{"features", features},
|
||||
};
|
||||
models.active_recipe["effective_features"] = resolve_recipe_features(models.active_recipe);
|
||||
models.status["runtime_recipe"] = models.active_recipe;
|
||||
}
|
||||
refresh_model_catalog(runtime);
|
||||
}
|
||||
|
||||
void prepare_model_load(ServerRuntime& runtime, const json& body, SDContextParams& context, SDGenerationParams& defaults, json* loaded_recipe) {
|
||||
check_keys(body, {"recipe", "models"});
|
||||
const auto recipe_id = body.at("recipe").get<std::string>();
|
||||
auto selection = body.at("models");
|
||||
if (!selection.is_object())
|
||||
throw std::runtime_error("models must be an object");
|
||||
auto& models = *runtime.models;
|
||||
std::lock_guard<std::mutex> lock(models.catalog_mutex);
|
||||
const auto found = models.recipes.find(recipe_id);
|
||||
if (found == models.recipes.end())
|
||||
throw std::runtime_error("unknown recipe");
|
||||
const auto& recipe = found->second;
|
||||
if (loaded_recipe)
|
||||
*loaded_recipe = recipe;
|
||||
context = models.base_context;
|
||||
defaults = models.base_defaults;
|
||||
apply_recipe_context(recipe.value("context", json::object()), context);
|
||||
apply_recipe_defaults(recipe.value("defaults", json::object()), defaults);
|
||||
std::set<std::string> allowed;
|
||||
for (const auto& slot : recipe.at("slots")) {
|
||||
const auto id = slot.at("id").get<std::string>();
|
||||
allowed.insert(id);
|
||||
if (id == "tae" || id == "taesd") {
|
||||
const std::string alias = id == "tae" ? "taesd" : "tae";
|
||||
allowed.insert(alias);
|
||||
if (selection.contains(alias)) {
|
||||
if (selection.contains(id))
|
||||
throw std::runtime_error("specify only one of tae and taesd");
|
||||
selection[id] = selection.at(alias);
|
||||
}
|
||||
}
|
||||
const std::string file_id = selection.value(id, std::string());
|
||||
if (file_id.empty()) {
|
||||
if (slot.at("required").get<bool>())
|
||||
throw std::runtime_error("missing required model: " + id);
|
||||
continue;
|
||||
}
|
||||
const auto file = models.files.find(file_id);
|
||||
if (file == models.files.end() || !matches_model_category(*find_model_slot(id), file->second.category)) {
|
||||
throw std::runtime_error("unknown model or incorrect category: " + id);
|
||||
}
|
||||
const auto& root = file->second.root.path;
|
||||
const fs::path path = fs::canonical(root / fs::u8path(file->second.relative_path));
|
||||
if (!model_path_inside(root, path) || !fs::is_regular_file(path)) {
|
||||
throw std::runtime_error("model file must remain inside the model directory: " + id);
|
||||
}
|
||||
context.*find_model_slot(id)->field = path.u8string();
|
||||
}
|
||||
for (auto it = selection.begin(); it != selection.end(); ++it) {
|
||||
if (!allowed.count(it.key()))
|
||||
throw std::runtime_error("unknown model slot: " + it.key());
|
||||
}
|
||||
for (const auto& group : recipe.value("required_any", json::array())) {
|
||||
if (std::none_of(group.begin(), group.end(), [&](const json& value) {
|
||||
return !selection.value(value.get<std::string>(), std::string()).empty();
|
||||
})) {
|
||||
throw std::runtime_error("select at least one model from: " + group.dump());
|
||||
}
|
||||
}
|
||||
if (!context.resolve_and_validate(IMG_GEN))
|
||||
throw std::runtime_error("invalid model context parameters");
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
#ifndef __SD_EXAMPLES_SERVER_MODEL_CATALOG_H__
|
||||
#define __SD_EXAMPLES_SERVER_MODEL_CATALOG_H__
|
||||
|
||||
#include <chrono>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <shared_mutex>
|
||||
#include <string>
|
||||
|
||||
#include "runtime.h"
|
||||
|
||||
struct ModelRoot {
|
||||
std::filesystem::path path;
|
||||
std::string id;
|
||||
std::string label;
|
||||
bool primary = false;
|
||||
};
|
||||
|
||||
struct ModelFile {
|
||||
std::string category;
|
||||
std::string name;
|
||||
std::string relative_path;
|
||||
ModelRoot root;
|
||||
};
|
||||
|
||||
std::string model_path_key(const std::filesystem::path& path);
|
||||
bool model_path_inside(const std::filesystem::path& root, const std::filesystem::path& path);
|
||||
ModelRoot make_model_root(const std::filesystem::path& path, bool primary);
|
||||
std::vector<ModelRoot> get_model_roots(const SDSvrParams& params);
|
||||
std::vector<std::filesystem::path> model_category_directories(const ModelRoot& root, const std::string& category);
|
||||
|
||||
struct ServerModels {
|
||||
std::shared_mutex runtime_mutex;
|
||||
std::mutex catalog_mutex;
|
||||
std::mutex status_mutex;
|
||||
SDCtxPtr context;
|
||||
SDContextParams base_context;
|
||||
SDGenerationParams base_defaults;
|
||||
std::map<std::string, json> recipes;
|
||||
std::map<std::string, ModelFile> files;
|
||||
std::chrono::steady_clock::time_point load_started_at;
|
||||
json active_recipe = nullptr;
|
||||
json catalog_errors = json::array();
|
||||
json status = {{"state", "empty"}, {"recipe", nullptr}, {"models", json::object()}, {"error", nullptr}, {"load_elapsed_seconds", nullptr}};
|
||||
};
|
||||
|
||||
void refresh_model_catalog(ServerRuntime& runtime);
|
||||
json model_status(ServerRuntime& runtime);
|
||||
void initialize_server_models(ServerRuntime& runtime);
|
||||
|
||||
json resolve_recipe_features(const json& recipe);
|
||||
json model_generation_features(const ServerRuntime& runtime);
|
||||
|
||||
void prepare_model_load(ServerRuntime& runtime, const json& body, SDContextParams& context, SDGenerationParams& defaults, json* loaded_recipe = nullptr);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,79 @@
|
||||
# Built-in recipe policy
|
||||
|
||||
Read these rules before adding or changing JSON files in this directory. A recipe
|
||||
represents a supported model-loading and capability configuration, not a saved
|
||||
prompt, a style preset, or a collection of sampling settings.
|
||||
|
||||
## Required rules
|
||||
|
||||
1. **Community editing adapters get a separate recipe.** When the base model
|
||||
does not natively support instruction/reference-image editing and needs a
|
||||
community LoRA to gain it, provide a dedicated editing recipe. Keep editing
|
||||
inputs disabled in the base recipe. Examples: `anima` / `anima-edit` and
|
||||
`krea2-raw` / `krea2-raw-edit`.
|
||||
2. **Split different task weights; share native multi-task weights.** If editing
|
||||
and text-to-image use different generation checkpoints, use separate recipes.
|
||||
If the same checkpoint natively supports both, use one recipe. Examples:
|
||||
`boogu-image` / `boogu-image-edit` are separate; `flux2-dev` and
|
||||
`qwen-image-21` each cover both generation and editing. Apply the same rule
|
||||
to video: separate HunyuanVideo 1.5 T2V/I2V and Wan 2.2 A14B T2V/I2V weights,
|
||||
but share one `wan22-ti2v-5b` recipe for its native T2V/I2V checkpoint.
|
||||
3. **Capability-extending weights get a separate recipe.** ControlNet,
|
||||
IP-Adapter, PuLID, PhotoMaker, motion modules, and similar adapters that add
|
||||
a distinct conditioning or generation capability belong in dedicated
|
||||
recipes. Make the extension's model slots required when the schema provides
|
||||
them. Do not add these as optional slots on the ordinary base recipe.
|
||||
4. **A LoRA alone is not a reason to split.** If adding a LoRA does not change
|
||||
supported functionality, reuse the base recipe. Style, character, quality,
|
||||
acceleration and distillation LoRAs do not get dedicated built-in recipes.
|
||||
Users select the LoRA and change steps, guidance or other generation settings
|
||||
separately. Standalone base/turbo/distilled checkpoints still follow the task,
|
||||
component and layer-count rules; a different filename alone is not a reason
|
||||
for another recipe.
|
||||
5. **Keep native components in the model's recipe.** Native vision encoders,
|
||||
projectors, connectors and other components required by the model belong in
|
||||
its existing recipe. Splitting a native component into another file does not
|
||||
make it a capability-extending adapter under rule 3. For example, Qwen vision
|
||||
projectors and LLaDA/LTX connectors do not get separate recipes. A slot may be
|
||||
optional when its weights can be bundled in another selected file.
|
||||
6. **Layer-count variants share the family recipe.** Adding, repeating, removing
|
||||
or pruning model layers does not justify a separate recipe when the runtime
|
||||
supports the variant with the same components and capabilities. This also
|
||||
applies to distilled checkpoints whose relevant difference is reduced depth.
|
||||
Use `flux1-dev` for FLUX.1 Lite, `sdxl-checkpoint` for SSD-1B and Segmind Vega,
|
||||
and the corresponding SD 1/2 checkpoint recipes for Tiny SD/Tiny SD2. Only an
|
||||
independent difference in task, required component compatibility or latent
|
||||
format can justify splitting such a variant; document that difference.
|
||||
|
||||
## Interpretation and review
|
||||
|
||||
- Instruction/reference-image editing is distinct from generic image-to-image
|
||||
denoising. The shared `img2img` capability does not imply native editing.
|
||||
- Native components and external capability adapters are distinguished by their
|
||||
role, not by whether their weights are stored in a separate file. LLaDA's
|
||||
SigVQ-containing connectors remain in its shared generation/editing recipe.
|
||||
- Do not merge models solely because they descend from the same family. Flex.2
|
||||
has different native inpainting/control conditioning, beyond its layer count
|
||||
([model card](https://huggingface.co/ostris/Flex.2-preview)). SDXS uses an
|
||||
adjusted AutoEncoderTiny and a one-step model, rather than only a shallower
|
||||
ordinary SD checkpoint ([runtime guide](../../../docs/distilled_sd.md#sdxs-512-dreamshaper)).
|
||||
Their native components stay in their own model recipe.
|
||||
- Quantization, file format, prompt wording, seeds, step counts and CFG values
|
||||
are not grounds for another recipe. Differences in required components,
|
||||
latent formats or supported capabilities must be documented.
|
||||
- Evaluate what an adapter actually changes. Do not infer new functionality just
|
||||
from a LoRA's name or from the presence of another weight file. In particular,
|
||||
do not create an Omni-Kontext recipe solely because a LoRA is selected.
|
||||
- A recipe does not load generation LoRAs automatically. Community-edit recipes
|
||||
must explain that the matching LoRA is required and must be selected separately.
|
||||
- Only advertise features implemented by the current runtime. Check the relevant
|
||||
model documentation and code, and match each task's slots and feature flags to
|
||||
its weights. Record any unverified inference paths in the change description.
|
||||
- Before submitting, validate all recipe JSON, inspect the embedded recipe API,
|
||||
and check that task-specific inputs appear only on the appropriate recipes.
|
||||
A catalog check is not a substitute for model-generation verification.
|
||||
|
||||
These are built-in catalog rules. Users may keep personal presets in
|
||||
`<model-dir>/recipes/`; they need not add those presets to the built-in list.
|
||||
See [the recipe schema and feature reference](../api.md#user-recipe-format)
|
||||
for supported fields.
|
||||
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "anima-edit",
|
||||
"name": "Anima Edit (LoRA)",
|
||||
"description": "Requires a matching community editing LoRA. Apply it after loading and supply reference images; uses the cosmos_reference preset.",
|
||||
"model_url": "https://huggingface.co/circlestone-labs/Anima",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Qwen 3 0.6B Base Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"sampling_method": "euler",
|
||||
"scheduler": "discrete",
|
||||
"cfg_scale": 4,
|
||||
"steps": 20,
|
||||
"width": 1024,
|
||||
"height": 1024
|
||||
},
|
||||
"features": [
|
||||
"flow_shift",
|
||||
"ref_images"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "anima",
|
||||
"name": "Anima",
|
||||
"description": "Supports all Anima variants supported by sd.cpp. Use a compatible Qwen Image VAE or TAE; adjust generation settings for distilled variants.",
|
||||
"model_url": "https://huggingface.co/circlestone-labs/Anima",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Qwen 3 0.6B Base Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"sampling_method": "euler",
|
||||
"cfg_scale": 4,
|
||||
"steps": 20,
|
||||
"width": 1024,
|
||||
"height": 1024
|
||||
},
|
||||
"features": [
|
||||
"flow_shift"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "animatediff-sd15",
|
||||
"name": "AnimateDiff SD 1.5",
|
||||
"description": "Use Video Generation with an SD 1.5 checkpoint and compatible motion module.",
|
||||
"model_url": "https://huggingface.co/guoyww/animatediff",
|
||||
"slots": [
|
||||
{
|
||||
"id": "model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "motion_module",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"defaults": {
|
||||
"sampling_method": "euler",
|
||||
"video_frames": 8,
|
||||
"fps": 8,
|
||||
"cfg_scale": 7.5,
|
||||
"steps": 20,
|
||||
"width": 512,
|
||||
"height": 512
|
||||
},
|
||||
"features": [
|
||||
"cache_unet",
|
||||
"clip_skip",
|
||||
"init_image"
|
||||
],
|
||||
"disabled_features": [
|
||||
"cache_dit",
|
||||
"img2img",
|
||||
"mask_image"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "boogu-image-edit",
|
||||
"name": "Boogu Image Edit",
|
||||
"description": "Supply reference images. The separate vision projector is needed only when it is not bundled in the text encoder.",
|
||||
"model_url": "https://huggingface.co/Boogu/Boogu-Image-0.1-Edit",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Qwen 3 VL 8B Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "llm_vision",
|
||||
"required": false,
|
||||
"label": "Vision projector (required for separate GGUF text encoders)"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"cfg_scale": 5,
|
||||
"steps": 20,
|
||||
"width": 1024,
|
||||
"height": 1024,
|
||||
"img_cfg_scale": 1,
|
||||
"sampling_method": "euler"
|
||||
},
|
||||
"features": [
|
||||
"flow_shift",
|
||||
"img_cfg",
|
||||
"ref_images"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "boogu-image",
|
||||
"name": "Boogu Image Base",
|
||||
"model_url": "https://huggingface.co/Boogu/Boogu-Image-0.1-Base",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Qwen 3 VL 8B Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"cfg_scale": 4,
|
||||
"steps": 20,
|
||||
"width": 1024,
|
||||
"height": 1024,
|
||||
"sampling_method": "euler"
|
||||
},
|
||||
"features": [
|
||||
"flow_shift"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "chroma-radiance",
|
||||
"name": "Chroma Radiance",
|
||||
"description": "Pixel-space generation without a VAE. Also accepts the x0 and experimental patch-32 variants.",
|
||||
"model_url": "https://huggingface.co/lodestones/Chroma1-Radiance",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "t5xxl",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"defaults": {
|
||||
"sampling_method": "euler",
|
||||
"cfg_scale": 3.5,
|
||||
"steps": 20,
|
||||
"width": 1024,
|
||||
"height": 1024
|
||||
},
|
||||
"features": [
|
||||
"flow_shift",
|
||||
"slg"
|
||||
],
|
||||
"disabled_features": [
|
||||
"preview",
|
||||
"vae_tiling"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "chroma",
|
||||
"name": "Chroma",
|
||||
"model_url": "https://huggingface.co/lodestones/Chroma1-HD",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "t5xxl",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"sampling_method": "euler",
|
||||
"cfg_scale": 3,
|
||||
"steps": 20,
|
||||
"width": 1024,
|
||||
"height": 1024
|
||||
},
|
||||
"features": [
|
||||
"flow_shift",
|
||||
"slg"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "cosxl-edit",
|
||||
"name": "CosXL Edit",
|
||||
"description": "Supply the image to edit as a reference image.",
|
||||
"model_url": "https://huggingface.co/stabilityai/cosxl",
|
||||
"slots": [
|
||||
{
|
||||
"id": "model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"defaults": {
|
||||
"img_cfg_scale": 1.5,
|
||||
"sampling_method": "euler_a",
|
||||
"scheduler": "karras"
|
||||
},
|
||||
"features": [
|
||||
"cache_unet",
|
||||
"clip_skip",
|
||||
"img_cfg",
|
||||
"ref_images",
|
||||
"shifted_timestep"
|
||||
],
|
||||
"disabled_features": [
|
||||
"cache_dit"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
# Built-in generation defaults
|
||||
|
||||
Reviewed against model-publisher cards and reference implementations on 2026-10-20.
|
||||
|
||||
These are starting values, not limits on supported resolutions or generation settings.
|
||||
Built-in step defaults above 20 are reduced to 20; the cited sources may recommend more steps.
|
||||
Users can still choose a higher step count.
|
||||
When several aspect ratios or ranges are published, the selected example or square bucket is noted below.
|
||||
A dash means no recipe override: the available primary sources did not establish a fixed value, or the size depends on the input image.
|
||||
Ordinary DiT recipes explicitly use Euler; PiD retains its LCM sampling path.
|
||||
Guidance-distilled models use `cfg_scale: 1` to disable external CFG in sd.cpp. FLUX embedded guidance is stored separately as `distilled_guidance`.
|
||||
For community edit adapters and other optional extensions, these are the base-model settings unless the source specifies otherwise.
|
||||
|
||||
| Recipe | CFG | Steps | Width × height | Source / notes |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `anima` | 4 | 20 | 1024 × 1024 | [Source](https://huggingface.co/circlestone-labs/Anima) The official ranges are 30–50 steps / CFG 4–5; CFG 4 selects the lower end. Edit uses the same base; tune the chosen editing LoRA separately. |
|
||||
| `anima-edit` | 4 | 20 | 1024 × 1024 | [Source](https://huggingface.co/circlestone-labs/Anima) The official ranges are 30–50 steps / CFG 4–5; CFG 4 selects the lower end. Edit uses the same base; tune the chosen editing LoRA separately. |
|
||||
| `animatediff-sd15` | 7.5 | 20 | 512 × 512 | [Source](https://raw.githubusercontent.com/guoyww/AnimateDiff/main/configs/prompts/1_animate/1_3_animate_ToonYou.yaml) |
|
||||
| `boogu-image` | 4 | 20 | 1024 × 1024 | [Source](https://huggingface.co/Boogu/Boogu-Image-0.1-Base) |
|
||||
| `boogu-image-edit` | 5 | 20 | 1024 × 1024 | [Source](https://huggingface.co/Boogu/Boogu-Image-0.1-Edit) |
|
||||
| `chroma` | 3 | 20 | 1024 × 1024 | [Source](https://huggingface.co/lodestones/Chroma1-HD/raw/main/README.md) |
|
||||
| `chroma-radiance` | 3.5 | 20 | 1024 × 1024 | [Source](https://huggingface.co/lodestones/Chroma1-Radiance/raw/main/inference_reference_code.py) |
|
||||
| `cosxl-edit` | — | — | — | [Source](https://huggingface.co/stabilityai/cosxl) No numerical generation defaults in the author’s model card; previous test values were removed. |
|
||||
| `ernie-image` | 4 | 20 | 1024 × 1024 | [Source](https://huggingface.co/baidu/ERNIE-Image) |
|
||||
| `ernie-image-turbo` | 1 | 8 | 1024 × 1024 | [Source](https://huggingface.co/baidu/ERNIE-Image-Turbo) |
|
||||
| `flex2` | 1 | 20 | 1024 × 1024 | [Source](https://huggingface.co/ostris/Flex.2-preview) |
|
||||
| `flux1-canny` | 1 | 20 | 1024 × 1024 | [Source](https://huggingface.co/black-forest-labs/FLUX.1-Canny-dev) |
|
||||
| `flux1-depth` | 1 | 20 | 1024 × 1024 | [Source](https://huggingface.co/black-forest-labs/FLUX.1-Depth-dev) |
|
||||
| `flux1-dev` | 1 | 20 | 1024 × 1024 | [Source](https://huggingface.co/black-forest-labs/FLUX.1-dev) |
|
||||
| `flux1-fill` | 1 | 20 | 1232 × 1632 | [Source](https://huggingface.co/black-forest-labs/FLUX.1-Fill-dev) |
|
||||
| `flux1-kontext` | 1 | 20 | — | [Source](https://raw.githubusercontent.com/huggingface/diffusers/main/src/diffusers/pipelines/flux/pipeline_flux_kontext.py) Output size normally follows the reference image; no fixed size is imposed by this recipe. |
|
||||
| `flux1-pulid` | 1 | 20 | 1024 × 1024 | [Source](https://huggingface.co/black-forest-labs/FLUX.1-dev) FLUX.1-dev defaults; identity conditioning is provided by PuLID. |
|
||||
| `flux1-schnell` | 1 | 4 | 1024 × 1024 | [Source](https://huggingface.co/black-forest-labs/FLUX.1-schnell) |
|
||||
| `flux2-dev` | 1 | 20 | 1024 × 1024 | [Source](https://huggingface.co/black-forest-labs/FLUX.2-dev) |
|
||||
| `flux2-klein-4b` | 1 | 4 | 1024 × 1024 | [Source](https://huggingface.co/black-forest-labs/FLUX.2-klein-4B) |
|
||||
| `flux2-klein-9b` | 1 | 4 | 1024 × 1024 | [Source](https://huggingface.co/black-forest-labs/FLUX.2-klein-9B) |
|
||||
| `flux2-klein-base-4b` | 4 | 20 | 1024 × 1024 | [Source](https://huggingface.co/black-forest-labs/FLUX.2-klein-base-4B) |
|
||||
| `flux2-klein-base-9b` | 4 | 20 | 1024 × 1024 | [Source](https://huggingface.co/black-forest-labs/FLUX.2-klein-base-9B) |
|
||||
| `flux3-klein` | 1 | 16 | 1024 × 1024 | [Source](https://raw.githubusercontent.com/black-forest-labs/flux-3-image-klein/main/README.md) |
|
||||
| `flux3-klein-base` | 4 | 20 | 1024 × 1024 | [Source](https://raw.githubusercontent.com/black-forest-labs/flux-3-image-klein/main/src/flux3/pipeline.py) |
|
||||
| `hidream-o1-dev` | 1 | 20 | 2048 × 2048 | [Source](https://huggingface.co/HiDream-ai/HiDream-O1-Image-Dev) |
|
||||
| `hunyuan-video-15-i2v` | 6 | 20 | 1280 × 720 | [Source](https://huggingface.co/tencent/HunyuanVideo-1.5) 720p base I2V defaults; CFG/step-distilled and 480p checkpoints use different settings. |
|
||||
| `hunyuan-video-15-t2v` | 6 | 20 | 1280 × 720 | [Source](https://huggingface.co/tencent/HunyuanVideo-1.5) 720p base T2V defaults; CFG-distilled / 480p checkpoints need their published settings. |
|
||||
| `ideogram4` | 7 | 20 | 1024 × 1024 | [Source](https://raw.githubusercontent.com/ideogram-oss/ideogram4/main/docs/inference.md) Constant-guidance pipeline defaults; this recipe does not reproduce the CLI’s per-step guidance schedule. |
|
||||
| `instruct-pix2pix` | — | 10 | — | [Source](https://huggingface.co/timbrooks/instruct-pix2pix) Official quick-start example; output size follows the input image. |
|
||||
| `iris-3b` | 3 | 20 | 1024 × 1024 | [Source](https://huggingface.co/speridlabs/iris-3b) |
|
||||
| `krea2-raw` | 3.5 | 20 | 1024 × 1024 | [Source](https://huggingface.co/krea/Krea-2-Raw) Base model defaults; edit requires a matching community LoRA with its own settings. |
|
||||
| `krea2-raw-edit` | 3.5 | 20 | 1024 × 1024 | [Source](https://huggingface.co/krea/Krea-2-Raw) Base model defaults; edit requires a matching community LoRA with its own settings. |
|
||||
| `krea2-turbo` | 1 | 8 | 2048 × 2048 | [Source](https://huggingface.co/krea/Krea-2-Turbo) Official CLI example; edit requires a matching community LoRA. |
|
||||
| `krea2-turbo-edit` | 1 | 8 | 2048 × 2048 | [Source](https://huggingface.co/krea/Krea-2-Turbo) Official CLI example; edit requires a matching community LoRA. |
|
||||
| `lens` | 5 | 20 | 1440 × 1440 | [Source](https://huggingface.co/microsoft/Lens) Official model card: RL model, default base_resolution 1440. |
|
||||
| `lens-turbo` | 1 | 4 | 1440 × 1440 | [Source](https://huggingface.co/microsoft/Lens-Turbo) Official model card: 4-step distilled model, default base_resolution 1440. |
|
||||
| `lingbot-video-dense` | 3 | 20 | 832 × 480 | [Source](https://huggingface.co/robbyant/lingbot-video-dense-1.3b) Official first-stage inference example; optional refiner is separate. |
|
||||
| `lingbot-video-moe` | 3 | 20 | 832 × 480 | [Source](https://huggingface.co/robbyant/lingbot-video-moe-30b-a3b) Official inference example. |
|
||||
| `llada-image` | 5 | 20 | 1024 × 1024 | [Source](https://huggingface.co/inclusionAI/LLaDA-Image) |
|
||||
| `llada-image-turbo` | 1 | 4 | 1024 × 1024 | [Source](https://huggingface.co/inclusionAI/LLaDA-Image-Turbo) |
|
||||
| `longcat-image` | 4 | 20 | 1344 × 768 | [Source](https://huggingface.co/meituan-longcat/LongCat-Image) |
|
||||
| `longcat-image-edit` | 4.5 | 20 | — | [Source](https://huggingface.co/meituan-longcat/LongCat-Image-Edit) Reference-image-dependent output size; no fixed size is imposed. |
|
||||
| `ltx23-dev` | 3 | 20 | 768 × 512 | [Source](https://raw.githubusercontent.com/Lightricks/LTX-2/main/packages/ltx-pipelines/src/ltx_pipelines/utils/constants.py) Official single-stage parameters, before optional latent upscaling. |
|
||||
| `ltx23-distilled` | 1 | 8 | 768 × 512 | [Source](https://raw.githubusercontent.com/Lightricks/LTX-2/main/packages/ltx-pipelines/src/ltx_pipelines/utils/constants.py) Model card specifies 8 steps / CFG 1; size uses official pipeline’s first stage. |
|
||||
| `ltx25-dev` | 3 | 20 | 768 × 512 | [Source](https://raw.githubusercontent.com/Lightricks/LTX-2/main/packages/ltx-pipelines/src/ltx_pipelines/utils/constants.py) Official non-distilled pipeline parameters for model versions >= 2.4, before optional upscaling. |
|
||||
| `mage-flow` | 5 | 20 | 1024 × 1024 | [Source](https://huggingface.co/microsoft/Mage-Flow) |
|
||||
| `mage-flow-edit` | 5 | 20 | 1024 × 1024 | [Source](https://huggingface.co/microsoft/Mage-Flow) |
|
||||
| `mage-flow-turbo` | 1 | 4 | 1024 × 1024 | [Source](https://huggingface.co/microsoft/Mage-Flow) |
|
||||
| `ming-image` | 1 | 12 | 2048 × 2048 | [Source](https://huggingface.co/inclusionAI/Ming-Image-0.1-Design) |
|
||||
| `minimax-h3-fl2va` | 1 | — | 1344 × 768 | [Source](https://huggingface.co/docs/diffusers/main/en/api/pipelines/minimax_h3) Guidance-distilled; official 768p canvas. No fixed step count is prescribed here; the upstream API counts sigma grid points rather than sd.cpp denoising steps. |
|
||||
| `minimax-h3-ref2va` | 1 | — | 1344 × 768 | [Source](https://huggingface.co/docs/diffusers/main/en/api/pipelines/minimax_h3) Guidance-distilled; official 768p canvas. No fixed step count is prescribed here; the upstream API counts sigma grid points rather than sd.cpp denoising steps. |
|
||||
| `minit2i` | 2.5 | 20 | 512 × 512 | [Source](https://huggingface.co/MiniT2I/MiniT2I/raw/main/pipeline.py) B/16 example and native model size; L/16 uses CFG 6. |
|
||||
| `moss-image-base` | 3 | 20 | 1024 × 1024 | [Source](https://huggingface.co/OpenMOSS-Team/MOSS-Image-Base) |
|
||||
| `moss-image-sft` | 3 | 20 | 1024 × 1024 | [Source](https://huggingface.co/OpenMOSS-Team/MOSS-Image-SFT) |
|
||||
| `nitrosd-realism` | 1 | 1 | 1024 × 1024 | [Source](https://huggingface.co/ChenDY/NitroFusion) |
|
||||
| `ovis-image` | 5 | 20 | 1024 × 1024 | [Source](https://huggingface.co/ATH-MaaS/Ovis-Image-7B) |
|
||||
| `pid` | 1 | 4 | 2048 × 2048 | [Source](https://huggingface.co/nvidia/PiD) Standalone PiD decoding at 2K; guidance is handled by the upstream generator. |
|
||||
| `pid-15` | 1 | 4 | 2048 × 2048 | [Source](https://huggingface.co/nvidia/PiD) Standalone PiD decoding at 2K; guidance is handled by the upstream generator. |
|
||||
| `pid-15-flux2` | 1 | 4 | 2048 × 2048 | [Source](https://huggingface.co/nvidia/PiD) Standalone PiD decoding at 2K; guidance is handled by the upstream generator. |
|
||||
| `pid-15-qwen-image` | 1 | 4 | 2048 × 2048 | [Source](https://huggingface.co/nvidia/PiD) Standalone PiD decoding at 2K; guidance is handled by the upstream generator. |
|
||||
| `pid-15-sd3` | 1 | 4 | 2048 × 2048 | [Source](https://huggingface.co/nvidia/PiD) Standalone PiD decoding at 2K; guidance is handled by the upstream generator. |
|
||||
| `pid-flux2` | 1 | 4 | 2048 × 2048 | [Source](https://huggingface.co/nvidia/PiD) Standalone PiD decoding at 2K; guidance is handled by the upstream generator. |
|
||||
| `pid-qwen-image` | 1 | 4 | 2048 × 2048 | [Source](https://huggingface.co/nvidia/PiD) Standalone PiD decoding at 2K; guidance is handled by the upstream generator. |
|
||||
| `pid-sd3` | 1 | 4 | 2048 × 2048 | [Source](https://huggingface.co/nvidia/PiD) Standalone PiD decoding at 2K; guidance is handled by the upstream generator. |
|
||||
| `pixart-alpha-1024` | 4.5 | 20 | 1024 × 1024 | [Source](https://raw.githubusercontent.com/huggingface/diffusers/main/src/diffusers/pipelines/pixart_alpha/pipeline_pixart_alpha.py) |
|
||||
| `pixart-alpha-512` | 4.5 | 20 | 512 × 512 | [Source](https://raw.githubusercontent.com/huggingface/diffusers/main/src/diffusers/pipelines/pixart_alpha/pipeline_pixart_alpha.py) |
|
||||
| `pixart-sigma` | 4.5 | 20 | 1024 × 1024 | [Source](https://raw.githubusercontent.com/huggingface/diffusers/main/src/diffusers/pipelines/pixart_alpha/pipeline_pixart_sigma.py) |
|
||||
| `qwen-image` | 4 | 20 | 1328 × 1328 | [Source](https://huggingface.co/Qwen/Qwen-Image) Official square resolution bucket; true_cfg_scale maps to cfg_scale. |
|
||||
| `qwen-image-21` | 1 | 20 | 2048 × 2048 | [Source](https://raw.githubusercontent.com/QwenLM/Qwen-Image-2.1/main/README.md) Original checkpoint defaults; select the matching TAEQI2.1 to replace its VAE. |
|
||||
| `qwen-image-21-turbo` | 1 | 8 | 2048 × 2048 | [Model card](https://huggingface.co/Qwen/Qwen-Image-2.1-Turbo), [fixed sigmas](https://huggingface.co/Qwen/Qwen-Image-2.1-Turbo/blob/main/model_index.json). Standalone Turbo weights; the fixed 8-step schedule is applied on model load. |
|
||||
| `qwen-image-edit` | 4 | 20 | — | [Source](https://huggingface.co/Qwen/Qwen-Image-Edit) Official editing example; output dimensions follow reference-image aspect ratio. |
|
||||
| `qwen-image-edit-2509` | 4 | 20 | — | [Source](https://huggingface.co/Qwen/Qwen-Image-Edit-2509) Official editing example; output dimensions follow reference-image aspect ratio. |
|
||||
| `qwen-image-edit-2511` | 4 | 20 | — | [Source](https://huggingface.co/Qwen/Qwen-Image-Edit-2511) Official editing example; output dimensions follow reference-image aspect ratio. |
|
||||
| `qwen-image-layered` | 4 | 20 | 640 × 640 | [Source](https://huggingface.co/Qwen/Qwen-Image-Layered) Official recommended 640 resolution bucket; layered RGBA VAE is required. |
|
||||
| `sd-turbo` | 1 | 1 | 512 × 512 | [Source](https://huggingface.co/stabilityai/sd-turbo) |
|
||||
| `sd1-checkpoint` | 7.5 | 20 | 512 × 512 | [Source](https://raw.githubusercontent.com/huggingface/diffusers/main/src/diffusers/pipelines/stable_diffusion/pipeline_stable_diffusion.py) |
|
||||
| `sd1-controlnet` | 7.5 | 20 | 512 × 512 | [Source](https://huggingface.co/lllyasviel/control_v11p_sd15_canny) |
|
||||
| `sd1-inpainting` | 7.5 | 20 | 512 × 512 | [Source](https://raw.githubusercontent.com/huggingface/diffusers/main/src/diffusers/pipelines/stable_diffusion/pipeline_stable_diffusion_inpaint.py) |
|
||||
| `sd1-ip-adapter` | 7.5 | 20 | 512 × 512 | [Source](https://raw.githubusercontent.com/huggingface/diffusers/main/src/diffusers/pipelines/stable_diffusion/pipeline_stable_diffusion.py) SD 1.x base pipeline defaults; adapter strength is configured separately. |
|
||||
| `sd2-512-checkpoint` | 7.5 | 20 | 512 × 512 | [Source](https://raw.githubusercontent.com/huggingface/diffusers/main/src/diffusers/pipelines/stable_diffusion/pipeline_stable_diffusion.py) |
|
||||
| `sd2-768-checkpoint` | 7.5 | 20 | 768 × 768 | [Source](https://raw.githubusercontent.com/huggingface/diffusers/main/src/diffusers/pipelines/stable_diffusion/pipeline_stable_diffusion.py) |
|
||||
| `sd2-inpainting` | 7.5 | 20 | 512 × 512 | [Source](https://raw.githubusercontent.com/huggingface/diffusers/main/src/diffusers/pipelines/stable_diffusion/pipeline_stable_diffusion_inpaint.py) |
|
||||
| `sd3-medium` | 7 | 20 | 1024 × 1024 | [Source](https://huggingface.co/stabilityai/stable-diffusion-3-medium-diffusers) |
|
||||
| `sd35-large` | 3.5 | 20 | 1024 × 1024 | [Source](https://huggingface.co/stabilityai/stable-diffusion-3.5-large) |
|
||||
| `sd35-medium` | 4.5 | 20 | 1024 × 1024 | [Source](https://huggingface.co/stabilityai/stable-diffusion-3.5-medium) |
|
||||
| `sdxl-checkpoint` | 5 | 20 | 1024 × 1024 | [Source](https://raw.githubusercontent.com/huggingface/diffusers/main/src/diffusers/pipelines/stable_diffusion_xl/pipeline_stable_diffusion_xl.py) |
|
||||
| `sdxl-controlnet` | 5 | 20 | 1024 × 1024 | [Source](https://raw.githubusercontent.com/huggingface/diffusers/main/src/diffusers/pipelines/stable_diffusion_xl/pipeline_stable_diffusion_xl.py) SDXL pipeline defaults; compatible ControlNet weights are required. |
|
||||
| `sdxl-inpainting` | 8 | 20 | 1024 × 1024 | [Source](https://huggingface.co/diffusers/stable-diffusion-xl-1.0-inpainting-0.1/raw/main/README.md) |
|
||||
| `sdxl-ip-adapter` | 5 | 20 | 1024 × 1024 | [Source](https://raw.githubusercontent.com/huggingface/diffusers/main/src/diffusers/pipelines/stable_diffusion_xl/pipeline_stable_diffusion_xl.py) SDXL base pipeline defaults; adapter strength is configured separately. |
|
||||
| `sdxl-photomaker` | — | — | 1024 × 1024 | [Source](https://huggingface.co/TencentARC/PhotoMaker) Use settings for the selected compatible SDXL checkpoint; no unique CFG/steps are prescribed by the model card. |
|
||||
| `sdxl-turbo` | 1 | 1 | 512 × 512 | [Source](https://huggingface.co/stabilityai/sdxl-turbo) |
|
||||
| `sdxs` | 1 | 1 | 512 × 512 | [Source](https://huggingface.co/IDKiro/sdxs-512-dreamshaper) |
|
||||
| `sefi-image` | 4 | 20 | — | [Source](https://huggingface.co/SeFi-Image/SeFi-Image-5B-Base) Base/RL family defaults; Turbo checkpoints require 4 steps / CFG 1. |
|
||||
| `sensenova-u15` | 4 | 20 | 2048 × 2048 | [Source](https://raw.githubusercontent.com/OpenSenseNova/SenseNova-U1/main/examples/README.md) |
|
||||
| `wan21-flf2v` | 5 | 20 | 1280 × 720 | [Source](https://raw.githubusercontent.com/Wan-Video/Wan2.1/main/generate.py) |
|
||||
| `wan21-i2v` | 5 | 20 | 832 × 480 | [Source](https://raw.githubusercontent.com/Wan-Video/Wan2.1/main/generate.py) 480p base defaults; also accepts compatible SkyReels V2 and single Wan 2.2 I2V experts. |
|
||||
| `wan21-t2v` | 5 | 20 | 1280 × 720 | [Source](https://raw.githubusercontent.com/Wan-Video/Wan2.1/main/generate.py) 14B base defaults; single Wan 2.2 experts and acceleration LoRAs need matching settings. |
|
||||
| `wan21-vace` | 5 | 20 | 832 × 480 | [Source](https://raw.githubusercontent.com/Wan-Video/Wan2.1/main/generate.py) |
|
||||
| `wan22-i2v` | 3.5 | 20 | 1280 × 720 | [Source](https://raw.githubusercontent.com/Wan-Video/Wan2.2/main/wan/configs/wan_i2v_A14B.py) |
|
||||
| `wan22-s2v` | 4.5 | 20 | — | [Source](https://raw.githubusercontent.com/Wan-Video/Wan2.2/main/wan/configs/wan_s2v_14B.py) The official S2V pipeline derives output dimensions from the input. |
|
||||
| `wan22-t2v` | 3 | 20 | 1280 × 720 | [Source](https://raw.githubusercontent.com/Wan-Video/Wan2.2/main/wan/configs/wan_t2v_A14B.py) |
|
||||
| `wan22-ti2v-5b` | 5 | 20 | 1280 × 704 | [Source](https://raw.githubusercontent.com/Wan-Video/Wan2.2/main/wan/configs/wan_ti2v_5B.py) |
|
||||
| `z-image` | 4 | 20 | 720 × 1280 | [Source](https://huggingface.co/Tongyi-MAI/Z-Image) |
|
||||
| `z-image-l2p` | — | — | — | [Source](https://huggingface.co/zhen-nan/L2P) No numerical inference recommendations in the author’s model card; previous test values were removed. |
|
||||
| `z-image-turbo` | 1 | 9 | 1024 × 1024 | [Source](https://huggingface.co/Tongyi-MAI/Z-Image-Turbo) |
|
||||
|
||||
TAE alternatives use the model-compatible weights listed by [TAESD](https://github.com/madebyollin/taesd) and [TAEHV](https://github.com/madebyollin/taehv).
|
||||
TAE slots are omitted for pixel-space models, PiD, layered RGBA decoding and Mage-VAE paths that the current runtime does not map to a compatible TAE.
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "ernie-image-turbo",
|
||||
"name": "ERNIE Image Turbo",
|
||||
"model_url": "https://huggingface.co/baidu/ERNIE-Image-Turbo",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Ministral 3 3B Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"cfg_scale": 1,
|
||||
"steps": 8,
|
||||
"width": 1024,
|
||||
"height": 1024,
|
||||
"sampling_method": "euler"
|
||||
},
|
||||
"features": [
|
||||
"flow_shift"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "ernie-image",
|
||||
"name": "ERNIE Image",
|
||||
"model_url": "https://huggingface.co/baidu/ERNIE-Image",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Ministral 3 3B Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"cfg_scale": 4,
|
||||
"steps": 20,
|
||||
"width": 1024,
|
||||
"height": 1024,
|
||||
"sampling_method": "euler"
|
||||
},
|
||||
"features": [
|
||||
"flow_shift"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "flex2",
|
||||
"name": "Flex.2 Preview",
|
||||
"model_url": "https://huggingface.co/ostris/Flex.2-preview",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "clip_l",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "t5xxl",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"sampling_method": "euler",
|
||||
"cfg_scale": 1,
|
||||
"steps": 20,
|
||||
"width": 1024,
|
||||
"height": 1024,
|
||||
"distilled_guidance": 3.5
|
||||
},
|
||||
"features": [
|
||||
"clip_skip",
|
||||
"distilled_guidance",
|
||||
"flow_shift",
|
||||
"slg"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "flux1-canny",
|
||||
"name": "FLUX.1 Canny dev",
|
||||
"description": "Select Canny weights and supply a precomputed edge map as Control Image. Edge detection is not performed by this recipe.",
|
||||
"model_url": "https://huggingface.co/black-forest-labs/FLUX.1-Canny-dev",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "clip_l",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "t5xxl",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"sampling_method": "euler",
|
||||
"cfg_scale": 1,
|
||||
"steps": 20,
|
||||
"width": 1024,
|
||||
"height": 1024,
|
||||
"distilled_guidance": 30
|
||||
},
|
||||
"features": [
|
||||
"clip_skip",
|
||||
"distilled_guidance",
|
||||
"flow_shift",
|
||||
"slg",
|
||||
"control_image"
|
||||
],
|
||||
"disabled_features": [
|
||||
"mask_image"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "flux1-depth",
|
||||
"name": "FLUX.1 Depth dev",
|
||||
"description": "Select Depth weights and supply a precomputed depth map as Control Image. Depth estimation is not performed by this recipe.",
|
||||
"model_url": "https://huggingface.co/black-forest-labs/FLUX.1-Depth-dev",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "clip_l",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "t5xxl",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"sampling_method": "euler",
|
||||
"distilled_guidance": 10,
|
||||
"scheduler": "flux",
|
||||
"cfg_scale": 1,
|
||||
"steps": 20,
|
||||
"width": 1024,
|
||||
"height": 1024
|
||||
},
|
||||
"features": [
|
||||
"clip_skip",
|
||||
"distilled_guidance",
|
||||
"flow_shift",
|
||||
"slg",
|
||||
"control_image"
|
||||
],
|
||||
"disabled_features": [
|
||||
"mask_image"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "flux1-dev",
|
||||
"name": "FLUX.1 dev",
|
||||
"description": "Supports FLUX.1 dev and compatible layer-count variants such as FLUX.1 Lite. Select the transformer with matching CLIP-L, T5XXL and FLUX.1 VAE.",
|
||||
"model_url": "https://huggingface.co/black-forest-labs/FLUX.1-dev",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "clip_l",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "t5xxl",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"sampling_method": "euler",
|
||||
"cfg_scale": 1,
|
||||
"steps": 20,
|
||||
"width": 1024,
|
||||
"height": 1024,
|
||||
"distilled_guidance": 3.5
|
||||
},
|
||||
"features": [
|
||||
"clip_skip",
|
||||
"distilled_guidance",
|
||||
"flow_shift",
|
||||
"slg"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "flux1-fill",
|
||||
"name": "FLUX.1 Fill dev",
|
||||
"description": "Select Fill weights and supply Init Image plus Mask Image for inpainting. Denoising strength defaults to 1 for a full denoising schedule.",
|
||||
"model_url": "https://huggingface.co/black-forest-labs/FLUX.1-Fill-dev",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "clip_l",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "t5xxl",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"sampling_method": "euler",
|
||||
"distilled_guidance": 30,
|
||||
"strength": 1.0,
|
||||
"scheduler": "flux",
|
||||
"cfg_scale": 1,
|
||||
"steps": 20,
|
||||
"width": 1232,
|
||||
"height": 1632
|
||||
},
|
||||
"features": [
|
||||
"clip_skip",
|
||||
"distilled_guidance",
|
||||
"flow_shift",
|
||||
"slg",
|
||||
"img_cfg"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "flux1-kontext",
|
||||
"name": "FLUX.1 Kontext dev",
|
||||
"description": "Select FLUX.1 Kontext weights. Supports text-to-image and native reference-image editing; an editing LoRA is not required.",
|
||||
"model_url": "https://huggingface.co/black-forest-labs/FLUX.1-Kontext-dev",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "clip_l",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "t5xxl",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"sampling_method": "euler",
|
||||
"cfg_scale": 1,
|
||||
"steps": 20,
|
||||
"distilled_guidance": 2.5
|
||||
},
|
||||
"features": [
|
||||
"clip_skip",
|
||||
"distilled_guidance",
|
||||
"flow_shift",
|
||||
"img_cfg",
|
||||
"ref_images",
|
||||
"slg"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "flux1-pulid",
|
||||
"name": "FLUX.1 dev PuLID",
|
||||
"description": "Supply a precomputed PuLID identity embedding with the generation request.",
|
||||
"model_url": "https://huggingface.co/guozinan/PuLID",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "clip_l",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "t5xxl",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "pulid_weights",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"sampling_method": "euler",
|
||||
"cfg_scale": 1,
|
||||
"steps": 20,
|
||||
"width": 1024,
|
||||
"height": 1024,
|
||||
"distilled_guidance": 3.5
|
||||
},
|
||||
"features": [
|
||||
"clip_skip",
|
||||
"distilled_guidance",
|
||||
"flow_shift",
|
||||
"slg"
|
||||
],
|
||||
"disabled_features": [
|
||||
"slg"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "flux1-schnell",
|
||||
"name": "FLUX.1 schnell",
|
||||
"model_url": "https://huggingface.co/black-forest-labs/FLUX.1-schnell",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "clip_l",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "t5xxl",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"sampling_method": "euler",
|
||||
"cfg_scale": 1,
|
||||
"steps": 4,
|
||||
"width": 1024,
|
||||
"height": 1024
|
||||
},
|
||||
"features": [
|
||||
"clip_skip",
|
||||
"flow_shift",
|
||||
"slg"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "flux2-dev",
|
||||
"name": "FLUX.2 dev",
|
||||
"description": "Supports text-to-image and reference-image editing.",
|
||||
"model_url": "https://huggingface.co/black-forest-labs/FLUX.2-dev",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Mistral Small 3.2 24B Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"distilled_guidance": 4,
|
||||
"sampling_method": "euler",
|
||||
"cfg_scale": 1,
|
||||
"steps": 20,
|
||||
"width": 1024,
|
||||
"height": 1024
|
||||
},
|
||||
"features": [
|
||||
"distilled_guidance",
|
||||
"flow_shift",
|
||||
"img_cfg",
|
||||
"ref_images",
|
||||
"slg"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "flux2-klein-4b",
|
||||
"name": "FLUX.2 Klein 4B",
|
||||
"description": "Supports reference-image editing. The FLUX.2 small decoder is an alternative VAE.",
|
||||
"model_url": "https://huggingface.co/black-forest-labs/FLUX.2-klein-4B",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Qwen 3 4B Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"cfg_scale": 1,
|
||||
"steps": 4,
|
||||
"width": 1024,
|
||||
"height": 1024,
|
||||
"sampling_method": "euler"
|
||||
},
|
||||
"features": [
|
||||
"flow_shift",
|
||||
"img_cfg",
|
||||
"ref_images",
|
||||
"slg"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "flux2-klein-9b",
|
||||
"name": "FLUX.2 Klein 9B",
|
||||
"description": "Supports text-to-image and reference-image editing.",
|
||||
"model_url": "https://huggingface.co/black-forest-labs/FLUX.2-klein-9B",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Qwen 3 8B Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"cfg_scale": 1,
|
||||
"steps": 4,
|
||||
"width": 1024,
|
||||
"height": 1024,
|
||||
"sampling_method": "euler"
|
||||
},
|
||||
"features": [
|
||||
"flow_shift",
|
||||
"img_cfg",
|
||||
"ref_images",
|
||||
"slg"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "flux2-klein-base-4b",
|
||||
"name": "FLUX.2 Klein Base 4B",
|
||||
"description": "Supports text-to-image and reference-image editing.",
|
||||
"model_url": "https://huggingface.co/black-forest-labs/FLUX.2-klein-base-4B",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Qwen 3 4B Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"sampling_method": "euler",
|
||||
"cfg_scale": 4,
|
||||
"steps": 20,
|
||||
"width": 1024,
|
||||
"height": 1024
|
||||
},
|
||||
"features": [
|
||||
"flow_shift",
|
||||
"img_cfg",
|
||||
"ref_images",
|
||||
"slg"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "flux2-klein-base-9b",
|
||||
"name": "FLUX.2 Klein Base 9B",
|
||||
"description": "Use the 9B base transformer with Qwen 3 8B. Supports reference-image editing.",
|
||||
"model_url": "https://huggingface.co/black-forest-labs/FLUX.2-klein-base-9B",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Qwen 3 8B Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"cfg_scale": 4,
|
||||
"steps": 20,
|
||||
"width": 1024,
|
||||
"height": 1024,
|
||||
"sampling_method": "euler"
|
||||
},
|
||||
"features": [
|
||||
"flow_shift",
|
||||
"img_cfg",
|
||||
"ref_images",
|
||||
"slg"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "flux3-klein-base",
|
||||
"name": "FLUX.3 Image Klein Base",
|
||||
"model_url": "https://huggingface.co/black-forest-labs/flux-3-image-klein-base",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Qwen 3 VL 4B Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"sampling_method": "euler",
|
||||
"cfg_scale": 4,
|
||||
"steps": 20,
|
||||
"width": 1024,
|
||||
"height": 1024
|
||||
},
|
||||
"features": [
|
||||
"flow_shift",
|
||||
"ref_images"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "flux3-klein",
|
||||
"name": "FLUX.3 Image Klein",
|
||||
"description": "Supports text-to-image and reference-image editing.",
|
||||
"model_url": "https://huggingface.co/black-forest-labs/flux-3-image-klein",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Qwen 3 VL 4B Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"sampling_method": "euler",
|
||||
"cfg_scale": 1,
|
||||
"steps": 16,
|
||||
"width": 1024,
|
||||
"height": 1024
|
||||
},
|
||||
"features": [
|
||||
"flow_shift",
|
||||
"ref_images"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "hidream-o1-dev",
|
||||
"name": "HiDream O1 Image dev",
|
||||
"description": "Bundled checkpoint; also supports reference-image editing.",
|
||||
"model_url": "https://huggingface.co/HiDream-ai/HiDream-O1-Image-Dev",
|
||||
"slots": [
|
||||
{
|
||||
"id": "model",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"defaults": {
|
||||
"cfg_scale": 1,
|
||||
"steps": 20,
|
||||
"width": 2048,
|
||||
"height": 2048,
|
||||
"sampling_method": "euler"
|
||||
},
|
||||
"features": [
|
||||
"flow_shift",
|
||||
"ref_images"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "hunyuan-video-15-i2v",
|
||||
"name": "HunyuanVideo 1.5 I2V",
|
||||
"description": "Select HunyuanVideo 1.5 I2V weights and supply a start image in Video Generation.",
|
||||
"model_url": "https://huggingface.co/tencent/HunyuanVideo-1.5",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Qwen 2.5 VL 7B Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "t5xxl",
|
||||
"required": true,
|
||||
"label": "ByT5 Small GlyphXL"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false,
|
||||
"label": "HunyuanVideo 1.5 VAE"
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false,
|
||||
"label": "TAEHV 1.5"
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"sampling_method": "euler",
|
||||
"video_frames": 33,
|
||||
"cfg_scale": 6,
|
||||
"steps": 20,
|
||||
"width": 1280,
|
||||
"height": 720,
|
||||
"flow_shift": 7
|
||||
},
|
||||
"features": [
|
||||
"flow_shift",
|
||||
"init_image"
|
||||
],
|
||||
"disabled_features": [
|
||||
"img2img",
|
||||
"mask_image"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "hunyuan-video-15-t2v",
|
||||
"name": "HunyuanVideo 1.5 T2V",
|
||||
"description": "Select HunyuanVideo 1.5 T2V weights and use Video Generation. Use the separate I2V recipe for I2V weights.",
|
||||
"model_url": "https://huggingface.co/tencent/HunyuanVideo-1.5",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Qwen 2.5 VL 7B Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "t5xxl",
|
||||
"required": true,
|
||||
"label": "ByT5 Small GlyphXL"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false,
|
||||
"label": "HunyuanVideo 1.5 VAE"
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false,
|
||||
"label": "TAEHV 1.5"
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"sampling_method": "euler",
|
||||
"video_frames": 33,
|
||||
"cfg_scale": 6,
|
||||
"steps": 20,
|
||||
"width": 1280,
|
||||
"height": 720,
|
||||
"flow_shift": 9
|
||||
},
|
||||
"features": [
|
||||
"flow_shift"
|
||||
],
|
||||
"disabled_features": [
|
||||
"img2img",
|
||||
"mask_image"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "ideogram4",
|
||||
"name": "Ideogram 4",
|
||||
"description": "Select the matching unconditional transformer for classifier-free guidance.",
|
||||
"model_url": "https://huggingface.co/ideogram-ai/ideogram-4-fp8",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "uncond_diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Qwen 3 VL 8B Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"cfg_scale": 7,
|
||||
"steps": 20,
|
||||
"width": 1024,
|
||||
"height": 1024,
|
||||
"sampling_method": "euler"
|
||||
},
|
||||
"features": [
|
||||
"flow_shift"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "instruct-pix2pix",
|
||||
"name": "Instruct-Pix2Pix",
|
||||
"description": "Supply the image to edit as a reference image.",
|
||||
"model_url": "https://huggingface.co/timbrooks/instruct-pix2pix",
|
||||
"slots": [
|
||||
{
|
||||
"id": "model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"defaults": {
|
||||
"img_cfg_scale": 1,
|
||||
"sampling_method": "euler_a",
|
||||
"scheduler": "karras",
|
||||
"steps": 10
|
||||
},
|
||||
"features": [
|
||||
"cache_unet",
|
||||
"clip_skip",
|
||||
"img_cfg",
|
||||
"ref_images"
|
||||
],
|
||||
"disabled_features": [
|
||||
"cache_dit"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "iris-3b",
|
||||
"name": "Iris 3B",
|
||||
"description": "Pixel-space model; no VAE is required.",
|
||||
"model_url": "https://huggingface.co/speridlabs/iris-3b",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Qwen 3 VL 4B Text Encoder"
|
||||
}
|
||||
],
|
||||
"defaults": {
|
||||
"cfg_scale": 3,
|
||||
"steps": 20,
|
||||
"width": 1024,
|
||||
"height": 1024,
|
||||
"sampling_method": "euler"
|
||||
},
|
||||
"features": [
|
||||
"flow_shift"
|
||||
],
|
||||
"disabled_features": [
|
||||
"preview",
|
||||
"vae_tiling"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "krea2-raw-edit",
|
||||
"name": "Krea 2 Raw Edit (LoRA)",
|
||||
"description": "Requires a matching Ostris-compatible community editing LoRA. Apply it after loading and supply reference images; uses the krea2_ostris_edit preset. Select a separate vision projector when it is not bundled in the text encoder.",
|
||||
"model_url": "https://huggingface.co/krea/Krea-2-Raw",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Qwen 3 VL 4B Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "llm_vision",
|
||||
"required": false,
|
||||
"label": "Vision projector (required for separate GGUF text encoders)"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"scheduler": "discrete",
|
||||
"sampling_method": "euler",
|
||||
"cfg_scale": 3.5,
|
||||
"steps": 20,
|
||||
"width": 1024,
|
||||
"height": 1024
|
||||
},
|
||||
"features": [
|
||||
"flow_shift",
|
||||
"ref_images"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "krea2-raw",
|
||||
"name": "Krea 2 Raw",
|
||||
"description": "For reference-image editing with a community LoRA, use the corresponding Krea 2 Edit recipe.",
|
||||
"model_url": "https://huggingface.co/krea/Krea-2-Raw",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Qwen 3 VL 4B Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"cfg_scale": 3.5,
|
||||
"steps": 20,
|
||||
"width": 1024,
|
||||
"height": 1024,
|
||||
"sampling_method": "euler"
|
||||
},
|
||||
"features": [
|
||||
"flow_shift"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "krea2-turbo-edit",
|
||||
"name": "Krea 2 Turbo Edit (LoRA)",
|
||||
"description": "Requires a matching Ostris-compatible community editing LoRA. Apply it after loading and supply reference images; uses the krea2_ostris_edit preset. Select a separate vision projector when it is not bundled in the text encoder.",
|
||||
"model_url": "https://huggingface.co/krea/Krea-2-Turbo",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Qwen 3 VL 4B Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "llm_vision",
|
||||
"required": false,
|
||||
"label": "Vision projector (required for separate GGUF text encoders)"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"scheduler": "discrete",
|
||||
"sampling_method": "euler",
|
||||
"cfg_scale": 1,
|
||||
"steps": 8,
|
||||
"width": 2048,
|
||||
"height": 2048
|
||||
},
|
||||
"features": [
|
||||
"flow_shift",
|
||||
"ref_images"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "krea2-turbo",
|
||||
"name": "Krea 2 Turbo",
|
||||
"description": "For reference-image editing with a community LoRA, use the corresponding Krea 2 Edit recipe.",
|
||||
"model_url": "https://huggingface.co/krea/Krea-2-Turbo",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Qwen 3 VL 4B Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"cfg_scale": 1,
|
||||
"steps": 8,
|
||||
"width": 2048,
|
||||
"height": 2048,
|
||||
"sampling_method": "euler"
|
||||
},
|
||||
"features": [
|
||||
"flow_shift"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "lens-turbo",
|
||||
"name": "LENS Turbo",
|
||||
"model_url": "https://huggingface.co/microsoft/Lens-Turbo",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "GPT-OSS 20B Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "tokenizer",
|
||||
"required": true,
|
||||
"label": "GPT-OSS tokenizer.json"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"cfg_scale": 1,
|
||||
"steps": 4,
|
||||
"width": 1440,
|
||||
"height": 1440,
|
||||
"sampling_method": "euler"
|
||||
},
|
||||
"features": [
|
||||
"flow_shift"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "lens",
|
||||
"name": "LENS",
|
||||
"model_url": "https://huggingface.co/microsoft/Lens",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "GPT-OSS 20B Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "tokenizer",
|
||||
"required": true,
|
||||
"label": "GPT-OSS tokenizer.json"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"cfg_scale": 5,
|
||||
"steps": 20,
|
||||
"width": 1440,
|
||||
"height": 1440,
|
||||
"sampling_method": "euler"
|
||||
},
|
||||
"features": [
|
||||
"flow_shift"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "lingbot-video-dense",
|
||||
"name": "LingBot Video Dense 1.3B",
|
||||
"description": "Use Video Generation.",
|
||||
"model_url": "https://huggingface.co/robbyant/lingbot-video-dense-1.3b",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Qwen 3 VL 4B Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false,
|
||||
"label": "Wan 2.1 VAE"
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"video_frames": 33,
|
||||
"cfg_scale": 3,
|
||||
"steps": 20,
|
||||
"width": 832,
|
||||
"height": 480,
|
||||
"sampling_method": "euler"
|
||||
},
|
||||
"features": [
|
||||
"flow_shift",
|
||||
"init_image"
|
||||
],
|
||||
"disabled_features": [
|
||||
"img2img",
|
||||
"mask_image"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "lingbot-video-moe",
|
||||
"name": "LingBot Video MoE 30B A3B",
|
||||
"description": "Use Video Generation.",
|
||||
"model_url": "https://huggingface.co/robbyant/lingbot-video-moe-30b-a3b",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Qwen 3 VL 4B Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false,
|
||||
"label": "Wan 2.1 VAE"
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"video_frames": 33,
|
||||
"cfg_scale": 3,
|
||||
"steps": 20,
|
||||
"width": 832,
|
||||
"height": 480,
|
||||
"sampling_method": "euler"
|
||||
},
|
||||
"features": [
|
||||
"flow_shift",
|
||||
"init_image"
|
||||
],
|
||||
"disabled_features": [
|
||||
"img2img",
|
||||
"mask_image"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "llada-image-turbo",
|
||||
"name": "LLaDA Image Turbo",
|
||||
"description": "Use matching turbo text encoder and connectors. Editing needs connectors that include the SigVQ encoder.",
|
||||
"model_url": "https://huggingface.co/inclusionAI/LLaDA-Image-Turbo",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "LLaDA-Image Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "tokenizer",
|
||||
"required": true,
|
||||
"label": "LLaDA tokenizer.json"
|
||||
},
|
||||
{
|
||||
"id": "embeddings_connectors",
|
||||
"required": true,
|
||||
"label": "LLaDA Turbo Connectors"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"cfg_scale": 1,
|
||||
"steps": 4,
|
||||
"width": 1024,
|
||||
"height": 1024,
|
||||
"sampling_method": "euler"
|
||||
},
|
||||
"features": [
|
||||
"ref_images"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "llada-image",
|
||||
"name": "LLaDA Image (base)",
|
||||
"description": "Use matching base transformer, text encoder and connectors; do not mix them with Turbo components. Editing needs connectors with SigVQ and 1024x1024 output.",
|
||||
"model_url": "https://huggingface.co/inclusionAI/LLaDA-Image",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "LLaDA-Image Base Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "tokenizer",
|
||||
"required": true,
|
||||
"label": "LLaDA tokenizer.json"
|
||||
},
|
||||
{
|
||||
"id": "embeddings_connectors",
|
||||
"required": true,
|
||||
"label": "LLaDA Base Connectors"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"sampling_method": "euler",
|
||||
"scheduler": "llada_image",
|
||||
"cfg_scale": 5,
|
||||
"steps": 20,
|
||||
"width": 1024,
|
||||
"height": 1024
|
||||
},
|
||||
"features": [
|
||||
"ref_images"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "longcat-image-edit",
|
||||
"name": "LongCat Image Edit",
|
||||
"description": "Supply reference images for editing.",
|
||||
"model_url": "https://huggingface.co/meituan-longcat/LongCat-Image-Edit",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Qwen 2.5 VL 7B Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"cfg_scale": 4.5,
|
||||
"steps": 20,
|
||||
"sampling_method": "euler"
|
||||
},
|
||||
"features": [
|
||||
"flow_shift",
|
||||
"img_cfg",
|
||||
"ref_images",
|
||||
"slg"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "longcat-image",
|
||||
"name": "LongCat Image",
|
||||
"model_url": "https://huggingface.co/meituan-longcat/LongCat-Image",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Qwen 2.5 VL 7B Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"cfg_scale": 4,
|
||||
"steps": 20,
|
||||
"width": 1344,
|
||||
"height": 768,
|
||||
"sampling_method": "euler"
|
||||
},
|
||||
"features": [
|
||||
"flow_shift",
|
||||
"slg"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "ltx23-dev",
|
||||
"name": "LTX 2.3 dev",
|
||||
"description": "Supports text, start-image and start/end-image video. Audio VAE is optional for silent video. Configure latent upscaling separately in generation settings. Optional distillation LoRAs use this recipe; select the LoRA and adjust the sampling settings separately.",
|
||||
"model_url": "https://huggingface.co/Lightricks/LTX-2.3",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Gemma 3 12B Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "embeddings_connectors",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false,
|
||||
"label": "LTX 2.3 Video VAE"
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "audio_vae",
|
||||
"required": false,
|
||||
"label": "LTX 2.3 Audio VAE"
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"sampling_method": "euler",
|
||||
"video_frames": 33,
|
||||
"fps": 24,
|
||||
"cfg_scale": 3,
|
||||
"steps": 20,
|
||||
"width": 768,
|
||||
"height": 512
|
||||
},
|
||||
"features": [
|
||||
"end_image",
|
||||
"flow_shift",
|
||||
"init_image"
|
||||
],
|
||||
"disabled_features": [
|
||||
"img2img",
|
||||
"mask_image"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "ltx23-distilled",
|
||||
"name": "LTX 2.3 Distilled 1.1",
|
||||
"description": "Supports text, start-image and start/end-image video. Audio VAE is optional for silent video. Configure latent upscaling separately in generation settings.",
|
||||
"model_url": "https://huggingface.co/Lightricks/LTX-2.3",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Gemma 3 12B Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "embeddings_connectors",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false,
|
||||
"label": "LTX 2.3 Video VAE"
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "audio_vae",
|
||||
"required": false,
|
||||
"label": "LTX 2.3 Audio VAE"
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"sampling_method": "euler",
|
||||
"video_frames": 121,
|
||||
"fps": 24,
|
||||
"cfg_scale": 1,
|
||||
"steps": 8,
|
||||
"width": 768,
|
||||
"height": 512
|
||||
},
|
||||
"features": [
|
||||
"end_image",
|
||||
"flow_shift",
|
||||
"init_image"
|
||||
],
|
||||
"disabled_features": [
|
||||
"img2img",
|
||||
"mask_image"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "ltx25-dev",
|
||||
"name": "LTX 2.5 dev",
|
||||
"description": "Use the conv video VAE and LTX-specific Gemma 4 with bundled projection. Audio VAE is optional for silent video.",
|
||||
"model_url": "https://huggingface.co/Lightricks/LTX-2.5",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "LTX-2.5 Gemma 4 12B with projection"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false,
|
||||
"label": "LTX 2.5 Conv Video VAE"
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "audio_vae",
|
||||
"required": false,
|
||||
"label": "LTX 2.5 Audio VAE"
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"sampling_method": "euler",
|
||||
"fps": 24,
|
||||
"video_frames": 33,
|
||||
"cfg_scale": 3,
|
||||
"steps": 20,
|
||||
"width": 768,
|
||||
"height": 512
|
||||
},
|
||||
"features": [
|
||||
"end_image",
|
||||
"flow_shift",
|
||||
"init_image"
|
||||
],
|
||||
"disabled_features": [
|
||||
"img2img",
|
||||
"mask_image"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "mage-flow-edit",
|
||||
"name": "Mage Flow Edit",
|
||||
"description": "Supply reference images. Select a separate vision projector when it is not bundled in the text encoder.",
|
||||
"model_url": "https://huggingface.co/microsoft/Mage-Flow-Edit",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Qwen 3 VL 4B Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm_vision",
|
||||
"required": false,
|
||||
"label": "Vision projector (required for separate GGUF text encoders)"
|
||||
}
|
||||
],
|
||||
"defaults": {
|
||||
"sampling_method": "euler",
|
||||
"cfg_scale": 5,
|
||||
"steps": 20,
|
||||
"width": 1024,
|
||||
"height": 1024
|
||||
},
|
||||
"features": [
|
||||
"flow_shift",
|
||||
"img_cfg",
|
||||
"ref_images"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "mage-flow-turbo",
|
||||
"name": "Mage Flow Turbo",
|
||||
"model_url": "https://huggingface.co/microsoft/Mage-Flow-Turbo",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Qwen 3 VL 4B Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"defaults": {
|
||||
"cfg_scale": 1,
|
||||
"steps": 4,
|
||||
"width": 1024,
|
||||
"height": 1024,
|
||||
"sampling_method": "euler"
|
||||
},
|
||||
"features": [
|
||||
"flow_shift"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "mage-flow",
|
||||
"name": "Mage Flow",
|
||||
"model_url": "https://huggingface.co/microsoft/Mage-Flow",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Qwen 3 VL 4B Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"defaults": {
|
||||
"cfg_scale": 5,
|
||||
"steps": 20,
|
||||
"width": 1024,
|
||||
"height": 1024,
|
||||
"sampling_method": "euler"
|
||||
},
|
||||
"features": [
|
||||
"flow_shift"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "ming-image",
|
||||
"name": "Ming Image 0.1",
|
||||
"model_url": "https://huggingface.co/inclusionAI/Ming-Image-0.1-Design",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Ling Mini 2.0 Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "tokenizer",
|
||||
"required": true,
|
||||
"label": "Ling tokenizer.json"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"cfg_scale": 1,
|
||||
"steps": 12,
|
||||
"width": 2048,
|
||||
"height": 2048,
|
||||
"sampling_method": "euler"
|
||||
},
|
||||
"features": [
|
||||
"flow_shift"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "minimax-h3-fl2va",
|
||||
"name": "MiniMax H3 FL2VA",
|
||||
"description": "Generate video and audio, optionally with start/end images. Supports full and pruned FL2VA weights. Audio VAE is optional for silent video.",
|
||||
"model_url": "https://huggingface.co/MiniMaxAI/MiniMax-H3",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "MiniMax-H3 Qwen 3 VL 32B Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false,
|
||||
"label": "MiniMax H3 Video VAE"
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "audio_vae",
|
||||
"required": false,
|
||||
"label": "MiniMax H3 Audio VAE"
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"video_frames": 56,
|
||||
"fps": 24,
|
||||
"cfg_scale": 1,
|
||||
"width": 1344,
|
||||
"height": 768,
|
||||
"sampling_method": "euler"
|
||||
},
|
||||
"features": [
|
||||
"end_image",
|
||||
"flow_shift",
|
||||
"init_image"
|
||||
],
|
||||
"disabled_features": [
|
||||
"img2img",
|
||||
"mask_image"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "minimax-h3-ref2va",
|
||||
"name": "MiniMax H3 Ref2VA",
|
||||
"description": "Supply image, video or audio references with compatible Ref2VA weights. Audio VAE is optional for silent video.",
|
||||
"model_url": "https://huggingface.co/MiniMaxAI/MiniMax-H3",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "MiniMax-H3 Qwen 3 VL 32B Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false,
|
||||
"label": "MiniMax H3 Video VAE"
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "audio_vae",
|
||||
"required": false,
|
||||
"label": "MiniMax H3 Audio VAE"
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"video_frames": 56,
|
||||
"fps": 24,
|
||||
"cfg_scale": 1,
|
||||
"width": 1344,
|
||||
"height": 768,
|
||||
"sampling_method": "euler"
|
||||
},
|
||||
"features": [
|
||||
"flow_shift",
|
||||
"ref_images"
|
||||
],
|
||||
"disabled_features": [
|
||||
"img2img",
|
||||
"mask_image"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "minit2i",
|
||||
"name": "MiniT2I",
|
||||
"description": "Pixel-space model; no VAE is required.",
|
||||
"model_url": "https://huggingface.co/MiniT2I/MiniT2I",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "t5xxl",
|
||||
"required": true,
|
||||
"label": "FLAN-T5 Large"
|
||||
}
|
||||
],
|
||||
"defaults": {
|
||||
"cfg_scale": 2.5,
|
||||
"steps": 20,
|
||||
"width": 512,
|
||||
"height": 512,
|
||||
"sampling_method": "euler"
|
||||
},
|
||||
"disabled_features": [
|
||||
"preview",
|
||||
"vae_tiling"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "moss-image-base",
|
||||
"name": "MOSS Image Base",
|
||||
"description": "Select the MOSS-Image-Base transformer with its matching text encoder and FLUX.2 VAE or TAE.",
|
||||
"model_url": "https://huggingface.co/OpenMOSS-Team/MOSS-Image-Base",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Qwen 3.5 9B Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "tokenizer",
|
||||
"required": true,
|
||||
"label": "Qwen 3.5 tokenizer.json"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"cfg_scale": 3,
|
||||
"steps": 20,
|
||||
"width": 1024,
|
||||
"height": 1024,
|
||||
"flow_shift": 5,
|
||||
"sampling_method": "euler"
|
||||
},
|
||||
"features": [
|
||||
"flow_shift",
|
||||
"slg"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "moss-image-sft",
|
||||
"name": "MOSS Image SFT",
|
||||
"description": "Select the MOSS-Image-SFT transformer with its matching text encoder and FLUX.2 VAE or TAE.",
|
||||
"model_url": "https://huggingface.co/OpenMOSS-Team/MOSS-Image-SFT",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Qwen 3.5 9B Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "tokenizer",
|
||||
"required": true,
|
||||
"label": "Qwen 3.5 tokenizer.json"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"cfg_scale": 3,
|
||||
"steps": 20,
|
||||
"width": 1024,
|
||||
"height": 1024,
|
||||
"flow_shift": 5,
|
||||
"sampling_method": "euler"
|
||||
},
|
||||
"features": [
|
||||
"flow_shift",
|
||||
"slg"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "nitrosd-realism",
|
||||
"name": "NitroSD Realism",
|
||||
"model_url": "https://huggingface.co/ChenDY/NitroFusion",
|
||||
"slots": [
|
||||
{
|
||||
"id": "model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"defaults": {
|
||||
"scheduler": "sgm_uniform",
|
||||
"shifted_timestep": 250,
|
||||
"cfg_scale": 1,
|
||||
"steps": 1,
|
||||
"width": 1024,
|
||||
"height": 1024
|
||||
},
|
||||
"features": [
|
||||
"cache_unet",
|
||||
"clip_skip",
|
||||
"shifted_timestep"
|
||||
],
|
||||
"disabled_features": [
|
||||
"cache_dit"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "ovis-image",
|
||||
"name": "Ovis Image",
|
||||
"model_url": "https://huggingface.co/ATH-MaaS/Ovis-Image-7B",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Ovis 2.5 Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"cfg_scale": 5,
|
||||
"steps": 20,
|
||||
"width": 1024,
|
||||
"height": 1024,
|
||||
"sampling_method": "euler"
|
||||
},
|
||||
"features": [
|
||||
"flow_shift",
|
||||
"slg"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "pid-15-flux2",
|
||||
"name": "PiD 1.5 (Flux.2 VAE)",
|
||||
"description": "Supply a reference image; the first image is used as the source latent. Select a matching Flux.2 PiD checkpoint and VAE.",
|
||||
"model_url": "https://huggingface.co/nvidia/PiD",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Gemma 2 2B ELM Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "tokenizer",
|
||||
"required": true,
|
||||
"label": "Gemma 2 tokenizer.json"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"context": {
|
||||
"vae_format": "flux2"
|
||||
},
|
||||
"defaults": {
|
||||
"sampling_method": "lcm",
|
||||
"scheduler": "lcm",
|
||||
"cfg_scale": 1,
|
||||
"steps": 4,
|
||||
"width": 2048,
|
||||
"height": 2048
|
||||
},
|
||||
"features": [
|
||||
"flow_shift",
|
||||
"ref_images"
|
||||
],
|
||||
"disabled_features": [
|
||||
"img2img",
|
||||
"mask_image",
|
||||
"preview"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "pid-15-qwen-image",
|
||||
"name": "PiD 1.5 (Qwen Image VAE)",
|
||||
"description": "Supply a reference image; the first image is used as the source latent. Select a matching Qwen Image PiD checkpoint and VAE. Use the Qwen Image 2D VAE.",
|
||||
"model_url": "https://huggingface.co/nvidia/PiD",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Gemma 2 2B ELM Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "tokenizer",
|
||||
"required": true,
|
||||
"label": "Gemma 2 tokenizer.json"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"context": {
|
||||
"vae_format": "wan"
|
||||
},
|
||||
"defaults": {
|
||||
"sampling_method": "lcm",
|
||||
"scheduler": "lcm",
|
||||
"cfg_scale": 1,
|
||||
"steps": 4,
|
||||
"width": 2048,
|
||||
"height": 2048
|
||||
},
|
||||
"features": [
|
||||
"flow_shift",
|
||||
"ref_images"
|
||||
],
|
||||
"disabled_features": [
|
||||
"img2img",
|
||||
"mask_image",
|
||||
"preview"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "pid-15-sd3",
|
||||
"name": "PiD 1.5 (SD3 VAE)",
|
||||
"description": "Supply a reference image; the first image is used as the source latent. Select a matching SD3 PiD checkpoint and VAE.",
|
||||
"model_url": "https://huggingface.co/nvidia/PiD",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Gemma 2 2B ELM Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "tokenizer",
|
||||
"required": true,
|
||||
"label": "Gemma 2 tokenizer.json"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"context": {
|
||||
"vae_format": "sd3"
|
||||
},
|
||||
"defaults": {
|
||||
"sampling_method": "lcm",
|
||||
"scheduler": "lcm",
|
||||
"cfg_scale": 1,
|
||||
"steps": 4,
|
||||
"width": 2048,
|
||||
"height": 2048
|
||||
},
|
||||
"features": [
|
||||
"flow_shift",
|
||||
"ref_images"
|
||||
],
|
||||
"disabled_features": [
|
||||
"img2img",
|
||||
"mask_image",
|
||||
"preview"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "pid-15",
|
||||
"name": "PiD 1.5 (Flux / Z-Image VAE)",
|
||||
"description": "Supply a reference image; the first image is used as the source latent. Select a Flux/Z-Image PiD checkpoint and matching Flux VAE.",
|
||||
"model_url": "https://huggingface.co/nvidia/PiD",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Gemma 2 2B ELM Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "tokenizer",
|
||||
"required": true,
|
||||
"label": "Gemma 2 tokenizer.json"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"context": {
|
||||
"vae_format": "flux"
|
||||
},
|
||||
"defaults": {
|
||||
"sampling_method": "lcm",
|
||||
"scheduler": "lcm",
|
||||
"cfg_scale": 1,
|
||||
"steps": 4,
|
||||
"width": 2048,
|
||||
"height": 2048
|
||||
},
|
||||
"features": [
|
||||
"flow_shift",
|
||||
"ref_images"
|
||||
],
|
||||
"disabled_features": [
|
||||
"img2img",
|
||||
"mask_image",
|
||||
"preview"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "pid-flux2",
|
||||
"name": "PiD (Flux.2 VAE)",
|
||||
"description": "Supply a reference image; the first image is used as the source latent. Select a matching Flux.2 PiD checkpoint and VAE.",
|
||||
"model_url": "https://huggingface.co/nvidia/PiD",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Gemma 2 2B ELM Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "tokenizer",
|
||||
"required": true,
|
||||
"label": "Gemma 2 tokenizer.json"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"context": {
|
||||
"vae_format": "flux2"
|
||||
},
|
||||
"defaults": {
|
||||
"sampling_method": "lcm",
|
||||
"scheduler": "lcm",
|
||||
"cfg_scale": 1,
|
||||
"steps": 4,
|
||||
"width": 2048,
|
||||
"height": 2048
|
||||
},
|
||||
"features": [
|
||||
"flow_shift",
|
||||
"ref_images"
|
||||
],
|
||||
"disabled_features": [
|
||||
"img2img",
|
||||
"mask_image",
|
||||
"preview"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "pid-qwen-image",
|
||||
"name": "PiD (Qwen Image VAE)",
|
||||
"description": "Supply a reference image; the first image is used as the source latent. Select a matching Qwen Image PiD checkpoint and VAE. Use the Qwen Image 2D VAE.",
|
||||
"model_url": "https://huggingface.co/nvidia/PiD",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Gemma 2 2B ELM Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "tokenizer",
|
||||
"required": true,
|
||||
"label": "Gemma 2 tokenizer.json"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"context": {
|
||||
"vae_format": "wan"
|
||||
},
|
||||
"defaults": {
|
||||
"sampling_method": "lcm",
|
||||
"scheduler": "lcm",
|
||||
"cfg_scale": 1,
|
||||
"steps": 4,
|
||||
"width": 2048,
|
||||
"height": 2048
|
||||
},
|
||||
"features": [
|
||||
"flow_shift",
|
||||
"ref_images"
|
||||
],
|
||||
"disabled_features": [
|
||||
"img2img",
|
||||
"mask_image",
|
||||
"preview"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "pid-sd3",
|
||||
"name": "PiD (SD3 VAE)",
|
||||
"description": "Supply a reference image; the first image is used as the source latent. Select a matching SD3 PiD checkpoint and VAE.",
|
||||
"model_url": "https://huggingface.co/nvidia/PiD",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Gemma 2 2B ELM Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "tokenizer",
|
||||
"required": true,
|
||||
"label": "Gemma 2 tokenizer.json"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"context": {
|
||||
"vae_format": "sd3"
|
||||
},
|
||||
"defaults": {
|
||||
"sampling_method": "lcm",
|
||||
"scheduler": "lcm",
|
||||
"cfg_scale": 1,
|
||||
"steps": 4,
|
||||
"width": 2048,
|
||||
"height": 2048
|
||||
},
|
||||
"features": [
|
||||
"flow_shift",
|
||||
"ref_images"
|
||||
],
|
||||
"disabled_features": [
|
||||
"img2img",
|
||||
"mask_image",
|
||||
"preview"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "pid",
|
||||
"name": "PiD (Flux / Z-Image VAE)",
|
||||
"description": "Supply a reference image; the first image is used as the source latent. Select a Flux/Z-Image PiD checkpoint and matching Flux VAE.",
|
||||
"model_url": "https://huggingface.co/nvidia/PiD",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Gemma 2 2B ELM Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "tokenizer",
|
||||
"required": true,
|
||||
"label": "Gemma 2 tokenizer.json"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"context": {
|
||||
"vae_format": "flux"
|
||||
},
|
||||
"defaults": {
|
||||
"sampling_method": "lcm",
|
||||
"scheduler": "lcm",
|
||||
"cfg_scale": 1,
|
||||
"steps": 4,
|
||||
"width": 2048,
|
||||
"height": 2048
|
||||
},
|
||||
"features": [
|
||||
"flow_shift",
|
||||
"ref_images"
|
||||
],
|
||||
"disabled_features": [
|
||||
"img2img",
|
||||
"mask_image",
|
||||
"preview"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "pixart-alpha-1024",
|
||||
"name": "PixArt Alpha XL 1024",
|
||||
"description": "Use the matching PixArt Alpha transformer and SD 1.x-style VAE. Resolution/aspect-ratio micro-conditioning is not currently applied by the runtime.",
|
||||
"model_url": "https://huggingface.co/PixArt-alpha/PixArt-XL-2-1024-MS",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "t5xxl",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"context": {
|
||||
"model_args": "pixart_vae_scale_factor=0.18215"
|
||||
},
|
||||
"defaults": {
|
||||
"scheduler": "discrete",
|
||||
"sampling_method": "euler",
|
||||
"cfg_scale": 4.5,
|
||||
"steps": 20,
|
||||
"width": 1024,
|
||||
"height": 1024
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "pixart-alpha-512",
|
||||
"name": "PixArt Alpha XL 512",
|
||||
"description": "Use the matching PixArt Alpha transformer and SD 1.x-style VAE. Resolution/aspect-ratio micro-conditioning is not currently applied by the runtime.",
|
||||
"model_url": "https://huggingface.co/PixArt-alpha/PixArt-XL-2-512x512",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "t5xxl",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"context": {
|
||||
"model_args": "pixart_vae_scale_factor=0.18215,pixart_pos_embed_base_size=32,pixart_interpolation_scale=1"
|
||||
},
|
||||
"defaults": {
|
||||
"scheduler": "discrete",
|
||||
"sampling_method": "euler",
|
||||
"cfg_scale": 4.5,
|
||||
"steps": 20,
|
||||
"width": 512,
|
||||
"height": 512
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "pixart-sigma",
|
||||
"name": "PixArt Sigma XL 1024",
|
||||
"model_url": "https://huggingface.co/PixArt-alpha/PixArt-Sigma-XL-2-1024-MS",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "t5xxl",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"cfg_scale": 4.5,
|
||||
"steps": 20,
|
||||
"width": 1024,
|
||||
"height": 1024,
|
||||
"sampling_method": "euler"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "qwen-image-21-turbo",
|
||||
"name": "Qwen Image 2.1 Turbo",
|
||||
"description": "Use the standalone Turbo diffusion weights for generation and editing with the fixed 8-step schedule. Select the Qwen Image 2.1 VAE or TAEQI2.1, and supply a vision projector when needed.",
|
||||
"model_url": "https://huggingface.co/Qwen/Qwen-Image-2.1-Turbo",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Qwen 3 VL 8B Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "llm_vision",
|
||||
"required": false,
|
||||
"label": "Vision projector (required for separate GGUF text encoders)"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false,
|
||||
"label": "Qwen Image 2.1 VAE"
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false,
|
||||
"label": "TAEQI2.1"
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"sampling_method": "euler",
|
||||
"cfg_scale": 1,
|
||||
"steps": 8,
|
||||
"width": 2048,
|
||||
"height": 2048,
|
||||
"custom_sigmas": [
|
||||
1.0,
|
||||
0.978453,
|
||||
0.95418,
|
||||
0.926626,
|
||||
0.89508,
|
||||
0.845148,
|
||||
0.704534,
|
||||
0.414568,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
"features": [
|
||||
"ref_images"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "qwen-image-21",
|
||||
"name": "Qwen Image 2.1",
|
||||
"description": "Supports generation and editing. Select the full Qwen Image 2.1 VAE or TAEQI2.1. Supply a separate vision projector when needed. Select acceleration LoRAs and adjust their settings separately.",
|
||||
"model_url": "https://huggingface.co/Qwen/Qwen-Image-2.1",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Qwen 3 VL 8B Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "llm_vision",
|
||||
"required": false,
|
||||
"label": "Vision projector (required for separate GGUF text encoders)"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false,
|
||||
"label": "Qwen Image 2.1 VAE"
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false,
|
||||
"label": "TAEQI2.1"
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"sampling_method": "euler",
|
||||
"cfg_scale": 1,
|
||||
"steps": 20,
|
||||
"width": 2048,
|
||||
"height": 2048
|
||||
},
|
||||
"features": [
|
||||
"flow_shift",
|
||||
"ref_images"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "qwen-image-edit-2509",
|
||||
"name": "Qwen Image Edit 2509",
|
||||
"description": "Supply reference images. Select a vision projector for GGUF text encoders; omit it if vision weights are included in the text encoder.",
|
||||
"model_url": "https://huggingface.co/Qwen/Qwen-Image-Edit-2509",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Qwen 2.5 VL 7B Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "llm_vision",
|
||||
"required": false,
|
||||
"label": "Vision projector (required for separate GGUF text encoders)"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false,
|
||||
"label": "Qwen Image VAE"
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"sampling_method": "euler",
|
||||
"flow_shift": 3.0,
|
||||
"cfg_scale": 4,
|
||||
"steps": 20
|
||||
},
|
||||
"features": [
|
||||
"flow_shift",
|
||||
"img_cfg",
|
||||
"ref_images"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "qwen-image-edit-2511",
|
||||
"name": "Qwen Image Edit 2511",
|
||||
"description": "Supply reference images. Select a vision projector for GGUF text encoders; omit it if vision weights are included in the text encoder.",
|
||||
"model_url": "https://huggingface.co/Qwen/Qwen-Image-Edit-2511",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Qwen 2.5 VL 7B Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "llm_vision",
|
||||
"required": false,
|
||||
"label": "Vision projector (required for separate GGUF text encoders)"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false,
|
||||
"label": "Qwen Image VAE"
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"context": {
|
||||
"model_args": "qwen_image_zero_cond_t=true"
|
||||
},
|
||||
"defaults": {
|
||||
"sampling_method": "euler",
|
||||
"flow_shift": 3.0,
|
||||
"cfg_scale": 4,
|
||||
"steps": 20
|
||||
},
|
||||
"features": [
|
||||
"flow_shift",
|
||||
"img_cfg",
|
||||
"ref_images"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "qwen-image-edit",
|
||||
"name": "Qwen Image Edit",
|
||||
"description": "Supply reference images. Select a vision projector for GGUF text encoders; omit it if vision weights are included in the text encoder.",
|
||||
"model_url": "https://huggingface.co/Qwen/Qwen-Image-Edit",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Qwen 2.5 VL 7B Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "llm_vision",
|
||||
"required": false,
|
||||
"label": "Vision projector (required for separate GGUF text encoders)"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false,
|
||||
"label": "Qwen Image VAE"
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"sampling_method": "euler",
|
||||
"flow_shift": 3.0,
|
||||
"cfg_scale": 4,
|
||||
"steps": 20
|
||||
},
|
||||
"features": [
|
||||
"flow_shift",
|
||||
"img_cfg",
|
||||
"ref_images"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "qwen-image-layered",
|
||||
"name": "Qwen Image Layered",
|
||||
"description": "Supply a reference image and use the dedicated layered VAE.",
|
||||
"model_url": "https://huggingface.co/Qwen/Qwen-Image-Layered",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Qwen 2.5 VL 7B Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": true,
|
||||
"label": "Qwen Image Layered VAE"
|
||||
}
|
||||
],
|
||||
"defaults": {
|
||||
"sampling_method": "euler",
|
||||
"flow_shift": 3.0,
|
||||
"cfg_scale": 4,
|
||||
"steps": 20,
|
||||
"width": 640,
|
||||
"height": 640
|
||||
},
|
||||
"features": [
|
||||
"flow_shift",
|
||||
"img_cfg",
|
||||
"ref_images"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "qwen-image",
|
||||
"name": "Qwen Image",
|
||||
"description": "Supports text-to-image and image-to-image; pruned transformer variants use the same components.",
|
||||
"model_url": "https://huggingface.co/Qwen/Qwen-Image",
|
||||
"slots": [
|
||||
{
|
||||
"id": "diffusion_model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"required": true,
|
||||
"label": "Qwen 2.5 VL 7B Text Encoder"
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false,
|
||||
"label": "Qwen Image VAE"
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"required_any": [
|
||||
[
|
||||
"vae",
|
||||
"tae"
|
||||
]
|
||||
],
|
||||
"defaults": {
|
||||
"sampling_method": "euler",
|
||||
"flow_shift": 3.0,
|
||||
"cfg_scale": 4,
|
||||
"steps": 20,
|
||||
"width": 1328,
|
||||
"height": 1328
|
||||
},
|
||||
"features": [
|
||||
"flow_shift"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "sd-turbo",
|
||||
"name": "SD Turbo",
|
||||
"description": "Select a single-file SD-Turbo checkpoint. Uses one step with CFG disabled (scale 1 in sd.cpp); use more steps for partial image-to-image denoising.",
|
||||
"model_url": "https://huggingface.co/stabilityai/sd-turbo",
|
||||
"slots": [
|
||||
{
|
||||
"id": "model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"defaults": {
|
||||
"sampling_method": "euler",
|
||||
"scheduler": "discrete",
|
||||
"cfg_scale": 1,
|
||||
"steps": 1,
|
||||
"width": 512,
|
||||
"height": 512
|
||||
},
|
||||
"features": [
|
||||
"cache_unet",
|
||||
"clip_skip"
|
||||
],
|
||||
"disabled_features": [
|
||||
"cache_dit"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "sd1-checkpoint",
|
||||
"name": "SD 1.x",
|
||||
"description": "Supports SD 1.x, compatible LCM checkpoints and layer-count variants. For LCM weights, select LCM sampling and adjust steps/CFG. Tiny SD Diffusers directories must first be converted into a single-file checkpoint.",
|
||||
"model_url": "https://huggingface.co/CompVis/stable-diffusion-v1-4",
|
||||
"slots": [
|
||||
{
|
||||
"id": "model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"label": "VAE override",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"defaults": {
|
||||
"cfg_scale": 7.5,
|
||||
"steps": 20,
|
||||
"width": 512,
|
||||
"height": 512
|
||||
},
|
||||
"features": [
|
||||
"cache_unet",
|
||||
"clip_skip"
|
||||
],
|
||||
"disabled_features": [
|
||||
"cache_dit"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "sd1-controlnet",
|
||||
"name": "SD 1.5 ControlNet",
|
||||
"description": "Supply a control image; input image and mask are optional for image-to-image or inpainting.",
|
||||
"model_url": "https://huggingface.co/lllyasviel/control_v11p_sd15_canny",
|
||||
"slots": [
|
||||
{
|
||||
"id": "model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "control_net",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"defaults": {
|
||||
"cfg_scale": 7.5,
|
||||
"steps": 20,
|
||||
"width": 512,
|
||||
"height": 512
|
||||
},
|
||||
"features": [
|
||||
"cache_unet",
|
||||
"clip_skip"
|
||||
],
|
||||
"disabled_features": [
|
||||
"cache_dit"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "sd1-inpainting",
|
||||
"name": "SD 1.5 Inpainting",
|
||||
"description": "Select an inpainting checkpoint, then supply an input image and mask.",
|
||||
"slots": [
|
||||
{
|
||||
"id": "model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"defaults": {
|
||||
"cfg_scale": 7.5,
|
||||
"steps": 20,
|
||||
"width": 512,
|
||||
"height": 512
|
||||
},
|
||||
"features": [
|
||||
"cache_unet",
|
||||
"clip_skip",
|
||||
"img_cfg"
|
||||
],
|
||||
"disabled_features": [
|
||||
"cache_dit"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "sd1-ip-adapter",
|
||||
"name": "SD 1.5 IP-Adapter / Plus",
|
||||
"description": "Select matching SD 1.5 IP-Adapter or Plus weights and CLIP Vision H, then supply an IP-Adapter image.",
|
||||
"model_url": "https://huggingface.co/h94/IP-Adapter",
|
||||
"slots": [
|
||||
{
|
||||
"id": "model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "clip_vision",
|
||||
"required": true,
|
||||
"label": "CLIP Vision H"
|
||||
},
|
||||
{
|
||||
"id": "ip_adapter",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"defaults": {
|
||||
"cfg_scale": 7.5,
|
||||
"steps": 20,
|
||||
"width": 512,
|
||||
"height": 512
|
||||
},
|
||||
"features": [
|
||||
"cache_unet",
|
||||
"clip_skip"
|
||||
],
|
||||
"disabled_features": [
|
||||
"cache_dit"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "sd2-512-checkpoint",
|
||||
"name": "SD 2.1 512",
|
||||
"description": "Supports SD 2.x 512 and compatible layer-count variants. Tiny SD2 Diffusers directories must first be converted into a single-file checkpoint.",
|
||||
"slots": [
|
||||
{
|
||||
"id": "model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"defaults": {
|
||||
"cfg_scale": 7.5,
|
||||
"steps": 20,
|
||||
"width": 512,
|
||||
"height": 512
|
||||
},
|
||||
"features": [
|
||||
"cache_unet",
|
||||
"clip_skip"
|
||||
],
|
||||
"disabled_features": [
|
||||
"cache_dit"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "sd2-768-checkpoint",
|
||||
"name": "SD 2.1 768",
|
||||
"slots": [
|
||||
{
|
||||
"id": "model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"defaults": {
|
||||
"cfg_scale": 7.5,
|
||||
"steps": 20,
|
||||
"width": 768,
|
||||
"height": 768
|
||||
},
|
||||
"features": [
|
||||
"cache_unet",
|
||||
"clip_skip"
|
||||
],
|
||||
"disabled_features": [
|
||||
"cache_dit"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "sd2-inpainting",
|
||||
"name": "SD 2 Inpainting",
|
||||
"description": "Select an inpainting checkpoint, then supply Init Image and Mask Image.",
|
||||
"slots": [
|
||||
{
|
||||
"id": "model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"defaults": {
|
||||
"scheduler": "discrete",
|
||||
"sampling_method": "euler_a",
|
||||
"cfg_scale": 7.5,
|
||||
"steps": 20,
|
||||
"width": 512,
|
||||
"height": 512
|
||||
},
|
||||
"features": [
|
||||
"cache_unet",
|
||||
"clip_skip",
|
||||
"img_cfg"
|
||||
],
|
||||
"disabled_features": [
|
||||
"cache_dit"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"id": "sd3-medium",
|
||||
"name": "SD 3 Medium",
|
||||
"description": "Checkpoint with CLIP-L, CLIP-G and T5 included.",
|
||||
"model_url": "https://huggingface.co/stabilityai/stable-diffusion-3-medium-diffusers",
|
||||
"slots": [
|
||||
{
|
||||
"id": "model",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"id": "vae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "tae",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"defaults": {
|
||||
"sampling_method": "euler",
|
||||
"cfg_scale": 7,
|
||||
"steps": 20,
|
||||
"width": 1024,
|
||||
"height": 1024
|
||||
},
|
||||
"features": [
|
||||
"clip_skip",
|
||||
"flow_shift",
|
||||
"slg"
|
||||
]
|
||||
}
|
||||
Loaded 100 of 132 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user