mirror of
https://github.com/leejet/stable-diffusion.cpp.git
synced 2026-11-10 19:06:33 +00:00
feat: Server: Add support for previews via sdcpp API (#2093)
Co-authored-by: leejet <leejet714@gmail.com>
This commit is contained in:
1 parent
203a882a28
commit
96f67fe631
9 files changed
+151
-7
No files matched your search
@@ -410,6 +410,20 @@ Field types:
|
|||||||
| `queue_position` | `integer` |
|
| `queue_position` | `integer` |
|
||||||
| `result` | `object \| null` |
|
| `result` | `object \| null` |
|
||||||
| `error` | `object \| null` |
|
| `error` | `object \| null` |
|
||||||
|
| `preview` | `object \| null` |
|
||||||
|
|
||||||
|
`preview` sub-fields:
|
||||||
|
|
||||||
|
| Field | Type | Notes |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `preview.pass` | `integer` | Sampling pass number, starting at 1 within the job |
|
||||||
|
| `preview.step` | `integer` | Positive logical sample step within this pass |
|
||||||
|
| `preview.total_steps` | `integer` | Actual sample steps in this pass, after schedule and strength adjustments |
|
||||||
|
| `preview.b64_json` | `string` | Base64-encoded PNG of the current preview frame |
|
||||||
|
|
||||||
|
The preview is updated in place as sampling progresses; poll `GET /sdcpp/v1/jobs/{id}` to retrieve the latest frame. Only the most recent preview is retained.
|
||||||
|
|
||||||
|
`step / total_steps` describes the current sampling pass, not overall job completion. A new batch item, high/low-noise stage, or highres pass increments `pass` and restarts `step`. Samplers with multiple denoiser evaluations per logical step may update a preview more than once at the same step. The frame and its pass/step metadata are published together.
|
||||||
|
|
||||||
### Endpoints
|
### Endpoints
|
||||||
|
|
||||||
@@ -437,6 +451,7 @@ Top-level fields:
|
|||||||
| `loras` | `array<object>` | Available LoRA entries |
|
| `loras` | `array<object>` | Available LoRA entries |
|
||||||
| `upscalers` | `array<object>` | Available highres upscalers, built-in and model-backed |
|
| `upscalers` | `array<object>` | Available highres upscalers, built-in and model-backed |
|
||||||
| `upscale` | `boolean` | Whether a compatible RGB ESRGAN model is available for `POST /sdcpp/v1/upscale` |
|
| `upscale` | `boolean` | Whether a compatible RGB ESRGAN model is available for `POST /sdcpp/v1/upscale` |
|
||||||
|
| `preview_modes` | `array<string>` | Available preview modes, e.g. `["none", "proj", "tae", "vae"]` |
|
||||||
| `limits` | `object` | Shared queue and size limits |
|
| `limits` | `object` | Shared queue and size limits |
|
||||||
|
|
||||||
`model`
|
`model`
|
||||||
@@ -598,6 +613,7 @@ Fields returned in `features_by_mode.img_gen`:
|
|||||||
- `cache`
|
- `cache`
|
||||||
- `cancel_queued`
|
- `cancel_queued`
|
||||||
- `cancel_generating`
|
- `cancel_generating`
|
||||||
|
- `preview`
|
||||||
|
|
||||||
Fields returned in `features_by_mode.vid_gen`:
|
Fields returned in `features_by_mode.vid_gen`:
|
||||||
|
|
||||||
@@ -610,6 +626,7 @@ Fields returned in `features_by_mode.vid_gen`:
|
|||||||
- `cache`
|
- `cache`
|
||||||
- `cancel_queued`
|
- `cancel_queued`
|
||||||
- `cancel_generating`
|
- `cancel_generating`
|
||||||
|
- `preview`
|
||||||
|
|
||||||
#### `POST /sdcpp/v1/img_gen`
|
#### `POST /sdcpp/v1/img_gen`
|
||||||
|
|
||||||
@@ -782,6 +799,9 @@ Example:
|
|||||||
"scm_mask": "",
|
"scm_mask": "",
|
||||||
"scm_policy_dynamic": true,
|
"scm_policy_dynamic": true,
|
||||||
|
|
||||||
|
"preview": "none",
|
||||||
|
"preview_interval": 1,
|
||||||
|
|
||||||
"output_format": "png",
|
"output_format": "png",
|
||||||
"output_compression": 100
|
"output_compression": 100
|
||||||
}
|
}
|
||||||
@@ -847,6 +867,8 @@ Top-level scalar fields:
|
|||||||
| `control_strength` | `number` |
|
| `control_strength` | `number` |
|
||||||
| `ip_adapter_strength` | `number` |
|
| `ip_adapter_strength` | `number` |
|
||||||
| `embed_image_metadata` | `boolean` |
|
| `embed_image_metadata` | `boolean` |
|
||||||
|
| `preview` | `string` |
|
||||||
|
| `preview_interval` | `integer` |
|
||||||
|
|
||||||
Image fields:
|
Image fields:
|
||||||
|
|
||||||
@@ -934,6 +956,10 @@ When omitted, backend defaults apply to these fields:
|
|||||||
- `sample_params.flow_shift`
|
- `sample_params.flow_shift`
|
||||||
- `sample_params.guidance.img_cfg`
|
- `sample_params.guidance.img_cfg`
|
||||||
|
|
||||||
|
### Preview Interval Semantics
|
||||||
|
|
||||||
|
`preview_interval` controls the period (in sample steps) at which preview frames are generated. The default is `1` (every step). Any non-positive values will be clamped to `1`. Note that if `preview` is set to `"none"`, no previews are produced regardless of the interval.
|
||||||
|
|
||||||
### Completion Result
|
### Completion Result
|
||||||
|
|
||||||
Example completed job:
|
Example completed job:
|
||||||
@@ -1130,6 +1156,9 @@ Example:
|
|||||||
"scm_mask": "",
|
"scm_mask": "",
|
||||||
"scm_policy_dynamic": true,
|
"scm_policy_dynamic": true,
|
||||||
|
|
||||||
|
"preview": "none",
|
||||||
|
"preview_interval": 1,
|
||||||
|
|
||||||
"output_format": "webm",
|
"output_format": "webm",
|
||||||
"output_compression": 100
|
"output_compression": 100
|
||||||
}
|
}
|
||||||
@@ -1181,6 +1210,8 @@ Top-level scalar fields:
|
|||||||
| `fps` | `integer` |
|
| `fps` | `integer` |
|
||||||
| `moe_boundary` | `number` |
|
| `moe_boundary` | `number` |
|
||||||
| `vace_strength` | `number` |
|
| `vace_strength` | `number` |
|
||||||
|
| `preview` | `string` |
|
||||||
|
| `preview_interval` | `integer` |
|
||||||
|
|
||||||
Image and frame fields:
|
Image and frame fields:
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,55 @@
|
|||||||
#include "common/media_io.h"
|
#include "common/media_io.h"
|
||||||
#include "common/resource_owners.hpp"
|
#include "common/resource_owners.hpp"
|
||||||
|
|
||||||
|
static void preview_callback(int step, int frame_count, sd_image_t* frames, bool is_noisy, void* data) {
|
||||||
|
(void)is_noisy;
|
||||||
|
if (frame_count <= 0 || frames == nullptr || frames[0].data == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AsyncGenerationJob* job = static_cast<AsyncGenerationJob*>(data);
|
||||||
|
const sd_image_t& frame = frames[0];
|
||||||
|
const sd_preview_info_t info = sd_get_preview_info();
|
||||||
|
|
||||||
|
auto image_bytes = encode_image_to_vector(EncodedImageFormat::PNG,
|
||||||
|
frame.data,
|
||||||
|
frame.width,
|
||||||
|
frame.height,
|
||||||
|
frame.channel,
|
||||||
|
"",
|
||||||
|
80);
|
||||||
|
if (image_bytes.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string b64 = base64_encode(image_bytes);
|
||||||
|
std::lock_guard<std::mutex> lock(job->preview_mutex);
|
||||||
|
job->preview_b64 = std::move(b64);
|
||||||
|
job->preview_step = step < 0 ? -step : step;
|
||||||
|
job->preview_pass = info.sample_pass;
|
||||||
|
job->preview_total_steps = info.total_steps;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void clear_preview_callback() {
|
||||||
|
sd_set_preview_callback(nullptr, PREVIEW_NONE, 1, false, false, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_preview_callback(AsyncGenerationJob& job) {
|
||||||
|
preview_t mode = str_to_preview(job.kind == AsyncJobKind::ImgGen
|
||||||
|
? job.img_gen.preview_mode.c_str()
|
||||||
|
: job.vid_gen.preview_mode.c_str());
|
||||||
|
if (mode == PREVIEW_COUNT || mode == PREVIEW_NONE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int interval = job.kind == AsyncJobKind::ImgGen
|
||||||
|
? job.img_gen.preview_interval
|
||||||
|
: job.vid_gen.preview_interval;
|
||||||
|
if (interval <= 0) {
|
||||||
|
interval = 1;
|
||||||
|
}
|
||||||
|
sd_set_preview_callback(preview_callback, mode, interval, true, false, &job);
|
||||||
|
}
|
||||||
|
|
||||||
const char* async_job_kind_name(AsyncJobKind kind) {
|
const char* async_job_kind_name(AsyncJobKind kind) {
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
case AsyncJobKind::ImgGen:
|
case AsyncJobKind::ImgGen:
|
||||||
@@ -161,6 +210,18 @@ json make_async_job_json(const AsyncJobManager& manager, const AsyncGenerationJo
|
|||||||
result["error"] = nullptr;
|
result["error"] = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (job.status == AsyncJobStatus::Generating) {
|
||||||
|
std::lock_guard<std::mutex> lock(job.preview_mutex);
|
||||||
|
if (!job.preview_b64.empty()) {
|
||||||
|
result["preview"] = {
|
||||||
|
{"pass", job.preview_pass},
|
||||||
|
{"step", job.preview_step},
|
||||||
|
{"total_steps", job.preview_total_steps},
|
||||||
|
{"b64_json", job.preview_b64},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,12 +235,14 @@ bool execute_img_gen_job(ServerRuntime& runtime,
|
|||||||
|
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(*runtime.sd_ctx_mutex);
|
std::lock_guard<std::mutex> lock(*runtime.sd_ctx_mutex);
|
||||||
|
set_preview_callback(job);
|
||||||
sd_image_t* raw_results = nullptr;
|
sd_image_t* raw_results = nullptr;
|
||||||
int num_results = 0;
|
int num_results = 0;
|
||||||
if (!generate_image(runtime.sd_ctx, ¶ms, &raw_results, &num_results)) {
|
if (!generate_image(runtime.sd_ctx, ¶ms, &raw_results, &num_results)) {
|
||||||
raw_results = nullptr;
|
raw_results = nullptr;
|
||||||
num_results = 0;
|
num_results = 0;
|
||||||
}
|
}
|
||||||
|
clear_preview_callback();
|
||||||
results.adopt(raw_results, num_results);
|
results.adopt(raw_results, num_results);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -247,10 +310,12 @@ bool execute_vid_gen_job(ServerRuntime& runtime,
|
|||||||
|
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(*runtime.sd_ctx_mutex);
|
std::lock_guard<std::mutex> lock(*runtime.sd_ctx_mutex);
|
||||||
|
set_preview_callback(job);
|
||||||
sd_image_t* raw_results = nullptr;
|
sd_image_t* raw_results = nullptr;
|
||||||
if (!generate_video(runtime.sd_ctx, ¶ms, &raw_results, &num_results, &generated_audio, &output_fps)) {
|
if (!generate_video(runtime.sd_ctx, ¶ms, &raw_results, &num_results, &generated_audio, &output_fps)) {
|
||||||
raw_results = nullptr;
|
raw_results = nullptr;
|
||||||
}
|
}
|
||||||
|
clear_preview_callback();
|
||||||
results.adopt(raw_results, num_results);
|
results.adopt(raw_results, num_results);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,11 @@ struct AsyncGenerationJob {
|
|||||||
int result_fps = 0;
|
int result_fps = 0;
|
||||||
std::string error_code;
|
std::string error_code;
|
||||||
std::string error_message;
|
std::string error_message;
|
||||||
|
mutable std::mutex preview_mutex;
|
||||||
|
std::string preview_b64;
|
||||||
|
int preview_pass = 0;
|
||||||
|
int preview_step = 0;
|
||||||
|
int preview_total_steps = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AsyncJobManager {
|
struct AsyncJobManager {
|
||||||
|
|||||||
@@ -205,6 +205,7 @@ static json make_img_gen_features_json() {
|
|||||||
{"cache", true},
|
{"cache", true},
|
||||||
{"cancel_queued", true},
|
{"cancel_queued", true},
|
||||||
{"cancel_generating", false},
|
{"cancel_generating", false},
|
||||||
|
{"preview", true},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,9 +220,18 @@ static json make_vid_gen_features_json() {
|
|||||||
{"cache", true},
|
{"cache", true},
|
||||||
{"cancel_queued", true},
|
{"cancel_queued", true},
|
||||||
{"cancel_generating", false},
|
{"cancel_generating", false},
|
||||||
|
{"preview", true},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static json make_preview_modes_json() {
|
||||||
|
json modes = json::array();
|
||||||
|
for (int i = 0; i < PREVIEW_COUNT; ++i) {
|
||||||
|
modes.push_back(sd_preview_name((preview_t)i));
|
||||||
|
}
|
||||||
|
return modes;
|
||||||
|
}
|
||||||
|
|
||||||
static json make_capabilities_json(ServerRuntime& runtime) {
|
static json make_capabilities_json(ServerRuntime& runtime) {
|
||||||
refresh_lora_cache(runtime);
|
refresh_lora_cache(runtime);
|
||||||
refresh_upscaler_cache(runtime);
|
refresh_upscaler_cache(runtime);
|
||||||
@@ -396,6 +406,7 @@ static json make_capabilities_json(ServerRuntime& runtime) {
|
|||||||
result["loras"] = available_loras;
|
result["loras"] = available_loras;
|
||||||
result["upscalers"] = available_upscalers;
|
result["upscalers"] = available_upscalers;
|
||||||
result["upscale"] = have_upscaler_models;
|
result["upscale"] = have_upscaler_models;
|
||||||
|
result["preview_modes"] = make_preview_modes_json();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -418,6 +429,8 @@ static bool parse_img_gen_request(const json& body,
|
|||||||
if (!assign_output_options(request, output_format, output_compression, true, error_message)) {
|
if (!assign_output_options(request, output_format, output_compression, true, error_message)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
request.preview_mode = body.value("preview", std::string("none"));
|
||||||
|
request.preview_interval = body.value("preview_interval", 1);
|
||||||
// Intentionally disable prompt-embedded LoRA tag parsing for server APIs.
|
// Intentionally disable prompt-embedded LoRA tag parsing for server APIs.
|
||||||
if (!request.gen_params.resolve_and_validate(IMG_GEN, "", runtime.ctx_params->hires_upscalers_dir, true)) {
|
if (!request.gen_params.resolve_and_validate(IMG_GEN, "", runtime.ctx_params->hires_upscalers_dir, true)) {
|
||||||
error_message = "invalid generation parameters";
|
error_message = "invalid generation parameters";
|
||||||
@@ -445,6 +458,8 @@ static bool parse_vid_gen_request(const json& body,
|
|||||||
if (!assign_output_options(request, output_format, output_compression, error_message)) {
|
if (!assign_output_options(request, output_format, output_compression, error_message)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
request.preview_mode = body.value("preview", std::string("none"));
|
||||||
|
request.preview_interval = body.value("preview_interval", 1);
|
||||||
// Intentionally disable prompt-embedded LoRA tag parsing for server APIs.
|
// Intentionally disable prompt-embedded LoRA tag parsing for server APIs.
|
||||||
if (!request.gen_params.resolve_and_validate(VID_GEN, "", runtime.ctx_params->hires_upscalers_dir, true)) {
|
if (!request.gen_params.resolve_and_validate(VID_GEN, "", runtime.ctx_params->hires_upscalers_dir, true)) {
|
||||||
error_message = "invalid generation parameters";
|
error_message = "invalid generation parameters";
|
||||||
|
|||||||
@@ -66,6 +66,8 @@ struct ImgGenJobRequest {
|
|||||||
SDGenerationParams gen_params;
|
SDGenerationParams gen_params;
|
||||||
std::string output_format = "png";
|
std::string output_format = "png";
|
||||||
int output_compression = 100;
|
int output_compression = 100;
|
||||||
|
std::string preview_mode = "none";
|
||||||
|
int preview_interval = 1;
|
||||||
|
|
||||||
sd_img_gen_params_t to_sd_img_gen_params_t() {
|
sd_img_gen_params_t to_sd_img_gen_params_t() {
|
||||||
return gen_params.to_sd_img_gen_params_t();
|
return gen_params.to_sd_img_gen_params_t();
|
||||||
@@ -76,6 +78,8 @@ struct VidGenJobRequest {
|
|||||||
SDGenerationParams gen_params;
|
SDGenerationParams gen_params;
|
||||||
std::string output_format = "webm";
|
std::string output_format = "webm";
|
||||||
int output_compression = 100;
|
int output_compression = 100;
|
||||||
|
std::string preview_mode = "none";
|
||||||
|
int preview_interval = 1;
|
||||||
|
|
||||||
sd_vid_gen_params_t to_sd_vid_gen_params_t() {
|
sd_vid_gen_params_t to_sd_vid_gen_params_t() {
|
||||||
return gen_params.to_sd_vid_gen_params_t();
|
return gen_params.to_sd_vid_gen_params_t();
|
||||||
|
|||||||
@@ -461,6 +461,11 @@ struct ggml_tensor;
|
|||||||
typedef void (*sd_log_cb_t)(enum sd_log_level_t level, const char* text, void* data);
|
typedef void (*sd_log_cb_t)(enum sd_log_level_t level, const char* text, void* data);
|
||||||
typedef void (*sd_progress_cb_t)(int step, int steps, float time, void* data);
|
typedef void (*sd_progress_cb_t)(int step, int steps, float time, void* data);
|
||||||
typedef void (*sd_preview_cb_t)(int step, int frame_count, sd_image_t* frames, bool is_noisy, void* data);
|
typedef void (*sd_preview_cb_t)(int step, int frame_count, sd_image_t* frames, bool is_noisy, void* data);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int sample_pass;
|
||||||
|
int total_steps;
|
||||||
|
} sd_preview_info_t;
|
||||||
typedef bool (*sd_graph_eval_callback_t)(struct ggml_tensor* t, bool ask, void* user_data);
|
typedef bool (*sd_graph_eval_callback_t)(struct ggml_tensor* t, bool ask, void* user_data);
|
||||||
|
|
||||||
SD_API void sd_set_log_callback(sd_log_cb_t sd_log_cb, void* data);
|
SD_API void sd_set_log_callback(sd_log_cb_t sd_log_cb, void* data);
|
||||||
@@ -469,6 +474,10 @@ SD_API void sd_set_progress_callback(sd_progress_cb_t cb, void* data);
|
|||||||
// negative interval previews only completed logical step -interval. Zero previews the final
|
// negative interval previews only completed logical step -interval. Zero previews the final
|
||||||
// completed step of the first sampling pass (base-resolution or high-noise).
|
// completed step of the first sampling pass (base-resolution or high-noise).
|
||||||
SD_API void sd_set_preview_callback(sd_preview_cb_t cb, enum preview_t mode, int interval, bool denoised, bool noisy, void* data);
|
SD_API void sd_set_preview_callback(sd_preview_cb_t cb, enum preview_t mode, int interval, bool denoised, bool noisy, void* data);
|
||||||
|
// Query from a preview callback. Passes are numbered from 1 since the last
|
||||||
|
// sd_set_preview_callback call; total_steps is the actual count in that pass.
|
||||||
|
// Both fields are zero before sampling starts.
|
||||||
|
SD_API sd_preview_info_t sd_get_preview_info();
|
||||||
SD_API void sd_set_backend_eval_callback(sd_graph_eval_callback_t cb, void* data);
|
SD_API void sd_set_backend_eval_callback(sd_graph_eval_callback_t cb, void* data);
|
||||||
SD_API int32_t sd_get_num_physical_cores();
|
SD_API int32_t sd_get_num_physical_cores();
|
||||||
SD_API const char* sd_get_system_info();
|
SD_API const char* sd_get_system_info();
|
||||||
|
|||||||
+19
-6
@@ -360,12 +360,13 @@ int32_t sd_get_num_physical_cores() {
|
|||||||
static sd_progress_cb_t sd_progress_cb = nullptr;
|
static sd_progress_cb_t sd_progress_cb = nullptr;
|
||||||
void* sd_progress_cb_data = nullptr;
|
void* sd_progress_cb_data = nullptr;
|
||||||
|
|
||||||
static sd_preview_cb_t sd_preview_cb = nullptr;
|
static sd_preview_info_t sd_preview_info = {};
|
||||||
static void* sd_preview_cb_data = nullptr;
|
static sd_preview_cb_t sd_preview_cb = nullptr;
|
||||||
preview_t sd_preview_mode = PREVIEW_NONE;
|
static void* sd_preview_cb_data = nullptr;
|
||||||
int sd_preview_interval = 1;
|
preview_t sd_preview_mode = PREVIEW_NONE;
|
||||||
bool sd_preview_denoised = true;
|
int sd_preview_interval = 1;
|
||||||
bool sd_preview_noisy = false;
|
bool sd_preview_denoised = true;
|
||||||
|
bool sd_preview_noisy = false;
|
||||||
|
|
||||||
static sd_graph_eval_callback_t sd_backend_eval_cb = nullptr;
|
static sd_graph_eval_callback_t sd_backend_eval_cb = nullptr;
|
||||||
static void* sd_backend_eval_cb_data = nullptr;
|
static void* sd_backend_eval_cb_data = nullptr;
|
||||||
@@ -696,6 +697,7 @@ void sd_set_progress_callback(sd_progress_cb_t cb, void* data) {
|
|||||||
sd_progress_cb_data = data;
|
sd_progress_cb_data = data;
|
||||||
}
|
}
|
||||||
void sd_set_preview_callback(sd_preview_cb_t cb, preview_t mode, int interval, bool denoised, bool noisy, void* data) {
|
void sd_set_preview_callback(sd_preview_cb_t cb, preview_t mode, int interval, bool denoised, bool noisy, void* data) {
|
||||||
|
sd_preview_info = {};
|
||||||
sd_preview_cb = cb;
|
sd_preview_cb = cb;
|
||||||
sd_preview_cb_data = data;
|
sd_preview_cb_data = data;
|
||||||
sd_preview_mode = mode;
|
sd_preview_mode = mode;
|
||||||
@@ -709,6 +711,17 @@ void sd_set_backend_eval_callback(sd_graph_eval_callback_t cb, void* data) {
|
|||||||
sd_backend_eval_cb_data = data;
|
sd_backend_eval_cb_data = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sd_begin_preview_pass(int total_steps) {
|
||||||
|
if (sd_preview_cb != nullptr) {
|
||||||
|
++sd_preview_info.sample_pass;
|
||||||
|
sd_preview_info.total_steps = total_steps;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sd_preview_info_t sd_get_preview_info() {
|
||||||
|
return sd_preview_info;
|
||||||
|
}
|
||||||
|
|
||||||
sd_preview_cb_t sd_get_preview_callback() {
|
sd_preview_cb_t sd_get_preview_callback() {
|
||||||
return sd_preview_cb;
|
return sd_preview_cb;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ std::vector<std::pair<std::string, float>> split_quotation_attention(
|
|||||||
sd_progress_cb_t sd_get_progress_callback();
|
sd_progress_cb_t sd_get_progress_callback();
|
||||||
void* sd_get_progress_callback_data();
|
void* sd_get_progress_callback_data();
|
||||||
|
|
||||||
|
void sd_begin_preview_pass(int total_steps);
|
||||||
sd_preview_cb_t sd_get_preview_callback();
|
sd_preview_cb_t sd_get_preview_callback();
|
||||||
void* sd_get_preview_callback_data();
|
void* sd_get_preview_callback_data();
|
||||||
preview_t sd_get_preview_mode();
|
preview_t sd_get_preview_mode();
|
||||||
|
|||||||
@@ -2373,7 +2373,8 @@ sd::Tensor<float> StableDiffusionGGML::sample(const std::shared_ptr<DiffusionMod
|
|||||||
noise *= eta;
|
noise *= eta;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t last_progress_us = ggml_time_us();
|
int64_t last_progress_us = ggml_time_us();
|
||||||
|
sd_begin_preview_pass(static_cast<int>(steps));
|
||||||
SamplePreviewContext preview = prepare_sample_preview_context();
|
SamplePreviewContext preview = prepare_sample_preview_context();
|
||||||
|
|
||||||
sd::Tensor<float> processed_init_latent = denoiser->process_latent_in(init_latent);
|
sd::Tensor<float> processed_init_latent = denoiser->process_latent_in(init_latent);
|
||||||
|
|||||||
Reference in new issue
Block a user