From b1350f6f5a32b8554b7b58435a281c908b0de497 Mon Sep 17 00:00:00 2001 From: spawner Date: Tue, 5 Aug 2025 18:42:40 +0800 Subject: [PATCH 1/3] Merge pull request #304 from spawner1145/main support lumina-image-2.0 --- loader.py | 2 +- tools/convert.py | 11 +++++++++-- tools/lcpp.patch | 41 ++++++++++++++++++++++++++++------------- 3 files changed, 38 insertions(+), 16 deletions(-) diff --git a/loader.py b/loader.py index 898fce6..2204b33 100644 --- a/loader.py +++ b/loader.py @@ -7,7 +7,7 @@ import gguf from .ops import GGMLTensor from .dequant import is_quantized, dequantize_tensor -IMG_ARCH_LIST = {"flux", "sd1", "sdxl", "sd3", "aura", "hidream", "cosmos", "ltxv", "hyvid", "wan"} +IMG_ARCH_LIST = {"flux", "sd1", "sdxl", "sd3", "aura", "hidream", "cosmos", "ltxv", "hyvid", "wan", "lumina2"} TXT_ARCH_LIST = {"t5", "t5encoder", "llama"} def get_orig_shape(reader, tensor_name): diff --git a/tools/convert.py b/tools/convert.py index 0078622..5029c87 100644 --- a/tools/convert.py +++ b/tools/convert.py @@ -139,8 +139,14 @@ class ModelSD1(ModelTemplate): ), # Non-diffusers ] -# The architectures are checked in order and the first successful match terminates the search. -arch_list = [ModelFlux, ModelSD3, ModelAura, ModelHiDream, CosmosPredict2, ModelLTXV, ModelHyVid, ModelWan, ModelSDXL, ModelSD1] +class ModelLumina2(ModelTemplate): + arch = "lumina2" + keys_detect = [ + ("cap_embedder.1.weight", "context_refiner.0.attention.qkv.weight") + ] + +arch_list = [ModelFlux, ModelSD3, ModelAura, ModelHiDream, CosmosPredict2, + ModelLTXV, ModelHyVid, ModelWan, ModelSDXL, ModelSD1, ModelLumina2] def is_model_arch(model, state_dict): # check if model is correct @@ -356,3 +362,4 @@ def convert_file(path, dst_path=None, interact=True, overwrite=False): if __name__ == "__main__": args = parse_args() convert_file(args.src, args.dst) + diff --git a/tools/lcpp.patch b/tools/lcpp.patch index f5f4174..92396e1 100644 --- a/tools/lcpp.patch +++ b/tools/lcpp.patch @@ -39,10 +39,10 @@ index b16c462f..6d1568f1 100644 const int idx = gguf_find_tensor(ctx, name); if (idx < 0) { diff --git a/src/llama.cpp b/src/llama.cpp -index 24e1f1f0..9957ea30 100644 +index 24e1f1f0..25db4c69 100644 --- a/src/llama.cpp +++ b/src/llama.cpp -@@ -205,6 +205,16 @@ enum llm_arch { +@@ -205,6 +205,17 @@ enum llm_arch { LLM_ARCH_GRANITE, LLM_ARCH_GRANITE_MOE, LLM_ARCH_CHAMELEON, @@ -56,10 +56,11 @@ index 24e1f1f0..9957ea30 100644 + LLM_ARCH_WAN, + LLM_ARCH_HIDREAM, + LLM_ARCH_COSMOS, ++ LLM_ARCH_LUMINA2, LLM_ARCH_UNKNOWN, }; -@@ -258,6 +268,16 @@ static const std::map LLM_ARCH_NAMES = { +@@ -258,6 +269,17 @@ static const std::map LLM_ARCH_NAMES = { { LLM_ARCH_GRANITE, "granite" }, { LLM_ARCH_GRANITE_MOE, "granitemoe" }, { LLM_ARCH_CHAMELEON, "chameleon" }, @@ -73,10 +74,11 @@ index 24e1f1f0..9957ea30 100644 + { LLM_ARCH_WAN, "wan" }, + { LLM_ARCH_HIDREAM, "hidream" }, + { LLM_ARCH_COSMOS, "cosmos" }, ++ { LLM_ARCH_LUMINA2, "lumina2" }, { LLM_ARCH_UNKNOWN, "(unknown)" }, }; -@@ -1531,6 +1551,16 @@ static const std::map> LLM_TENSOR_N +@@ -1531,6 +1553,17 @@ static const std::map> LLM_TENSOR_N { LLM_TENSOR_ATTN_K_NORM, "blk.%d.attn_k_norm" }, }, }, @@ -90,10 +92,11 @@ index 24e1f1f0..9957ea30 100644 + { LLM_ARCH_WAN, {}}, + { LLM_ARCH_HIDREAM, {}}, + { LLM_ARCH_COSMOS, {}}, ++ { LLM_ARCH_LUMINA2, {}}, { LLM_ARCH_UNKNOWN, { -@@ -5403,6 +5433,24 @@ static void llm_load_hparams( +@@ -5403,6 +5436,25 @@ static void llm_load_hparams( // get general kv ml.get_key(LLM_KV_GENERAL_NAME, model.name, false); @@ -109,6 +112,7 @@ index 24e1f1f0..9957ea30 100644 + case LLM_ARCH_WAN: + case LLM_ARCH_HIDREAM: + case LLM_ARCH_COSMOS: ++ case LLM_ARCH_LUMINA2: + model.ftype = ml.ftype; + return; + default: @@ -118,7 +122,7 @@ index 24e1f1f0..9957ea30 100644 // get hparams kv ml.get_key(LLM_KV_VOCAB_SIZE, hparams.n_vocab, false) || ml.get_arr_n(LLM_KV_TOKENIZER_LIST, hparams.n_vocab); -@@ -18016,6 +18064,132 @@ static void llama_tensor_dequantize_internal( +@@ -18016,6 +18068,134 @@ static void llama_tensor_dequantize_internal( workers.clear(); } @@ -174,7 +178,8 @@ index 24e1f1f0..9957ea30 100644 + ++qs.i_attention_wv; + } else if ( // Rules for fused qkv attention + (name.find("attn_qkv.weight") != std::string::npos) || -+ (name.find("attn.qkv.weight") != std::string::npos) ++ (name.find("attn.qkv.weight") != std::string::npos) || ++ (name.find("attention.qkv.weight") != std::string::npos) + ) { + if (ftype == LLAMA_FTYPE_MOSTLY_Q3_K_M || ftype == LLAMA_FTYPE_MOSTLY_Q3_K_L) { + new_type = GGML_TYPE_Q4_K; @@ -191,7 +196,8 @@ index 24e1f1f0..9957ea30 100644 + (name.find(".ffn.2.weight") != std::string::npos) || // is this even the right way around? + (name.find(".ff.net.2.weight") != std::string::npos) || + (name.find(".mlp.layer2.weight") != std::string::npos) || -+ (name.find(".adaln_modulation_mlp.2.weight") != std::string::npos) ++ (name.find(".adaln_modulation_mlp.2.weight") != std::string::npos) || ++ (name.find(".feed_forward.w2.weight") != std::string::npos) + ) { + // TODO: add back `layer_info` with some model specific logic + logic further down + if (ftype == LLAMA_FTYPE_MOSTLY_Q3_K_M) { @@ -251,7 +257,7 @@ index 24e1f1f0..9957ea30 100644 static ggml_type llama_tensor_get_type(quantize_state_internal & qs, ggml_type new_type, const ggml_tensor * tensor, llama_ftype ftype) { const std::string name = ggml_get_name(tensor); -@@ -18513,7 +18687,9 @@ static void llama_model_quantize_internal(const std::string & fname_inp, const s +@@ -18513,7 +18693,9 @@ static void llama_model_quantize_internal(const std::string & fname_inp, const s if (llama_model_has_encoder(&model)) { n_attn_layer *= 3; } @@ -262,7 +268,7 @@ index 24e1f1f0..9957ea30 100644 } size_t total_size_org = 0; -@@ -18547,6 +18723,51 @@ static void llama_model_quantize_internal(const std::string & fname_inp, const s +@@ -18547,6 +18729,51 @@ static void llama_model_quantize_internal(const std::string & fname_inp, const s ctx_outs[i_split] = gguf_init_empty(); } gguf_add_tensor(ctx_outs[i_split], tensor); @@ -314,7 +320,7 @@ index 24e1f1f0..9957ea30 100644 } // Set split info if needed -@@ -18647,6 +18868,101 @@ static void llama_model_quantize_internal(const std::string & fname_inp, const s +@@ -18647,6 +18874,110 @@ static void llama_model_quantize_internal(const std::string & fname_inp, const s // do not quantize relative position bias (T5) quantize &= name.find("attn_rel_b.weight") == std::string::npos; @@ -408,6 +414,15 @@ index 24e1f1f0..9957ea30 100644 + quantize &= name.find("pos_embedder.") == std::string::npos; + quantize &= name.find("final_layer.") == std::string::npos; + } ++ if (model.arch == LLM_ARCH_LUMINA2) { ++ image_model = true; ++ quantize &= name.find("t_embedder.") == std::string::npos; ++ quantize &= name.find("x_embedder.") == std::string::npos; ++ quantize &= name.find("final_layer.") == std::string::npos; ++ quantize &= name.find("cap_embedder.") == std::string::npos; ++ quantize &= name.find("context_refiner.") == std::string::npos; ++ quantize &= name.find("noise_refiner.") == std::string::npos; ++ } + // ignore 3D/4D tensors for image models as the code was never meant to handle these + if (image_model) { + quantize &= ggml_n_dims(tensor) == 2; @@ -416,7 +431,7 @@ index 24e1f1f0..9957ea30 100644 enum ggml_type new_type; void * new_data; size_t new_size; -@@ -18655,6 +18971,9 @@ static void llama_model_quantize_internal(const std::string & fname_inp, const s +@@ -18655,6 +18986,9 @@ static void llama_model_quantize_internal(const std::string & fname_inp, const s new_type = default_type; // get more optimal quantization type based on the tensor shape, layer, etc. @@ -426,7 +441,7 @@ index 24e1f1f0..9957ea30 100644 if (!params->pure && ggml_is_quantized(default_type)) { new_type = llama_tensor_get_type(qs, new_type, tensor, ftype); } -@@ -18664,6 +18983,7 @@ static void llama_model_quantize_internal(const std::string & fname_inp, const s +@@ -18664,6 +18998,7 @@ static void llama_model_quantize_internal(const std::string & fname_inp, const s if (params->output_tensor_type < GGML_TYPE_COUNT && strcmp(tensor->name, "output.weight") == 0) { new_type = params->output_tensor_type; } From f1377afd9b5696a2a44784740e97d874719b0267 Mon Sep 17 00:00:00 2001 From: sfinktah Date: Tue, 5 Aug 2025 20:44:09 +1000 Subject: [PATCH 2/3] Updated quantizing tool guide to compile with Visual Studio 2022 (#288) --- tools/README.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/tools/README.md b/tools/README.md index ec98261..228bc22 100644 --- a/tools/README.md +++ b/tools/README.md @@ -40,6 +40,8 @@ git apply ..\lcpp.patch Compile the llama-quantize binary. This example uses cmake, on linux you can just use make. +### Visual Studio 2019, Linux, etc... + ``` mkdir build cmake -B build @@ -47,6 +49,31 @@ cmake --build build --config Debug -j10 --target llama-quantize cd .. ``` +### Visual Studio 2022 + +``` +mkdir build +cmake -B build -DCMAKE_CXX_STANDARD=17 -DCMAKE_CXX_STANDARD_REQUIRED=ON -DCMAKE_CXX_FLAGS="-std=c++17" +``` + +Edit the `llama.cpp\common\log.cpp` file, inserts two lines after the existing first line: + +``` +#include "log.h" + +#define _SILENCE_CXX23_CHRONO_DEPRECATION_WARNING +#include +``` + +Then you can build the project: +``` +cmake --build build --config Debug -j10 --target llama-quantize +cd .. +``` + +### Quantize your model + + Now you can use the newly build binary to quantize your model to the desired format: ``` llama.cpp\build\bin\Debug\llama-quantize.exe E:\models\unet\flux1-dev-BF16.gguf E:\models\unet\flux1-dev-Q4_K_S.gguf Q4_K_S From 79ba1d4b17933dbe0e1597201063ba1865f23759 Mon Sep 17 00:00:00 2001 From: City <125218114+city96@users.noreply.github.com> Date: Tue, 5 Aug 2025 12:44:57 +0200 Subject: [PATCH 3/3] Qwen image arch string --- loader.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/loader.py b/loader.py index 2204b33..3d72922 100644 --- a/loader.py +++ b/loader.py @@ -7,7 +7,7 @@ import gguf from .ops import GGMLTensor from .dequant import is_quantized, dequantize_tensor -IMG_ARCH_LIST = {"flux", "sd1", "sdxl", "sd3", "aura", "hidream", "cosmos", "ltxv", "hyvid", "wan", "lumina2"} +IMG_ARCH_LIST = {"flux", "sd1", "sdxl", "sd3", "aura", "hidream", "cosmos", "ltxv", "hyvid", "wan", "lumina2", "qwen_image"} TXT_ARCH_LIST = {"t5", "t5encoder", "llama"} def get_orig_shape(reader, tensor_name):