mirror of
https://github.com/leejet/stable-diffusion.cpp.git
synced 2026-11-11 19:36:33 +00:00
feat: add vace support (#819)
* add wan vace t2v support * add --vace-strength option * add vace i2v support * fix the processing of vace_context * add vace v2v support * update docs
This commit is contained in:
1 parent
2c9b1e2594
commit
52a97b3ac1
16 files changed
+651
-285
No files matched your search
+73
-14
@@ -35,6 +35,8 @@
|
||||
#define SAFE_STR(s) ((s) ? (s) : "")
|
||||
#define BOOL_STR(b) ((b) ? "true" : "false")
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
const char* modes_str[] = {
|
||||
"img_gen",
|
||||
"vid_gen",
|
||||
@@ -75,6 +77,7 @@ struct SDParams {
|
||||
std::string mask_image_path;
|
||||
std::string control_image_path;
|
||||
std::vector<std::string> ref_image_paths;
|
||||
std::string control_video_path;
|
||||
bool increase_ref_index = false;
|
||||
|
||||
std::string prompt;
|
||||
@@ -91,10 +94,10 @@ struct SDParams {
|
||||
std::vector<int> high_noise_skip_layers = {7, 8, 9};
|
||||
sd_sample_params_t high_noise_sample_params;
|
||||
|
||||
float moe_boundary = 0.875f;
|
||||
|
||||
int video_frames = 1;
|
||||
int fps = 16;
|
||||
float moe_boundary = 0.875f;
|
||||
int video_frames = 1;
|
||||
int fps = 16;
|
||||
float vace_strength = 1.f;
|
||||
|
||||
float strength = 0.75f;
|
||||
float control_strength = 0.9f;
|
||||
@@ -159,6 +162,7 @@ void print_params(SDParams params) {
|
||||
for (auto& path : params.ref_image_paths) {
|
||||
printf(" %s\n", path.c_str());
|
||||
};
|
||||
printf(" control_video_path: %s\n", params.control_video_path.c_str());
|
||||
printf(" increase_ref_index: %s\n", params.increase_ref_index ? "true" : "false");
|
||||
printf(" offload_params_to_cpu: %s\n", params.offload_params_to_cpu ? "true" : "false");
|
||||
printf(" clip_on_cpu: %s\n", params.clip_on_cpu ? "true" : "false");
|
||||
@@ -179,7 +183,7 @@ void print_params(SDParams params) {
|
||||
printf(" flow_shift: %.2f\n", params.flow_shift);
|
||||
printf(" strength(img2img): %.2f\n", params.strength);
|
||||
printf(" rng: %s\n", sd_rng_type_name(params.rng_type));
|
||||
printf(" seed: %ld\n", params.seed);
|
||||
printf(" seed: %zd\n", params.seed);
|
||||
printf(" batch_count: %d\n", params.batch_count);
|
||||
printf(" vae_tiling: %s\n", params.vae_tiling_params.enabled ? "true" : "false");
|
||||
printf(" upscale_repeats: %d\n", params.upscale_repeats);
|
||||
@@ -187,6 +191,7 @@ void print_params(SDParams params) {
|
||||
printf(" chroma_use_t5_mask: %s\n", params.chroma_use_t5_mask ? "true" : "false");
|
||||
printf(" chroma_t5_mask_pad: %d\n", params.chroma_t5_mask_pad);
|
||||
printf(" video_frames: %d\n", params.video_frames);
|
||||
printf(" vace_strength: %.2f\n", params.vace_strength);
|
||||
printf(" fps: %d\n", params.fps);
|
||||
free(sample_params_str);
|
||||
free(high_noise_sample_params_str);
|
||||
@@ -226,6 +231,9 @@ void print_usage(int argc, const char* argv[]) {
|
||||
printf(" -i, --end-img [IMAGE] path to the end image, required by flf2v\n");
|
||||
printf(" --control-image [IMAGE] path to image condition, control net\n");
|
||||
printf(" -r, --ref-image [PATH] reference image for Flux Kontext models (can be used multiple times) \n");
|
||||
printf(" --control-video [PATH] path to control video frames, It must be a directory path.\n");
|
||||
printf(" The video frames inside should be stored as images in lexicographical (character) order\n");
|
||||
printf(" For example, if the control video path is `frames`, the directory contain images such as 00.png, 01.png, … etc.\n");
|
||||
printf(" --increase-ref-index automatically increase the indices of references images based on the order they are listed (starting with 1).\n");
|
||||
printf(" -o, --output OUTPUT path to write result image to (default: ./output.png)\n");
|
||||
printf(" -p, --prompt [PROMPT] the prompt to render\n");
|
||||
@@ -292,6 +300,7 @@ void print_usage(int argc, const char* argv[]) {
|
||||
printf(" --moe-boundary BOUNDARY timestep boundary for Wan2.2 MoE model. (default: 0.875)\n");
|
||||
printf(" only enabled if `--high-noise-steps` is set to -1\n");
|
||||
printf(" --flow-shift SHIFT shift value for Flow models like SD3.x or WAN (default: auto)\n");
|
||||
printf(" --vace-strength wan vace strength\n");
|
||||
printf(" -v, --verbose print extra info\n");
|
||||
}
|
||||
|
||||
@@ -486,6 +495,7 @@ void parse_args(int argc, const char** argv, SDParams& params) {
|
||||
{"", "--input-id-images-dir", "", ¶ms.input_id_images_path},
|
||||
{"", "--mask", "", ¶ms.mask_image_path},
|
||||
{"", "--control-image", "", ¶ms.control_image_path},
|
||||
{"", "--control-video", "", ¶ms.control_video_path},
|
||||
{"-o", "--output", "", ¶ms.output_path},
|
||||
{"-p", "--prompt", "", ¶ms.prompt},
|
||||
{"-n", "--negative-prompt", "", ¶ms.negative_prompt},
|
||||
@@ -526,6 +536,7 @@ void parse_args(int argc, const char** argv, SDParams& params) {
|
||||
{"", "--control-strength", "", ¶ms.control_strength},
|
||||
{"", "--moe-boundary", "", ¶ms.moe_boundary},
|
||||
{"", "--flow-shift", "", ¶ms.flow_shift},
|
||||
{"", "--vace-strength", "", ¶ms.vace_strength},
|
||||
{"", "--vae-tile-overlap", "", ¶ms.vae_tiling_params.target_overlap},
|
||||
};
|
||||
|
||||
@@ -1111,6 +1122,7 @@ int main(int argc, const char* argv[]) {
|
||||
sd_image_t control_image = {(uint32_t)params.width, (uint32_t)params.height, 3, NULL};
|
||||
sd_image_t mask_image = {(uint32_t)params.width, (uint32_t)params.height, 1, NULL};
|
||||
std::vector<sd_image_t> ref_images;
|
||||
std::vector<sd_image_t> control_frames;
|
||||
|
||||
auto release_all_resources = [&]() {
|
||||
free(init_image.data);
|
||||
@@ -1122,6 +1134,11 @@ int main(int argc, const char* argv[]) {
|
||||
ref_image.data = NULL;
|
||||
}
|
||||
ref_images.clear();
|
||||
for (auto frame : control_frames) {
|
||||
free(frame.data);
|
||||
frame.data = NULL;
|
||||
}
|
||||
control_frames.clear();
|
||||
};
|
||||
|
||||
if (params.init_image_path.size() > 0) {
|
||||
@@ -1180,14 +1197,12 @@ int main(int argc, const char* argv[]) {
|
||||
return 1;
|
||||
}
|
||||
if (params.canny_preprocess) { // apply preprocessor
|
||||
control_image.data = preprocess_canny(control_image.data,
|
||||
control_image.width,
|
||||
control_image.height,
|
||||
0.08f,
|
||||
0.08f,
|
||||
0.8f,
|
||||
1.0f,
|
||||
false);
|
||||
preprocess_canny(control_image,
|
||||
0.08f,
|
||||
0.08f,
|
||||
0.8f,
|
||||
1.0f,
|
||||
false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1209,6 +1224,48 @@ int main(int argc, const char* argv[]) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!params.control_video_path.empty()) {
|
||||
std::string dir = params.control_video_path;
|
||||
|
||||
if (!fs::exists(dir) || !fs::is_directory(dir)) {
|
||||
fprintf(stderr, "'%s' is not a valid directory\n", dir.c_str());
|
||||
release_all_resources();
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (const auto& entry : fs::directory_iterator(dir)) {
|
||||
if (!entry.is_regular_file())
|
||||
continue;
|
||||
|
||||
std::string path = entry.path().string();
|
||||
std::string ext = entry.path().extension().string();
|
||||
std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
|
||||
|
||||
if (ext == ".jpg" || ext == ".jpeg" || ext == ".png" || ext == ".bmp") {
|
||||
if (params.verbose) {
|
||||
printf("load control frame %zu from '%s'\n", control_frames.size(), path.c_str());
|
||||
}
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
uint8_t* image_buffer = load_image(path.c_str(), width, height, params.width, params.height);
|
||||
if (image_buffer == NULL) {
|
||||
fprintf(stderr, "load image from '%s' failed\n", path.c_str());
|
||||
release_all_resources();
|
||||
return 1;
|
||||
}
|
||||
|
||||
control_frames.push_back({(uint32_t)params.width,
|
||||
(uint32_t)params.height,
|
||||
3,
|
||||
image_buffer});
|
||||
|
||||
if (control_frames.size() >= params.video_frames) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (params.mode == VID_GEN) {
|
||||
vae_decode_only = false;
|
||||
}
|
||||
@@ -1292,6 +1349,8 @@ int main(int argc, const char* argv[]) {
|
||||
params.clip_skip,
|
||||
init_image,
|
||||
end_image,
|
||||
control_frames.data(),
|
||||
(int)control_frames.size(),
|
||||
params.width,
|
||||
params.height,
|
||||
params.sample_params,
|
||||
@@ -1300,6 +1359,7 @@ int main(int argc, const char* argv[]) {
|
||||
params.strength,
|
||||
params.seed,
|
||||
params.video_frames,
|
||||
params.vace_strength,
|
||||
};
|
||||
|
||||
results = generate_video(sd_ctx, &vid_gen_params, &num_results);
|
||||
@@ -1342,7 +1402,6 @@ int main(int argc, const char* argv[]) {
|
||||
|
||||
// create directory if not exists
|
||||
{
|
||||
namespace fs = std::filesystem;
|
||||
const fs::path out_path = params.output_path;
|
||||
if (const fs::path out_dir = out_path.parent_path(); !out_dir.empty()) {
|
||||
std::error_code ec;
|
||||
|
||||
Reference in new issue
Block a user