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
1 change: 1 addition & 0 deletions conversion/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
TEXT_MODEL_MAP: dict[str, str] = {
"AfmoeForCausalLM": "afmoe",
"LagunaForCausalLM": "laguna",
"FlintForCausalLM": "flint",
"ApertusForCausalLM": "llama",
"ArceeForCausalLM": "llama",
"ArcticForCausalLM": "arctic",
Expand Down
5 changes: 4 additions & 1 deletion conversion/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -1701,7 +1701,7 @@ def set_gguf_parameters(self):
self.gguf_writer.add_expert_group_used_count(n_group_used)
logger.info(f"gguf: expert groups used count = {n_group_used}")

if (score_func := self.find_hparam(["score_function", "scoring_func", "score_func", "moe_router_activation", "moe_router_activation_func", "expert_selection_fn", "router_score_func"], optional=True)) is not None:
if (score_func := self.find_hparam(["score_function", "scoring_func", "score_func", "moe_router_activation", "moe_router_activation_func", "expert_selection_fn", "router_score_func", "router_score_function"], optional=True)) is not None:
if score_func == "sigmoid":
self.gguf_writer.add_expert_gating_func(gguf.ExpertGatingFuncType.SIGMOID)
elif score_func == "softmax":
Expand Down Expand Up @@ -1939,6 +1939,9 @@ def get_vocab_base_pre(self, tokenizer) -> str:
if chkhsh == "52df12b4c8d4176e7481aab4b6e8454d1fd0a210a04a574f6d4e067d10e23c3e":
# ref: https://huggingface.co/CohereLabs/North-Mini-Code-1.0
res = "cohere2moe"
if chkhsh == "d5420e601e979078c670bc503d9ac411c311fa76b76a76267c31e0d6ba816637":
# ref: https://huggingface.co/RecursiveSI/flint-preview
res = "flint"
if chkhsh == "e636dc30a262dcc0d8c323492e32ae2b70728f4df7dfe9737d9f920a282b8aea":
# ref: https://huggingface.co/Qwen/Qwen1.5-7B
res = "qwen2"
Expand Down
38 changes: 38 additions & 0 deletions conversion/flint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from __future__ import annotations

from .base import ModelBase, gguf
from .qwen import Qwen2MoeModel


@ModelBase.register("FlintForCausalLM")
@ModelBase.example("RecursiveSI/flint-preview")
class FlintModel(Qwen2MoeModel):
model_arch = gguf.MODEL_ARCH.FLINT

def set_gguf_parameters(self):
super().set_gguf_parameters()
dense = self.hparams["mlp_only_layers"]
if dense != list(range(len(dense))):
raise ValueError("Flint dense layers must precede the MoE layers")
self.gguf_writer.add_leading_dense_block_count(len(dense))
self.gguf_writer.add_expert_shared_count(
self.hparams["shared_expert_intermediate_size"] // self.hparams["moe_intermediate_size"]
)
self.gguf_writer.add_expert_weights_norm(True)
self.gguf_writer.add_expert_weights_scale(1.0)
self.gguf_writer.add_sliding_window(self.hparams["sliding_window"])
self.gguf_writer.add_sliding_window_pattern([
kind == "sliding_attention" for kind in self.hparams["layer_types"]
])
self.gguf_writer.add_rope_pattern([
i not in self.hparams["no_rope_layer_indices"] for i in range(self.block_count)
])

def modify_tensors(self, data_torch, name, bid):
if name.endswith(".softmax_offset"):
name += ".weight"
if name.endswith(".gate.expert_bias"):
if not self.hparams["router_expert_bias"]:
return
name += ".bias"
yield from super().modify_tensors(data_torch, name, bid)
1 change: 1 addition & 0 deletions convert_hf_to_gguf_update.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ class TOKENIZER_TYPE(IntEnum):
{"name": "command-r", "tokt": TOKENIZER_TYPE.BPE, "repo": "https://huggingface.co/CohereForAI/c4ai-command-r-v01", },
{"name": "tiny_aya", "tokt": TOKENIZER_TYPE.BPE, "repo": "https://huggingface.co/CohereLabs/tiny-aya-base", },
{"name": "cohere2moe", "tokt": TOKENIZER_TYPE.BPE, "repo": "https://huggingface.co/CohereLabs/North-Mini-Code-1.0", },
{"name": "flint", "tokt": TOKENIZER_TYPE.BPE, "repo": "https://huggingface.co/RecursiveSI/flint-preview", },
{"name": "qwen2", "tokt": TOKENIZER_TYPE.BPE, "repo": "https://huggingface.co/Qwen/Qwen1.5-7B", },
{"name": "olmo", "tokt": TOKENIZER_TYPE.BPE, "repo": "https://huggingface.co/allenai/OLMo-1.7-7B-hf", },
{"name": "dbrx", "tokt": TOKENIZER_TYPE.BPE, "repo": "https://huggingface.co/databricks/dbrx-base", },
Expand Down
29 changes: 29 additions & 0 deletions gguf-py/gguf/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,7 @@ class MODEL_ARCH(IntEnum):
QWEN2VL = auto()
QWEN3 = auto()
QWEN3MOE = auto()
FLINT = auto()
QWEN3NEXT = auto()
HRM_TEXT = auto()
BEAM = auto()
Expand Down Expand Up @@ -1391,6 +1392,7 @@ class MODEL_TENSOR(IntEnum):
MODEL_ARCH.QWEN2MOE: "qwen2moe",
MODEL_ARCH.QWEN2VL: "qwen2vl",
MODEL_ARCH.QWEN3: "qwen3",
MODEL_ARCH.FLINT: "flint",
MODEL_ARCH.QWEN3MOE: "qwen3moe",
MODEL_ARCH.QWEN3NEXT: "qwen3next",
MODEL_ARCH.HRM_TEXT: "hrm_text",
Expand Down Expand Up @@ -2953,6 +2955,33 @@ class MODEL_TENSOR(IntEnum):
MODEL_TENSOR.FFN_DOWN_EXP,
MODEL_TENSOR.FFN_UP_EXP,
],

