diff --git a/ggml/src/gguf.cpp b/ggml/src/gguf.cpp index 61026df1c6ab..c4b9b54290ea 100644 --- a/ggml/src/gguf.cpp +++ b/ggml/src/gguf.cpp @@ -91,41 +91,48 @@ struct type_to_gguf_type { static constexpr enum gguf_type value = GGUF_TYPE_FLOAT64; }; -static const std::map GGUF_TYPE_SIZE = { - {GGUF_TYPE_UINT8, sizeof(uint8_t)}, - {GGUF_TYPE_INT8, sizeof(int8_t)}, - {GGUF_TYPE_UINT16, sizeof(uint16_t)}, - {GGUF_TYPE_INT16, sizeof(int16_t)}, - {GGUF_TYPE_UINT32, sizeof(uint32_t)}, - {GGUF_TYPE_INT32, sizeof(int32_t)}, - {GGUF_TYPE_FLOAT32, sizeof(float)}, - {GGUF_TYPE_BOOL, sizeof(int8_t)}, - {GGUF_TYPE_STRING, 0}, // undefined - {GGUF_TYPE_ARRAY, 0}, // undefined - {GGUF_TYPE_UINT64, sizeof(uint64_t)}, - {GGUF_TYPE_INT64, sizeof(int64_t)}, - {GGUF_TYPE_FLOAT64, sizeof(double)}, -}; -static_assert(GGUF_TYPE_COUNT == 13, "GGUF_TYPE_COUNT != 13"); - -static const std::map GGUF_TYPE_NAME = { - {GGUF_TYPE_UINT8, "u8"}, - {GGUF_TYPE_INT8, "i8"}, - {GGUF_TYPE_UINT16, "u16"}, - {GGUF_TYPE_INT16, "i16"}, - {GGUF_TYPE_UINT32, "u32"}, - {GGUF_TYPE_INT32, "i32"}, - {GGUF_TYPE_FLOAT32, "f32"}, - {GGUF_TYPE_BOOL, "bool"}, - {GGUF_TYPE_STRING, "str"}, - {GGUF_TYPE_ARRAY, "arr"}, - {GGUF_TYPE_UINT64, "u64"}, - {GGUF_TYPE_INT64, "i64"}, - {GGUF_TYPE_FLOAT64, "f64"}, -}; -static_assert(GGUF_TYPE_COUNT == 13, "GGUF_TYPE_COUNT != 13"); +static const std::map & get_gguf_type_size_map() { + static const std::map GGUF_TYPE_SIZE = { + {GGUF_TYPE_UINT8, sizeof(uint8_t)}, + {GGUF_TYPE_INT8, sizeof(int8_t)}, + {GGUF_TYPE_UINT16, sizeof(uint16_t)}, + {GGUF_TYPE_INT16, sizeof(int16_t)}, + {GGUF_TYPE_UINT32, sizeof(uint32_t)}, + {GGUF_TYPE_INT32, sizeof(int32_t)}, + {GGUF_TYPE_FLOAT32, sizeof(float)}, + {GGUF_TYPE_BOOL, sizeof(int8_t)}, + {GGUF_TYPE_STRING, 0}, // undefined + {GGUF_TYPE_ARRAY, 0}, // undefined + {GGUF_TYPE_UINT64, sizeof(uint64_t)}, + {GGUF_TYPE_INT64, sizeof(int64_t)}, + {GGUF_TYPE_FLOAT64, sizeof(double)}, + }; + static_assert(GGUF_TYPE_COUNT == 13, "GGUF_TYPE_COUNT != 13"); + return GGUF_TYPE_SIZE; +} + +static const std::map & get_gguf_type_name_map() { + static const std::map GGUF_TYPE_NAME = { + {GGUF_TYPE_UINT8, "u8"}, + {GGUF_TYPE_INT8, "i8"}, + {GGUF_TYPE_UINT16, "u16"}, + {GGUF_TYPE_INT16, "i16"}, + {GGUF_TYPE_UINT32, "u32"}, + {GGUF_TYPE_INT32, "i32"}, + {GGUF_TYPE_FLOAT32, "f32"}, + {GGUF_TYPE_BOOL, "bool"}, + {GGUF_TYPE_STRING, "str"}, + {GGUF_TYPE_ARRAY, "arr"}, + {GGUF_TYPE_UINT64, "u64"}, + {GGUF_TYPE_INT64, "i64"}, + {GGUF_TYPE_FLOAT64, "f64"}, + }; + static_assert(GGUF_TYPE_COUNT == 13, "GGUF_TYPE_COUNT != 13"); + return GGUF_TYPE_NAME; +} size_t gguf_type_size(enum gguf_type type) { + const auto & GGUF_TYPE_SIZE = get_gguf_type_size_map(); auto it = GGUF_TYPE_SIZE.find(type); return it == GGUF_TYPE_SIZE.end() ? 0 : it->second; } @@ -999,6 +1006,7 @@ void gguf_free(struct gguf_context * ctx) { } const char * gguf_type_name(enum gguf_type type) { + const auto & GGUF_TYPE_NAME = get_gguf_type_name_map(); auto it = GGUF_TYPE_NAME.find(type); return it == GGUF_TYPE_NAME.end() ? nullptr : it->second; } diff --git a/src/llama-arch.cpp b/src/llama-arch.cpp index 4a52d977297c..b09fe1e25058 100644 --- a/src/llama-arch.cpp +++ b/src/llama-arch.cpp @@ -5,7 +5,8 @@ #include #include -static const std::map LLM_ARCH_NAMES = { +static const std::map & get_llm_arch_names() { + static const std::map LLM_ARCH_NAMES = { { LLM_ARCH_CLIP, "clip" }, // dummy, only used by llama-quantize { LLM_ARCH_LLAMA, "llama" }, { LLM_ARCH_LLAMA4, "llama4" }, @@ -139,9 +140,12 @@ static const std::map LLM_ARCH_NAMES = { { LLM_ARCH_TALKIE, "talkie" }, { LLM_ARCH_MELLUM, "mellum" }, { LLM_ARCH_UNKNOWN, "(unknown)" }, -}; + }; + return LLM_ARCH_NAMES; +} -static const std::map LLM_KV_NAMES = { +static const std::map & get_llm_kv_names() { + static const std::map LLM_KV_NAMES = { { LLM_KV_GENERAL_TYPE, "general.type" }, { LLM_KV_GENERAL_ARCHITECTURE, "general.architecture" }, { LLM_KV_GENERAL_QUANTIZATION_VERSION, "general.quantization_version" }, @@ -354,9 +358,12 @@ static const std::map LLM_KV_NAMES = { { LLM_KV_TOKENIZER_PREFIX_ID, "tokenizer.ggml.prefix_token_id" }, { LLM_KV_TOKENIZER_SUFFIX_ID, "tokenizer.ggml.suffix_token_id" }, { LLM_KV_TOKENIZER_MIDDLE_ID, "tokenizer.ggml.middle_token_id" }, -}; + }; + return LLM_KV_NAMES; +} -static const std::map LLM_TENSOR_NAMES = { +static const std::map & get_llm_tensor_names() { + static const std::map LLM_TENSOR_NAMES = { { LLM_TENSOR_TOKEN_EMBD, "token_embd" }, { LLM_TENSOR_OUTPUT_NORM, "output_norm" }, { LLM_TENSOR_OUTPUT_NORM_LFM2, "token_embd_norm" }, // fix for wrong tensor name @@ -569,7 +576,9 @@ static const std::map LLM_TENSOR_NAMES = { { LLM_TENSOR_MASKED_EMBD_ORDERING, "masked_embd_ordering" }, { LLM_TENSOR_FC, "fc" }, { LLM_TENSOR_D2T, "d2t" }, -}; + }; + return LLM_TENSOR_NAMES; +} // declare information about the model weight tensors: // - the layer in which the tensor is going to be used. this is needed in order to assign the correct buffer type for the weight @@ -581,7 +590,8 @@ static const std::map LLM_TENSOR_NAMES = { // assignment of the buffer types and extra overhead during computation // example: https://github.com/ggml-org/llama.cpp/pull/17548 // -static const std::map LLM_TENSOR_INFOS = { +static const std::map & get_llm_tensor_infos() { + static const std::map LLM_TENSOR_INFOS = { {LLM_TENSOR_TOKEN_EMBD, {LLM_TENSOR_LAYER_INPUT, GGML_OP_GET_ROWS}}, {LLM_TENSOR_POS_EMBD, {LLM_TENSOR_LAYER_INPUT, GGML_OP_GET_ROWS}}, {LLM_TENSOR_TOKEN_TYPES, {LLM_TENSOR_LAYER_INPUT, GGML_OP_GET_ROWS}}, @@ -798,12 +808,14 @@ static const std::map LLM_TENSOR_INFOS = { // eagle3 {LLM_TENSOR_FC, {LLM_TENSOR_LAYER_OUTPUT, GGML_OP_MUL_MAT}}, {LLM_TENSOR_D2T, {LLM_TENSOR_LAYER_OUTPUT, GGML_OP_GET_ROWS}}, -}; + }; + return LLM_TENSOR_INFOS; +} LLM_KV::LLM_KV(llm_arch arch, const char * suffix) : arch(arch), suffix(suffix) {} std::string LLM_KV::operator()(llm_kv kv) const { - std::string name = ::format(LLM_KV_NAMES.at(kv), LLM_ARCH_NAMES.at(arch)); + std::string name = ::format(get_llm_kv_names().at(kv), get_llm_arch_names().at(arch)); if (suffix != nullptr) { name += "."; @@ -817,6 +829,7 @@ LLM_TN_IMPL::LLM_TN_IMPL(llm_arch arch, llm_tensor tensor, const char * suffix, : arch(arch), tensor(tensor), suffix(suffix), bid(bid), xid(xid) {} std::string LLM_TN_IMPL::str() const { + const auto & LLM_TENSOR_NAMES = get_llm_tensor_names(); if (LLM_TENSOR_NAMES.find(tensor) == LLM_TENSOR_NAMES.end()) { GGML_ABORT("unknown tensor name for tensor id %d", static_cast(tensor)); } @@ -832,6 +845,7 @@ std::string LLM_TN_IMPL::str() const { std::vector llm_arch_all() { std::vector ret; + const auto & LLM_ARCH_NAMES = get_llm_arch_names(); ret.reserve(LLM_ARCH_NAMES.size()); for (const auto & [arch, _] : LLM_ARCH_NAMES) { ret.push_back(arch); @@ -840,6 +854,7 @@ std::vector llm_arch_all() { } const char * llm_arch_name(llm_arch arch) { + const auto & LLM_ARCH_NAMES = get_llm_arch_names(); auto it = LLM_ARCH_NAMES.find(arch); if (it == LLM_ARCH_NAMES.end()) { return "unknown"; @@ -848,7 +863,7 @@ const char * llm_arch_name(llm_arch arch) { } llm_arch llm_arch_from_string(const std::string & name) { - for (const auto & kv : LLM_ARCH_NAMES) { // NOLINT + for (const auto & kv : get_llm_arch_names()) { // NOLINT if (kv.second == name) { return kv.first; } @@ -858,7 +873,7 @@ llm_arch llm_arch_from_string(const std::string & name) { } const llm_tensor_info & llm_tensor_info_for(llm_tensor tensor) { - return LLM_TENSOR_INFOS.at(tensor); + return get_llm_tensor_infos().at(tensor); } bool llm_arch_is_recurrent(const llm_arch & arch) { diff --git a/src/llama-chat.cpp b/src/llama-chat.cpp index d08ce353a113..6c16838fda83 100644 --- a/src/llama-chat.cpp +++ b/src/llama-chat.cpp @@ -27,7 +27,8 @@ static std::string trim(const std::string & str) { return str.substr(start, end - start); } -static const std::map LLM_CHAT_TEMPLATES = { +static const std::map & get_llm_chat_templates() { + static const std::map LLM_CHAT_TEMPLATES = { { "chatml", LLM_CHAT_TEMPLATE_CHATML }, { "llama2", LLM_CHAT_TEMPLATE_LLAMA_2 }, { "llama2-sys", LLM_CHAT_TEMPLATE_LLAMA_2_SYS }, @@ -82,10 +83,12 @@ static const std::map LLM_CHAT_TEMPLATES = { { "grok-2", LLM_CHAT_TEMPLATE_GROK_2 }, { "pangu-embedded", LLM_CHAT_TEMPLATE_PANGU_EMBED }, { "solar-open", LLM_CHAT_TEMPLATE_SOLAR_OPEN }, -}; + }; + return LLM_CHAT_TEMPLATES; +} llm_chat_template llm_chat_template_from_str(const std::string & name) { - return LLM_CHAT_TEMPLATES.at(name); + return get_llm_chat_templates().at(name); } llm_chat_template llm_chat_detect_template(const std::string & tmpl) { @@ -96,6 +99,7 @@ llm_chat_template llm_chat_detect_template(const std::string & tmpl) { // ignore } #endif + const auto & LLM_CHAT_TEMPLATES = get_llm_chat_templates(); auto chat_template = LLM_CHAT_TEMPLATES.find(tmpl); if (chat_template != LLM_CHAT_TEMPLATES.end()) { return chat_template->second; @@ -956,6 +960,7 @@ int32_t llm_chat_apply_template( // public interface int32_t llama_chat_builtin_templates(const char ** output, size_t len) { + const auto & LLM_CHAT_TEMPLATES = get_llm_chat_templates(); auto it = LLM_CHAT_TEMPLATES.begin(); for (size_t i = 0; i < std::min(len, LLM_CHAT_TEMPLATES.size()); i++) { output[i] = it->first.c_str(); diff --git a/src/llama-model.cpp b/src/llama-model.cpp index f9a1a7a446b1..201580ca9012 100644 --- a/src/llama-model.cpp +++ b/src/llama-model.cpp @@ -820,19 +820,22 @@ static const char * llama_expert_gating_func_name(llama_expert_gating_func_type } } -static const std::map LLAMA_ROPE_SCALING_TYPES = { - { LLAMA_ROPE_SCALING_TYPE_NONE, "none" }, - { LLAMA_ROPE_SCALING_TYPE_LINEAR, "linear" }, - { LLAMA_ROPE_SCALING_TYPE_YARN, "yarn" }, - { LLAMA_ROPE_SCALING_TYPE_LONGROPE, "longrope" }, -}; +static const std::map & get_llama_rope_scaling_types() { + static const std::map LLAMA_ROPE_SCALING_TYPES = { + { LLAMA_ROPE_SCALING_TYPE_NONE, "none" }, + { LLAMA_ROPE_SCALING_TYPE_LINEAR, "linear" }, + { LLAMA_ROPE_SCALING_TYPE_YARN, "yarn" }, + { LLAMA_ROPE_SCALING_TYPE_LONGROPE, "longrope" }, + }; + return LLAMA_ROPE_SCALING_TYPES; +} std::string llama_rope_scaling_type_name(llama_rope_scaling_type rope_scaling_type) { - return LLAMA_ROPE_SCALING_TYPES.at(rope_scaling_type); + return get_llama_rope_scaling_types().at(rope_scaling_type); } static llama_rope_scaling_type llama_rope_scaling_type_from_string(const std::string & name) { - for (const auto & kv : LLAMA_ROPE_SCALING_TYPES) { + for (const auto & kv : get_llama_rope_scaling_types()) { if (kv.second == name) { return (llama_rope_scaling_type) kv.first; } @@ -845,17 +848,21 @@ static llama_rope_scaling_type llama_rope_scaling_type_from_string(const std::st // graph builders. Only gated activations that map cleanly to llm_ffn_op_type are // listed; unrecognized values fall back to GeGLU, which matches the historical // default for ModernBert-style architectures. -static const std::map LLM_FFN_OP_TYPES_FROM_STRING = { - { "gelu", LLM_FFN_GEGLU }, - { "geglu", LLM_FFN_GEGLU }, - { "silu", LLM_FFN_SWIGLU }, - { "swish", LLM_FFN_SWIGLU }, - { "swiglu", LLM_FFN_SWIGLU }, - { "relu", LLM_FFN_RELU }, - { "reglu", LLM_FFN_REGLU }, -}; +static const std::map & get_llm_ffn_op_types_from_string() { + static const std::map LLM_FFN_OP_TYPES_FROM_STRING = { + { "gelu", LLM_FFN_GEGLU }, + { "geglu", LLM_FFN_GEGLU }, + { "silu", LLM_FFN_SWIGLU }, + { "swish", LLM_FFN_SWIGLU }, + { "swiglu", LLM_FFN_SWIGLU }, + { "relu", LLM_FFN_RELU }, + { "reglu", LLM_FFN_REGLU }, + }; + return LLM_FFN_OP_TYPES_FROM_STRING; +} llm_ffn_op_type llm_ffn_op_type_from_string(const std::string & name, llm_ffn_op_type fallback) { + const auto & LLM_FFN_OP_TYPES_FROM_STRING = get_llm_ffn_op_types_from_string(); const auto it = LLM_FFN_OP_TYPES_FROM_STRING.find(name); if (it != LLM_FFN_OP_TYPES_FROM_STRING.end()) { return it->second; diff --git a/src/unicode-data.cpp b/src/unicode-data.cpp index 04dcd7fcfbce..8904adf6a115 100644 --- a/src/unicode-data.cpp +++ b/src/unicode-data.cpp @@ -2283,7 +2283,8 @@ const std::initializer_list> unicode_ranges_flags {0x110000, 0x0000}, }; -const std::unordered_set unicode_set_whitespace = { +const std::unordered_set & get_unicode_set_whitespace() { + static const std::unordered_set unicode_set_whitespace = { 0x000009, 0x00000A, 0x00000B, @@ -2309,7 +2310,9 @@ const std::unordered_set unicode_set_whitespace = { 0x00202F, 0x00205F, 0x003000, -}; + }; + return unicode_set_whitespace; +} // list is always in ascending order, to enable binary search const std::initializer_list> unicode_map_lowercase = { diff --git a/src/unicode-data.h b/src/unicode-data.h index f6973ebd2e35..cafaa0064ea1 100644 --- a/src/unicode-data.h +++ b/src/unicode-data.h @@ -14,7 +14,11 @@ struct range_nfd { static const uint32_t MAX_CODEPOINTS = 0x110000; extern const std::initializer_list> unicode_ranges_flags; -extern const std::unordered_set unicode_set_whitespace; +// Firefox (no static constructors): the std::unordered_set has a non-trivial +// constructor/destructor, so expose it via a lazily-initialized accessor instead +// of a load-time global. The initializer_list globals are constant-initialized +// and need no such treatment. +const std::unordered_set & get_unicode_set_whitespace(); extern const std::initializer_list> unicode_map_lowercase; extern const std::initializer_list> unicode_map_uppercase; extern const std::initializer_list unicode_ranges_nfd; diff --git a/src/unicode.cpp b/src/unicode.cpp index 4a2f58237548..052d0fa8c670 100644 --- a/src/unicode.cpp +++ b/src/unicode.cpp @@ -128,6 +128,7 @@ static std::vector unicode_cpt_flags_array() { } } + const auto & unicode_set_whitespace = get_unicode_set_whitespace(); for (auto cpt : unicode_set_whitespace) { cpt_flags[cpt].is_whitespace = true; }