mirror of
https://github.com/leejet/stable-diffusion.cpp.git
synced 2026-05-13 18:59:41 +00:00
Compare commits
No commits in common. "09b12d5f6d51d862749e8e0ee8baac8f012089e2" and "1d6cb0f8c33ddadf1bff8aff40ec2e5b1ccb4940" have entirely different histories.
09b12d5f6d
...
1d6cb0f8c3
14
.github/workflows/build.yml
vendored
14
.github/workflows/build.yml
vendored
@ -64,7 +64,7 @@ jobs:
|
|||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@v4
|
uses: pnpm/action-setup@v4
|
||||||
with:
|
with:
|
||||||
version: 10.15.1
|
version: 9
|
||||||
|
|
||||||
- name: Dependencies
|
- name: Dependencies
|
||||||
id: depends
|
id: depends
|
||||||
@ -127,7 +127,7 @@ jobs:
|
|||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@v4
|
uses: pnpm/action-setup@v4
|
||||||
with:
|
with:
|
||||||
version: 10.15.1
|
version: 9
|
||||||
|
|
||||||
- name: Dependencies
|
- name: Dependencies
|
||||||
id: depends
|
id: depends
|
||||||
@ -205,7 +205,7 @@ jobs:
|
|||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@v4
|
uses: pnpm/action-setup@v4
|
||||||
with:
|
with:
|
||||||
version: 10.15.1
|
version: 9
|
||||||
|
|
||||||
- name: Get commit hash
|
- name: Get commit hash
|
||||||
id: commit
|
id: commit
|
||||||
@ -264,7 +264,7 @@ jobs:
|
|||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@v4
|
uses: pnpm/action-setup@v4
|
||||||
with:
|
with:
|
||||||
version: 10.15.1
|
version: 9
|
||||||
|
|
||||||
- name: Dependencies
|
- name: Dependencies
|
||||||
id: depends
|
id: depends
|
||||||
@ -345,7 +345,7 @@ jobs:
|
|||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@v4
|
uses: pnpm/action-setup@v4
|
||||||
with:
|
with:
|
||||||
version: 10.15.1
|
version: 9
|
||||||
|
|
||||||
- name: Install cuda-toolkit
|
- name: Install cuda-toolkit
|
||||||
id: cuda-toolkit
|
id: cuda-toolkit
|
||||||
@ -460,7 +460,7 @@ jobs:
|
|||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@v4
|
uses: pnpm/action-setup@v4
|
||||||
with:
|
with:
|
||||||
version: 10.15.1
|
version: 9
|
||||||
|
|
||||||
- name: Cache ROCm Installation
|
- name: Cache ROCm Installation
|
||||||
id: cache-rocm
|
id: cache-rocm
|
||||||
@ -573,7 +573,7 @@ jobs:
|
|||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@v4
|
uses: pnpm/action-setup@v4
|
||||||
with:
|
with:
|
||||||
version: 10.15.1
|
version: 9
|
||||||
|
|
||||||
- name: Free disk space
|
- name: Free disk space
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@ -1,9 +1,6 @@
|
|||||||
set(TARGET sd-cli)
|
set(TARGET sd-cli)
|
||||||
|
|
||||||
add_executable(${TARGET}
|
add_executable(${TARGET} main.cpp)
|
||||||
image_metadata.cpp
|
|
||||||
main.cpp
|
|
||||||
)
|
|
||||||
install(TARGETS ${TARGET} RUNTIME)
|
install(TARGETS ${TARGET} RUNTIME)
|
||||||
target_link_libraries(${TARGET} PRIVATE stable-diffusion zip ${CMAKE_THREAD_LIBS_INIT})
|
target_link_libraries(${TARGET} PRIVATE stable-diffusion ${CMAKE_THREAD_LIBS_INIT})
|
||||||
target_compile_features(${TARGET} PUBLIC c_std_11 cxx_std_17)
|
target_compile_features(${TARGET} PUBLIC c_std_11 cxx_std_17)
|
||||||
@ -10,18 +10,13 @@ CLI Options:
|
|||||||
--preview-interval <int> interval in denoising steps between consecutive updates of the image preview file (default is 1, meaning updating at
|
--preview-interval <int> interval in denoising steps between consecutive updates of the image preview file (default is 1, meaning updating at
|
||||||
every step)
|
every step)
|
||||||
--output-begin-idx <int> starting index for output image sequence, must be non-negative (default 0 if specified %d in output path, 1 otherwise)
|
--output-begin-idx <int> starting index for output image sequence, must be non-negative (default 0 if specified %d in output path, 1 otherwise)
|
||||||
--image <string> path to the image to inspect (for metadata mode)
|
|
||||||
--metadata-format <string> metadata output format, one of [text, json] (default: text)
|
|
||||||
--canny apply canny preprocessor (edge detection)
|
--canny apply canny preprocessor (edge detection)
|
||||||
--convert-name convert tensor name (for convert mode)
|
--convert-name convert tensor name (for convert mode)
|
||||||
-v, --verbose print extra info
|
-v, --verbose print extra info
|
||||||
--color colors the logging tags according to level
|
--color colors the logging tags according to level
|
||||||
--taesd-preview-only prevents usage of taesd for decoding the final image. (for use with --preview tae)
|
--taesd-preview-only prevents usage of taesd for decoding the final image. (for use with --preview tae)
|
||||||
--preview-noisy enables previewing noisy inputs of the models rather than the denoised outputs
|
--preview-noisy enables previewing noisy inputs of the models rather than the denoised outputs
|
||||||
--metadata-raw include raw hex previews for unparsed metadata payloads
|
-M, --mode run mode, one of [img_gen, vid_gen, upscale, convert], default: img_gen
|
||||||
--metadata-brief truncate long metadata text values in text output
|
|
||||||
--metadata-all include structural/container entries such as IHDR, IDAT, and non-metadata JPEG segments
|
|
||||||
-M, --mode run mode, one of [img_gen, vid_gen, upscale, convert, metadata], default: img_gen
|
|
||||||
--preview preview method. must be one of the following [none, proj, tae, vae] (default is none)
|
--preview preview method. must be one of the following [none, proj, tae, vae] (default is none)
|
||||||
-h, --help show this help message and exit
|
-h, --help show this help message and exit
|
||||||
|
|
||||||
@ -130,7 +125,6 @@ Generation Options:
|
|||||||
--vace-strength <float> wan vace strength
|
--vace-strength <float> wan vace strength
|
||||||
--increase-ref-index automatically increase the indices of references images based on the order they are listed (starting with 1).
|
--increase-ref-index automatically increase the indices of references images based on the order they are listed (starting with 1).
|
||||||
--disable-auto-resize-ref-image disable auto resize of ref images
|
--disable-auto-resize-ref-image disable auto resize of ref images
|
||||||
--disable-image-metadata do not embed generation metadata on image files
|
|
||||||
-s, --seed RNG seed (default: 42, use random seed for < 0)
|
-s, --seed RNG seed (default: 42, use random seed for < 0)
|
||||||
--sampling-method sampling method, one of [euler, euler_a, heun, dpm2, dpm++2s_a, dpm++2m, dpm++2mv2, ipndm, ipndm_v, lcm, ddim_trailing,
|
--sampling-method sampling method, one of [euler, euler_a, heun, dpm2, dpm++2s_a, dpm++2m, dpm++2mv2, ipndm, ipndm_v, lcm, ddim_trailing,
|
||||||
tcd, res_multistep, res_2s] (default: euler for Flux/SD3/Wan, euler_a
|
tcd, res_multistep, res_2s] (default: euler for Flux/SD3/Wan, euler_a
|
||||||
@ -153,12 +147,3 @@ Generation Options:
|
|||||||
--scm-mask SCM steps mask for cache-dit: comma-separated 0/1 (e.g., "1,1,1,0,0,1,0,0,1,0") - 1=compute, 0=can cache
|
--scm-mask SCM steps mask for cache-dit: comma-separated 0/1 (e.g., "1,1,1,0,0,1,0,0,1,0") - 1=compute, 0=can cache
|
||||||
--scm-policy SCM policy: 'dynamic' (default) or 'static'
|
--scm-policy SCM policy: 'dynamic' (default) or 'static'
|
||||||
```
|
```
|
||||||
|
|
||||||
Metadata mode inspects PNG/JPEG container metadata without loading any model:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./bin/sd-cli -M metadata --image ./output.png
|
|
||||||
./bin/sd-cli -M metadata --image ./output.jpg --metadata-format json
|
|
||||||
./bin/sd-cli -M metadata --image ./output.png --metadata-raw
|
|
||||||
./bin/sd-cli -M metadata --image ./output.png --metadata-all
|
|
||||||
```
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -1,21 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <iosfwd>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
enum class MetadataOutputFormat {
|
|
||||||
TEXT,
|
|
||||||
JSON,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct MetadataReadOptions {
|
|
||||||
MetadataOutputFormat output_format = MetadataOutputFormat::TEXT;
|
|
||||||
bool include_raw = false;
|
|
||||||
bool brief = false;
|
|
||||||
bool include_structural = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool print_image_metadata(const std::string& image_path,
|
|
||||||
const MetadataReadOptions& options,
|
|
||||||
std::ostream& out,
|
|
||||||
std::string& error);
|
|
||||||
@ -18,7 +18,6 @@
|
|||||||
#include "common/common.hpp"
|
#include "common/common.hpp"
|
||||||
|
|
||||||
#include "avi_writer.h"
|
#include "avi_writer.h"
|
||||||
#include "image_metadata.h"
|
|
||||||
|
|
||||||
const char* previews_str[] = {
|
const char* previews_str[] = {
|
||||||
"none",
|
"none",
|
||||||
@ -33,8 +32,6 @@ struct SDCliParams {
|
|||||||
SDMode mode = IMG_GEN;
|
SDMode mode = IMG_GEN;
|
||||||
std::string output_path = "output.png";
|
std::string output_path = "output.png";
|
||||||
int output_begin_idx = -1;
|
int output_begin_idx = -1;
|
||||||
std::string image_path;
|
|
||||||
std::string metadata_format = "text";
|
|
||||||
|
|
||||||
bool verbose = false;
|
bool verbose = false;
|
||||||
bool canny_preprocess = false;
|
bool canny_preprocess = false;
|
||||||
@ -47,9 +44,6 @@ struct SDCliParams {
|
|||||||
bool taesd_preview = false;
|
bool taesd_preview = false;
|
||||||
bool preview_noisy = false;
|
bool preview_noisy = false;
|
||||||
bool color = false;
|
bool color = false;
|
||||||
bool metadata_raw = false;
|
|
||||||
bool metadata_brief = false;
|
|
||||||
bool metadata_all = false;
|
|
||||||
|
|
||||||
bool normal_exit = false;
|
bool normal_exit = false;
|
||||||
|
|
||||||
@ -61,14 +55,6 @@ struct SDCliParams {
|
|||||||
"--output",
|
"--output",
|
||||||
"path to write result image to. you can use printf-style %d format specifiers for image sequences (default: ./output.png) (eg. output_%03d.png)",
|
"path to write result image to. you can use printf-style %d format specifiers for image sequences (default: ./output.png) (eg. output_%03d.png)",
|
||||||
&output_path},
|
&output_path},
|
||||||
{"",
|
|
||||||
"--image",
|
|
||||||
"path to the image to inspect (for metadata mode)",
|
|
||||||
&image_path},
|
|
||||||
{"",
|
|
||||||
"--metadata-format",
|
|
||||||
"metadata output format, one of [text, json] (default: text)",
|
|
||||||
&metadata_format},
|
|
||||||
{"",
|
{"",
|
||||||
"--preview-path",
|
"--preview-path",
|
||||||
"path to write preview image to (default: ./preview.png)",
|
"path to write preview image to (default: ./preview.png)",
|
||||||
@ -111,18 +97,6 @@ struct SDCliParams {
|
|||||||
"--preview-noisy",
|
"--preview-noisy",
|
||||||
"enables previewing noisy inputs of the models rather than the denoised outputs",
|
"enables previewing noisy inputs of the models rather than the denoised outputs",
|
||||||
true, &preview_noisy},
|
true, &preview_noisy},
|
||||||
{"",
|
|
||||||
"--metadata-raw",
|
|
||||||
"include raw hex previews for unparsed metadata payloads",
|
|
||||||
true, &metadata_raw},
|
|
||||||
{"",
|
|
||||||
"--metadata-brief",
|
|
||||||
"truncate long metadata text values in text output",
|
|
||||||
true, &metadata_brief},
|
|
||||||
{"",
|
|
||||||
"--metadata-all",
|
|
||||||
"include structural/container entries such as IHDR, IDAT, and non-metadata JPEG segments",
|
|
||||||
true, &metadata_all},
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -175,7 +149,7 @@ struct SDCliParams {
|
|||||||
options.manual_options = {
|
options.manual_options = {
|
||||||
{"-M",
|
{"-M",
|
||||||
"--mode",
|
"--mode",
|
||||||
"run mode, one of [img_gen, vid_gen, upscale, convert, metadata], default: img_gen",
|
"run mode, one of [img_gen, vid_gen, upscale, convert], default: img_gen",
|
||||||
on_mode_arg},
|
on_mode_arg},
|
||||||
{"",
|
{"",
|
||||||
"--preview",
|
"--preview",
|
||||||
@ -191,7 +165,7 @@ struct SDCliParams {
|
|||||||
};
|
};
|
||||||
|
|
||||||
bool process_and_check() {
|
bool process_and_check() {
|
||||||
if (mode != METADATA && output_path.length() == 0) {
|
if (output_path.length() == 0) {
|
||||||
LOG_ERROR("error: the following arguments are required: output_path");
|
LOG_ERROR("error: the following arguments are required: output_path");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -200,16 +174,6 @@ struct SDCliParams {
|
|||||||
if (output_path == "output.png") {
|
if (output_path == "output.png") {
|
||||||
output_path = "output.gguf";
|
output_path = "output.gguf";
|
||||||
}
|
}
|
||||||
} else if (mode == METADATA) {
|
|
||||||
if (image_path.empty()) {
|
|
||||||
LOG_ERROR("error: metadata mode needs an image path (--image)");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (metadata_format != "text" && metadata_format != "json") {
|
|
||||||
LOG_ERROR("error: invalid metadata format %s, must be one of [text, json]",
|
|
||||||
metadata_format.c_str());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -219,8 +183,6 @@ struct SDCliParams {
|
|||||||
oss << "SDCliParams {\n"
|
oss << "SDCliParams {\n"
|
||||||
<< " mode: " << modes_str[mode] << ",\n"
|
<< " mode: " << modes_str[mode] << ",\n"
|
||||||
<< " output_path: \"" << output_path << "\",\n"
|
<< " output_path: \"" << output_path << "\",\n"
|
||||||
<< " image_path: \"" << image_path << "\",\n"
|
|
||||||
<< " metadata_format: \"" << metadata_format << "\",\n"
|
|
||||||
<< " verbose: " << (verbose ? "true" : "false") << ",\n"
|
<< " verbose: " << (verbose ? "true" : "false") << ",\n"
|
||||||
<< " color: " << (color ? "true" : "false") << ",\n"
|
<< " color: " << (color ? "true" : "false") << ",\n"
|
||||||
<< " canny_preprocess: " << (canny_preprocess ? "true" : "false") << ",\n"
|
<< " canny_preprocess: " << (canny_preprocess ? "true" : "false") << ",\n"
|
||||||
@ -230,10 +192,7 @@ struct SDCliParams {
|
|||||||
<< " preview_path: \"" << preview_path << "\",\n"
|
<< " preview_path: \"" << preview_path << "\",\n"
|
||||||
<< " preview_fps: " << preview_fps << ",\n"
|
<< " preview_fps: " << preview_fps << ",\n"
|
||||||
<< " taesd_preview: " << (taesd_preview ? "true" : "false") << ",\n"
|
<< " taesd_preview: " << (taesd_preview ? "true" : "false") << ",\n"
|
||||||
<< " preview_noisy: " << (preview_noisy ? "true" : "false") << ",\n"
|
<< " preview_noisy: " << (preview_noisy ? "true" : "false") << "\n"
|
||||||
<< " metadata_raw: " << (metadata_raw ? "true" : "false") << ",\n"
|
|
||||||
<< " metadata_brief: " << (metadata_brief ? "true" : "false") << ",\n"
|
|
||||||
<< " metadata_all: " << (metadata_all ? "true" : "false") << "\n"
|
|
||||||
<< "}";
|
<< "}";
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
@ -258,18 +217,71 @@ void parse_args(int argc, const char** argv, SDCliParams& cli_params, SDContextP
|
|||||||
exit(cli_params.normal_exit ? 0 : 1);
|
exit(cli_params.normal_exit ? 0 : 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool valid = cli_params.process_and_check();
|
if (!cli_params.process_and_check() ||
|
||||||
if (valid && cli_params.mode != METADATA) {
|
!ctx_params.process_and_check(cli_params.mode) ||
|
||||||
valid = ctx_params.process_and_check(cli_params.mode) &&
|
!gen_params.process_and_check(cli_params.mode, ctx_params.lora_model_dir)) {
|
||||||
gen_params.process_and_check(cli_params.mode, ctx_params.lora_model_dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!valid) {
|
|
||||||
print_usage(argc, argv, options_vec);
|
print_usage(argc, argv, options_vec);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string get_image_params(const SDCliParams& cli_params, const SDContextParams& ctx_params, const SDGenerationParams& gen_params, int64_t seed) {
|
||||||
|
std::string parameter_string = gen_params.prompt_with_lora + "\n";
|
||||||
|
if (gen_params.negative_prompt.size() != 0) {
|
||||||
|
parameter_string += "Negative prompt: " + gen_params.negative_prompt + "\n";
|
||||||
|
}
|
||||||
|
parameter_string += "Steps: " + std::to_string(gen_params.sample_params.sample_steps) + ", ";
|
||||||
|
parameter_string += "CFG scale: " + std::to_string(gen_params.sample_params.guidance.txt_cfg) + ", ";
|
||||||
|
if (gen_params.sample_params.guidance.slg.scale != 0 && gen_params.skip_layers.size() != 0) {
|
||||||
|
parameter_string += "SLG scale: " + std::to_string(gen_params.sample_params.guidance.txt_cfg) + ", ";
|
||||||
|
parameter_string += "Skip layers: [";
|
||||||
|
for (const auto& layer : gen_params.skip_layers) {
|
||||||
|
parameter_string += std::to_string(layer) + ", ";
|
||||||
|
}
|
||||||
|
parameter_string += "], ";
|
||||||
|
parameter_string += "Skip layer start: " + std::to_string(gen_params.sample_params.guidance.slg.layer_start) + ", ";
|
||||||
|
parameter_string += "Skip layer end: " + std::to_string(gen_params.sample_params.guidance.slg.layer_end) + ", ";
|
||||||
|
}
|
||||||
|
parameter_string += "Guidance: " + std::to_string(gen_params.sample_params.guidance.distilled_guidance) + ", ";
|
||||||
|
parameter_string += "Eta: " + std::to_string(gen_params.sample_params.eta) + ", ";
|
||||||
|
parameter_string += "Seed: " + std::to_string(seed) + ", ";
|
||||||
|
parameter_string += "Size: " + std::to_string(gen_params.get_resolved_width()) + "x" + std::to_string(gen_params.get_resolved_height()) + ", ";
|
||||||
|
parameter_string += "Model: " + sd_basename(ctx_params.model_path) + ", ";
|
||||||
|
parameter_string += "RNG: " + std::string(sd_rng_type_name(ctx_params.rng_type)) + ", ";
|
||||||
|
if (ctx_params.sampler_rng_type != RNG_TYPE_COUNT) {
|
||||||
|
parameter_string += "Sampler RNG: " + std::string(sd_rng_type_name(ctx_params.sampler_rng_type)) + ", ";
|
||||||
|
}
|
||||||
|
parameter_string += "Sampler: " + std::string(sd_sample_method_name(gen_params.sample_params.sample_method));
|
||||||
|
if (!gen_params.custom_sigmas.empty()) {
|
||||||
|
parameter_string += ", Custom Sigmas: [";
|
||||||
|
for (size_t i = 0; i < gen_params.custom_sigmas.size(); ++i) {
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << std::fixed << std::setprecision(4) << gen_params.custom_sigmas[i];
|
||||||
|
parameter_string += oss.str() + (i == gen_params.custom_sigmas.size() - 1 ? "" : ", ");
|
||||||
|
}
|
||||||
|
parameter_string += "]";
|
||||||
|
} else if (gen_params.sample_params.scheduler != SCHEDULER_COUNT) { // Only show schedule if not using custom sigmas
|
||||||
|
parameter_string += " " + std::string(sd_scheduler_name(gen_params.sample_params.scheduler));
|
||||||
|
}
|
||||||
|
parameter_string += ", ";
|
||||||
|
for (const auto& te : {ctx_params.clip_l_path, ctx_params.clip_g_path, ctx_params.t5xxl_path, ctx_params.llm_path, ctx_params.llm_vision_path}) {
|
||||||
|
if (!te.empty()) {
|
||||||
|
parameter_string += "TE: " + sd_basename(te) + ", ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!ctx_params.diffusion_model_path.empty()) {
|
||||||
|
parameter_string += "Unet: " + sd_basename(ctx_params.diffusion_model_path) + ", ";
|
||||||
|
}
|
||||||
|
if (!ctx_params.vae_path.empty()) {
|
||||||
|
parameter_string += "VAE: " + sd_basename(ctx_params.vae_path) + ", ";
|
||||||
|
}
|
||||||
|
if (gen_params.clip_skip != -1) {
|
||||||
|
parameter_string += "Clip skip: " + std::to_string(gen_params.clip_skip) + ", ";
|
||||||
|
}
|
||||||
|
parameter_string += "Version: stable-diffusion.cpp";
|
||||||
|
return parameter_string;
|
||||||
|
}
|
||||||
|
|
||||||
void sd_log_cb(enum sd_log_level_t level, const char* log, void* data) {
|
void sd_log_cb(enum sd_log_level_t level, const char* log, void* data) {
|
||||||
SDCliParams* cli_params = (SDCliParams*)data;
|
SDCliParams* cli_params = (SDCliParams*)data;
|
||||||
log_print(level, log, cli_params->verbose, cli_params->color);
|
log_print(level, log, cli_params->verbose, cli_params->color);
|
||||||
@ -402,14 +414,12 @@ bool save_results(const SDCliParams& cli_params,
|
|||||||
if (!img.data)
|
if (!img.data)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
std::string params = gen_params.embed_image_metadata
|
std::string params = get_image_params(cli_params, ctx_params, gen_params, gen_params.seed + idx);
|
||||||
? get_image_params(ctx_params, gen_params, gen_params.seed + idx)
|
|
||||||
: "";
|
|
||||||
int ok = 0;
|
int ok = 0;
|
||||||
if (is_jpg) {
|
if (is_jpg) {
|
||||||
ok = stbi_write_jpg(path.string().c_str(), img.width, img.height, img.channel, img.data, 90, params.size() > 0 ? params.c_str() : nullptr);
|
ok = stbi_write_jpg(path.string().c_str(), img.width, img.height, img.channel, img.data, 90, params.c_str());
|
||||||
} else {
|
} else {
|
||||||
ok = stbi_write_png(path.string().c_str(), img.width, img.height, img.channel, img.data, 0, params.size() > 0 ? params.c_str() : nullptr);
|
ok = stbi_write_png(path.string().c_str(), img.width, img.height, img.channel, img.data, 0, params.c_str());
|
||||||
}
|
}
|
||||||
LOG_INFO("save result image %d to '%s' (%s)", idx, path.string().c_str(), ok ? "success" : "failure");
|
LOG_INFO("save result image %d to '%s' (%s)", idx, path.string().c_str(), ok ? "success" : "failure");
|
||||||
return ok != 0;
|
return ok != 0;
|
||||||
@ -475,27 +485,6 @@ int main(int argc, const char* argv[]) {
|
|||||||
SDGenerationParams gen_params;
|
SDGenerationParams gen_params;
|
||||||
|
|
||||||
parse_args(argc, argv, cli_params, ctx_params, gen_params);
|
parse_args(argc, argv, cli_params, ctx_params, gen_params);
|
||||||
sd_set_log_callback(sd_log_cb, (void*)&cli_params);
|
|
||||||
log_verbose = cli_params.verbose;
|
|
||||||
log_color = cli_params.color;
|
|
||||||
|
|
||||||
if (cli_params.mode == METADATA) {
|
|
||||||
MetadataReadOptions options;
|
|
||||||
options.output_format = cli_params.metadata_format == "json"
|
|
||||||
? MetadataOutputFormat::JSON
|
|
||||||
: MetadataOutputFormat::TEXT;
|
|
||||||
options.include_raw = cli_params.metadata_raw;
|
|
||||||
options.brief = cli_params.metadata_brief;
|
|
||||||
options.include_structural = cli_params.metadata_all;
|
|
||||||
|
|
||||||
std::string error;
|
|
||||||
if (!print_image_metadata(cli_params.image_path, options, std::cout, error)) {
|
|
||||||
LOG_ERROR("%s", error.c_str());
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gen_params.video_frames > 4) {
|
if (gen_params.video_frames > 4) {
|
||||||
size_t last_dot_pos = cli_params.preview_path.find_last_of(".");
|
size_t last_dot_pos = cli_params.preview_path.find_last_of(".");
|
||||||
std::string base_path = cli_params.preview_path;
|
std::string base_path = cli_params.preview_path;
|
||||||
@ -513,6 +502,9 @@ int main(int argc, const char* argv[]) {
|
|||||||
if (cli_params.preview_method == PREVIEW_PROJ)
|
if (cli_params.preview_method == PREVIEW_PROJ)
|
||||||
cli_params.preview_fps /= 4;
|
cli_params.preview_fps /= 4;
|
||||||
|
|
||||||
|
sd_set_log_callback(sd_log_cb, (void*)&cli_params);
|
||||||
|
log_verbose = cli_params.verbose;
|
||||||
|
log_color = cli_params.color;
|
||||||
sd_set_preview_callback(step_callback,
|
sd_set_preview_callback(step_callback,
|
||||||
cli_params.preview_method,
|
cli_params.preview_method,
|
||||||
cli_params.preview_interval,
|
cli_params.preview_interval,
|
||||||
|
|||||||
@ -39,16 +39,14 @@ const char* modes_str[] = {
|
|||||||
"vid_gen",
|
"vid_gen",
|
||||||
"convert",
|
"convert",
|
||||||
"upscale",
|
"upscale",
|
||||||
"metadata",
|
|
||||||
};
|
};
|
||||||
#define SD_ALL_MODES_STR "img_gen, vid_gen, convert, upscale, metadata"
|
#define SD_ALL_MODES_STR "img_gen, vid_gen, convert, upscale"
|
||||||
|
|
||||||
enum SDMode {
|
enum SDMode {
|
||||||
IMG_GEN,
|
IMG_GEN,
|
||||||
VID_GEN,
|
VID_GEN,
|
||||||
CONVERT,
|
CONVERT,
|
||||||
UPSCALE,
|
UPSCALE,
|
||||||
METADATA,
|
|
||||||
MODE_COUNT
|
MODE_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -779,7 +777,7 @@ struct SDContextParams {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool process_and_check(SDMode mode) {
|
bool process_and_check(SDMode mode) {
|
||||||
if (mode != UPSCALE && mode != METADATA && model_path.length() == 0 && diffusion_model_path.length() == 0) {
|
if (mode != UPSCALE && model_path.length() == 0 && diffusion_model_path.length() == 0) {
|
||||||
LOG_ERROR("error: the following arguments are required: model_path/diffusion_model\n");
|
LOG_ERROR("error: the following arguments are required: model_path/diffusion_model\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -967,7 +965,6 @@ struct SDGenerationParams {
|
|||||||
std::string control_video_path;
|
std::string control_video_path;
|
||||||
bool auto_resize_ref_image = true;
|
bool auto_resize_ref_image = true;
|
||||||
bool increase_ref_index = false;
|
bool increase_ref_index = false;
|
||||||
bool embed_image_metadata = true;
|
|
||||||
|
|
||||||
std::vector<int> skip_layers = {7, 8, 9};
|
std::vector<int> skip_layers = {7, 8, 9};
|
||||||
sd_sample_params_t sample_params;
|
sd_sample_params_t sample_params;
|
||||||
@ -1202,16 +1199,10 @@ struct SDGenerationParams {
|
|||||||
"disable auto resize of ref images",
|
"disable auto resize of ref images",
|
||||||
false,
|
false,
|
||||||
&auto_resize_ref_image},
|
&auto_resize_ref_image},
|
||||||
{"",
|
|
||||||
"--disable-image-metadata",
|
|
||||||
"do not embed generation metadata on image files",
|
|
||||||
false,
|
|
||||||
&embed_image_metadata},
|
|
||||||
{"",
|
{"",
|
||||||
"--vae-tiling",
|
"--vae-tiling",
|
||||||
"process vae in tiles to reduce memory usage",
|
"process vae in tiles to reduce memory usage",
|
||||||
true,
|
true, &vae_tiling_params.enabled},
|
||||||
&vae_tiling_params.enabled},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
auto on_seed_arg = [&](int argc, const char** argv, int index) {
|
auto on_seed_arg = [&](int argc, const char** argv, int index) {
|
||||||
@ -1576,7 +1567,6 @@ struct SDGenerationParams {
|
|||||||
|
|
||||||
load_if_exists("auto_resize_ref_image", auto_resize_ref_image);
|
load_if_exists("auto_resize_ref_image", auto_resize_ref_image);
|
||||||
load_if_exists("increase_ref_index", increase_ref_index);
|
load_if_exists("increase_ref_index", increase_ref_index);
|
||||||
load_if_exists("embed_image_metadata", embed_image_metadata);
|
|
||||||
|
|
||||||
load_if_exists("skip_layers", skip_layers);
|
load_if_exists("skip_layers", skip_layers);
|
||||||
load_if_exists("high_noise_skip_layers", high_noise_skip_layers);
|
load_if_exists("high_noise_skip_layers", high_noise_skip_layers);
|
||||||
@ -2104,65 +2094,3 @@ uint8_t* load_image_from_memory(const char* image_bytes,
|
|||||||
int expected_channel = 3) {
|
int expected_channel = 3) {
|
||||||
return load_image_common(true, image_bytes, len, width, height, expected_width, expected_height, expected_channel);
|
return load_image_common(true, image_bytes, len, width, height, expected_width, expected_height, expected_channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string get_image_params(const SDContextParams& ctx_params, const SDGenerationParams& gen_params, int64_t seed) {
|
|
||||||
std::string parameter_string;
|
|
||||||
if (gen_params.prompt_with_lora.size() != 0) {
|
|
||||||
parameter_string += gen_params.prompt_with_lora + "\n";
|
|
||||||
} else {
|
|
||||||
parameter_string += gen_params.prompt + "\n";
|
|
||||||
}
|
|
||||||
if (gen_params.negative_prompt.size() != 0) {
|
|
||||||
parameter_string += "Negative prompt: " + gen_params.negative_prompt + "\n";
|
|
||||||
}
|
|
||||||
parameter_string += "Steps: " + std::to_string(gen_params.sample_params.sample_steps) + ", ";
|
|
||||||
parameter_string += "CFG scale: " + std::to_string(gen_params.sample_params.guidance.txt_cfg) + ", ";
|
|
||||||
if (gen_params.sample_params.guidance.slg.scale != 0 && gen_params.skip_layers.size() != 0) {
|
|
||||||
parameter_string += "SLG scale: " + std::to_string(gen_params.sample_params.guidance.txt_cfg) + ", ";
|
|
||||||
parameter_string += "Skip layers: [";
|
|
||||||
for (const auto& layer : gen_params.skip_layers) {
|
|
||||||
parameter_string += std::to_string(layer) + ", ";
|
|
||||||
}
|
|
||||||
parameter_string += "], ";
|
|
||||||
parameter_string += "Skip layer start: " + std::to_string(gen_params.sample_params.guidance.slg.layer_start) + ", ";
|
|
||||||
parameter_string += "Skip layer end: " + std::to_string(gen_params.sample_params.guidance.slg.layer_end) + ", ";
|
|
||||||
}
|
|
||||||
parameter_string += "Guidance: " + std::to_string(gen_params.sample_params.guidance.distilled_guidance) + ", ";
|
|
||||||
parameter_string += "Eta: " + std::to_string(gen_params.sample_params.eta) + ", ";
|
|
||||||
parameter_string += "Seed: " + std::to_string(seed) + ", ";
|
|
||||||
parameter_string += "Size: " + std::to_string(gen_params.get_resolved_width()) + "x" + std::to_string(gen_params.get_resolved_height()) + ", ";
|
|
||||||
parameter_string += "Model: " + sd_basename(ctx_params.model_path) + ", ";
|
|
||||||
parameter_string += "RNG: " + std::string(sd_rng_type_name(ctx_params.rng_type)) + ", ";
|
|
||||||
if (ctx_params.sampler_rng_type != RNG_TYPE_COUNT) {
|
|
||||||
parameter_string += "Sampler RNG: " + std::string(sd_rng_type_name(ctx_params.sampler_rng_type)) + ", ";
|
|
||||||
}
|
|
||||||
parameter_string += "Sampler: " + std::string(sd_sample_method_name(gen_params.sample_params.sample_method));
|
|
||||||
if (!gen_params.custom_sigmas.empty()) {
|
|
||||||
parameter_string += ", Custom Sigmas: [";
|
|
||||||
for (size_t i = 0; i < gen_params.custom_sigmas.size(); ++i) {
|
|
||||||
std::ostringstream oss;
|
|
||||||
oss << std::fixed << std::setprecision(4) << gen_params.custom_sigmas[i];
|
|
||||||
parameter_string += oss.str() + (i == gen_params.custom_sigmas.size() - 1 ? "" : ", ");
|
|
||||||
}
|
|
||||||
parameter_string += "]";
|
|
||||||
} else if (gen_params.sample_params.scheduler != SCHEDULER_COUNT) { // Only show schedule if not using custom sigmas
|
|
||||||
parameter_string += " " + std::string(sd_scheduler_name(gen_params.sample_params.scheduler));
|
|
||||||
}
|
|
||||||
parameter_string += ", ";
|
|
||||||
for (const auto& te : {ctx_params.clip_l_path, ctx_params.clip_g_path, ctx_params.t5xxl_path, ctx_params.llm_path, ctx_params.llm_vision_path}) {
|
|
||||||
if (!te.empty()) {
|
|
||||||
parameter_string += "TE: " + sd_basename(te) + ", ";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!ctx_params.diffusion_model_path.empty()) {
|
|
||||||
parameter_string += "Unet: " + sd_basename(ctx_params.diffusion_model_path) + ", ";
|
|
||||||
}
|
|
||||||
if (!ctx_params.vae_path.empty()) {
|
|
||||||
parameter_string += "VAE: " + sd_basename(ctx_params.vae_path) + ", ";
|
|
||||||
}
|
|
||||||
if (gen_params.clip_skip != -1) {
|
|
||||||
parameter_string += "Clip skip: " + std::to_string(gen_params.clip_skip) + ", ";
|
|
||||||
}
|
|
||||||
parameter_string += "Version: stable-diffusion.cpp";
|
|
||||||
return parameter_string;
|
|
||||||
}
|
|
||||||
|
|||||||
@ -70,10 +70,4 @@ endif()
|
|||||||
|
|
||||||
install(TARGETS ${TARGET} RUNTIME)
|
install(TARGETS ${TARGET} RUNTIME)
|
||||||
target_link_libraries(${TARGET} PRIVATE stable-diffusion ${CMAKE_THREAD_LIBS_INIT})
|
target_link_libraries(${TARGET} PRIVATE stable-diffusion ${CMAKE_THREAD_LIBS_INIT})
|
||||||
|
|
||||||
# due to httplib; it contains a pragma for MSVC, but other things need explicit flags
|
|
||||||
if(WIN32 AND NOT MSVC)
|
|
||||||
target_link_libraries(${TARGET} PRIVATE ws2_32)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
target_compile_features(${TARGET} PUBLIC c_std_11 cxx_std_17)
|
target_compile_features(${TARGET} PUBLIC c_std_11 cxx_std_17)
|
||||||
@ -205,7 +205,6 @@ Default Generation Options:
|
|||||||
--vace-strength <float> wan vace strength
|
--vace-strength <float> wan vace strength
|
||||||
--increase-ref-index automatically increase the indices of references images based on the order they are listed (starting with 1).
|
--increase-ref-index automatically increase the indices of references images based on the order they are listed (starting with 1).
|
||||||
--disable-auto-resize-ref-image disable auto resize of ref images
|
--disable-auto-resize-ref-image disable auto resize of ref images
|
||||||
--disable-image-metadata do not embed generation metadata on image files
|
|
||||||
-s, --seed RNG seed (default: 42, use random seed for < 0)
|
-s, --seed RNG seed (default: 42, use random seed for < 0)
|
||||||
--sampling-method sampling method, one of [euler, euler_a, heun, dpm2, dpm++2s_a, dpm++2m, dpm++2mv2, ipndm, ipndm_v, lcm, ddim_trailing,
|
--sampling-method sampling method, one of [euler, euler_a, heun, dpm2, dpm++2s_a, dpm++2m, dpm++2mv2, ipndm, ipndm_v, lcm, ddim_trailing,
|
||||||
tcd, res_multistep, res_2s] (default: euler for Flux/SD3/Wan, euler_a
|
tcd, res_multistep, res_2s] (default: euler for Flux/SD3/Wan, euler_a
|
||||||
|
|||||||
@ -220,23 +220,12 @@ std::string extract_and_remove_sd_cpp_extra_args(std::string& text) {
|
|||||||
enum class ImageFormat { JPEG,
|
enum class ImageFormat { JPEG,
|
||||||
PNG };
|
PNG };
|
||||||
|
|
||||||
static int stbi_ext_write_png_to_func(stbi_write_func* func, void* context, int x, int y, int comp, const void* data, int stride_bytes, const char* parameters) {
|
|
||||||
int len;
|
|
||||||
unsigned char* png = stbi_write_png_to_mem((const unsigned char*)data, stride_bytes, x, y, comp, &len, parameters);
|
|
||||||
if (png == NULL)
|
|
||||||
return 0;
|
|
||||||
func(context, png, len);
|
|
||||||
STBIW_FREE(png);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<uint8_t> write_image_to_vector(
|
std::vector<uint8_t> write_image_to_vector(
|
||||||
ImageFormat format,
|
ImageFormat format,
|
||||||
const uint8_t* image,
|
const uint8_t* image,
|
||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
int channels,
|
int channels,
|
||||||
std::string params = "",
|
|
||||||
int quality = 90) {
|
int quality = 90) {
|
||||||
std::vector<uint8_t> buffer;
|
std::vector<uint8_t> buffer;
|
||||||
|
|
||||||
@ -260,7 +249,7 @@ std::vector<uint8_t> write_image_to_vector(
|
|||||||
result = stbi_write_jpg_to_func(c_func, &ctx, width, height, channels, image, quality);
|
result = stbi_write_jpg_to_func(c_func, &ctx, width, height, channels, image, quality);
|
||||||
break;
|
break;
|
||||||
case ImageFormat::PNG:
|
case ImageFormat::PNG:
|
||||||
result = stbi_ext_write_png_to_func(c_func, &ctx, width, height, channels, image, width * channels, params.size() > 0 ? params.c_str() : nullptr);
|
result = stbi_write_png_to_func(c_func, &ctx, width, height, channels, image, width * channels);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw std::runtime_error("invalid image format");
|
throw std::runtime_error("invalid image format");
|
||||||
@ -508,15 +497,11 @@ void register_openai_api_endpoints(httplib::Server& svr, ServerRuntime& rt) {
|
|||||||
if (results[i].data == nullptr) {
|
if (results[i].data == nullptr) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
std::string params = gen_params.embed_image_metadata
|
|
||||||
? get_image_params(*runtime->ctx_params, gen_params, gen_params.seed + i)
|
|
||||||
: "";
|
|
||||||
auto image_bytes = write_image_to_vector(output_format == "jpeg" ? ImageFormat::JPEG : ImageFormat::PNG,
|
auto image_bytes = write_image_to_vector(output_format == "jpeg" ? ImageFormat::JPEG : ImageFormat::PNG,
|
||||||
results[i].data,
|
results[i].data,
|
||||||
results[i].width,
|
results[i].width,
|
||||||
results[i].height,
|
results[i].height,
|
||||||
results[i].channel,
|
results[i].channel,
|
||||||
params,
|
|
||||||
output_compression);
|
output_compression);
|
||||||
if (image_bytes.empty()) {
|
if (image_bytes.empty()) {
|
||||||
LOG_ERROR("write image to mem failed");
|
LOG_ERROR("write image to mem failed");
|
||||||
@ -762,15 +747,11 @@ void register_openai_api_endpoints(httplib::Server& svr, ServerRuntime& rt) {
|
|||||||
for (int i = 0; i < num_results; i++) {
|
for (int i = 0; i < num_results; i++) {
|
||||||
if (results[i].data == nullptr)
|
if (results[i].data == nullptr)
|
||||||
continue;
|
continue;
|
||||||
std::string params = gen_params.embed_image_metadata
|
|
||||||
? get_image_params(*runtime->ctx_params, gen_params, gen_params.seed + i)
|
|
||||||
: "";
|
|
||||||
auto image_bytes = write_image_to_vector(output_format == "jpeg" ? ImageFormat::JPEG : ImageFormat::PNG,
|
auto image_bytes = write_image_to_vector(output_format == "jpeg" ? ImageFormat::JPEG : ImageFormat::PNG,
|
||||||
results[i].data,
|
results[i].data,
|
||||||
results[i].width,
|
results[i].width,
|
||||||
results[i].height,
|
results[i].height,
|
||||||
results[i].channel,
|
results[i].channel,
|
||||||
params,
|
|
||||||
output_compression);
|
output_compression);
|
||||||
std::string b64 = base64_encode(image_bytes);
|
std::string b64 = base64_encode(image_bytes);
|
||||||
json item;
|
json item;
|
||||||
@ -1081,15 +1062,11 @@ void register_sdapi_endpoints(httplib::Server& svr, ServerRuntime& rt) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string params = gen_params.embed_image_metadata
|
|
||||||
? get_image_params(*runtime->ctx_params, gen_params, gen_params.seed + i)
|
|
||||||
: "";
|
|
||||||
auto image_bytes = write_image_to_vector(ImageFormat::PNG,
|
auto image_bytes = write_image_to_vector(ImageFormat::PNG,
|
||||||
results[i].data,
|
results[i].data,
|
||||||
results[i].width,
|
results[i].width,
|
||||||
results[i].height,
|
results[i].height,
|
||||||
results[i].channel,
|
results[i].channel);
|
||||||
params);
|
|
||||||
|
|
||||||
if (image_bytes.empty()) {
|
if (image_bytes.empty()) {
|
||||||
LOG_ERROR("write image to mem failed");
|
LOG_ERROR("write image to mem failed");
|
||||||
|
|||||||
@ -1311,7 +1311,6 @@ bool ModelLoader::load_tensors(on_new_tensor_cb_t on_new_tensor_cb, int n_thread
|
|||||||
std::atomic<int64_t> memcpy_time_ms(0);
|
std::atomic<int64_t> memcpy_time_ms(0);
|
||||||
std::atomic<int64_t> copy_to_backend_time_ms(0);
|
std::atomic<int64_t> copy_to_backend_time_ms(0);
|
||||||
std::atomic<int64_t> convert_time_ms(0);
|
std::atomic<int64_t> convert_time_ms(0);
|
||||||
std::atomic<uint64_t> bytes_processed(0);
|
|
||||||
|
|
||||||
int num_threads_to_use = n_threads_p > 0 ? n_threads_p : sd_get_num_physical_cores();
|
int num_threads_to_use = n_threads_p > 0 ? n_threads_p : sd_get_num_physical_cores();
|
||||||
LOG_DEBUG("using %d threads for model loading", num_threads_to_use);
|
LOG_DEBUG("using %d threads for model loading", num_threads_to_use);
|
||||||
@ -1523,8 +1522,6 @@ bool ModelLoader::load_tensors(on_new_tensor_cb_t on_new_tensor_cb, int n_thread
|
|||||||
t1 = ggml_time_ms();
|
t1 = ggml_time_ms();
|
||||||
copy_to_backend_time_ms.fetch_add(t1 - t0);
|
copy_to_backend_time_ms.fetch_add(t1 - t0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes_processed.fetch_add((uint64_t)nbytes_to_read);
|
|
||||||
}
|
}
|
||||||
if (zip != nullptr) {
|
if (zip != nullptr) {
|
||||||
zip_close(zip);
|
zip_close(zip);
|
||||||
@ -1538,11 +1535,7 @@ bool ModelLoader::load_tensors(on_new_tensor_cb_t on_new_tensor_cb, int n_thread
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
size_t curr_num = total_tensors_processed + current_idx;
|
size_t curr_num = total_tensors_processed + current_idx;
|
||||||
float elapsed_seconds = (ggml_time_ms() - t_start) / 1000.0f;
|
pretty_progress(static_cast<int>(curr_num), static_cast<int>(total_tensors_to_process), (ggml_time_ms() - t_start) / 1000.0f / (curr_num + 1e-6f));
|
||||||
pretty_bytes_progress(static_cast<int>(curr_num),
|
|
||||||
static_cast<int>(total_tensors_to_process),
|
|
||||||
bytes_processed.load(),
|
|
||||||
elapsed_seconds);
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1555,10 +1548,7 @@ bool ModelLoader::load_tensors(on_new_tensor_cb_t on_new_tensor_cb, int n_thread
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
total_tensors_processed += file_tensors.size();
|
total_tensors_processed += file_tensors.size();
|
||||||
pretty_bytes_progress(static_cast<int>(total_tensors_processed),
|
pretty_progress(static_cast<int>(total_tensors_processed), static_cast<int>(total_tensors_to_process), (ggml_time_ms() - t_start) / 1000.0f / (total_tensors_processed + 1e-6f));
|
||||||
static_cast<int>(total_tensors_to_process),
|
|
||||||
bytes_processed.load(),
|
|
||||||
(ggml_time_ms() - t_start) / 1000.0f);
|
|
||||||
if (total_tensors_processed < total_tensors_to_process) {
|
if (total_tensors_processed < total_tensors_to_process) {
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|||||||
59
src/util.cpp
59
src/util.cpp
@ -337,13 +337,17 @@ std::vector<std::string> split_string(const std::string& str, char delimiter) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string build_progress_bar(int step, int steps) {
|
void pretty_progress(int step, int steps, float time) {
|
||||||
|
if (sd_progress_cb) {
|
||||||
|
sd_progress_cb(step, steps, time, sd_progress_cb_data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (step == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
std::string progress = " |";
|
std::string progress = " |";
|
||||||
int max_progress = 50;
|
int max_progress = 50;
|
||||||
int32_t current = 0;
|
int32_t current = (int32_t)(step * 1.f * max_progress / steps);
|
||||||
if (steps > 0) {
|
|
||||||
current = (int32_t)(step * 1.f * max_progress / steps);
|
|
||||||
}
|
|
||||||
for (int i = 0; i < 50; i++) {
|
for (int i = 0; i < 50; i++) {
|
||||||
if (i > current) {
|
if (i > current) {
|
||||||
progress += " ";
|
progress += " ";
|
||||||
@ -354,57 +358,16 @@ static std::string build_progress_bar(int step, int steps) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
progress += "|";
|
progress += "|";
|
||||||
return progress;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void print_progress_line(int step, int steps, const std::string& speed_text) {
|
|
||||||
if (step == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
std::string progress = build_progress_bar(step, steps);
|
|
||||||
const char* lf = (step == steps ? "\n" : "");
|
const char* lf = (step == steps ? "\n" : "");
|
||||||
printf("\r%s %i/%i - %s\033[K%s", progress.c_str(), step, steps, speed_text.c_str(), lf);
|
|
||||||
fflush(stdout); // for linux
|
|
||||||
}
|
|
||||||
|
|
||||||
void pretty_progress(int step, int steps, float time) {
|
|
||||||
if (sd_progress_cb) {
|
|
||||||
sd_progress_cb(step, steps, time, sd_progress_cb_data);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (step == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const char* unit = "s/it";
|
const char* unit = "s/it";
|
||||||
float speed = time;
|
float speed = time;
|
||||||
if (speed < 1.0f && speed > 0.f) {
|
if (speed < 1.0f && speed > 0.f) {
|
||||||
speed = 1.0f / speed;
|
speed = 1.0f / speed;
|
||||||
unit = "it/s";
|
unit = "it/s";
|
||||||
}
|
}
|
||||||
print_progress_line(step, steps, sd_format("%.2f%s", speed, unit));
|
printf("\r%s %i/%i - %.2f%s\033[K%s", progress.c_str(), step, steps, speed, unit, lf);
|
||||||
}
|
fflush(stdout); // for linux
|
||||||
|
|
||||||
void pretty_bytes_progress(int step, int steps, uint64_t bytes_processed, float elapsed_seconds) {
|
|
||||||
if (sd_progress_cb) {
|
|
||||||
float time = elapsed_seconds / (step + 1e-6f);
|
|
||||||
sd_progress_cb(step, steps, time, sd_progress_cb_data);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (step == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
double bytes_per_second = 0.0;
|
|
||||||
if (elapsed_seconds > 0.0f) {
|
|
||||||
bytes_per_second = bytes_processed / (double)elapsed_seconds;
|
|
||||||
}
|
|
||||||
|
|
||||||
double speed_mb = bytes_per_second / (1024.0 * 1024.0);
|
|
||||||
if (speed_mb >= 1024.0) {
|
|
||||||
print_progress_line(step, steps, sd_format("%.2fGB/s", speed_mb / 1024.0));
|
|
||||||
} else {
|
|
||||||
print_progress_line(step, steps, sd_format("%.2fMB/s", speed_mb));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ltrim(const std::string& s) {
|
std::string ltrim(const std::string& s) {
|
||||||
|
|||||||
@ -64,7 +64,6 @@ protected:
|
|||||||
std::string path_join(const std::string& p1, const std::string& p2);
|
std::string path_join(const std::string& p1, const std::string& p2);
|
||||||
std::vector<std::string> split_string(const std::string& str, char delimiter);
|
std::vector<std::string> split_string(const std::string& str, char delimiter);
|
||||||
void pretty_progress(int step, int steps, float time);
|
void pretty_progress(int step, int steps, float time);
|
||||||
void pretty_bytes_progress(int step, int steps, uint64_t bytes_processed, float elapsed_seconds);
|
|
||||||
|
|
||||||
void log_printf(sd_log_level_t level, const char* file, int line, const char* format, ...);
|
void log_printf(sd_log_level_t level, const char* file, int line, const char* format, ...);
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user