MODEL_ARCH.FLINT: [
MODEL_TENSOR.TOKEN_EMBD,
MODEL_TENSOR.OUTPUT_NORM,
MODEL_TENSOR.OUTPUT,
MODEL_TENSOR.ATTN_NORM,
MODEL_TENSOR.ATTN_QKV,
MODEL_TENSOR.ATTN_Q,
MODEL_TENSOR.ATTN_Q_NORM,
MODEL_TENSOR.ATTN_K,
MODEL_TENSOR.ATTN_K_NORM,
MODEL_TENSOR.ATTN_V,
MODEL_TENSOR.ATTN_OUT,
MODEL_TENSOR.FFN_NORM,
MODEL_TENSOR.FFN_GATE_INP,
MODEL_TENSOR.FFN_GATE_EXP,
MODEL_TENSOR.FFN_DOWN_EXP,
MODEL_TENSOR.FFN_UP_EXP,
MODEL_TENSOR.ATTN_SINKS,
MODEL_TENSOR.FFN_GATE,
MODEL_TENSOR.FFN_UP,
MODEL_TENSOR.FFN_DOWN,
MODEL_TENSOR.FFN_GATE_SHEXP,
MODEL_TENSOR.FFN_UP_SHEXP,
MODEL_TENSOR.FFN_DOWN_SHEXP,
MODEL_TENSOR.FFN_EXP_PROBS_B,
],
MODEL_ARCH.QWEN3NEXT: [
MODEL_TENSOR.TOKEN_EMBD,
MODEL_TENSOR.OUTPUT_NORM,
Expand Down
1 change: 1 addition & 0 deletions gguf-py/gguf/tensor_mapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,7 @@ class TensorNameMap:
),

