mirror of
https://github.com/leejet/stable-diffusion.cpp.git
synced 2026-07-24 03:40:53 -05:00
Compare commits
5 Commits
master-90e
...
master-afe
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
afea457eda | ||
|
|
646e77638e | ||
|
|
3ac48ea1a7 | ||
|
|
607e39489f | ||
|
|
ccae95aec9 |
12
README.md
12
README.md
@@ -306,14 +306,14 @@ sd -m ../models/v1-5-pruned-emaonly.safetensors -p "a lovely cat" --upscale-mode
|
||||
|
||||
#### Using PhotoMaker to personalize image generation
|
||||
|
||||
You can use [PhotoMaker](https://github.com/TencentARC/PhotoMaker) to personalize generated images with your own ID.
|
||||
You can use [PhotoMaker](https://github.com/TencentARC/PhotoMaker) to personalize generated images with your own ID.
|
||||
|
||||
**NOTE**, currently PhotoMaker **ONLY** works with **SDXL** (any SDXL model files will work).
|
||||
|
||||
Download PhotoMaker model file (in safetensor format) [here](https://huggingface.co/bssrdf/PhotoMaker). The official release of the model file (in .bin format) does not work with ```stablediffusion.cpp```.
|
||||
|
||||
- Specify the PhotoMaker model path using the `--stacked-id-embd-dir PATH` parameter.
|
||||
- Specify the input images path using the `--input-id-images-dir PATH` parameter.
|
||||
- Specify the PhotoMaker model path using the `--stacked-id-embd-dir PATH` parameter.
|
||||
- Specify the input images path using the `--input-id-images-dir PATH` parameter.
|
||||
- input images **must** have the same width and height for preprocessing (to be improved)
|
||||
|
||||
In prompt, make sure you have a class word followed by the trigger word ```"img"``` (hard-coded for now). The class word could be one of ```"man, woman, girl, boy"```. If input ID images contain asian faces, add ```Asian``` before the class
|
||||
@@ -367,6 +367,12 @@ These projects wrap `stable-diffusion.cpp` for easier use in other languages/fra
|
||||
* Golang: [seasonjs/stable-diffusion](https://github.com/seasonjs/stable-diffusion)
|
||||
* C#: [DarthAffe/StableDiffusion.NET](https://github.com/DarthAffe/StableDiffusion.NET)
|
||||
|
||||
## UIs
|
||||
|
||||
These projects use `stable-diffusion.cpp` as a backend for their image generation.
|
||||
|
||||
- [Jellybox](https://jellybox.com)
|
||||
|
||||
## Contributors
|
||||
|
||||
Thank you to all the people who have already contributed to stable-diffusion.cpp!
|
||||
|
||||
@@ -17,6 +17,10 @@
|
||||
#define STB_IMAGE_WRITE_STATIC
|
||||
#include "stb_image_write.h"
|
||||
|
||||
#define STB_IMAGE_RESIZE_IMPLEMENTATION
|
||||
#define STB_IMAGE_RESIZE_STATIC
|
||||
#include "stb_image_resize.h"
|
||||
|
||||
const char* rng_type_to_str[] = {
|
||||
"std_default",
|
||||
"cuda",
|
||||
@@ -663,21 +667,46 @@ int main(int argc, const char* argv[]) {
|
||||
fprintf(stderr, "load image from '%s' failed\n", params.input_path.c_str());
|
||||
return 1;
|
||||
}
|
||||
if (c != 3) {
|
||||
fprintf(stderr, "input image must be a 3 channels RGB image, but got %d channels\n", c);
|
||||
if (c < 3) {
|
||||
fprintf(stderr, "the number of channels for the input image must be >= 3, but got %d channels\n", c);
|
||||
free(input_image_buffer);
|
||||
return 1;
|
||||
}
|
||||
if (params.width <= 0 || params.width % 64 != 0) {
|
||||
fprintf(stderr, "error: the width of image must be a multiple of 64\n");
|
||||
if (params.width <= 0) {
|
||||
fprintf(stderr, "error: the width of image must be greater than 0\n");
|
||||
free(input_image_buffer);
|
||||
return 1;
|
||||
}
|
||||
if (params.height <= 0 || params.height % 64 != 0) {
|
||||
fprintf(stderr, "error: the height of image must be a multiple of 64\n");
|
||||
if (params.height <= 0) {
|
||||
fprintf(stderr, "error: the height of image must be greater than 0\n");
|
||||
free(input_image_buffer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Resize input image ...
|
||||
if (params.height % 64 != 0 || params.width % 64 != 0) {
|
||||
int resized_height = params.height + (64 - params.height % 64);
|
||||
int resized_width = params.width + (64 - params.width % 64);
|
||||
|
||||
uint8_t* resized_image_buffer = (uint8_t*)malloc(resized_height * resized_width * 3);
|
||||
if (resized_image_buffer == NULL) {
|
||||
fprintf(stderr, "error: allocate memory for resize input image\n");
|
||||
free(input_image_buffer);
|
||||
return 1;
|
||||
}
|
||||
stbir_resize(input_image_buffer, params.width, params.height, 0,
|
||||
resized_image_buffer, resized_width, resized_height, 0, STBIR_TYPE_UINT8,
|
||||
3 /*RGB channel*/, STBIR_ALPHA_CHANNEL_NONE, 0,
|
||||
STBIR_EDGE_CLAMP, STBIR_EDGE_CLAMP,
|
||||
STBIR_FILTER_BOX, STBIR_FILTER_BOX,
|
||||
STBIR_COLORSPACE_SRGB, nullptr);
|
||||
|
||||
// Save resized result
|
||||
free(input_image_buffer);
|
||||
input_image_buffer = resized_image_buffer;
|
||||
params.height = resized_height;
|
||||
params.width = resized_width;
|
||||
}
|
||||
}
|
||||
|
||||
sd_ctx_t* sd_ctx = new_sd_ctx(params.model_path.c_str(),
|
||||
|
||||
@@ -484,6 +484,7 @@ __STATIC_INLINE__ void sd_tiling(ggml_tensor* input, ggml_tensor* output, const
|
||||
if (tile_count < num_tiles) {
|
||||
pretty_progress(num_tiles, num_tiles, last_time);
|
||||
}
|
||||
ggml_free(tiles_ctx);
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ struct ggml_tensor* ggml_group_norm_32(struct ggml_context* ctx,
|
||||
|
||||
13
lora.hpp
13
lora.hpp
@@ -11,7 +11,7 @@ struct LoraModel : public GGMLModule {
|
||||
std::string file_path;
|
||||
ModelLoader model_loader;
|
||||
bool load_failed = false;
|
||||
bool applied = false;
|
||||
bool applied = false;
|
||||
|
||||
LoraModel(ggml_backend_t backend,
|
||||
ggml_type wtype,
|
||||
@@ -91,10 +91,15 @@ struct LoraModel : public GGMLModule {
|
||||
k_tensor = k_tensor.substr(0, k_pos);
|
||||
replace_all_chars(k_tensor, '.', '_');
|
||||
// LOG_DEBUG("k_tensor %s", k_tensor.c_str());
|
||||
if (k_tensor == "model_diffusion_model_output_blocks_2_2_conv") { // fix for SDXL
|
||||
k_tensor = "model_diffusion_model_output_blocks_2_1_conv";
|
||||
std::string lora_up_name = "lora." + k_tensor + ".lora_up.weight";
|
||||
if (lora_tensors.find(lora_up_name) == lora_tensors.end()) {
|
||||
if (k_tensor == "model_diffusion_model_output_blocks_2_2_conv") {
|
||||
// fix for some sdxl lora, like lcm-lora-xl
|
||||
k_tensor = "model_diffusion_model_output_blocks_2_1_conv";
|
||||
lora_up_name = "lora." + k_tensor + ".lora_up.weight";
|
||||
}
|
||||
}
|
||||
std::string lora_up_name = "lora." + k_tensor + ".lora_up.weight";
|
||||
|
||||
std::string lora_down_name = "lora." + k_tensor + ".lora_down.weight";
|
||||
std::string alpha_name = "lora." + k_tensor + ".alpha";
|
||||
std::string scale_name = "lora." + k_tensor + ".scale";
|
||||
|
||||
17
model.cpp
17
model.cpp
@@ -211,6 +211,8 @@ std::string convert_sdxl_lora_name(std::string tensor_name) {
|
||||
{"unet", "model_diffusion_model"},
|
||||
{"te2", "cond_stage_model_1_transformer"},
|
||||
{"te1", "cond_stage_model_transformer"},
|
||||
{"text_encoder_2", "cond_stage_model_1_transformer"},
|
||||
{"text_encoder", "cond_stage_model_transformer"},
|
||||
};
|
||||
for (auto& pair_i : sdxl_lora_name_lookup) {
|
||||
if (tensor_name.compare(0, pair_i.first.length(), pair_i.first) == 0) {
|
||||
@@ -446,18 +448,25 @@ std::string convert_tensor_name(const std::string& name) {
|
||||
} else {
|
||||
new_name = name;
|
||||
}
|
||||
} else if (contains(name, "lora_up") || contains(name, "lora_down") || contains(name, "lora.up") || contains(name, "lora.down")) {
|
||||
} else if (contains(name, "lora_up") || contains(name, "lora_down") ||
|
||||
contains(name, "lora.up") || contains(name, "lora.down") ||
|
||||
contains(name, "lora_linear")) {
|
||||
size_t pos = new_name.find(".processor");
|
||||
if (pos != std::string::npos) {
|
||||
new_name.replace(pos, strlen(".processor"), "");
|
||||
}
|
||||
pos = new_name.find_last_of('_');
|
||||
pos = new_name.rfind("lora");
|
||||
if (pos != std::string::npos) {
|
||||
std::string name_without_network_parts = new_name.substr(0, pos);
|
||||
std::string network_part = new_name.substr(pos + 1);
|
||||
std::string name_without_network_parts = new_name.substr(0, pos - 1);
|
||||
std::string network_part = new_name.substr(pos);
|
||||
// LOG_DEBUG("%s %s", name_without_network_parts.c_str(), network_part.c_str());
|
||||
std::string new_key = convert_diffusers_name_to_compvis(name_without_network_parts, '.');
|
||||
new_key = convert_sdxl_lora_name(new_key);
|
||||
replace_all_chars(new_key, '.', '_');
|
||||
size_t npos = network_part.rfind("_linear_layer");
|
||||
if (npos != std::string::npos) {
|
||||
network_part.replace(npos, strlen("_linear_layer"), "");
|
||||
}
|
||||
if (starts_with(network_part, "lora.")) {
|
||||
network_part = "lora_" + network_part.substr(5);
|
||||
}
|
||||
|
||||
@@ -1610,7 +1610,7 @@ sd_image_t* txt2img(sd_ctx_t* sd_ctx,
|
||||
if (sd_ctx->sd->stacked_id && !sd_ctx->sd->pmid_lora->applied) {
|
||||
t0 = ggml_time_ms();
|
||||
sd_ctx->sd->pmid_lora->apply(sd_ctx->sd->tensors, sd_ctx->sd->n_threads);
|
||||
t1 = ggml_time_ms();
|
||||
t1 = ggml_time_ms();
|
||||
sd_ctx->sd->pmid_lora->applied = true;
|
||||
LOG_INFO("pmid_lora apply completed, taking %.2fs", (t1 - t0) * 1.0f / 1000);
|
||||
if (sd_ctx->sd->free_params_immediately) {
|
||||
|
||||
Reference in New Issue
Block a user