vincespeed commited on
Commit
9653662
·
verified ·
1 Parent(s): 7206e15

Upload 3 files

Browse files
README.md CHANGED
@@ -1,3 +1,278 @@
1
  ---
2
- license: apache-2.0
 
 
 
 
 
 
 
 
 
3
  ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ license: other
3
+ base_model: IFM/K2-Horizon-MoVA-36B-A4B-GGUF
4
+ base_model_relation: quantized
5
+ tags:
6
+ - gguf
7
+ - moe
8
+ - k2-horizon
9
+ - mova
10
+ - apex-quant
11
+ pipeline_tag: text-generation
12
  ---
13
+
14
+ # K2-Horizon-MoVA-36B-A4B — Apex Quant GGUF Models
15
+
16
+ This repository contains 3 quantized GGUF profiles of the **K2-Horizon-MoVA-36B-A4B** model, produced using **Apex-Quant** technology.
17
+
18
+ > ⚠️ **Runtime requirement:** These models require the **patched llama.cpp fork** described in [Building the Runtime](#-building-the-runtime-patched-llamacpp). Unpatched builds of the fork either fail to load on Windows (MSVC regex error) or produce **garbage output** (repetitive tokens such as `>`). See [Fixes](#-why-a-patched-fork-is-required).
19
+
20
+ ## 📦 Model Profile Summary
21
+
22
+ | Profile | Size | BPW | Use Case |
23
+ |---------|------|-----|----------|
24
+ | **i-quality** | 23.8 GB | 5.47 | Highest quality, production environments |
25
+ | **i-balanced** | 26.2 GB | 6.02 | Maximum expert precision (densest expert quant) |
26
+ | **i-compact** | 17.6 GB | 4.04 | Compact deployment, low VRAM/RAM |
27
+
28
+ > **BPW** = Bits Per Weight. Higher value = better quality.
29
+ >
30
+ > Note: unlike most model families, here **i-balanced is larger than i-quality** — it keeps all routed experts at Q5_K or higher, while i-quality compresses mid-layer experts to IQ4_XS. Choose based on your memory budget vs. precision preference.
31
+
32
+ ## 📁 File Structure
33
+
34
+ ```
35
+ models/
36
+ ├── K2-Horizon-36B-i-quality.gguf # 23.8 GB — highest quality
37
+ ├── K2-Horizon-36B-i-balanced.gguf # 26.2 GB — max expert precision
38
+ └── K2-Horizon-36B-i-compact.gguf # 17.6 GB — compact
39
+ ```
40
+
41
+ ## 🔗 Source Model
42
+
43
+ These models were created based on the **K2-Horizon-MoVA-36B-A4B** model.
44
+
45
+ - **Model Page:** https://huggingface.co/IFM/K2-Horizon-MoVA-36B-A4B-GGUF
46
+ - **Architecture:** K2Horizon MoE with MoVA (Mixture-of-Value Attention)
47
+ - **Total Parameters:** ~36B (~4B active per token)
48
+ - **Context Length:** 524,288 tokens (training context; usable range depends on KV-cache RAM)
49
+ - **Reference Implementation:** vLLM (`K2HorizonForCausalLM`)
50
+ - **Official llama.cpp fork:** https://github.com/MBZUAI-IFM/llama.cpp
51
+
52
+ ## 🛠️ Technology
53
+
54
+ These quantized models were produced using **Apex-Quant** technology.
55
+
56
+ - **Apex-Quant:** MoE-aware mixed-precision quantization (layer-band importance: edge / near / mid)
57
+ - **Infrastructure:** llama.cpp (`llama-quantize`, `--tensor-type-file`)
58
+ - **Config Generator:** `apex-quant/scripts/generate_config.sh --profile <profile> --layers 48`
59
+
60
+ ## ⚙️ Building the Runtime (patched llama.cpp)
61
+
62
+ ### Why a patched fork is required
63
+
64
+ The K2-Horizon support fork ([MBZUAI-IFM/llama.cpp](https://github.com/MBZUAI-IFM/llama.cpp)) provides the base K2-Horizon support. On top of the pinned commit below, **two fixes** are required for reliable operation (both verified empirically in our test setup):
65
+
66
+ | # | Issue | Observed Symptom | Fix |
67
+ |---|-------|------------------|-----|
68
+ | 1 | Tokenizer pre-regex contains `\u200C`/`\u200D` escapes unsupported by MSVC `std::regex` | Model fails to load on **Windows**: `Failed to process regex ... regex_error(error_escape)` | Remove the `\u200C\|\u200D` alternation from the K2_HORIZON pre-tokenization regex |
69
+ | 2 | Decoder residual/norm wiring diverged from the vLLM reference behavior | Model loads fine but generates **garbage/repeated tokens** (`> > > ...`), possible crashes during graph reservation | Rewrite residual flow in `k2-horizon.cpp` forward pass following vLLM semantics (see note below) |
70
+
71
+ Both fixes are provided as ready-to-apply patches below.
72
+
73
+ ### Step-by-step
74
+
75
+ ```bash
76
+ # 1. Clone the official K2-Horizon fork and pin the exact commit these models were validated against
77
+ git clone https://github.com/MBZUAI-IFM/llama.cpp llama-cpp-k2horizon
78
+ cd llama-cpp-k2horizon
79
+ git checkout 35999d101cf2233fc54f09c3c8d599da7303ce02
80
+
81
+ # 2. Apply the two patches (from this repo's patches/ directory)
82
+ git apply /path/to/patches/0001-fix-k2-horizon-msvc-regex.patch
83
+ git apply /path/to/patches/0002-fix-k2-horizon-parallel-norm.patch
84
+ ```
85
+
86
+ #### Patch 1 — MSVC tokenizer regex fix (`src/llama-vocab.cpp`)
87
+
88
+ MSVC's `std::regex` rejects `\uXXXX` escape sequences, so loading any K2-Horizon model crashes on Windows before inference even starts. The zero-width joiner/non-joiner alternatives are irrelevant for BPE pre-tokenization quality and are removed:
89
+
90
+ ```diff
91
+ case LLAMA_VOCAB_PRE_TYPE_K2_HORIZON:
92
+ regex_exprs = {
93
+ - "...(?:\\p{L}|\\p{M}|\\u200C|\\u200D)+...",
94
+ + "...(?:\\p{L}|\\p{M})+...",
95
+ };
96
+ ```
97
+
98
+ *(Full, exact diff: [`patches/0001-fix-k2-horizon-msvc-regex.patch`](patches/0001-fix-k2-horizon-msvc-regex.patch))*
99
+
100
+ #### Patch 2 — Parallel norm residual fix (`src/models/k2-horizon.cpp`)
101
+
102
+ This patch rewires the decoder residual path to follow the vLLM reference semantics (`K2HorizonRMSNorm.forward(x, residual)`), where the running sum of sublayer outputs is tracked across layers and folded in *before* normalization.
103
+
104
+ > **Status note:** With this patch applied, the repeated-token (`> > >`) failure mode and the graph-reservation crash disappeared and generation became coherent. The exact causal mechanism has **not** been independently verified against the upstream weights — treat this patch as a validated fix rather than a proven diagnosis.
105
+
106
+ The new residual flow tracks an accumulated `residual` tensor across layers:
107
+
108
+ ```cpp
109
+ ggml_tensor * residual = nullptr; // outside the layer loop
110
+
111
+ for (int il = 0; il < n_layer; ++il) {
112
+ // --- parallel norm BEFORE attention ---
113
+ if (il == 0) {
114
+ residual = inpL; // layer 0: residual = embedding
115
+ cur = group_rms_norm(inpL, attn_norm);
116
+ } else {
117
+ cur = ggml_add(ctx0, inpL, residual); // prev MLP out + accumulated sum
118
+ residual = cur;
119
+ cur = group_rms_norm(cur, attn_norm);
120
+ }
121
+ /* ...attention... */
122
+
123
+ // --- parallel norm BEFORE FFN ---
124
+ cur = ggml_add(ctx0, cur, residual); // attn out + accumulated sum
125
+ residual = cur;
126
+ cur = group_rms_norm(cur, ffn_norm);
127
+ /* ...MoE FFN... */
128
+
129
+ cur = build_cvec(cur, il);
130
+ inpL = cur; // NO residual add here (deferred)
131
+ }
132
+
133
+ // final layer: fold last MLP output into the accumulated sum, then normalize
134
+ cur = ggml_add(ctx0, inpL, residual);
135
+ cur = group_rms_norm(cur, output_norm);
136
+ ```
137
+
138
+ *(Full, exact diff: [`patches/0002-fix-k2-horizon-parallel-norm.patch`](patches/0002-fix-k2-horizon-parallel-norm.patch))*
139
+
140
+ ### Compile
141
+
142
+ **Windows (Visual Studio 2022 + CUDA):**
143
+ ```bat
144
+ cmake -B build -G "Visual Studio 17 2022" -A x64 -DCMAKE_BUILD_TYPE=Release -DLLAMA_CUDA=ON
145
+ cmake --build build --config Release
146
+ ```
147
+
148
+ **Linux (GCC/Clang + CUDA):**
149
+ ```bash
150
+ cmake -B build -DCMAKE_BUILD_TYPE=Release -DLLAMA_CUDA=ON
151
+ cmake --build build --config Release -j$(nproc)
152
+ ```
153
+
154
+ CPU-only builds work too (drop `-DLLAMA_CUDA=ON`).
155
+
156
+ ### Verify your build
157
+
158
+ ```bash
159
+ ./build/bin/Release/llama-cli -m K2-Horizon-36B-i-compact.gguf -n 30 --temp 0.7 --top-p 0.9 -p "Merhaba dünya"
160
+ ```
161
+
162
+ ✅ **Working:** coherent natural-language answer (~27–45 tok/s decode with full CUDA offload).
163
+ ❌ **Broken:** repeated `>` or command-line echo → one of the patches was not applied.
164
+
165
+ ## 📋 Technical Details
166
+
167
+ ### Architecture Information (from GGUF metadata)
168
+ - **Architecture:** `k2-horizon`
169
+ - **Block Count:** 48 layers (3 leading dense blocks, 45 MoE blocks)
170
+ - **Expert Count:** 100 routed experts/layer
171
+ - **Expert Used Count:** 8 (top-8 routing)
172
+ - **Shared Experts:** 1/layer
173
+ - **Expert Gating:** softmax with weight normalization (scale 2.5)
174
+ - **Hidden Size:** 2,560
175
+ - **Feed Forward Size:** 6,144 (dense) / 768 (per expert)
176
+ - **Attention Heads:** 32 (KV heads: 8, grouped query attention)
177
+ - **Head Dimension:** 128 (full RoPE rotation)
178
+ - **RoPE Frequency Base:** 10,000,000
179
+ - **Layer Norm:** Grouped RMSNorm (2 groups), ε = 1e-6
180
+ - **MoVA:** Mixture-of-Value Attention — 64 value experts/layer, top-4 routed
181
+ - **Residual Scheme:** Parallel (pre-norm), per vLLM reference
182
+
183
+ ### Quantize Profile Details
184
+
185
+ Layer bands (48 layers): **EDGE** = L0–4 & L43–47 · **NEAR** = L5–9 & L38–42 · **MID** = L10–37
186
+
187
+ #### i-quality (Q6_K/Q5_K/IQ4_XS)
188
+ - **Routed Expert FFN:** EDGE Q6_K / NEAR Q5_K / MID IQ4_XS
189
+ - **Shared FFN:** Q8_0
190
+ - **Attention:** Q6_K
191
+ - **BPW:** 5.47
192
+ - **File Size:** 23.8 GB
193
+
194
+ #### i-balanced (Q6_K/Q5_K)
195
+ - **Routed Expert FFN:** EDGE Q6_K / NEAR Q5_K / MID Q5_K
196
+ - **Shared FFN:** Q8_0
197
+ - **Attention:** Q6_K
198
+ - **BPW:** 6.02
199
+ - **File Size:** 26.2 GB
200
+
201
+ #### i-compact (Q4_K/Q3_K)
202
+ - **Routed Expert FFN:** EDGE Q4_K / NEAR Q3_K / MID Q3_K
203
+ - **Shared FFN:** Q6_K
204
+ - **Attention:** Q4_K
205
+ - **BPW:** 4.04
206
+ - **File Size:** 17.6 GB
207
+
208
+ ## 💻 Usage
209
+
210
+ ### With llama.cpp (patched fork)
211
+
212
+ ```bash
213
+ # Interactive chat
214
+ ./build/bin/Release/llama-cli -m models/K2-Horizon-36B-i-quality.gguf \
215
+ -n 256 --temp 0.7 --top-p 0.9 -p "Hello, how are you?"
216
+
217
+ # Single-shot completion
218
+ ./build/bin/Release/llama-completion -m models/K2-Horizon-36B-i-compact.gguf \
219
+ -n 128 -p "Explain mixture-of-experts models:"
220
+ ```
221
+
222
+ ### With Python (llama-cpp-python)
223
+
224
+ Build `llama-cpp-python` **against the same patched source tree** (see above), e.g.:
225
+
226
+ ```bash
227
+ CMAKE_BUILD_ARGS="-DLLAMA_CURL=OFF" pip install llama-cpp-python \
228
+ --global-option=build_ext \
229
+ --global-option="--library_dir=$(pwd)/build/lib" \
230
+ --global-option="--include_dir=$(pwd)/include"
231
+ ```
232
+
233
+ ```python
234
+ from llama_cpp import Llama
235
+
236
+ llm = Llama(
237
+ model_path="models/K2-Horizon-36B-i-quality.gguf",
238
+ n_ctx=8192,
239
+ n_threads=8,
240
+ )
241
+
242
+ output = llm("Hello, how are you?", max_tokens=256)
243
+ print(output["choices"][0]["text"])
244
+ ```
245
+
246
+ ## 📊 Model Comparison
247
+
248
+ | Criterion | i-quality | i-balanced | i-compact |
249
+ |-----------|-----------|------------|-----------|
250
+ | **Quality** | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
251
+ | **Speed** | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐�� |
252
+ | **RAM/VRAM** | High | Highest | Low |
253
+ | **Size** | 23.8 GB | 26.2 GB | 17.6 GB |
254
+ | **BPW** | 5.47 | 6.02 | 4.04 |
255
+
256
+ ## 📝 Notes
257
+
258
+ - All models are in **GGUF** format and were generated from the BF16 master checkpoint.
259
+ - The **K2Horizon** architecture combines Mixture-of-Experts (100×8) with **MoVA** (64×4 value experts) and grouped RMSNorm. Residual wiring follows the vLLM reference (see [runtime fixes](#-building-the-runtime-patched-llamacpp)).
260
+ - Measured performance (full CUDA offload, 49/49 layers): prompt eval ≈ 28–139 tok/s, generation ≈ 27–45 tok/s (i-compact, consumer GPU).
261
+ - Only the 3 APEX profiles are published here; the 70 GB BF16 master stays upstream.
262
+
263
+ ## 📄 License
264
+
265
+ ⚠️ Please review the **original model's license/terms** before commercial use. The GGUF files are repackaged quantizations of the upstream weights.
266
+
267
+ ## 🙏 Acknowledgments
268
+
269
+ - **[MBZUAI-IFM](https://github.com/MBZUAI-IFM)** — K2-Horizon model and official llama.cpp fork
270
+ - **[localai-org/apex-quant](https://github.com/localai-org/apex-quant)** — Apex-Quant MoE-aware mixed-precision quantization framework
271
+ - **[ggerganov/llama.cpp](https://github.com/ggerganov/llama.cpp)** — GGUF format and quantization engine
272
+
273
+ ## 🔗 Related Links
274
+
275
+ - **Source GGUF:** https://huggingface.co/IFM/K2-Horizon-MoVA-36B-A4B-GGUF
276
+ - **llama.cpp fork:** https://github.com/MBZUAI-IFM/llama.cpp
277
+ - **Apex-Quant:** https://github.com/localai-org/apex-quant
278
+ - **GGUF Format:** https://github.com/ggerganov/ggml/blob/master/docs/gguf.md
patches/0001-fix-k2-horizon-msvc-regex.patch ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ diff --git a/src/llama-vocab.cpp b/src/llama-vocab.cpp
2
+ index 4d054db..00c7c68 100644
3
+ --- a/src/llama-vocab.cpp
4
+ +++ b/src/llama-vocab.cpp
5
+ @@ -537,7 +537,7 @@ struct llm_tokenizer_bpe : llm_tokenizer {
6
+ break;
7
+ case LLAMA_VOCAB_PRE_TYPE_K2_HORIZON:
8
+ regex_exprs = {
9
+ - "(?:'[sS]|'[tT]|'[rR][eE]|'[vV][eE]|'[mM]|'[lL][lL]|'[dD])|[^\\r\\n\\p{L}\\p{N}]?(?:\\p{L}|\\p{M}|\\u200C|\\u200D)+|\\p{N}{1,3}| ?[^\\s\\p{L}\\p{N}]+[\\r\\n]*|\\s*[\\r\\n]+|\\s+(?!\\S)|\\s+",
10
+ + "(?:'[sS]|'[tT]|'[rR][eE]|'[vV][eE]|'[mM]|'[lL][lL]|'[dD])|[^\\r\\n\\p{L}\\p{N}]?(?:\\p{L}|\\p{M})+|\\p{N}{1,3}| ?[^\\s\\p{L}\\p{N}]+[\\r\\n]*|\\s*[\\r\\n]+|\\s+(?!\\S)|\\s+",
11
+ };
12
+ break;
13
+ case LLAMA_VOCAB_PRE_TYPE_WHITESPACE:
patches/0002-fix-k2-horizon-parallel-norm.patch ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ diff --git a/src/models/k2-horizon.cpp b/src/models/k2-horizon.cpp
2
+ index ac901da..f8ee389 100644
3
+ --- a/src/models/k2-horizon.cpp
4
+ +++ b/src/models/k2-horizon.cpp
5
+ @@ -393,22 +393,37 @@ llama_model_k2_horizon::graph::graph(
6
+ auto * inp_attn = build_attn_inp_kv();
7
+ ggml_tensor * inp_out_ids = build_inp_out_ids();
8
+
9
+ + // ============ PARALLEL NORM (GPT-NeoX/PaLM style) - vLLM reference
10
+ + // residual tracks accumulated sum across layers
11
+ + ggml_tensor * residual = nullptr;
12
+
13
+ for (int il = 0; il < n_layer; ++il) {
14
+ res->t_layer_inp[il] = inpL;
15
+ - ggml_tensor * inpSA = inpL; // for residuals
16
+
17
+ const bool is_moe_layer = n_expert > 0 && static_cast<uint32_t>(il) >= hparams.n_layer_dense_lead;
18
+ const bool is_mova_layer = is_moe_layer && hparams.n_value_expert > 0;
19
+
20
+ - // ============ grouped rms norm
21
+ - cur = k2_horizon_group_rms_norm(
22
+ - ctx0,
23
+ - inpL,
24
+ - model.layers[il].attn_norm,
25
+ - hparams.n_norm_groups,
26
+ - hparams.f_norm_rms_eps
27
+ - );
28
+ + // ============ parallel norm before attention
29
+ + if (il == 0) {
30
+ + residual = inpL;
31
+ + cur = k2_horizon_group_rms_norm(
32
+ + ctx0,
33
+ + inpL,
34
+ + model.layers[il].attn_norm,
35
+ + hparams.n_norm_groups,
36
+ + hparams.f_norm_rms_eps
37
+ + );
38
+ + } else {
39
+ + cur = ggml_add(ctx0, inpL, residual);
40
+ + residual = cur;
41
+ + cur = k2_horizon_group_rms_norm(
42
+ + ctx0,
43
+ + cur,
44
+ + model.layers[il].attn_norm,
45
+ + hparams.n_norm_groups,
46
+ + hparams.f_norm_rms_eps
47
+ + );
48
+ + }
49
+ cb(cur, "attn_norm", il);
50
+
51
+ // ============ setup attention tensors
52
+ @@ -547,17 +562,15 @@ llama_model_k2_horizon::graph::graph(
53
+ // ============ output layer, and take (usually) last token for generation
54
+ if (il == n_layer - 1 && inp_out_ids != nullptr) {
55
+ cur = ggml_get_rows(ctx0, cur, inp_out_ids);
56
+ - inpSA = ggml_get_rows(ctx0, inpSA, inp_out_ids); // pull the same positions for inpSA
57
+ + residual = ggml_get_rows(ctx0, residual, inp_out_ids);
58
+ }
59
+
60
+ - // ============ add residuals
61
+ - ggml_tensor * ffn_inp = ggml_add(ctx0, cur, inpSA);
62
+ - cb(ffn_inp, "ffn_inp", il);
63
+ -
64
+ - // ============ group RMSNorm before FFN
65
+ + // ============ parallel norm before FFN
66
+ + cur = ggml_add(ctx0, cur, residual);
67
+ + residual = cur;
68
+ cur = k2_horizon_group_rms_norm(
69
+ ctx0,
70
+ - ffn_inp,
71
+ + cur,
72
+ model.layers[il].ffn_norm,
73
+ hparams.n_norm_groups,
74
+ hparams.f_norm_rms_eps
75
+ @@ -626,8 +639,7 @@ llama_model_k2_horizon::graph::graph(
76
+ }
77
+ cb(cur, "ffn_out", il);
78
+
79
+ - // ============ FFN residual
80
+ - cur = ggml_add(ctx0, cur, ffn_inp);
81
+ + // ============ cvec adapter (residual add happens next layer / final norm)
82
+ cur = build_cvec(cur, il);
83
+ cb(cur, "l_out", il);
84
+
85
+ @@ -635,10 +647,11 @@ llama_model_k2_horizon::graph::graph(
86
+ inpL = cur;
87
+ }
88
+
89
+ - // final group rms norm. also becomes last layer embedding
90
+ + // final: add last mlp_out to accumulated residual, then group rms norm
91
+ + cur = ggml_add(ctx0, inpL, residual);
92
+ cur = k2_horizon_group_rms_norm(
93
+ ctx0,
94
+ - inpL,
95
+ + cur,
96
+ model.output_norm,
97
+ hparams.n_norm_groups,
98
+ hparams.f_norm_rms_eps