Commit a0c8508 for stable-diffusion.cpp

commit a0c8508e726d6620a6a7d34fa59c25a0fc43b5cf
Author: George <35490284+noctrex@users.noreply.github.com>
Date:   Thu Oct 22 17:51:59 2026 +0300

    feat: add --taesd-preview-only to shared context params (#2184)

diff --git a/docs/taesd.md b/docs/taesd.md
index 954086d..8331f44 100644
--- a/docs/taesd.md
+++ b/docs/taesd.md
@@ -49,3 +49,5 @@ curl -L -o taeqi2_1.safetensors https://huggingface.co/madebyollin/taeqi2_1/reso
 ```

 Replace `--vae PATH` with `--taesd taeqi2_1.safetensors` in the [Qwen Image 2.1 examples](qwen_image_2.1.md) to use it for encoding and decoding. For previews only, keep `--vae PATH` and add `--taesd taeqi2_1.safetensors --taesd-preview-only --preview tae`.
+
+`sd-server` accepts the same `--taesd` and `--taesd-preview-only` options; the preview method is selected per request instead of via `--preview`.
diff --git a/examples/cli/main.cpp b/examples/cli/main.cpp
index 8ee5186..ee1e56f 100644
--- a/examples/cli/main.cpp
+++ b/examples/cli/main.cpp
@@ -47,7 +47,6 @@ struct SDCliParams {
     int preview_interval     = 1;
     std::string preview_path = "preview.png";
     int preview_fps          = 16;
-    bool taesd_preview       = false;
     bool preview_noisy       = false;
     bool color               = false;
     bool metadata_raw        = false;
@@ -114,10 +113,6 @@ struct SDCliParams {
              "--color",
              "colors the logging tags according to level",
              true, &color},
-            {"",
-             "--taesd-preview-only",
-             std::string("prevents usage of taesd for decoding the final image. (for use with --preview ") + previews_str[PREVIEW_TAE] + ")",
-             true, &taesd_preview},
             {"",
              "--preview-noisy",
              "enables previewing noisy inputs of the models rather than the denoised outputs",
@@ -268,7 +263,6 @@ struct SDCliParams {
             << "  preview_interval: " << preview_interval << ",\n"
             << "  preview_path: \"" << preview_path << "\",\n"
             << "  preview_fps: " << preview_fps << ",\n"
-            << "  taesd_preview: " << (taesd_preview ? "true" : "false") << ",\n"
             << "  preview_noisy: " << (preview_noisy ? "true" : "false") << ",\n"
             << "  imatrix_out: \"" << imatrix_out << "\",\n"
             << "  metadata_raw: " << (metadata_raw ? "true" : "false") << ",\n"
@@ -885,7 +879,7 @@ int main(int argc, const char* argv[]) {
         }
     }

-    sd_ctx_params_t sd_ctx_params = ctx_params.to_sd_ctx_params_t(cli_params.taesd_preview);
+    sd_ctx_params_t sd_ctx_params = ctx_params.to_sd_ctx_params_t();

     SDImageVec results;
     int num_results             = 0;
diff --git a/examples/common/common.cpp b/examples/common/common.cpp
index 7f65eda..df76c51 100644
--- a/examples/common/common.cpp
+++ b/examples/common/common.cpp
@@ -641,6 +641,10 @@ ArgOptions SDContextParams::get_options() {
          "--sage-attn",
          "use native CUDA SageAttention in the diffusion model, with flash/default attention fallback",
          true, &sage_attn},
+        {"",
+         "--taesd-preview-only",
+         "prevents usage of taesd for decoding the final image; the VAE keeps encoding / decoding and taesd is only used for step previews",
+         true, &taesd_preview_only},
     };

     auto on_type_arg = [&](int argc, const char** argv, int index) {
@@ -1014,6 +1018,7 @@ std::string SDContextParams::to_string() const {
         << "  attn_scale: " << attn_scale << ",\n"
         << "  diffusion_conv_direct: " << (diffusion_conv_direct ? "true" : "false") << ",\n"
         << "  vae_conv_direct: " << (vae_conv_direct ? "true" : "false") << ",\n"
+        << "  taesd_preview_only: " << (taesd_preview_only ? "true" : "false") << ",\n"
         << "  prediction: " << sd_prediction_name(prediction) << ",\n"
         << "  lora_apply_mode: " << sd_lora_apply_mode_name(lora_apply_mode) << ",\n"
         << "  force_sdxl_vae_conv_scale: " << (force_sdxl_vae_conv_scale ? "true" : "false") << "\n"
@@ -1021,7 +1026,7 @@ std::string SDContextParams::to_string() const {
     return oss.str();
 }

-sd_ctx_params_t SDContextParams::to_sd_ctx_params_t(bool taesd_preview) {
+sd_ctx_params_t SDContextParams::to_sd_ctx_params_t() {
     prepare_backend_assignments();
     embedding_vec.clear();
     embedding_vec.reserve(embedding_map.size());
@@ -1071,7 +1076,7 @@ sd_ctx_params_t SDContextParams::to_sd_ctx_params_t(bool taesd_preview) {
     sd_ctx_params.sage_attn                       = sage_attn;
     sd_ctx_params.linear_scale                    = linear_scale;
     sd_ctx_params.attn_scale                      = attn_scale;
-    sd_ctx_params.tae_preview_only                = taesd_preview;
+    sd_ctx_params.tae_preview_only                = taesd_preview_only;
     sd_ctx_params.diffusion_conv_direct           = diffusion_conv_direct;
     sd_ctx_params.vae_conv_direct                 = vae_conv_direct;
     sd_ctx_params.force_sdxl_vae_conv_scale       = force_sdxl_vae_conv_scale;
diff --git a/examples/common/common.h b/examples/common/common.h
index 992f74c..7b9f691 100644
--- a/examples/common/common.h
+++ b/examples/common/common.h
@@ -180,6 +180,7 @@ struct SDContextParams {
     bool sage_attn             = false;
     bool diffusion_conv_direct = false;
     bool vae_conv_direct       = false;
+    bool taesd_preview_only    = false;

     prediction_t prediction           = PREDICTION_COUNT;
     lora_apply_mode_t lora_apply_mode = LORA_APPLY_AUTO;
@@ -197,7 +198,7 @@ struct SDContextParams {
     bool validate(SDMode mode);
     bool resolve_and_validate(SDMode mode);
     std::string to_string() const;
-    sd_ctx_params_t to_sd_ctx_params_t(bool taesd_preview);
+    sd_ctx_params_t to_sd_ctx_params_t();
 };

 struct SDGenerationParams {
diff --git a/examples/server/main.cpp b/examples/server/main.cpp
index d79c6e2..a10cb66 100644
--- a/examples/server/main.cpp
+++ b/examples/server/main.cpp
@@ -93,7 +93,7 @@ int main(int argc, const char** argv) {
     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);
+    sd_ctx_params_t sd_ctx_params = ctx_params.to_sd_ctx_params_t();
     ServerModels models;
     if (!ctx_params.model_path.empty() || !ctx_params.diffusion_model_path.empty()) {
         const auto started = std::chrono::steady_clock::now();
diff --git a/examples/server/routes_models.cpp b/examples/server/routes_models.cpp
index ea14eb8..9e4e396 100644
--- a/examples/server/routes_models.cpp
+++ b/examples/server/routes_models.cpp
@@ -94,7 +94,7 @@ static void change_model(ServerRuntime& runtime, const httplib::Request& req, ht
         *runtime.ctx_params         = unload ? models.base_context : std::move(context);
         *runtime.default_gen_params = unload ? models.base_defaults : std::move(defaults);
         if (!unload) {
-            auto params = runtime.ctx_params->to_sd_ctx_params_t(false);
+            auto params = runtime.ctx_params->to_sd_ctx_params_t();
             models.context.reset(new_sd_ctx(&params));
             if (!models.context) {
                 throw std::runtime_error("Model initialization failed; check the server log for component compatibility and memory errors");