huihui-ai commited on
Commit
363560a
·
verified ·
1 Parent(s): cff6db8

Upload folder using huggingface_hub

Browse files
.gitattributes CHANGED
@@ -33,3 +33,6 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ Huihui-Kolibri-1-abliterated-Q4_K_M.gguf filter=lfs diff=lfs merge=lfs -text
37
+ Q8_0/Huihui-Kolibri-1-abliterated-Q8_0-00001-of-00002.gguf filter=lfs diff=lfs merge=lfs -text
38
+ Q8_0/Huihui-Kolibri-1-abliterated-Q8_0-00002-of-00002.gguf filter=lfs diff=lfs merge=lfs -text
Huihui-Kolibri-1-abliterated-Q4_K_M.gguf ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c4d5d43a98fea775eb1accc62d495cc35b8ba7f582156cb787e9a8c1d49d76f2
3
+ size 47871649600
Q8_0/Huihui-Kolibri-1-abliterated-Q8_0-00001-of-00002.gguf ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:78cca56b12683cf787c2d10238e772979fd9151f5a2d66ba28b77f764b775470
3
+ size 44679459392
Q8_0/Huihui-Kolibri-1-abliterated-Q8_0-00002-of-00002.gguf ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d02962c10c53d5245533aa334141d86afabfa5dc70cb109d19c999041ea5927c
3
+ size 38455934560
kolibri1-llama.cpp.patch ADDED
@@ -0,0 +1,669 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ From c222b50c1d4fd9ccb0ebad1d7749bda9689b3b5c Mon Sep 17 00:00:00 2001
2
+ From: Seraphiel102 <[email protected]>
3
+ Date: Sat, 3 Oct 2026 19:39:38 +0100
4
+ Subject: [PATCH 1/4] graph : add SIGMOID_LOGIT_ADD expert gating (select top-k
5
+ on logits + bias, weight by unbiased sigmoid)
6
+
7
+ Kolibri 1 (torchtitan sigmoid_logit_add router) selects experts on the
8
+ biased raw logits and weights them by the unbiased sigmoid(logits). The
9
+ existing DeepSeek-V3 path selects on sigmoid(logits) + bias, which picks
10
+ different experts whenever the bias is non-zero.
11
+
12
+ Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
13
+ ---
14
+ src/llama-graph.cpp | 12 ++++++++++--
15
+ src/llama-hparams.h | 1 +
16
+ 2 files changed, 11 insertions(+), 2 deletions(-)
17
+
18
+ diff --git a/src/llama-graph.cpp b/src/llama-graph.cpp
19
+ index 16a3ed2..0719af8 100644
20
+ --- a/src/llama-graph.cpp
21
+ +++ b/src/llama-graph.cpp
22
+ @@ -2041,7 +2041,8 @@ ggml_tensor * llm_graph_context::build_moe_ffn(
23
+
24
+ if (probs_in == nullptr) {
25
+ logits = build_lora_mm(gate_inp, cur); // [n_expert, n_tokens]
26
+ - if (gating_op == LLAMA_EXPERT_GATING_FUNC_TYPE_SQRT_SOFTPLUS) {
27
+ + if (gating_op == LLAMA_EXPERT_GATING_FUNC_TYPE_SQRT_SOFTPLUS ||
28
+ + gating_op == LLAMA_EXPERT_GATING_FUNC_TYPE_SIGMOID_LOGIT_ADD) {
29
+ ggml_prec_set_acc(logits, GGML_PREC_F32);
30
+ }
31
+ cb(logits, "ffn_moe_logits", il);
32
+ @@ -2061,6 +2062,7 @@ ggml_tensor * llm_graph_context::build_moe_ffn(
33
+ probs = ggml_soft_max(ctx0, logits); // [n_expert, n_tokens]
34
+ } break;
35
+ case LLAMA_EXPERT_GATING_FUNC_TYPE_SIGMOID:
36
+ + case LLAMA_EXPERT_GATING_FUNC_TYPE_SIGMOID_LOGIT_ADD:
37
+ {
38
+ probs = ggml_sigmoid(ctx0, logits); // [n_expert, n_tokens]
39
+ } break;
40
+ @@ -2080,7 +2082,13 @@ ggml_tensor * llm_graph_context::build_moe_ffn(
41
+ // add experts selection bias - introduced in DeepSeek V3
42
+ // leave probs unbiased as it's later used to get expert weights
43
+ ggml_tensor * selection_probs = probs;
44
+ - if (exp_probs_b != nullptr) {
45
+ + if (gating_op == LLAMA_EXPERT_GATING_FUNC_TYPE_SIGMOID_LOGIT_ADD) {
46
+ + // Kolibri 1: select on the biased raw logits (not on sigmoid(logits) + bias);
47
+ + // the expert weights stay the unbiased sigmoid(logits)
48
+ + GGML_ASSERT(exp_probs_b != nullptr && "SIGMOID_LOGIT_ADD gating requires exp_probs_b");
49
+ + selection_probs = ggml_add(ctx0, logits, exp_probs_b);
50
+ + cb(selection_probs, "ffn_moe_logits_biased", il);
51
+ + } else if (exp_probs_b != nullptr) {
52
+ selection_probs = ggml_add(ctx0, probs, exp_probs_b);
53
+ cb(selection_probs, "ffn_moe_probs_biased", il);
54
+ }
55
+ diff --git a/src/llama-hparams.h b/src/llama-hparams.h
56
+ index 6c504c5..f2e773b 100644
57
+ --- a/src/llama-hparams.h
58
+ +++ b/src/llama-hparams.h
59
+ @@ -19,6 +19,7 @@ enum llama_expert_gating_func_type {
60
+ LLAMA_EXPERT_GATING_FUNC_TYPE_SIGMOID = 2,
61
+ LLAMA_EXPERT_GATING_FUNC_TYPE_SOFTMAX_WEIGHT = 3, // applied to the router weights instead of the logits
62
+ LLAMA_EXPERT_GATING_FUNC_TYPE_SQRT_SOFTPLUS = 4,
63
+ + LLAMA_EXPERT_GATING_FUNC_TYPE_SIGMOID_LOGIT_ADD = 5, // select top-k on logits + exp_probs_b, weight by unbiased sigmoid(logits)
64
+ };
65
+
66
+ enum llama_swa_type {
67
+ --
68
+ 2.43.0
69
+
70
+
71
+ From ff8bd81628232b5a81cca248e9f7e6617e2ce58c Mon Sep 17 00:00:00 2001
72
+ From: Seraphiel102 <[email protected]>
73
+ Date: Sat, 3 Oct 2026 19:39:38 +0100
74
+ Subject: [PATCH 2/4] convert : add Kolibri1ForCausalLM (Aleph-Alpha/Kolibri-1)
75
+
76
+ - gguf-py: MODEL_ARCH.KOLIBRI1, ExpertGatingFuncType.SIGMOID_LOGIT_ADD,
77
+ arch-specific mapping of the sandwich norms (post_attn_norm ->
78
+ attn post norm, post_attention_layernorm -> ffn_norm, post_ffn_norm ->
79
+ ffn post norm) and moe.router.expert_bias -> exp_probs_b
80
+ - converter: per-layer sliding-window pattern from config.layer_types,
81
+ shared expert kept out of the routed-expert merge; FP8 128x128 block
82
+ dequant via the existing fp8 path
83
+ - tokenizer pre-type kolibri1 (same split regex as qwen2)
84
+
85
+ Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
86
+ ---
87
+ conversion/__init__.py | 1 +
88
+ conversion/base.py | 3 ++
89
+ conversion/kolibri.py | 60 ++++++++++++++++++++++++++++++++++
90
+ convert_hf_to_gguf_update.py | 1 +
91
+ gguf-py/gguf/constants.py | 26 +++++++++++++++
92
+ gguf-py/gguf/tensor_mapping.py | 15 +++++++++
93
+ src/llama-vocab.cpp | 3 +-
94
+ 7 files changed, 108 insertions(+), 1 deletion(-)
95
+ create mode 100644 conversion/kolibri.py
96
+
97
+ diff --git a/conversion/__init__.py b/conversion/__init__.py
98
+ index 051ddf9..49105d0 100644
99
+ --- a/conversion/__init__.py
100
+ +++ b/conversion/__init__.py
101
+ @@ -19,6 +19,7 @@ __all__ = [
102
+ TEXT_MODEL_MAP: dict[str, str] = {
103
+ "AfmoeForCausalLM": "afmoe",
104
+ "LagunaForCausalLM": "laguna",
105
+ + "Kolibri1ForCausalLM": "kolibri",
106
+ "ApertusForCausalLM": "llama",
107
+ "ArceeForCausalLM": "llama",
108
+ "ArcticForCausalLM": "arctic",
109
+ diff --git a/conversion/base.py b/conversion/base.py
110
+ index 0f3bd9a..b0cff23 100644
111
+ --- a/conversion/base.py
112
+ +++ b/conversion/base.py
113
+ @@ -1941,6 +1941,9 @@ class TextModel(ModelBase):
114
+ if chkhsh == "4b05e02dad1c5ae07d266fd3342ddb644c6f6be058d728bc0a33af31a1d6ee66":
115
+ # ref: https://huggingface.co/jhu-clsp/mmBERT-base
116
+ res = "mmbert"
117
+ + if chkhsh == "6e040dfe72e4b85855588c53acf4909ac4e98e55bc3a33cd7db499180dc42a78":
118
+ + # ref: https://huggingface.co/Aleph-Alpha/Kolibri-1
119
+ + res = "kolibri1"
120
+
121
+ if res is None:
122
+ logger.warning("\n")
123
+ diff --git a/conversion/kolibri.py b/conversion/kolibri.py
124
+ new file mode 100644
125
+ index 0000000..2cbff9b
126
+ --- /dev/null
127
+ +++ b/conversion/kolibri.py
128
+ @@ -0,0 +1,60 @@
129
+ +from __future__ import annotations
130
+ +
131
+ +from typing import Callable, Iterable, TYPE_CHECKING
132
+ +
133
+ +if TYPE_CHECKING:
134
+ + from torch import Tensor
135
+ +
136
+ +from .base import ModelBase, gguf
137
+ +
138
+ +from .qwen import Qwen3MoeModel
139
+ +
140
+ +
141
+ [email protected]("Kolibri1ForCausalLM")
142
+ [email protected]("Aleph-Alpha/Kolibri-1")
143
+ +class Kolibri1Model(Qwen3MoeModel):
144
+ + """Aleph Alpha Kolibri 1: Qwen3-MoE with sandwich norms, one ungated shared
145
+ + expert, interleaved sliding-window (RoPE) / full (NoPE) attention, and a
146
+ + router that selects top-k on logits + expert_bias but weights by the
147
+ + unbiased sigmoid(logits)."""
148
+ +
149
+ + model_arch = gguf.MODEL_ARCH.KOLIBRI1
150
+ +
151
+ + def set_gguf_parameters(self):
152
+ + super().set_gguf_parameters()
153
+ +
154
+ + layer_types = self.hparams["layer_types"]
155
+ + if len(layer_types) != self.block_count:
156
+ + raise ValueError(f"layer_types has {len(layer_types)} entries, expected {self.block_count}")
157
+ + unknown = set(layer_types) - {"sliding_attention", "full_attention"}
158
+ + if unknown:
159
+ + raise ValueError(f"Unsupported Kolibri 1 layer_types: {sorted(unknown)}")
160
+ +
161
+ + sliding_window = self.hparams.get("sliding_window")
162
+ + if not sliding_window or sliding_window <= 0:
163
+ + raise ValueError(f"Kolibri 1 needs a positive sliding_window, got {sliding_window}")
164
+ +
165
+ + self.gguf_writer.add_sliding_window(sliding_window)
166
+ + self.gguf_writer.add_sliding_window_pattern([t == "sliding_attention" for t in layer_types])
167
+ +
168
+ + self.gguf_writer.add_expert_shared_count(1)
169
+ + self.gguf_writer.add_expert_weights_norm(bool(self.hparams.get("norm_topk_prob", False)))
170
+ + self.gguf_writer.add_expert_gating_func(gguf.ExpertGatingFuncType.SIGMOID_LOGIT_ADD)
171
+ +
172
+ + @classmethod
173
+ + def filter_tensors(cls, item: tuple[str, Callable[[], Tensor]]) -> tuple[str, Callable[[], Tensor]] | None:
174
+ + name, gen = item
175
+ +
176
+ + # model.layers.N.moe.router.expert_bias -> exp_probs_b.bias
177
+ + if name.endswith(".moe.router.expert_bias"):
178
+ + name = name + ".bias"
179
+ +
180
+ + return super().filter_tensors((name, gen))
181
+ +
182
+ + def modify_tensors(self, data_torch: Tensor, name: str, bid: int | None) -> Iterable[tuple[str, Tensor]]:
183
+ + # the shared expert would otherwise be swallowed by the routed-expert merge in Qwen2MoeModel
184
+ + if ".mlp.shared_experts." in name:
185
+ + yield from ModelBase.modify_tensors(self, data_torch, name, bid)
186
+ + return
187
+ +
188
+ + yield from super().modify_tensors(data_torch, name, bid)
189
+ diff --git a/convert_hf_to_gguf_update.py b/convert_hf_to_gguf_update.py
190
+ index d39d2f6..641de2d 100755
191
+ --- a/convert_hf_to_gguf_update.py
192
+ +++ b/convert_hf_to_gguf_update.py
193
+ @@ -151,6 +151,7 @@ models = [
194
+ {"name": "kormo", "tokt": TOKENIZER_TYPE.BPE, "repo": "https://huggingface.co/KORMo-Team/KORMo-tokenizer", },
195
+ {"name": "youtu", "tokt": TOKENIZER_TYPE.BPE, "repo": "https://huggingface.co/tencent/Youtu-LLM-2B", },
196
+ {"name": "solar-open", "tokt": TOKENIZER_TYPE.BPE, "repo": "https://huggingface.co/upstage/Solar-Open-100B", },
197
+ + {"name": "kolibri1", "tokt": TOKENIZER_TYPE.BPE, "repo": "https://huggingface.co/Aleph-Alpha/Kolibri-1", },
198
+ {"name": "exaone-moe", "tokt": TOKENIZER_TYPE.BPE, "repo": "https://huggingface.co/LGAI-EXAONE/K-EXAONE-236B-A23B", },
199
+ {"name": "qwen35", "tokt": TOKENIZER_TYPE.BPE, "repo": "https://huggingface.co/Qwen/Qwen3.5-9B-Instruct", },
200
+ {"name": "joyai-llm", "tokt": TOKENIZER_TYPE.BPE, "repo": "https://huggingface.co/jdopensource/JoyAI-LLM-Flash", },
201
+ diff --git a/gguf-py/gguf/constants.py b/gguf-py/gguf/constants.py
202
+ index 1e0a6b1..935e88e 100644
203
+ --- a/gguf-py/gguf/constants.py
204
+ +++ b/gguf-py/gguf/constants.py
205
+ @@ -615,6 +615,7 @@ class MODEL_ARCH(IntEnum):
206
+ DOTS3NOTE = auto()
207
+ ARCEE = auto()
208
+ AFMOE = auto()
209
+ + KOLIBRI1 = auto()
210
+ LAGUNA = auto()
211
+ ERNIE4_5 = auto()
212
+ ERNIE4_5_MOE = auto()
213
+ @@ -1394,6 +1395,7 @@ MODEL_ARCH_NAMES: dict[MODEL_ARCH, str] = {
214
+ MODEL_ARCH.DOTS3NOTE: "dots3note",
215
+ MODEL_ARCH.ARCEE: "arcee",
216
+ MODEL_ARCH.AFMOE: "afmoe",
217
+ + MODEL_ARCH.KOLIBRI1: "kolibri1",
218
+ MODEL_ARCH.LAGUNA: "laguna",
219
+ MODEL_ARCH.ERNIE4_5: "ernie4_5",
220
+ MODEL_ARCH.ERNIE4_5_MOE: "ernie4_5-moe",
221
+ @@ -4864,6 +4866,29 @@ MODEL_TENSORS: dict[MODEL_ARCH, list[MODEL_TENSOR]] = {
222
+ MODEL_TENSOR.FFN_POST_NORM,
223
+ MODEL_TENSOR.FFN_EXP_PROBS_B,
224
+ ],
225
+ + MODEL_ARCH.KOLIBRI1: [
226
+ + MODEL_TENSOR.TOKEN_EMBD,
227
+ + MODEL_TENSOR.OUTPUT_NORM,
228
+ + MODEL_TENSOR.OUTPUT,
229
+ + MODEL_TENSOR.ATTN_NORM,
230
+ + MODEL_TENSOR.ATTN_POST_NORM,
231
+ + MODEL_TENSOR.ATTN_Q,
232
+ + MODEL_TENSOR.ATTN_K,
233
+ + MODEL_TENSOR.ATTN_V,
234
+ + MODEL_TENSOR.ATTN_OUT,
235
+ + MODEL_TENSOR.ATTN_Q_NORM,
236
+ + MODEL_TENSOR.ATTN_K_NORM,
237
+ + MODEL_TENSOR.FFN_NORM,
238
+ + MODEL_TENSOR.FFN_POST_NORM,
239
+ + MODEL_TENSOR.FFN_GATE_INP,
240
+ + MODEL_TENSOR.FFN_EXP_PROBS_B,
241
+ + MODEL_TENSOR.FFN_GATE_EXP,
242
+ + MODEL_TENSOR.FFN_DOWN_EXP,
243
+ + MODEL_TENSOR.FFN_UP_EXP,
244
+ + MODEL_TENSOR.FFN_GATE_SHEXP,
245
+ + MODEL_TENSOR.FFN_UP_SHEXP,
246
+ + MODEL_TENSOR.FFN_DOWN_SHEXP,
247
+ + ],
248
+ MODEL_ARCH.LAGUNA: [
249
+ MODEL_TENSOR.TOKEN_EMBD,
250
+ MODEL_TENSOR.OUTPUT_NORM,
251
+ @@ -5910,6 +5935,7 @@ class ExpertGatingFuncType(IntEnum):
252
+ SOFTMAX = 1
253
+ SIGMOID = 2
254
+ SQRTSOFTPLUS = 4
255
+ + SIGMOID_LOGIT_ADD = 5 # select top-k on logits + bias, weight by unbiased sigmoid(logits)
256
+
257
+
258
+ # TODO: add GGMLFileType from ggml_ftype in ggml.h
259
+ diff --git a/gguf-py/gguf/tensor_mapping.py b/gguf-py/gguf/tensor_mapping.py
260
+ index cef04d0..b9a7a4d 100644
261
+ --- a/gguf-py/gguf/tensor_mapping.py
262
+ +++ b/gguf-py/gguf/tensor_mapping.py
263
+ @@ -2859,6 +2859,21 @@ class TensorNameMap:
264
+
265
+ # architecture-specific block mappings
266
+ arch_block_mappings_cfg: dict[MODEL_ARCH, dict[MODEL_TENSOR, tuple[str, ...]]] = {
267
+ + MODEL_ARCH.KOLIBRI1: {
268
+ + # sandwich norms: HF "post_attention_layernorm" is the PRE-FFN norm here
269
+ + MODEL_TENSOR.ATTN_POST_NORM: (
270
+ + "model.layers.{bid}.post_attn_norm",
271
+ + ),
272
+ + MODEL_TENSOR.FFN_NORM: (
273
+ + "model.layers.{bid}.post_attention_layernorm",
274
+ + ),
275
+ + MODEL_TENSOR.FFN_POST_NORM: (
276
+ + "model.layers.{bid}.post_ffn_norm",
277
+ + ),
278
+ + MODEL_TENSOR.FFN_EXP_PROBS_B: (
279
+ + "model.layers.{bid}.moe.router.expert_bias",
280
+ + ),
281
+ + },
282
+ MODEL_ARCH.ARCTIC: {
283
+ MODEL_TENSOR.FFN_NORM: (
284
+ "model.layers.{bid}.residual_layernorm",
285
+ diff --git a/src/llama-vocab.cpp b/src/llama-vocab.cpp
286
+ index 015e983..b43a8e8 100644
287
+ --- a/src/llama-vocab.cpp
288
+ +++ b/src/llama-vocab.cpp
289
+ @@ -2293,7 +2293,8 @@ void llama_vocab::impl::load(llama_model_loader & ml, const LLM_KV & kv) {
290
+ tokenizer_pre == "qwen2" ||
291
+ tokenizer_pre == "deepseek-r1-qwen" ||
292
+ tokenizer_pre == "kormo" ||
293
+ - tokenizer_pre == "f2llmv2") {
294
+ + tokenizer_pre == "f2llmv2" ||
295
+ + tokenizer_pre == "kolibri1") {
296
+ pre_type = LLAMA_VOCAB_PRE_TYPE_QWEN2;
297
+ clean_spaces = false;
298
+ } else if (
299
+ --
300
+ 2.43.0
301
+
302
+
303
+ From 8952f522e2a19cdbb1e36f60ccc52879254f5142 Mon Sep 17 00:00:00 2001
304
+ From: Seraphiel102 <[email protected]>
305
+ Date: Sat, 3 Oct 2026 19:39:38 +0100
306
+ Subject: [PATCH 3/4] model : add Kolibri 1 (kolibri1)
307
+
308
+ Qwen3-MoE style GQA with q/k norm, interleaved sliding-window (RoPE) /
309
+ full-attention (NoPE) layers via iSWA, sandwich norms, every layer MoE
310
+ with one ungated shared expert and SIGMOID_LOGIT_ADD routing.
311
+
312
+ Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
313
+ ---
314
+ src/llama-arch.cpp | 1 +
315
+ src/llama-arch.h | 1 +
316
+ src/llama-model.cpp | 4 +
317
+ src/models/kolibri1.cpp | 208 ++++++++++++++++++++++++++++++++++++++++
318
+ src/models/models.h | 13 +++
319
+ 5 files changed, 227 insertions(+)
320
+ create mode 100644 src/models/kolibri1.cpp
321
+
322
+ diff --git a/src/llama-arch.cpp b/src/llama-arch.cpp
323
+ index 2af5445..078475b 100644
324
+ --- a/src/llama-arch.cpp
325
+ +++ b/src/llama-arch.cpp
326
+ @@ -117,6 +117,7 @@ static const std::map<llm_arch, const char *> LLM_ARCH_NAMES = {
327
+ { LLM_ARCH_ARCEE, "arcee" },
328
+ { LLM_ARCH_AFMOE, "afmoe" },
329
+ { LLM_ARCH_LAGUNA, "laguna" },
330
+ + { LLM_ARCH_KOLIBRI1, "kolibri1" },
331
+ { LLM_ARCH_ERNIE4_5, "ernie4_5" },
332
+ { LLM_ARCH_ERNIE4_5_MOE, "ernie4_5-moe" },
333
+ { LLM_ARCH_HUNYUAN_MOE, "hunyuan-moe" },
334
+ diff --git a/src/llama-arch.h b/src/llama-arch.h
335
+ index 148d293..9e977bf 100644
336
+ --- a/src/llama-arch.h
337
+ +++ b/src/llama-arch.h
338
+ @@ -122,6 +122,7 @@ enum llm_arch {
339
+ LLM_ARCH_ARCEE,
340
+ LLM_ARCH_AFMOE,
341
+ LLM_ARCH_LAGUNA,
342
+ + LLM_ARCH_KOLIBRI1,
343
+ LLM_ARCH_ERNIE4_5,
344
+ LLM_ARCH_ERNIE4_5_MOE,
345
+ LLM_ARCH_HUNYUAN_MOE,
346
+ diff --git a/src/llama-model.cpp b/src/llama-model.cpp
347
+ index 97e0cee..6795734 100644
348
+ --- a/src/llama-model.cpp
349
+ +++ b/src/llama-model.cpp
350
+ @@ -276,6 +276,8 @@ static llama_model * llama_model_mapping(llm_arch arch, const llama_model_params
351
+ return new llama_model_afmoe(params);
352
+ case LLM_ARCH_LAGUNA:
353
+ return new llama_model_laguna(params);
354
+ + case LLM_ARCH_KOLIBRI1:
355
+ + return new llama_model_kolibri1(params);
356
+ case LLM_ARCH_ERNIE4_5:
357
+ return new llama_model_ernie4_5(params);
358
+ case LLM_ARCH_ERNIE4_5_MOE:
359
+ @@ -1029,6 +1031,7 @@ static const char * llama_expert_gating_func_name(llama_expert_gating_func_type
360
+ case LLAMA_EXPERT_GATING_FUNC_TYPE_SOFTMAX: return "softmax";
361
+ case LLAMA_EXPERT_GATING_FUNC_TYPE_SIGMOID: return "sigmoid";
362
+ case LLAMA_EXPERT_GATING_FUNC_TYPE_SQRT_SOFTPLUS: return "sqrtsoftplus";
363
+ + case LLAMA_EXPERT_GATING_FUNC_TYPE_SIGMOID_LOGIT_ADD: return "sigmoid_logit_add";
364
+ default: return "unknown";
365
+ }
366
+ }
367
+ @@ -3182,6 +3185,7 @@ llama_rope_type llama_model_rope_type(const llama_model * model) {
368
+ case LLM_ARCH_PANGU_EMBED:
369
+ case LLM_ARCH_AFMOE:
370
+ case LLM_ARCH_LAGUNA:
371
+ + case LLM_ARCH_KOLIBRI1:
372
+ case LLM_ARCH_QWEN3NEXT:
373
+ case LLM_ARCH_MIMO2:
374
+ case LLM_ARCH_STEP35:
375
+ diff --git a/src/models/kolibri1.cpp b/src/models/kolibri1.cpp
376
+ new file mode 100644
377
+ index 0000000..d2a9523
378
+ --- /dev/null
379
+ +++ b/src/models/kolibri1.cpp
380
+ @@ -0,0 +1,208 @@
381
+ +#include "models.h"
382
+ +
383
+ +// Aleph Alpha Kolibri 1
384
+ +// - Qwen3-MoE style attention (GQA + per-head q/k RMSNorm)
385
+ +// - interleaved attention: sliding-window layers use RoPE, full-attention layers use no positional encoding
386
+ +// - sandwich norms around attention and MoE
387
+ +// - every layer is MoE + one ungated shared expert
388
+ +// - router: top-k selected on (logits + expert_bias), weighted by unbiased sigmoid(logits), no renormalization
389
+ +
390
+ +void llama_model_kolibri1::load_arch_hparams(llama_model_loader & ml) {
391
+ + ml.get_key(LLM_KV_ATTENTION_LAYERNORM_RMS_EPS, hparams.f_norm_rms_eps);
392
+ + ml.get_key_or_arr(LLM_KV_EXPERT_FEED_FORWARD_LENGTH, hparams.n_ff_exp_arr, hparams.n_layer_all);
393
+ + ml.get_key(LLM_KV_EXPERT_SHARED_FEED_FORWARD_LENGTH, hparams.n_ff_shexp);
394
+ + ml.get_key(LLM_KV_EXPERT_SHARED_COUNT, hparams.n_expert_shared);
395
+ + ml.get_key(LLM_KV_EXPERT_GATING_FUNC, hparams.expert_gating_func);
396
+ + ml.get_key(LLM_KV_EXPERT_WEIGHTS_NORM, hparams.expert_weights_norm, false);
397
+ + ml.get_key(LLM_KV_ATTENTION_SLIDING_WINDOW, hparams.n_swa);
398
+ +
399
+ + if (hparams.n_swa == 0) {
400
+ + throw std::runtime_error("kolibri1: sliding_window must be > 0");
401
+ + }
402
+ + if (hparams.n_expert_shared != 1) {
403
+ + throw std::runtime_error(format("kolibri1: expected exactly 1 shared expert, got %u", hparams.n_expert_shared));
404
+ + }
405
+ + if (hparams.expert_gating_func != LLAMA_EXPERT_GATING_FUNC_TYPE_SIGMOID_LOGIT_ADD) {
406
+ + throw std::runtime_error(format("kolibri1: expected expert_gating_func %d (sigmoid_logit_add), got %u",
407
+ + (int) LLAMA_EXPERT_GATING_FUNC_TYPE_SIGMOID_LOGIT_ADD, hparams.expert_gating_func));
408
+ + }
409
+ +
410
+ + // 4 sliding + 1 full by default; the converter writes the exact per-layer pattern from config.layer_types
411
+ + hparams.swa_type = LLAMA_SWA_TYPE_STANDARD;
412
+ + load_swa_pattern(ml, 5);
413
+ +
414
+ + // full-attention layers are NoPE (handled in the graph); sliding layers use the base rope params
415
+ + hparams.rope_freq_base_train_swa = hparams.rope_freq_base_train;
416
+ + hparams.rope_freq_scale_train_swa = hparams.rope_freq_scale_train;
417
+ + ml.get_key(LLM_KV_ROPE_FREQ_BASE_SWA, hparams.rope_freq_base_train_swa, false);
418
+ +
419
+ + type = LLM_TYPE_UNKNOWN;
420
+ +}
421
+ +
422
+ +void llama_model_kolibri1::load_arch_tensors(llama_model_loader &) {
423
+ + LLAMA_LOAD_LOCALS;
424
+ +
425
+ + tok_embd = create_tensor(tn(LLM_TENSOR_TOKEN_EMBD, "weight"), {n_embd, n_vocab}, 0);
426
+ +
427
+ + output_norm = create_tensor(tn(LLM_TENSOR_OUTPUT_NORM, "weight"), {n_embd}, 0);
428
+ + output = create_tensor(tn(LLM_TENSOR_OUTPUT, "weight"), {n_embd, n_vocab}, TENSOR_NOT_REQUIRED);
429
+ + if (output == NULL) {
430
+ + output = create_tensor(tn(LLM_TENSOR_TOKEN_EMBD, "weight"), {n_embd, n_vocab}, TENSOR_DUPLICATED);
431
+ + }
432
+ +
433
+ + if (n_expert == 0 || n_expert_used == 0) {
434
+ + throw std::runtime_error("kolibri1: n_expert and n_expert_used must be > 0");
435
+ + }
436
+ +
437
+ + const int64_t n_ff_exp = hparams.n_ff_exp();
438
+ + const int64_t n_ff_shexp = hparams.n_ff_shexp;
439
+ +
440
+ + for (int i = 0; i < n_layer; ++i) {
441
+ + auto & layer = layers[i];
442
+ +
443
+ + layer.attn_norm = create_tensor(tn(LLM_TENSOR_ATTN_NORM, "weight", i), {n_embd}, 0);
444
+ + layer.attn_post_norm = create_tensor(tn(LLM_TENSOR_ATTN_POST_NORM, "weight", i), {n_embd}, 0);
445
+ +
446
+ + create_tensor_qkv(layer, i, n_embd, n_embd_head_k * n_head, n_embd_k_gqa, n_embd_v_gqa, 0);
447
+ + layer.wo = create_tensor(tn(LLM_TENSOR_ATTN_OUT, "weight", i), {n_embd_head_k * n_head, n_embd}, 0);
448
+ +
449
+ + layer.attn_q_norm = create_tensor(tn(LLM_TENSOR_ATTN_Q_NORM, "weight", i), {n_embd_head_k}, 0);
450
+ + layer.attn_k_norm = create_tensor(tn(LLM_TENSOR_ATTN_K_NORM, "weight", i), {n_embd_head_k}, 0);
451
+ +
452
+ + layer.ffn_norm = create_tensor(tn(LLM_TENSOR_FFN_NORM, "weight", i), {n_embd}, 0);
453
+ + layer.ffn_post_norm = create_tensor(tn(LLM_TENSOR_FFN_POST_NORM, "weight", i), {n_embd}, 0);
454
+ +
455
+ + layer.ffn_gate_inp = create_tensor(tn(LLM_TENSOR_FFN_GATE_INP, "weight", i), {n_embd, n_expert}, 0);
456
+ + layer.ffn_exp_probs_b = create_tensor(tn(LLM_TENSOR_FFN_EXP_PROBS_B, "bias", i), {n_expert}, 0);
457
+ +
458
+ + layer.ffn_gate_exps = create_tensor(tn(LLM_TENSOR_FFN_GATE_EXPS, "weight", i), { n_embd, n_ff_exp, n_expert}, 0);
459
+ + layer.ffn_down_exps = create_tensor(tn(LLM_TENSOR_FFN_DOWN_EXPS, "weight", i), {n_ff_exp, n_embd, n_expert}, 0);
460
+ + layer.ffn_up_exps = create_tensor(tn(LLM_TENSOR_FFN_UP_EXPS, "weight", i), { n_embd, n_ff_exp, n_expert}, 0);
461
+ +
462
+ + layer.ffn_gate_shexp = create_tensor(tn(LLM_TENSOR_FFN_GATE_SHEXP, "weight", i), { n_embd, n_ff_shexp}, 0);
463
+ + layer.ffn_down_shexp = create_tensor(tn(LLM_TENSOR_FFN_DOWN_SHEXP, "weight", i), {n_ff_shexp, n_embd}, 0);
464
+ + layer.ffn_up_shexp = create_tensor(tn(LLM_TENSOR_FFN_UP_SHEXP, "weight", i), { n_embd, n_ff_shexp}, 0);
465
+ + }
466
+ +}
467
+ +
468
+ +std::unique_ptr<llm_graph_context> llama_model_kolibri1::build_arch_graph(const llm_graph_params & params) const {
469
+ + return std::make_unique<graph>(*this, params);
470
+ +}
471
+ +
472
+ +llama_model_kolibri1::graph::graph(const llama_model & model, const llm_graph_params & params) : llm_graph_context(params) {
473
+ + const int64_t n_embd_head = hparams.n_embd_head_v();
474
+ + GGML_ASSERT(n_embd_head == hparams.n_embd_head_k());
475
+ +
476
+ + ggml_tensor * cur;
477
+ + ggml_tensor * inpL;
478
+ +
479
+ + inpL = build_inp_embd(model.tok_embd);
480
+ +
481
+ + ggml_tensor * inp_pos = build_inp_pos();
482
+ + auto * inp_attn = build_attn_inp_kv_iswa();
483
+ + ggml_tensor * inp_out_ids = build_inp_out_ids();
484
+ +
485
+ + const float kq_scale = 1.0f/sqrtf(float(n_embd_head));
486
+ +
487
+ + for (int il = 0; il < n_layer; ++il) {
488
+ + const auto & layer = model.layers[il];
489
+ +
490
+ + // sliding layers: RoPE; full-attention layers: no positional encoding (RNoPE)
491
+ + const bool use_rope = hparams.is_swa(il);
492
+ +
493
+ + ggml_tensor * inpSA = inpL;
494
+ +
495
+ + cur = build_norm(inpL, layer.attn_norm, NULL, LLM_NORM_RMS, il);
496
+ + cb(cur, "attn_norm", il);
497
+ +
498
+ + // self-attention
499
+ + {
500
+ + auto [Qcur, Kcur, Vcur] = build_qkv(layer, cur, n_embd_head, n_head, n_head_kv, il);
501
+ +
502
+ + Qcur = build_norm(Qcur, layer.attn_q_norm, NULL, LLM_NORM_RMS, il);
503
+ + Kcur = build_norm(Kcur, layer.attn_k_norm, NULL, LLM_NORM_RMS, il);
504
+ + cb(Qcur, "Qcur_normed", il);
505
+ + cb(Kcur, "Kcur_normed", il);
506
+ +
507
+ + if (use_rope) {
508
+ + const float freq_base_l = model.get_rope_freq_base (cparams, il);
509
+ + const float freq_scale_l = model.get_rope_freq_scale(cparams, il);
510
+ +
511
+ + Qcur = ggml_rope_ext(
512
+ + ctx0, Qcur, inp_pos, nullptr,
513
+ + n_rot, rope_type, n_ctx_orig, freq_base_l, freq_scale_l,
514
+ + ext_factor, attn_factor, beta_fast, beta_slow);
515
+ + Kcur = ggml_rope_ext(
516
+ + ctx0, Kcur, inp_pos, nullptr,
517
+ + n_rot, rope_type, n_ctx_orig, freq_base_l, freq_scale_l,
518
+ + ext_factor, attn_factor, beta_fast, beta_slow);
519
+ + cb(Qcur, "Qcur_rope", il);
520
+ + cb(Kcur, "Kcur_rope", il);
521
+ + }
522
+ +
523
+ + cur = build_attn(inp_attn,
524
+ + layer.wo, NULL, layer.wo_s,
525
+ + Qcur, Kcur, Vcur, nullptr, nullptr, nullptr, kq_scale, il);
526
+ + cb(cur, "attn_out", il);
527
+ + }
528
+ +
529
+ + cur = build_norm(cur, layer.attn_post_norm, NULL, LLM_NORM_RMS, il);
530
+ + cb(cur, "attn_post_norm", il);
531
+ +
532
+ + if (il == n_layer - 1 && inp_out_ids) {
533
+ + cur = ggml_get_rows(ctx0, cur, inp_out_ids);
534
+ + inpSA = ggml_get_rows(ctx0, inpSA, inp_out_ids);
535
+ + }
536
+ +
537
+ + ggml_tensor * ffn_inp = ggml_add(ctx0, cur, inpSA);
538
+ + cb(ffn_inp, "ffn_inp", il);
539
+ +
540
+ + // HF "post_attention_layernorm" = pre-FFN norm
541
+ + cur = build_norm(ffn_inp, layer.ffn_norm, NULL, LLM_NORM_RMS, il);
542
+ + cb(cur, "ffn_norm", il);
543
+ +
544
+ + ggml_tensor * moe_out = build_moe_ffn(cur,
545
+ + layer.ffn_gate_inp,
546
+ + layer.ffn_up_exps,
547
+ + layer.ffn_gate_exps,
548
+ + layer.ffn_down_exps,
549
+ + layer.ffn_exp_probs_b,
550
+ + n_expert, n_expert_used,
551
+ + LLM_FFN_SILU,
552
+ + hparams.expert_weights_norm,
553
+ + 0.0f,
554
+ + (llama_expert_gating_func_type) hparams.expert_gating_func,
555
+ + il);
556
+ + cb(moe_out, "ffn_moe_out", il);
557
+ +
558
+ + ggml_tensor * ffn_shexp = build_ffn(cur,
559
+ + layer.ffn_up_shexp, NULL, NULL,
560
+ + layer.ffn_gate_shexp, NULL, NULL,
561
+ + layer.ffn_down_shexp, NULL, NULL,
562
+ + NULL,
563
+ + LLM_FFN_SILU, LLM_FFN_PAR, il);
564
+ + cb(ffn_shexp, "ffn_shexp", il);
565
+ +
566
+ + cur = ggml_add(ctx0, moe_out, ffn_shexp);
567
+ + cb(cur, "ffn_out", il);
568
+ +
569
+ + cur = build_norm(cur, layer.ffn_post_norm, NULL, LLM_NORM_RMS, il);
570
+ + cb(cur, "ffn_post_norm", il);
571
+ +
572
+ + cur = ggml_add(ctx0, cur, ffn_inp);
573
+ + cur = build_cvec(cur, il);
574
+ + cb(cur, "l_out", il);
575
+ +
576
+ + inpL = cur;
577
+ + }
578
+ +
579
+ + cur = build_norm(inpL, model.output_norm, NULL, LLM_NORM_RMS, -1);
580
+ + cb(cur, "result_norm", -1);
581
+ + res->t_embd = cur;
582
+ +
583
+ + cur = build_lora_mm(model.output, cur, model.output_s);
584
+ + cb(cur, "result_output", -1);
585
+ + res->t_logits = cur;
586
+ +
587
+ + ggml_build_forward_expand(gf, cur);
588
+ +}
589
+ diff --git a/src/models/models.h b/src/models/models.h
590
+ index 387a4ad..137e821 100644
591
+ --- a/src/models/models.h
592
+ +++ b/src/models/models.h
593
+ @@ -1955,6 +1955,19 @@ struct llama_model_afmoe : public llama_model_base {
594
+ };
595
+
596
+
597
+ +struct llama_model_kolibri1 : public llama_model_base {
598
+ + llama_model_kolibri1(const struct llama_model_params & params) : llama_model_base(params) {}
599
+ + void load_arch_hparams(llama_model_loader & ml) override;
600
+ + void load_arch_tensors(llama_model_loader & ml) override;
601
+ +
602
+ + struct graph : public llm_graph_context {
603
+ + graph(const llama_model & model, const llm_graph_params & params);
604
+ + };
605
+ +
606
+ + std::unique_ptr<llm_graph_context> build_arch_graph(const llm_graph_params & params) const override;
607
+ +};
608
+ +
609
+ +
610
+ struct llama_model_laguna : public llama_model_base {
611
+ llama_model_laguna(const struct llama_model_params & params) : llama_model_base(params) {}
612
+ void load_arch_hparams(llama_model_loader & ml) override;
613
+ --
614
+ 2.43.0
615
+
616
+
617
+ From 71240454fd46302263a5d78a84db203b8e66fdde Mon Sep 17 00:00:00 2001
618
+ From: Seraphiel102 <[email protected]>
619
+ Date: Sat, 3 Oct 2026 19:40:26 +0100
620
+ Subject: [PATCH 4/4] tests : cover kolibri1 in test-llama-archs
621
+
622
+ Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
623
+ ---
624
+ tests/test-llama-archs.cpp | 8 +++++---
625
+ 1 file changed, 5 insertions(+), 3 deletions(-)
626
+
627
+ diff --git a/tests/test-llama-archs.cpp b/tests/test-llama-archs.cpp
628
+ index 93bf47b..2677538 100644
629
+ --- a/tests/test-llama-archs.cpp
630
+ +++ b/tests/test-llama-archs.cpp
631
+ @@ -143,7 +143,7 @@ static gguf_context_ptr get_gguf_ctx(const llm_arch arch, const bool moe) {
632
+ n_layer = 4;
633
+ } else if (arch == LLM_ARCH_STEP35 || arch == LLM_ARCH_LAGUNA) {
634
+ n_embd = 160; // exercise per-head tensor split granularity with head size 80
635
+ - } else if (arch == LLM_ARCH_QWEN3 || arch == LLM_ARCH_MUSE_GLIMMER || arch == LLM_ARCH_AFMOE) {
636
+ + } else if (arch == LLM_ARCH_QWEN3 || arch == LLM_ARCH_MUSE_GLIMMER || arch == LLM_ARCH_AFMOE || arch == LLM_ARCH_KOLIBRI1) {
637
+ n_head = 4;
638
+ } else if (arch == LLM_ARCH_DEEPSEEK2
639
+ || arch == LLM_ARCH_DEEPSEEK32
640
+ @@ -172,7 +172,7 @@ static gguf_context_ptr get_gguf_ctx(const llm_arch arch, const bool moe) {
641
+ uint32_t n_head_kv = n_head;
642
+ if (arch == LLM_ARCH_QWEN3) {
643
+ n_head_kv = 1; // MQA coverage
644
+ - } else if (arch == LLM_ARCH_MUSE_GLIMMER || arch == LLM_ARCH_AFMOE) {
645
+ + } else if (arch == LLM_ARCH_MUSE_GLIMMER || arch == LLM_ARCH_AFMOE || arch == LLM_ARCH_KOLIBRI1) {
646
+ n_head_kv = 2; // GQA coverage
647
+ }
648
+ const uint32_t n_embd_head = n_embd / n_head;
649
+ @@ -418,7 +418,8 @@ static gguf_context_ptr get_gguf_ctx(const llm_arch arch, const bool moe) {
650
+ ms.add_kv(LLM_KV_EXPERT_COUNT, uint32_t(2));
651
+ ms.add_kv(LLM_KV_EXPERT_USED_COUNT, uint32_t(2));
652
+ ms.add_kv(LLM_KV_EXPERT_SHARED_COUNT, uint32_t(1));
653
+ - ms.add_kv(LLM_KV_EXPERT_GATING_FUNC, arch == LLM_ARCH_DEEPSEEK4 ? uint32_t(4) : uint32_t(2)); // sqrtsoftplus : sigmoid
654
+ + ms.add_kv(LLM_KV_EXPERT_GATING_FUNC, arch == LLM_ARCH_DEEPSEEK4 ? uint32_t(4) :
655
+ + arch == LLM_ARCH_KOLIBRI1 ? uint32_t(5) : uint32_t(2)); // sqrtsoftplus : sigmoid_logit_add : sigmoid
656
+ ms.add_kv(LLM_KV_EXPERT_GROUP_SCALE, 1.0f);
657
+ ms.add_kv(LLM_KV_EXPERTS_PER_GROUP, uint32_t(1));
658
+ }
659
+ @@ -608,6 +609,7 @@ static bool moe_mandatory(const llm_arch arch) {
660
+ case LLM_ARCH_BAILINGMOE3:
661
+ case LLM_ARCH_DOTS1:
662
+ case LLM_ARCH_AFMOE:
663
+ + case LLM_ARCH_KOLIBRI1:
664
+ case LLM_ARCH_ERNIE4_5:
665
+ case LLM_ARCH_ERNIE4_5_MOE:
666
+ case LLM_ARCH_HUNYUAN_MOE:
667
+ --
668
+ 2.43.0
669
+