Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 52 additions & 20 deletions src/conditioner.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ struct Conditioner {
public:
virtual SDCondition get_learned_condition(int n_threads,
const ConditionerParams& conditioner_params) = 0;
virtual void alloc_params_buffer() = 0;
virtual bool alloc_params_buffer() = 0;
virtual void free_params_buffer() = 0;
virtual void get_param_tensors(std::map<std::string, ggml_tensor*>& tensors) = 0;
virtual size_t get_params_buffer_size() = 0;
Expand Down Expand Up @@ -176,11 +176,16 @@ struct FrozenCLIPEmbedderWithCustomWords : public Conditioner {
}
}

void alloc_params_buffer() override {
text_model->alloc_params_buffer();
bool alloc_params_buffer() override {
if (!text_model->alloc_params_buffer()) {
return false;
}
if (sd_version_is_sdxl(version)) {
text_model2->alloc_params_buffer();
if (!text_model2->alloc_params_buffer()) {
return false;
}
}
return true;
}

void free_params_buffer() override {
Expand Down Expand Up @@ -781,16 +786,23 @@ struct SD3CLIPEmbedder : public Conditioner {
}
}

void alloc_params_buffer() override {
bool alloc_params_buffer() override {
if (clip_l) {
clip_l->alloc_params_buffer();
if (!clip_l->alloc_params_buffer()) {
return false;
}
}
if (clip_g) {
clip_g->alloc_params_buffer();
if (!clip_g->alloc_params_buffer()) {
return false;
}
}
if (t5) {
t5->alloc_params_buffer();
if (!t5->alloc_params_buffer()) {
return false;
}
}
return true;
}

void free_params_buffer() override {
Expand Down Expand Up @@ -1145,15 +1157,21 @@ struct FluxCLIPEmbedder : public Conditioner {
}
}

void alloc_params_buffer() override {
bool alloc_params_buffer() override {
if (clip_l) {
clip_l->alloc_params_buffer();
if (!clip_l->alloc_params_buffer()) {
return false;
}
}
if (t5) {
t5->alloc_params_buffer();
if (!t5->alloc_params_buffer()) {
return false;
}
}
return true;
}


void free_params_buffer() override {
if (clip_l) {
clip_l->free_params_buffer();
Expand Down Expand Up @@ -1388,10 +1406,13 @@ struct T5CLIPEmbedder : public Conditioner {
}
}

void alloc_params_buffer() override {
bool alloc_params_buffer() override {
if (t5) {
t5->alloc_params_buffer();
if (!t5->alloc_params_buffer()) {
return false;
}
}
return true;
}

void free_params_buffer() override {
Expand Down Expand Up @@ -1578,8 +1599,11 @@ struct AnimaConditioner : public Conditioner {
llm->get_param_tensors(tensors, "text_encoders.llm");
}

void alloc_params_buffer() override {
llm->alloc_params_buffer();
bool alloc_params_buffer() override {
if (!llm->alloc_params_buffer()) {
return false;
}
return true;
}

void free_params_buffer() override {
Expand Down Expand Up @@ -1717,8 +1741,11 @@ struct LLMEmbedder : public Conditioner {
llm->get_param_tensors(tensors, "text_encoders.llm");
}

void alloc_params_buffer() override {
llm->alloc_params_buffer();
bool alloc_params_buffer() override {
if (!llm->alloc_params_buffer()) {
return false;
}
return true;
}

void free_params_buffer() override {
Expand Down Expand Up @@ -2239,9 +2266,14 @@ struct LTXAVEmbedder : public Conditioner {
projector->get_param_tensors(tensors, "text_embedding_projection");
}

void alloc_params_buffer() override {
llm->alloc_params_buffer();
projector->alloc_params_buffer();
bool alloc_params_buffer() override {
if (!llm->alloc_params_buffer()) {
return false;
}
if (!projector->alloc_params_buffer()) {
return false;
}
return true;
}

void free_params_buffer() override {
Expand Down
6 changes: 5 additions & 1 deletion src/control.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,11 @@ struct ControlNet : public GGMLRunner {

bool load_from_file(const std::string& file_path, int n_threads) {
LOG_INFO("loading control net from '%s'", file_path.c_str());
alloc_params_buffer();
if (!alloc_params_buffer()) {
LOG_ERROR("control net model buffer allocation failed");
return false;
}

std::map<std::string, ggml_tensor*> tensors;
control_net.get_param_tensors(tensors);
std::set<std::string> ignore_tensors;
Expand Down
6 changes: 5 additions & 1 deletion src/esrgan.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,11 @@ struct ESRGAN : public GGMLRunner {
rrdb_net = std::make_unique<RRDBNet>(detected_scale, detected_num_block, detected_num_in_ch, detected_num_out_ch, detected_num_feat, detected_num_grow_ch);
rrdb_net->init(params_ctx, {}, "");

alloc_params_buffer();
if (!alloc_params_buffer()) {
LOG_ERROR("esrgan model buffer allocation failed");
return false;
}

std::map<std::string, ggml_tensor*> esrgan_tensors;
rrdb_net->get_param_tensors(esrgan_tensors);

Expand Down
6 changes: 5 additions & 1 deletion src/flux.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1592,7 +1592,11 @@ namespace Flux {
VERSION_FLUX2,
false);

flux->alloc_params_buffer();
if (!flux->alloc_params_buffer()) {
LOG_ERROR("flux model allocation failed");
return;
}

std::map<std::string, ggml_tensor*> tensors;
flux->get_param_tensors(tensors, "model.diffusion_model");

Expand Down
7 changes: 5 additions & 2 deletions src/hidream_o1.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -492,8 +492,11 @@ namespace HiDreamO1 {
vision_runner->get_param_tensors(tensors);
}

void alloc_params_buffer() override {
vision_runner->alloc_params_buffer();
bool alloc_params_buffer() override {
if (!vision_runner->alloc_params_buffer()) {
return false;
}
return true;
}

void free_params_buffer() override {
Expand Down
13 changes: 10 additions & 3 deletions src/llm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1769,8 +1769,11 @@ namespace LLM {
model.get_param_tensors(tensors, prefix);
}

void alloc_params_buffer() {
model.alloc_params_buffer();
bool alloc_params_buffer() {
if (!model.alloc_params_buffer()) {
return false;
}
return true;
}

std::tuple<std::vector<int>, std::vector<float>> tokenize(std::string text,
Expand Down Expand Up @@ -2012,7 +2015,11 @@ namespace LLM {
"text_encoders.llm",
true);

llm->alloc_params_buffer();
if (!llm->alloc_params_buffer()) {
LOG_ERROR("llm model allocation failed");
return;
}

std::map<std::string, ggml_tensor*> tensors;
llm->get_param_tensors(tensors, "text_encoders.llm");

Expand Down
6 changes: 5 additions & 1 deletion src/lora.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,11 @@ struct LoraModel : public GGMLRunner {
lora_tensors[name] = real;
}

alloc_params_buffer();
if (!alloc_params_buffer()) {
LOG_ERROR("lora model buffer allocation failed");
return false;
}


dry_run = false;
model_loader.load_tensors(on_new_tensor_cb, n_threads);
Expand Down
6 changes: 5 additions & 1 deletion src/ltx_audio_vae.h
Original file line number Diff line number Diff line change
Expand Up @@ -1068,7 +1068,11 @@ namespace LTXV {
tensor_storage_map,
prefix);

ltx_audio_vae->alloc_params_buffer();
if (!ltx_audio_vae->alloc_params_buffer()) {
LOG_ERROR("ltx audio vae buffer allocation failed");
return;
}

std::map<std::string, ggml_tensor*> tensors;
ltx_audio_vae->get_param_tensors(tensors, "");

Expand Down
6 changes: 5 additions & 1 deletion src/ltx_vae.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1534,7 +1534,11 @@ struct LTXVideoVAE : public VAE {
true,
VERSION_LTXAV);

vae->alloc_params_buffer();
if (!vae->alloc_params_buffer()) {
LOG_ERROR("vae buffer allocation failed");
return;
}

std::map<std::string, ggml_tensor*> tensors;
vae->get_param_tensors(tensors, "first_stage_model");

Expand Down
5 changes: 4 additions & 1 deletion src/ltxv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2017,7 +2017,10 @@ namespace LTXV {
tensor_storage_map,
"model.diffusion_model");

ltxav->alloc_params_buffer();
if (!ltxav->alloc_params_buffer()) {
LOG_ERROR("ltxav buffer allocation failed");
return;
}
std::map<std::string, ggml_tensor*> tensors;
ltxav->get_param_tensors(tensors, "model.diffusion_model");

Expand Down
6 changes: 5 additions & 1 deletion src/mmdit.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -953,7 +953,11 @@ struct MMDiTRunner : public DiffusionModelRunner {
{
LOG_INFO("loading from '%s'", file_path.c_str());

mmdit->alloc_params_buffer();
if (!mmdit->alloc_params_buffer()) {
LOG_ERROR("mmdit embeds buffer allocation failed");
return;
}

std::map<std::string, ggml_tensor*> tensors;
mmdit->get_param_tensors(tensors, "model.diffusion_model");

Expand Down
6 changes: 6 additions & 0 deletions src/model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -999,6 +999,12 @@ bool ModelLoader::load_tensors(on_new_tensor_cb_t on_new_tensor_cb, int n_thread
continue;
}

if (dst_tensor->data == nullptr) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this is the best place to check for this, because the allocation can't fail for individual tensors; it's all-or-nothing.

Take a look at StableDiffusionGGML::init, in stable-diffusion.cpp, a bit before load_tensors: some components do report allocation failure, but not all. We should probably propagate the underlying alloc_params_buffer error in all cases.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have seen that code in stable-diffusion.cpp and wondered about the reasoning behind it. I am just a newbie, and I guess there is a reason for writing the code this way.
So I decided to keep that as is - and better add this little quick fix.
And you’re right, the allocation problem is an all-or-nothing issue. So the message refers to the first tensor and then the program exits.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think load_tensors() is the right primary place to handle this.

dst_tensor->data == nullptr is only a downstream symptom. The actual allocation failure happens earlier in StableDiffusionGGML::init(): some components already check alloc_params_buffer() and return false on failure, but cond_stage_model, diffusion_model, and high_noise_diffusion_model currently ignore the return value.

Could we instead propagate those failures there, e.g. check:

  • cond_stage_model->alloc_params_buffer()
  • diffusion_model->alloc_params_buffer()
  • high_noise_diffusion_model->alloc_params_buffer()

and return false with a component-level error message?

The null-data check in load_tensors() can still be kept as a defensive guard, but the current message memory allocation failed '<tensor>' is misleading because params buffer allocation is all-or-nothing, not per tensor.

LOG_ERROR("process tensor data failed: '%s'", tensor_storage.name.c_str());
failed = true;
break;
}

// skip mmapped tensors
if (dst_tensor->buffer != nullptr && dst_tensor->buffer == fdata.mmbuffer.get()) {
continue;
Expand Down
5 changes: 4 additions & 1 deletion src/pmid.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -615,7 +615,10 @@ struct PhotoMakerIDEmbed : public GGMLRunner {
};

model_loader->load_tensors(on_new_tensor_cb, n_threads);
alloc_params_buffer();
if (!alloc_params_buffer()) {
LOG_ERROR("PhotoMaker ID embeds buffer allocation failed");
return false;
}

dry_run = false;
model_loader->load_tensors(on_new_tensor_cb, n_threads);
Expand Down
6 changes: 5 additions & 1 deletion src/qwen_image.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -705,7 +705,11 @@ namespace Qwen {
"model.diffusion_model",
VERSION_QWEN_IMAGE);

qwen_image->alloc_params_buffer();
if (!qwen_image->alloc_params_buffer()) {
LOG_ERROR("qwen_image buffer allocation failed");
return;
}

std::map<std::string, ggml_tensor*> tensors;
qwen_image->get_param_tensors(tensors, "model.diffusion_model");

Expand Down
18 changes: 12 additions & 6 deletions src/stable-diffusion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -984,14 +984,20 @@ class StableDiffusionGGML {
ggml_free(ctx);
return false;
}
if (cond_stage_model) {
cond_stage_model->alloc_params_buffer();
if (cond_stage_model && !cond_stage_model->alloc_params_buffer()) {
LOG_ERROR("Conditioner model params buffer allocation failed");
ggml_free(ctx);
return false;
}
if (diffusion_model) {
diffusion_model->alloc_params_buffer();
if (diffusion_model && !diffusion_model->alloc_params_buffer()) {
LOG_ERROR("Diffusion model params buffer allocation failed");
ggml_free(ctx);
return false;
}
if (high_noise_diffusion_model) {
high_noise_diffusion_model->alloc_params_buffer();
if (high_noise_diffusion_model && !high_noise_diffusion_model->alloc_params_buffer()) {
LOG_ERROR("High noise diffusion model params buffer allocation failed");
ggml_free(ctx);
return false;
}
if (first_stage_model && !first_stage_model->alloc_params_buffer()) {
LOG_ERROR("VAE params buffer allocation failed");
Expand Down
12 changes: 9 additions & 3 deletions src/t5.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -475,8 +475,11 @@ struct T5Embedder {
model.get_param_tensors(tensors, prefix);
}

void alloc_params_buffer() {
model.alloc_params_buffer();
bool alloc_params_buffer() {
if (!model.alloc_params_buffer()) {
return false;
}
return true;
}

std::tuple<std::vector<int>, std::vector<float>, std::vector<float>> tokenize(std::string text,
Expand Down Expand Up @@ -578,7 +581,10 @@ struct T5Embedder {

std::shared_ptr<T5Embedder> t5 = std::make_shared<T5Embedder>(backend, backend, tensor_storage_map, "", true);

t5->alloc_params_buffer();
if (!t5->alloc_params_buffer()) {
LOG_ERROR("t5 params buffer allocation failed");
return;
}
std::map<std::string, ggml_tensor*> tensors;
t5->get_param_tensors(tensors, "");

Expand Down
Loading
Loading