GGUF Versions Q4 possibly bugged..
didnt test right now but depending on how you did the conversion its possible that smaller quants than Q4_K_M are bugged and deliver bad image quality.
if you use City96's tools the you should probably replace this block to maintain the "high precision" blocks to get decent images even with Q2 quants.
edit the llama.cpp file and recompile llama-quantize:
// Qwen-Image-Edit-2509 block high precision test
if (arch == LLM_ARCH_QWEN_IMAGE){
bool keep_f32 = false;
// Check for bias parameters (always keep in F32)
if (name.find(".bias") != std::string::npos) {
keep_f32 = true;
}
// Check for specific modules in block 0
else if (name.find("transformer_blocks.0.") != std::string::npos) {
const std::string modules[] = {
"img_mod", "img_mod.1", "attn.to_q", "attn.to_k", "attn.to_v",
"attn.add_k_proj", "attn.add_v_proj", "attn.add_q_proj",
"attn.to_out.0", "attn.to_add_out", "img_mlp.net.0.proj",
"img_mlp.net.2", "txt_mod.1", "txt_mlp.net.0.proj", "txt_mlp.net.2"
};
for (const auto& module : modules) {
if (name.find(module) != std::string::npos) {
keep_f32 = true;
break;
}
}
}
// Check for specific modules in block 33
else if (name.find("transformer_blocks.33.") != std::string::npos) {
if (name.find("img_mod") != std::string::npos) {
keep_f32 = true;
}
}
// Check for specific modules in block 58
else if (name.find("transformer_blocks.58.") != std::string::npos) {
if (name.find("attn.to_k") != std::string::npos) {
keep_f32 = true;
}
}
// Check for specific modules in block 59
else if (name.find("transformer_blocks.59.") != std::string::npos) {
const std::string modules[] = {
"attn.to_out", "img_mod.1", "attn.to_q", "attn.to_k", "attn.to_v",
"attn.add_k_proj", "attn.add_v_proj", "attn.add_q_proj",
"attn.to_out.0", "attn.to_add_out", "img_mlp.net.0.proj",
"img_mlp.net.2", "txt_mod.1", "txt_mlp.net.0.proj", "txt_mlp.net.2"
};
for (const auto& module : modules) {
if (name.find(module) != std::string::npos) {
keep_f32 = true;
break;
}
}
}
// Check for other specific modules
else {
const std::string modules[] = {
"time_text_embed", "img_in", "txt_in", "norm_out.linear", "proj_out"
};
for (const auto& module : modules) {
if (name.find(module) != std::string::npos) {
keep_f32 = true;
break;
}
}
}
if (keep_f32) {
new_type = GGML_TYPE_Q8_0;
}
}
in know i was lazy keep_f32 should get replaced with keep_q8 but thats only cosmetic.
so with this change all needed transformer_blocks for qwen-image-edit-2509 stays in Q8, similar to FP8 and doesnt degrade the edit and output image as described here: https://huggingface.co/QuantStack/Qwen-Image-Edit-2509-GGUF/discussions/6
did some iterations after the first fix to get smaller models, sort out whats really needen and actually im fine with the results.
BTW at least Q5_K is needed, thats whats the default from Q4_K_M and thats why eg Q4_K_S Q4_0 and Q4_1 and lower are affected from this issue.
this was my fist attempt but the above posted code, gives similar sized output gguf's with very good results.
// first/last block high precision test
if (arch == LLM_ARCH_QWEN_IMAGE){
if (
(name.find("transformer_blocks.0.") != std::string::npos) ||
(name.find("transformer_blocks.59.") != std::string::npos) // this should be dynamic
) {
if (ftype == LLAMA_FTYPE_MOSTLY_Q2_K ||
ftype == LLAMA_FTYPE_MOSTLY_Q3_K_S ||
ftype == LLAMA_FTYPE_MOSTLY_Q3_K_M ||
ftype == LLAMA_FTYPE_MOSTLY_Q3_K_L ||
ftype == LLAMA_FTYPE_MOSTLY_Q4_0 ||
ftype == LLAMA_FTYPE_MOSTLY_Q4_1 ||
ftype == LLAMA_FTYPE_MOSTLY_Q4_K_S ||
ftype == LLAMA_FTYPE_MOSTLY_Q4_K_M) {
new_type = GGML_TYPE_Q5_K; // Minimum Q5_K for low quants
}
else if (ftype == LLAMA_FTYPE_MOSTLY_Q5_K_M) {
new_type = GGML_TYPE_Q6_K;
}
}
}