MODEL_TENSOR.ATTN_SINKS: (
"model.layers.{bid}.self_attn.softmax_offset", # flint
"model.layers.{bid}.self_attn.sinks", # openai-moe
"model.layers.{bid}.self_attn.attention_sink_bias", # mimov2
"model.layers.{bid}.self_attn.learnable_sink_param", # hy-v4
Expand Down
1 change: 1 addition & 0 deletions src/llama-arch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ static const std::map<llm_arch, const char *> LLM_ARCH_NAMES = {
{ LLM_ARCH_QWEN2MOE, "qwen2moe" },
{ LLM_ARCH_QWEN2VL, "qwen2vl" },
{ LLM_ARCH_QWEN3, "qwen3" },
{ LLM_ARCH_FLINT, "flint" },
{ LLM_ARCH_QWEN3MOE, "qwen3moe" },
{ LLM_ARCH_QWEN3NEXT, "qwen3next" },
{ LLM_ARCH_QWEN3VL, "qwen3vl" },
Expand Down
1 change: 1 addition & 0 deletions src/llama-arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ enum llm_arch {
LLM_ARCH_QWEN2VL,
LLM_ARCH_QWEN3,
LLM_ARCH_QWEN3MOE,
LLM_ARCH_FLINT,
LLM_ARCH_QWEN3NEXT,
LLM_ARCH_QWEN3VL,
LLM_ARCH_QWEN3VLMOE,
Expand Down
7 changes: 5 additions & 2 deletions src/llama-graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1684,7 +1684,10 @@ llm_graph_amax_src1 llm_graph_context::build_amax_src1_f16(
constexpr float k_ln_2 = 0.6931471805599453f;

ggml_tensor * e;
e = ggml_scale(ctx0, amax, 1.0f/32768.0f);
// note: this can technically be:
// e = ggml_scale(ctx0, amax, 1.0f/32768.0f);
// but we leave x32 headroom for the F16 sums of 32 values in Q8 activation blocks
e = ggml_scale(ctx0, amax, 1.0f/1024.0f);
e = ggml_log (ctx0, e);
e = ggml_scale(ctx0, e, k_log2_e);
e = ggml_ceil (ctx0, e);
Expand Down Expand Up @@ -2505,7 +2508,7 @@ ggml_tensor * llm_graph_context::build_moe_ffn(
// ref: https://github.com/ggml-org/llama.cpp/pull/30656#issuecomment-6269597922
llm_graph_amax_src1 amax_src1 = { nullptr, nullptr };

if (arch == LLM_ARCH_MISTRAL4 || arch == LLM_ARCH_MELLUM) {
if (arch == LLM_ARCH_MISTRAL4 || arch == LLM_ARCH_MELLUM || arch == LLM_ARCH_FLINT) {
amax_src1 = build_amax_src1_f16(cur);
cur = amax_src1.res;
}
Expand Down
2 changes: 1 addition & 1 deletion src/llama-graph.h
Original file line number Diff line number Diff line change
Expand Up @@ -1121,7 +1121,7 @@ struct llm_graph_context {
ggml_tensor * slots = nullptr) const;

// rescale `cur` (the src1 of a matmul) by a power of two, computed from its maximum absolute
// when the values already fit in F16, the factors are exactly 1.0f
// keep both individual values and Q8 activation block sums within F16 range
llm_graph_amax_src1 build_amax_src1_f16(
ggml_tensor * cur) const;

Expand Down
5 changes: 4 additions & 1 deletion src/llama-kv-cache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -882,7 +882,10 @@ bool llama_kv_cache::update(llama_context * lctx, bool do_shift, const stream_co
LLAMA_LOG_DEBUG("%s: applying K-shift\n", __func__);

// apply K-shift if needed
if (hparams.rope_type != LLAMA_ROPE_TYPE_NONE) {
if (hparams.rope_type != LLAMA_ROPE_TYPE_NONE &&
std::any_of(layers.begin(), layers.end(), [&](const auto & layer) {
return hparams.has_rope(layer.il);
})) {
ggml_backend_sched_reset(sched);

auto * res = lctx->get_gf_res_reserve();
Expand Down
3 changes: 3 additions & 0 deletions src/llama-model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ static llama_model * llama_model_mapping(llm_arch arch, const llama_model_params
return new llama_model_qwen2moe(params);
case LLM_ARCH_QWEN3:
return new llama_model_qwen3(params);
case LLM_ARCH_FLINT:
return new llama_model_flint(params);
case LLM_ARCH_QWEN3MOE:
return new llama_model_qwen3moe(params);
case LLM_ARCH_QWEN3VL:
Expand Down Expand Up @@ -3569,6 +3571,7 @@ llama_rope_type llama_model_rope_type(const llama_model * model) {
case LLM_ARCH_QWEN2MOE:
case LLM_ARCH_QWEN3:
case LLM_ARCH_VLLM_DECISION2:
case LLM_ARCH_FLINT:
case LLM_ARCH_QWEN3MOE:
case LLM_ARCH_LLADA_MOE:
case LLM_ARCH_RND1:
Expand Down
12 changes: 11 additions & 1 deletion src/llama-vocab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,13 @@ struct llm_tokenizer_bpe : llm_tokenizer {
llm_tokenizer_bpe(const llama_vocab & vocab) {
GGML_ASSERT(vocab.get_type() == LLAMA_VOCAB_TYPE_BPE);
switch (vocab.get_pre_type()) {
case LLAMA_VOCAB_PRE_TYPE_FLINT:
regex_exprs = {
"\\p{N}{1,3}",
"[一-龥぀-ゟ゠-ヿ]+",
"[^\\r\\n\\p{L}\\p{N}]?[\\p{Lu}\\p{Lt}\\p{Lm}\\p{Lo}\\p{M}]*[\\p{Ll}\\p{Lm}\\p{Lo}\\p{M}]+(?:'[sS]|'[tT]|'[rR][eE]|'[vV][eE]|'[mM]|'[lL][lL]|'[dD])?|[^\\r\\n\\p{L}\\p{N}]?[\\p{Lu}\\p{Lt}\\p{Lm}\\p{Lo}\\p{M}]+[\\p{Ll}\\p{Lm}\\p{Lo}\\p{M}]*(?:'[sS]|'[tT]|'[rR][eE]|'[vV][eE]|'[mM]|'[lL][lL]|'[dD])?| ?[\\p{P}\\p{S}]+[\\r\\n]*|\\s*[\\r\\n]+|\\s+(?!\\S)|\\s+",
};
break;
case LLAMA_VOCAB_PRE_TYPE_LLAMA3:
regex_exprs = {
// original regex from tokenizer.json
Expand Down Expand Up @@ -2417,6 +2424,9 @@ void llama_vocab::impl::load(llama_model_loader & ml, const LLM_KV & kv) {
LLAMA_LOG_WARN("%s: ************************************ \n", __func__);
LLAMA_LOG_WARN("%s: \n", __func__);
pre_type = LLAMA_VOCAB_PRE_TYPE_DEFAULT;
} else if (tokenizer_pre == "flint") {
pre_type = LLAMA_VOCAB_PRE_TYPE_FLINT;
clean_spaces = false;
} else if (tokenizer_pre == "default") {
pre_type = LLAMA_VOCAB_PRE_TYPE_DEFAULT;
} else if (tokenizer_pre == "minicpm5") {
Expand Down Expand Up @@ -3147,7 +3157,6 @@ void llama_vocab::impl::load(llama_model_loader & ml, const LLM_KV & kv) {
// this is currently determined based on the token text, which is obviously not ideal
// ref: https://github.com/ggml-org/llama.cpp/issues/9606
special_eog_ids.clear();

if (special_fim_pad_id != LLAMA_TOKEN_NULL && special_eog_ids.count(special_fim_pad_id) == 0) {
special_eog_ids.insert(special_fim_pad_id);
}
Expand Down Expand Up @@ -3181,6 +3190,7 @@ void llama_vocab::impl::load(llama_model_loader & ml, const LLM_KV & kv) {
|| t.first == "[EOT]" // Kimi-K2
|| t.first == "[EOS]" // Kimi-K2
|| t.first == "<|end_of_text|>"
|| (pre_type == LLAMA_VOCAB_PRE_TYPE_FLINT && (t.first == "<|user|>" || t.first == "<|observation|>"))
|| t.first == "<end_of_utterance>" // smoldocling
|| t.first == "<eos>" // gemma4
|| t.first == "<turn|>" // gemma4
Expand Down
1 change: 1 addition & 0 deletions src/llama-vocab.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ enum llama_vocab_pre_type {
LLAMA_VOCAB_PRE_TYPE_UFAKZEKA = 59,
LLAMA_VOCAB_PRE_TYPE_MMBERT = 60,
LLAMA_VOCAB_PRE_TYPE_K2_HORIZON = 61,
LLAMA_VOCAB_PRE_TYPE_FLINT = 63,
};

struct LLM_KV;
Expand Down
Loading