char-fork/llama.cpp

git clone https://git.t4t.associates/char-fork/llama.cpp

Yaniss Amazouzmodel: add NVIDIA Nemotron-3-Puzzle-75B-A9B (NemotronHPuzzle) support (#25444)c61b98b87

char/aliceai-t5-moe
19.1 KiB444 linesraw
1#include "models.h"
2
3void llama_model_cohere2moe::load_arch_hparams(llama_model_loader & ml) {
4    const bool found_norm     = ml.get_key(LLM_KV_ATTENTION_LAYERNORM_EPS,     hparams.f_norm_eps,     false);
5    const bool found_norm_rms = ml.get_key(LLM_KV_ATTENTION_LAYERNORM_RMS_EPS, hparams.f_norm_rms_eps, false);
6    if (!found_norm && !found_norm_rms) {
7        throw std::runtime_error("missing Cohere2 MoE norm epsilon");
8    }
9    if (!found_norm_rms) {
10        hparams.f_norm_rms_eps = 0.0f;
11    }
12
13    ml.get_key(LLM_KV_ATTENTION_SLIDING_WINDOW,    hparams.n_swa);
14    ml.get_key(LLM_KV_LOGIT_SCALE,                 hparams.f_logit_scale);
15    ml.get_key(LLM_KV_LEADING_DENSE_BLOCK_COUNT,   hparams.n_layer_dense_lead);
16    ml.get_key_or_arr(LLM_KV_EXPERT_FEED_FORWARD_LENGTH, hparams.n_ff_exp_arr, hparams.n_layer_all);
17    ml.get_key(LLM_KV_EXPERT_SHARED_FEED_FORWARD_LENGTH, hparams.n_ff_shexp, false);
18    ml.get_key(LLM_KV_EXPERT_SHARED_COUNT,         hparams.n_expert_shared, false);
19    ml.get_key(LLM_KV_EXPERT_WEIGHTS_NORM,         hparams.expert_weights_norm, false);
20    ml.get_key(LLM_KV_EXPERT_WEIGHTS_SCALE,        hparams.expert_weights_scale, false);
21    ml.get_key(LLM_KV_EXPERT_GATING_FUNC,          hparams.expert_gating_func, false);
22
23    if (hparams.expert_gating_func == LLAMA_EXPERT_GATING_FUNC_TYPE_NONE) {
24        hparams.expert_gating_func = LLAMA_EXPERT_GATING_FUNC_TYPE_SIGMOID;
25    }
26
27    hparams.swa_type = LLAMA_SWA_TYPE_STANDARD;
28    uint32_t swa_period = 4;
29    if (ml.get_key_or_arr(LLM_KV_ATTENTION_SLIDING_WINDOW_PATTERN, swa_period, false)) {
30        hparams.set_swa_pattern(swa_period, true);
31    } else {
32        ml.get_key_or_arr(LLM_KV_ATTENTION_SLIDING_WINDOW_PATTERN, hparams.is_swa_impl, hparams.n_layer());
33    }
34
35    hparams.rope_freq_base_train_swa  = hparams.rope_freq_base_train;
36    hparams.rope_freq_scale_train_swa = hparams.rope_freq_scale_train;
37    ml.get_key(LLM_KV_ROPE_FREQ_BASE_SWA, hparams.rope_freq_base_train_swa, false);
38
39    switch (hparams.n_layer()) {
40        case 49: type = LLM_TYPE_30B_A3B; break;
41        default: type = LLM_TYPE_UNKNOWN;
42    }
43}
44
45void llama_model_cohere2moe::load_arch_tensors(llama_model_loader & ml) {
46    LLAMA_LOAD_LOCALS;
47
48    const bool mtp_only = (hparams.n_layer_nextn > 0) && (ml.get_weight("blk.0.attn_norm.weight") == nullptr);
49    // Trunk-only: the GGUF declares MTP layers in metadata but the actual MTP
50    // tensors live in a separate file. Mark MTP tensors NOT_REQUIRED so the
51    // trunk loads cleanly.
52    const std::string mtp_probe = "blk." + std::to_string(n_layer) + ".nextn.eh_proj.weight";
53    const bool trunk_only = (hparams.n_layer_nextn > 0) && (ml.get_weight(mtp_probe.c_str()) == nullptr);
54    const int trunk_flags = mtp_only  ? TENSOR_NOT_REQUIRED : 0;
55    int mtp_flags         = trunk_only ? TENSOR_NOT_REQUIRED : 0;
56
57    if (!ml.load_mtp) {
58        mtp_flags |= TENSOR_SKIP;
59    }
60
61    tok_embd = create_tensor(tn(LLM_TENSOR_TOKEN_EMBD, "weight"), { n_embd, n_vocab }, 0);
62
63    // output
64    output_norm = create_tensor(tn(LLM_TENSOR_OUTPUT_NORM, "weight"), { n_embd }, 0);
65    output      = create_tensor(tn(LLM_TENSOR_OUTPUT,      "weight"), { n_embd, n_vocab }, TENSOR_NOT_REQUIRED);
66
67    // if output is NULL, init from the input tok embed
68    if (output == NULL) {
69        output = create_tensor(tn(LLM_TENSOR_TOKEN_EMBD, "weight"), { n_embd, n_vocab }, TENSOR_DUPLICATED);
70    }
71
72    if (n_expert == 0) {
73        throw std::runtime_error("n_expert must be > 0 for Cohere2Moe");
74    }
75    if (n_expert_used == 0) {
76        throw std::runtime_error("n_expert_used must be > 0 for Cohere2Moe");
77    }
78
79    auto load_block_trunk = [&](int i, int flags) {
80        auto & layer = layers[i];
81
82        layer.attn_norm = create_tensor(tn(LLM_TENSOR_ATTN_NORM, "weight", i), { n_embd }, flags);
83
84        create_tensor_qkv(layer, i, n_embd, n_embd_head_k * n_head, n_embd_gqa, n_embd_gqa, flags);
85        layer.wo = create_tensor(tn(LLM_TENSOR_ATTN_OUT, "weight", i), { n_embd_head_k * n_head, n_embd }, flags);
86
87        if (static_cast<uint32_t>(i) < hparams.n_layer_dense_lead) {
88            layer.ffn_gate = create_tensor(tn(LLM_TENSOR_FFN_GATE, "weight", i), { n_embd, n_ff }, flags);
89            layer.ffn_down = create_tensor(tn(LLM_TENSOR_FFN_DOWN, "weight", i), { n_ff, n_embd }, flags);
90            layer.ffn_up   = create_tensor(tn(LLM_TENSOR_FFN_UP,   "weight", i), { n_embd, n_ff }, flags);
91        } else {
92            const int64_t n_ff_exp = hparams.n_ff_exp() ? hparams.n_ff_exp() : n_ff;
93
94            layer.ffn_gate_inp  = create_tensor(tn(LLM_TENSOR_FFN_GATE_INP,  "weight", i), { n_embd, n_expert }, flags);
95            layer.ffn_down_exps = create_tensor(tn(LLM_TENSOR_FFN_DOWN_EXPS, "weight", i), { n_ff_exp, n_embd, n_expert }, flags);
96            create_tensor_gate_up_exps(layer, i, n_embd, n_ff_exp, n_expert, flags);
97
98            if (hparams.n_expert_shared > 0) {
99                const int64_t n_ff_shexp = hparams.n_ff_shexp ? hparams.n_ff_shexp : n_ff_exp * hparams.n_expert_shared;
100                layer.ffn_gate_shexp = create_tensor(tn(LLM_TENSOR_FFN_GATE_SHEXP, "weight", i), { n_embd, n_ff_shexp }, flags);
101                layer.ffn_down_shexp = create_tensor(tn(LLM_TENSOR_FFN_DOWN_SHEXP, "weight", i), { n_ff_shexp, n_embd }, flags);
102                layer.ffn_up_shexp   = create_tensor(tn(LLM_TENSOR_FFN_UP_SHEXP,   "weight", i), { n_embd, n_ff_shexp }, flags);
103            }
104        }
105    };
106
107    auto load_block_mtp = [&](int i, int flags) {
108        auto & layer = layers[i];
109
110        // MTP block looks like a full-attention Cohere2 MoE decoder block.
111        layer.attn_norm = create_tensor(tn(LLM_TENSOR_ATTN_NORM, "weight", i), { n_embd }, flags);
112
113        create_tensor_qkv(layer, i, n_embd, n_embd_head_k * n_head, n_embd_gqa, n_embd_gqa, flags);
114        layer.wo = create_tensor(tn(LLM_TENSOR_ATTN_OUT, "weight", i), { n_embd_head_k * n_head, n_embd }, flags);
115
116        const int64_t n_ff_exp = hparams.n_ff_exp() ? hparams.n_ff_exp() : n_ff;
117
118        // Routed experts
119        layer.ffn_gate_inp  = create_tensor(tn(LLM_TENSOR_FFN_GATE_INP,  "weight", i), { n_embd, n_expert }, flags);
120        layer.ffn_down_exps = create_tensor(tn(LLM_TENSOR_FFN_DOWN_EXPS, "weight", i), { n_ff_exp, n_embd, n_expert }, flags);
121        create_tensor_gate_up_exps(layer, i, n_embd, n_ff_exp, n_expert, flags);
122
123        if (hparams.n_expert_shared > 0) {
124            const int64_t n_ff_shexp = hparams.n_ff_shexp ? hparams.n_ff_shexp : n_ff_exp * hparams.n_expert_shared;
125
126            // Shared experts
127            layer.ffn_gate_shexp = create_tensor(tn(LLM_TENSOR_FFN_GATE_SHEXP, "weight", i), { n_embd, n_ff_shexp }, flags);
128            layer.ffn_down_shexp = create_tensor(tn(LLM_TENSOR_FFN_DOWN_SHEXP, "weight", i), { n_ff_shexp, n_embd }, flags);
129            layer.ffn_up_shexp   = create_tensor(tn(LLM_TENSOR_FFN_UP_SHEXP,   "weight", i), { n_embd, n_ff_shexp }, flags);
130        }
131
132        // NextN-specific tensors that define the MTP block.
133        layer.nextn.eh_proj          = create_tensor(tn(LLM_TENSOR_NEXTN_EH_PROJ,          "weight", i), { 2 * n_embd, n_embd }, flags);
134        layer.nextn.enorm            = create_tensor(tn(LLM_TENSOR_NEXTN_ENORM,            "weight", i), { n_embd },              flags);
135        layer.nextn.hnorm            = create_tensor(tn(LLM_TENSOR_NEXTN_HNORM,            "weight", i), { n_embd },              flags);
136        layer.nextn.embed_tokens     = create_tensor(tn(LLM_TENSOR_NEXTN_EMBED_TOKENS,     "weight", i), { n_embd, n_vocab },     TENSOR_NOT_REQUIRED);
137        layer.nextn.shared_head_head = create_tensor(tn(LLM_TENSOR_NEXTN_SHARED_HEAD_HEAD, "weight", i), { n_embd, n_vocab },     TENSOR_NOT_REQUIRED);
138        layer.nextn.shared_head_norm = create_tensor(tn(LLM_TENSOR_NEXTN_SHARED_HEAD_NORM, "weight", i), { n_embd },              TENSOR_NOT_REQUIRED);
139    };
140
141    for (int i = 0; i < n_layer; ++i) {
142        load_block_trunk(i, trunk_flags);
143    }
144    // MTP/NextN layers are loaded as extra decoder blocks.
145    for (int i = n_layer; i < n_layer_all; ++i) {
146        load_block_mtp(i, mtp_flags);
147    }
148}
149
150std::unique_ptr<llm_graph_context> llama_model_cohere2moe::build_arch_graph(const llm_graph_params & params) const {
151    if (params.gtype == LLM_GRAPH_TYPE_DECODER_MTP) {
152        return std::make_unique<graph_mtp>(*this, params);
153    }
154    return std::make_unique<graph>(*this, params);
155}
156
157llama_model_cohere2moe::graph::graph(const llama_model & model, const llm_graph_params & params) : llm_graph_context(params) {
158    const int64_t n_embd_head = hparams.n_embd_head_v();
159
160    GGML_ASSERT(n_embd_head == hparams.n_embd_head_k());
161    GGML_ASSERT(n_embd_head == n_rot);
162
163    const llm_norm_type cohere2moe_norm_type = hparams.f_norm_rms_eps == 0.0f ? LLM_NORM : LLM_NORM_RMS;
164    const float f_logit_scale = hparams.f_logit_scale;
165    ggml_tensor * cur;
166    ggml_tensor * inpL = build_inp_embd(model.tok_embd);
167    ggml_tensor * inp_pos = build_inp_pos();
168
169    auto * inp_attn = build_attn_inp_kv_iswa();
170    ggml_tensor * inp_out_ids = build_inp_out_ids();
171
172    // MTP/NextN layers are loaded as extra decoder blocks but not executed in the main pass.
173    for (int il = 0; il < n_layer; ++il) {
174        const bool is_swa = hparams.is_swa(il);
175        // Dense-prefix full-attention layers use RoPE; later layers follow the SWA pattern.
176        const bool force_rope = static_cast<uint32_t>(il) < hparams.n_layer_dense_lead;
177
178        cur = build_norm(inpL, model.layers[il].attn_norm, nullptr, cohere2moe_norm_type, il);
179        cb(cur, "attn_norm", il);
180
181        ggml_tensor * ffn_inp = cur;
182
183        {
184            const auto & layer = model.layers[il];
185
186            auto [Qcur, Kcur, Vcur] = build_qkv(layer, cur,
187                    n_embd_head, n_head, n_head_kv, il);
188
189            if (is_swa || force_rope) {
190                ggml_tensor * rope_factors = model.get_rope_factors(cparams, il);
191
192                Qcur = ggml_rope_ext(
193                        ctx0, Qcur, inp_pos, rope_factors,
194                        n_rot, rope_type, n_ctx_orig, freq_base, freq_scale,
195                        ext_factor, attn_factor, beta_fast, beta_slow);
196
197                Kcur = ggml_rope_ext(
198                        ctx0, Kcur, inp_pos, rope_factors,
199                        n_rot, rope_type, n_ctx_orig, freq_base, freq_scale,
200                        ext_factor, attn_factor, beta_fast, beta_slow);
201            }
202
203            cb(Qcur, "Qcur", il);
204            cb(Kcur, "Kcur", il);
205            cb(Vcur, "Vcur", il);
206
207            cur = build_attn(inp_attn,
208                    layer.wo, layer.wo_b, layer.wo_s,
209                    Qcur, Kcur, Vcur, nullptr, nullptr, nullptr,
210                    1.0f / sqrtf(float(n_embd_head)), il);
211        }
212
213        if (il == n_layer - 1 && inp_out_ids && cparams.embeddings_nextn_masked) {
214            cur     = ggml_get_rows(ctx0, cur, inp_out_ids);
215            inpL    = ggml_get_rows(ctx0, inpL, inp_out_ids);
216            ffn_inp = ggml_get_rows(ctx0, ffn_inp, inp_out_ids);
217        }
218
219        ggml_tensor * attn_out = cur;
220
221        const auto & layer = model.layers[il];
222
223        if (layer.ffn_gate_inp == nullptr) {
224            cur = build_ffn(ffn_inp,
225                    layer.ffn_up,   nullptr, layer.ffn_up_s,
226                    layer.ffn_gate, nullptr, layer.ffn_gate_s,
227                    layer.ffn_down, nullptr, layer.ffn_down_s,
228                    nullptr, LLM_FFN_SILU, LLM_FFN_PAR, il);
229            cb(cur, "ffn_out", il);
230        } else {
231            cur = build_moe_ffn(ffn_inp,
232                    layer.ffn_gate_inp,
233                    layer.ffn_up_exps,
234                    layer.ffn_gate_exps,
235                    layer.ffn_down_exps,
236                    nullptr,
237                    n_expert, n_expert_used,
238                    LLM_FFN_SILU, hparams.expert_weights_norm,
239                    hparams.expert_weights_scale,
240                    (llama_expert_gating_func_type) hparams.expert_gating_func,
241                    il,
242                    nullptr, layer.ffn_gate_up_exps,
243                    layer.ffn_up_exps_s,
244                    layer.ffn_gate_exps_s,
245                    layer.ffn_down_exps_s);
246            cb(cur, "ffn_moe_out", il);
247
248            if (layer.ffn_up_shexp) {
249                ggml_tensor * ffn_shexp = build_ffn(ffn_inp,
250                        layer.ffn_up_shexp,   nullptr, layer.ffn_up_shexp_s,
251                        layer.ffn_gate_shexp, nullptr, layer.ffn_gate_shexp_s,
252                        layer.ffn_down_shexp, nullptr, layer.ffn_down_shexp_s,
253                        nullptr, LLM_FFN_SILU, LLM_FFN_PAR, il);
254                cb(ffn_shexp, "ffn_shexp", il);
255
256                cur = ggml_add(ctx0, cur, ffn_shexp);
257                cur = ggml_scale(ctx0, cur, 0.5f);
258                cb(cur, "ffn_out", il);
259            }
260        }
261
262        cur = ggml_add(ctx0, cur, inpL);
263        cur = ggml_add(ctx0, cur, attn_out);
264
265        cur = build_cvec(cur, il);
266        cb(cur, "l_out", il);
267
268        inpL = cur;
269    }
270
271    cur = inpL;
272    cur = build_norm(cur, model.output_norm, nullptr, cohere2moe_norm_type, -1);
273
274    cb(cur, "h_nextn", -1);
275    res->t_h_nextn = cur;
276
277    if (!cparams.embeddings_nextn_masked && inp_out_ids) {
278        cur = ggml_get_rows(ctx0, cur, inp_out_ids);
279    }
280
281    cb(cur, "result_norm", -1);
282    res->t_embd = cur;
283
284    cur = build_lora_mm(model.output, cur);
285
286    if (f_logit_scale) {
287        cur = ggml_scale(ctx0, cur, f_logit_scale);
288    }
289
290    cb(cur, "result_output", -1);
291    res->t_logits = cur;
292
293    ggml_build_forward_expand(gf, cur);
294}
295
296llama_model_cohere2moe::graph_mtp::graph_mtp(const llama_model & model, const llm_graph_params & params) : llm_graph_context(params) {
297    GGML_ASSERT(hparams.n_layer_nextn > 0 && "COHERE2MOE MTP requires n_layer_nextn > 0");
298    GGML_ASSERT(hparams.n_layer_nextn == 1 && "COHERE2MOE MTP currently only supports a single MTP block");
299
300    const int64_t n_embd_head = hparams.n_embd_head_v();
301    GGML_ASSERT(n_embd_head == hparams.n_embd_head_k());
302    GGML_ASSERT(n_embd_head == n_rot);
303
304    const int il = hparams.n_layer();
305    const auto & layer = model.layers[il];
306    GGML_ASSERT(layer.nextn.eh_proj && "MTP block missing nextn.eh_proj");
307    GGML_ASSERT(layer.nextn.enorm   && "MTP block missing nextn.enorm");
308    GGML_ASSERT(layer.nextn.hnorm   && "MTP block missing nextn.hnorm");
309    GGML_ASSERT(layer.ffn_gate_inp  && "MTP block missing ffn_gate_inp");
310
311    const llm_norm_type cohere2moe_norm_type = hparams.f_norm_rms_eps == 0.0f ? LLM_NORM : LLM_NORM_RMS;
312
313    // TODO: extract in a common llm_graph_context::build_inp_embd_h()
314    auto inp = std::make_unique<llm_graph_input_embd_h>(hparams.n_embd);
315
316    inp->tokens = ggml_new_tensor_1d(ctx0, GGML_TYPE_I32, n_tokens);
317    ggml_set_input(inp->tokens);
318
319    inp->embd = ggml_new_tensor_2d(ctx0, GGML_TYPE_F32, hparams.n_embd_inp(), n_tokens);
320    ggml_set_input(inp->embd);
321
322    // TODO: make static using `ggml_build_forward_select()`
323    //       see llm_graph_context::build_inp_embd() for reference
324    ggml_tensor * tok_embd;
325    if (ubatch.token) {
326        ggml_tensor * tok_embd_w = layer.nextn.embed_tokens ? layer.nextn.embed_tokens : model.tok_embd;
327        tok_embd = ggml_get_rows(ctx0, tok_embd_w, inp->tokens);
328    } else {
329        tok_embd = inp->embd;
330    }
331    cb(tok_embd, "mtp_tok_embd", il);
332
333    inp->h = ggml_new_tensor_2d(ctx0, GGML_TYPE_F32, hparams.n_embd, n_tokens);
334    ggml_set_input(inp->h);
335    ggml_set_name(inp->h, "mtp_h_input");
336
337    ggml_tensor * h_embd = inp->h;
338
339    res->add_input(std::move(inp));
340
341    ggml_tensor * inp_pos     = build_inp_pos();
342    ggml_tensor * inp_out_ids = build_inp_out_ids();
343    auto * inp_attn = build_attn_inp_kv_iswa();
344
345    ggml_tensor * h_norm = build_norm(h_embd, layer.nextn.hnorm, nullptr, cohere2moe_norm_type, il);
346    cb(h_norm, "mtp_hnorm", il);
347
348    ggml_tensor * e_norm = build_norm(tok_embd, layer.nextn.enorm, nullptr, cohere2moe_norm_type, il);
349    cb(e_norm, "mtp_enorm", il);
350
351    ggml_tensor * concat = ggml_concat(ctx0, e_norm, h_norm, /*dim=*/ 0);
352    cb(concat, "mtp_concat", il);
353
354    ggml_tensor * cur = build_lora_mm(layer.nextn.eh_proj, concat, layer.nextn.eh_proj_s);
355    cb(cur, "mtp_eh_proj", il);
356
357    ggml_tensor * inpL = cur;
358
359    cur = build_norm(cur, layer.attn_norm, nullptr, cohere2moe_norm_type, il);
360    cb(cur, "mtp_attn_norm", il);
361    ggml_tensor * ffn_inp = cur;
362
363    auto [Qcur, Kcur, Vcur] = build_qkv(layer, cur, n_embd_head, n_head, n_head_kv, il);
364    ggml_tensor * rope_factors = model.get_rope_factors(cparams, il);
365    Qcur = ggml_rope_ext(
366            ctx0, Qcur, inp_pos, rope_factors,
367            n_rot, rope_type, n_ctx_orig, freq_base, freq_scale,
368            ext_factor, attn_factor, beta_fast, beta_slow);
369    Kcur = ggml_rope_ext(
370            ctx0, Kcur, inp_pos, rope_factors,
371            n_rot, rope_type, n_ctx_orig, freq_base, freq_scale,
372            ext_factor, attn_factor, beta_fast, beta_slow);
373
374    cb(Qcur, "mtp_Qcur", il);
375    cb(Kcur, "mtp_Kcur", il);
376    cb(Vcur, "mtp_Vcur", il);
377
378    cur = build_attn(inp_attn,
379            layer.wo, layer.wo_b, layer.wo_s,
380            Qcur, Kcur, Vcur, nullptr, nullptr, nullptr,
381            1.0f / sqrtf(float(n_embd_head)), il);
382    cb(cur, "mtp_attn_out", il);
383
384    ggml_tensor * attn_out = cur;
385
386    cur = build_moe_ffn(ffn_inp,
387            layer.ffn_gate_inp,
388            layer.ffn_up_exps,
389            layer.ffn_gate_exps,
390            layer.ffn_down_exps,
391            nullptr,
392            n_expert, n_expert_used,
393            LLM_FFN_SILU, hparams.expert_weights_norm,
394            hparams.expert_weights_scale,
395            (llama_expert_gating_func_type) hparams.expert_gating_func,
396            il,
397            nullptr, layer.ffn_gate_up_exps,
398            layer.ffn_up_exps_s,
399            layer.ffn_gate_exps_s,
400            layer.ffn_down_exps_s);
401    cb(cur, "mtp_ffn_moe_out", il);
402
403    if (layer.ffn_up_shexp) {
404        ggml_tensor * ffn_shexp = build_ffn(ffn_inp,
405                layer.ffn_up_shexp,   nullptr, layer.ffn_up_shexp_s,
406                layer.ffn_gate_shexp, nullptr, layer.ffn_gate_shexp_s,
407                layer.ffn_down_shexp, nullptr, layer.ffn_down_shexp_s,
408                nullptr, LLM_FFN_SILU, LLM_FFN_PAR, il);
409        cb(ffn_shexp, "mtp_ffn_shexp", il);
410
411        cur = ggml_add(ctx0, cur, ffn_shexp);
412        cur = ggml_scale(ctx0, cur, 0.5f);
413        cb(cur, "mtp_ffn_out", il);
414    }
415
416    cur = ggml_add(ctx0, cur, inpL);
417    cur = ggml_add(ctx0, cur, attn_out);
418    cb(cur, "mtp_post_ffn", il);
419
420    ggml_tensor * head_norm_w = layer.nextn.shared_head_norm
421            ? layer.nextn.shared_head_norm
422            : model.output_norm;
423    GGML_ASSERT(head_norm_w && "COHERE2MOE MTP: missing both nextn.shared_head_norm and output_norm");
424    cur = build_norm(cur, head_norm_w, nullptr, cohere2moe_norm_type, -1);
425
426    cb(cur, "h_nextn", -1);
427    res->t_h_nextn = cur;
428
429    cur = ggml_get_rows(ctx0, cur, inp_out_ids);
430    cb(cur, "mtp_shared_head_norm", -1);
431
432    ggml_tensor * head_w = layer.nextn.shared_head_head ? layer.nextn.shared_head_head : model.output;
433    GGML_ASSERT(head_w && "COHERE2MOE MTP: missing LM head (nextn.shared_head_head or model.output)");
434    cur = build_lora_mm(head_w, cur, layer.nextn.shared_head_head ? layer.nextn.shared_head_head_s : nullptr);
435
436    if (hparams.f_logit_scale) {
437        cur = ggml_scale(ctx0, cur, hparams.f_logit_scale);
438    }
439
440    cb(cur, "result_output", -1);
441    res->t_logits = cur;
442
443    ggml_build_forward_expand(gf, cur);
444}