diff --git a/src/conditioning/conditioner.hpp b/src/conditioning/conditioner.hpp index b332ba5a8..6982dd926 100644 --- a/src/conditioning/conditioner.hpp +++ b/src/conditioning/conditioner.hpp @@ -134,6 +134,7 @@ struct ConditionerParams { const std::vector>* ref_images = nullptr; // for qwen image edit const std::vector* minimax_h3_references = nullptr; RefImageParams ref_image_params; + bool allow_cache = false; }; struct Conditioner { @@ -1873,6 +1874,10 @@ struct LLMEmbedder : public Conditioner { std::shared_ptr llm; std::shared_ptr byt5; + bool h3_text_cache_valid = false; + std::string h3_text_cache_text; + SDCondition h3_text_cache; + LLMEmbedder(ggml_backend_t backend, const String2TensorStorage& tensor_storage_map = {}, SDVersion version = VERSION_QWEN_IMAGE, @@ -2190,6 +2195,25 @@ struct LLMEmbedder : public Conditioner { SDCondition get_learned_condition(int n_threads, const ConditionerParams& conditioner_params) override { + const bool h3_text_cacheable = + sd_version_is_minimax_h3(version) && + conditioner_params.allow_cache && + (conditioner_params.minimax_h3_references == nullptr || + conditioner_params.minimax_h3_references->empty()) && + (conditioner_params.ref_images == nullptr || + conditioner_params.ref_images->empty()); + + if (sd_version_is_minimax_h3(version) && !h3_text_cacheable) { + h3_text_cache_valid = false; + } + + if (h3_text_cacheable && + h3_text_cache_valid && + h3_text_cache_text == conditioner_params.text) { + LOG_INFO("H3 conditioning cache hit"); + return h3_text_cache; + } + std::string prompt; std::pair prompt_attn_range; std::vector extra_prompts; @@ -2945,6 +2969,14 @@ struct LLMEmbedder : public Conditioner { int64_t tag_count = static_cast(tags.size()); result.c_token_types = sd::Tensor({tag_count}, std::move(tags)); } + + if (h3_text_cacheable) { + h3_text_cache_text = conditioner_params.text; + h3_text_cache = result; + h3_text_cache_valid = true; + LOG_INFO("H3 conditioning cache stored"); + } + return result; } }; diff --git a/src/pipeline/diffusion_engine.cpp b/src/pipeline/diffusion_engine.cpp index 5d51e2417..7e396f8b0 100644 --- a/src/pipeline/diffusion_engine.cpp +++ b/src/pipeline/diffusion_engine.cpp @@ -1681,6 +1681,8 @@ bool StableDiffusionGGML::apply_loras(const sd_lora_t* loras, uint32_t lora_coun extension->collect_loras(all_loras); } + conditioning_cache_allowed_ = all_loras.empty(); + int64_t t0 = ggml_time_ms(); end_runners(); clear_lora_adapters(); diff --git a/src/pipeline/diffusion_engine.h b/src/pipeline/diffusion_engine.h index 13cb6e8f2..9e74beb9b 100644 --- a/src/pipeline/diffusion_engine.h +++ b/src/pipeline/diffusion_engine.h @@ -171,6 +171,7 @@ class StableDiffusionGGML { std::recursive_mutex execution_mutex; std::unique_ptr config_; RunnerState runner_state_; + bool conditioning_cache_allowed_ = false; bool executing_ = false; std::shared_ptr denoiser; diff --git a/src/pipeline/video.cpp b/src/pipeline/video.cpp index cc979c0fa..1622bf39b 100644 --- a/src/pipeline/video.cpp +++ b/src/pipeline/video.cpp @@ -1065,6 +1065,10 @@ namespace sd::pipeline { condition_params.zero_out_masked = true; condition_params.ref_images = &latents.ref_images; condition_params.minimax_h3_references = &latents.minimax_presentation_refs; + condition_params.allow_cache = + sd_version_is_minimax_h3(sd->version) && + sd->conditioning_cache_allowed_ && + !request.use_uncond; if (sd_version_is_lingbot_video(sd->version) || sd_version_is_minimax_h3(sd->version)) { condition_params.ref_image_params.vlm_resize_mode = RefImageResizeMode::AREA; }