mirror of
https://github.com/leejet/stable-diffusion.cpp.git
synced 2026-08-03 00:30:41 -05:00
feat: add hunyuan video 1.5 support (#1795)
This commit is contained in:
@@ -1782,6 +1782,7 @@ struct LLMEmbedder : public Conditioner {
|
||||
SDVersion version;
|
||||
std::shared_ptr<BPETokenizer> tokenizer;
|
||||
std::shared_ptr<LLM::LLMRunner> llm;
|
||||
std::shared_ptr<T5Runner> byt5;
|
||||
|
||||
LLMEmbedder(ggml_backend_t backend,
|
||||
const String2TensorStorage& tensor_storage_map = {},
|
||||
@@ -1819,54 +1820,97 @@ struct LLMEmbedder : public Conditioner {
|
||||
"text_encoders.llm",
|
||||
enable_vision,
|
||||
weight_manager);
|
||||
if (sd_version_is_hunyuan_video(version)) {
|
||||
const std::string byt5_prefix = "text_encoders.t5xxl.transformer";
|
||||
for (const auto& [name, _] : tensor_storage_map) {
|
||||
if (starts_with(name, byt5_prefix + ".")) {
|
||||
byt5 = std::make_shared<T5Runner>(backend,
|
||||
tensor_storage_map,
|
||||
byt5_prefix,
|
||||
false,
|
||||
weight_manager);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void get_param_tensors(std::map<std::string, ggml_tensor*>& tensors) override {
|
||||
llm->get_param_tensors(tensors, "text_encoders.llm");
|
||||
if (byt5) {
|
||||
byt5->get_param_tensors(tensors, "text_encoders.t5xxl.transformer");
|
||||
}
|
||||
}
|
||||
|
||||
void set_max_graph_vram_bytes(size_t max_vram_bytes) override {
|
||||
llm->set_max_graph_vram_bytes(max_vram_bytes);
|
||||
if (byt5) {
|
||||
byt5->set_max_graph_vram_bytes(max_vram_bytes);
|
||||
}
|
||||
}
|
||||
|
||||
void set_stream_layers_enabled(bool enabled) override {
|
||||
llm->set_stream_layers_enabled(enabled);
|
||||
if (byt5) {
|
||||
byt5->set_stream_layers_enabled(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
void set_runtime_backends(const std::vector<ggml_backend_t>& backends) override {
|
||||
llm->set_runtime_backends(backends);
|
||||
if (byt5) {
|
||||
byt5->set_runtime_backends(backends);
|
||||
}
|
||||
}
|
||||
|
||||
void set_graph_cut_layer_split_enabled(bool enabled) override {
|
||||
if (llm) {
|
||||
llm->set_graph_cut_layer_split_enabled(enabled);
|
||||
}
|
||||
if (byt5) {
|
||||
byt5->set_graph_cut_layer_split_enabled(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
void set_graph_cut_layer_split_backend_vram_limits(const std::vector<size_t>& limits) override {
|
||||
if (llm) {
|
||||
llm->set_graph_cut_layer_split_backend_vram_limits(limits);
|
||||
}
|
||||
if (byt5) {
|
||||
byt5->set_graph_cut_layer_split_backend_vram_limits(limits);
|
||||
}
|
||||
}
|
||||
|
||||
void get_layer_split_param_tensors(std::map<std::string, ggml_tensor*>& tensors) override {
|
||||
llm->get_param_tensors(tensors, "text_encoders.llm");
|
||||
if (byt5) {
|
||||
byt5->get_param_tensors(tensors, "text_encoders.t5xxl.transformer");
|
||||
}
|
||||
}
|
||||
|
||||
void set_flash_attention_enabled(bool enabled) override {
|
||||
llm->set_flash_attention_enabled(enabled);
|
||||
if (byt5) {
|
||||
byt5->set_flash_attention_enabled(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
void set_weight_adapter(const std::shared_ptr<WeightAdapter>& adapter) override {
|
||||
if (llm) {
|
||||
llm->set_weight_adapter(adapter);
|
||||
}
|
||||
if (byt5) {
|
||||
byt5->set_weight_adapter(adapter);
|
||||
}
|
||||
}
|
||||
|
||||
void runner_done() override {
|
||||
if (llm) {
|
||||
llm->runner_done();
|
||||
}
|
||||
if (byt5) {
|
||||
byt5->runner_done();
|
||||
}
|
||||
}
|
||||
|
||||
std::tuple<std::vector<int>, std::vector<float>, std::vector<float>> tokenize(std::string text,
|
||||
@@ -2060,7 +2104,24 @@ struct LLMEmbedder : public Conditioner {
|
||||
int64_t t0 = ggml_time_ms();
|
||||
RefImageResizeMode resize_mode = conditioner_params.ref_image_params.vlm_resize_mode;
|
||||
|
||||
if (sd_version_is_lingbot_video(version)) {
|
||||
if (sd_version_is_hunyuan_video(version)) {
|
||||
prompt_template_encode_start_idx = 98;
|
||||
out_layers = {26};
|
||||
|
||||
prompt =
|
||||
"<|im_start|>system\nYou are a helpful assistant. Describe the video by detailing the following aspects:\n"
|
||||
"1. The main content and theme of the video.\n"
|
||||
"2. The color, shape, size, texture, quantity, text, and spatial relationships of the objects.\n"
|
||||
"3. Actions, events, behaviors temporal relationships, physical movement changes of the objects.\n"
|
||||
"4. background environment, light, style and atmosphere.\n"
|
||||
"5. camera angles, movements, and transitions used in the video.<|im_end|>\n"
|
||||
"<|im_start|>user\n";
|
||||
|
||||
prompt_attn_range.first = static_cast<int>(prompt.size());
|
||||
prompt += conditioner_params.text;
|
||||
prompt_attn_range.second = static_cast<int>(prompt.size());
|
||||
prompt += "<|im_end|>\n<|im_start|>assistant\n";
|
||||
} else if (sd_version_is_lingbot_video(version)) {
|
||||
const int pad_token = 151643;
|
||||
const std::string prompt_prefix =
|
||||
"<|im_start|>system\nGiven a user input that may include a text prompt alone, "
|
||||
@@ -2590,6 +2651,46 @@ struct LLMEmbedder : public Conditioner {
|
||||
spell_quotes,
|
||||
max_length);
|
||||
std::vector<sd::Tensor<float>> extra_hidden_states_vec;
|
||||
if (sd_version_is_hunyuan_video(version) && byt5) {
|
||||
std::vector<std::string> quoted_texts;
|
||||
auto collect_quoted = [&](const std::string& open, const std::string& close) {
|
||||
size_t begin = 0;
|
||||
while ((begin = conditioner_params.text.find(open, begin)) != std::string::npos) {
|
||||
size_t content_begin = begin + open.size();
|
||||
size_t end = conditioner_params.text.find(close, content_begin);
|
||||
if (end == std::string::npos) {
|
||||
break;
|
||||
}
|
||||
quoted_texts.push_back(conditioner_params.text.substr(content_begin, end - content_begin));
|
||||
begin = end + close.size();
|
||||
}
|
||||
};
|
||||
collect_quoted("\"", "\"");
|
||||
collect_quoted("\xE2\x80\x98", "\xE2\x80\x99");
|
||||
collect_quoted("\xE2\x80\x9C", "\xE2\x80\x9D");
|
||||
|
||||
if (!quoted_texts.empty()) {
|
||||
std::string byt5_text;
|
||||
for (const auto& text : quoted_texts) {
|
||||
byt5_text += "Text \"" + text + "\". ";
|
||||
}
|
||||
std::vector<int> tokens;
|
||||
tokens.reserve(byt5_text.size() + 1);
|
||||
for (unsigned char byte : byt5_text) {
|
||||
tokens.push_back(static_cast<int>(byte) + 3);
|
||||
}
|
||||
tokens.push_back(1);
|
||||
sd::Tensor<int32_t> input_ids({static_cast<int64_t>(tokens.size())}, tokens);
|
||||
auto byt5_hidden_states = byt5->compute(n_threads,
|
||||
input_ids,
|
||||
sd::Tensor<float>(),
|
||||
false,
|
||||
true,
|
||||
true);
|
||||
GGML_ASSERT(!byt5_hidden_states.empty());
|
||||
extra_hidden_states_vec.push_back(std::move(byt5_hidden_states));
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < extra_prompts.size(); i++) {
|
||||
auto extra_hidden_states = encode_prompt(n_threads,
|
||||
extra_prompts[i],
|
||||
|
||||
Reference in New Issue
Block a user