char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
c61b98b87
char/aliceai-t5-moe
1#include "models.h" 2 3#include "llama-kv-cache-dsa.h" 4 5// https://huggingface.co/zai-org/GLM-5.2/blob/main/config.json#L26 6const std::array < uint32_t ,LLAMA_MAX_LAYERS > GLM_5_2_DEFAULT_INDEXER_TYPES = { 71 ,1 , 81 ,0 ,0 ,0 , 91 ,0 ,0 ,0 , 101 ,0 ,0 ,0 , 111 ,0 ,0 ,0 , 121 ,0 ,0 ,0 , 131 ,0 ,0 ,0 , 141 ,0 ,0 ,0 , 151 ,0 ,0 ,0 , 161 ,0 ,0 ,0 , 171 ,0 ,0 ,0 , 181 ,0 ,0 ,0 , 191 ,0 ,0 ,0 , 201 ,0 ,0 ,0 , 211 ,0 ,0 ,0 , 221 ,0 ,0 ,0 , 231 ,0 ,0 ,0 , 241 ,0 ,0 ,0 , 251 ,0 ,0 ,0 , 261 ,0 ,0 ,0 , 27}; 28 29void llama_model_glm_dsa::load_arch_hparams (llama_model_loader & ml ) { 30ml .get_key_or_arr (LLM_KV_EXPERT_FEED_FORWARD_LENGTH ,hparams .n_ff_exp_arr ,hparams .n_layer_all ); 31ml .get_key (LLM_KV_ATTENTION_LAYERNORM_RMS_EPS ,hparams .f_norm_rms_eps ); 32ml .get_key_or_arr (LLM_KV_ROPE_DIMENSION_SECTIONS ,hparams .rope_sections ,4 , false); 33 34// MoE parameters 35ml .get_key (LLM_KV_EXPERT_SHARED_COUNT ,hparams .n_expert_shared ); 36ml .get_key (LLM_KV_LEADING_DENSE_BLOCK_COUNT ,hparams .n_layer_dense_lead , false); 37ml .get_key (LLM_KV_EXPERT_WEIGHTS_SCALE ,hparams .expert_weights_scale , false); 38ml .get_key (LLM_KV_EXPERT_WEIGHTS_NORM ,hparams .expert_weights_norm , false); 39 40// deepseek MLA parameters 41ml .get_key (LLM_KV_ATTENTION_Q_LORA_RANK ,hparams .n_lora_q ); 42ml .get_key (LLM_KV_ATTENTION_KV_LORA_RANK ,hparams .n_lora_kv ); 43ml .get_key (LLM_KV_ATTENTION_KEY_LENGTH_MLA ,hparams .n_embd_head_k_mla_impl , false); 44ml .get_key (LLM_KV_ATTENTION_VALUE_LENGTH_MLA ,hparams .n_embd_head_v_mla_impl , false); 45ml .get_key_or_arr (LLM_KV_EXPERT_FEED_FORWARD_LENGTH ,hparams .n_ff_exp_arr ,hparams .n_layer_all ); 46ml .get_key (LLM_KV_EXPERT_SHARED_COUNT ,hparams .n_expert_shared ); 47 48// DSA parameters 49ml .get_key (LLM_KV_ATTENTION_INDEXER_HEAD_COUNT ,hparams .indexer_n_head ); 50ml .get_key (LLM_KV_ATTENTION_INDEXER_KEY_LENGTH ,hparams .indexer_head_size ); 51ml .get_key (LLM_KV_ATTENTION_INDEXER_TOP_K ,hparams .indexer_top_k ); 52 53// Expert gating function (GLM-4.5 uses sigmoid) 54ml .get_key (LLM_KV_EXPERT_GATING_FUNC ,hparams .expert_gating_func , false); 55if (hparams .expert_gating_func == LLAMA_EXPERT_GATING_FUNC_TYPE_NONE ) { 56hparams .expert_gating_func = LLAMA_EXPERT_GATING_FUNC_TYPE_SIGMOID ; 57 } 58 59// BC for GLM 5, 5.1 (full indexers) without indexer_types metadata 60const bool is_pre_5_2 = hparams .n_ctx_train < 1048576 ; 61if (is_pre_5_2 ) { 62 std::fill (hparams .is_indexer_full_impl .begin (),hparams .is_indexer_full_impl .end (),1 ); 63 }else { 64hparams .is_indexer_full_impl = GLM_5_2_DEFAULT_INDEXER_TYPES ; 65 } 66ml .get_key_or_arr (LLM_KV_ATTENTION_INDEXER_TYPES ,hparams .is_indexer_full_impl ,hparams .n_layer (), false); 67 68switch (hparams .n_layer ()) { 69case 78 :type = LLM_TYPE_744B_A40B ;break ; 70default :type = LLM_TYPE_UNKNOWN ; 71 } 72} 73 74void llama_model_glm_dsa::load_arch_tensors (llama_model_loader & ml ) { 75LLAMA_LOAD_LOCALS ; 76const int64_t n_expert_shared = hparams .n_expert_shared ; 77 78// MTP-only: the GGUF carries only the NextN/MTP block(s) (user split target/draft). 79const bool mtp_only = (hparams .n_layer_nextn > 0 )&& (ml .get_weight ("blk.0.attn_norm.weight" )== nullptr ); 80// Trunk-only: the GGUF declares MTP layers in metadata but the actual MTP 81// tensors live in a separate file (or were stripped at conversion). Mark 82// MTP tensors NOT_REQUIRED so the trunk loads cleanly. 83const std::string mtp_probe = "blk." + std::to_string (n_layer )+ ".nextn.eh_proj.weight" ; 84const bool trunk_only = (hparams .n_layer_nextn > 0 )&& (ml .get_weight (mtp_probe .c_str ())== nullptr ); 85const int trunk_flags = mtp_only ?TENSOR_NOT_REQUIRED :0 ; 86int mtp_flags = trunk_only ?TENSOR_NOT_REQUIRED :0 ; 87 88if (!ml .load_mtp ) { 89mtp_flags |=TENSOR_SKIP ; 90 } 91 92const bool is_mla = hparams .is_mla (); 93if (!is_mla ) { 94throw std::runtime_error ("GLM_DSA architecture requires MLA" ); 95 } 96 97// note: these are the actual head sizes you get when treating as MHA or after "decompression" using wv_b for MLA 98const int64_t n_embd_head_k_mla = hparams .n_embd_head_k_mla (); 99const int64_t n_embd_head_v_mla = hparams .n_embd_head_v_mla (); 100 101const int64_t n_embd_head_qk_rope = hparams .n_rot (); 102const int64_t n_embd_head_qk_nope = n_embd_head_k_mla - n_embd_head_qk_rope ; 103 104const int64_t q_lora_rank = hparams .n_lora_q ; 105const int64_t kv_lora_rank = hparams .n_lora_kv ; 106 107const int64_t n_ff_exp = hparams .n_ff_exp (); 108 109tok_embd = create_tensor (tn (LLM_TENSOR_TOKEN_EMBD ,"weight" ), {n_embd ,n_vocab },0 ); 110 111// output 112output_norm = create_tensor (tn (LLM_TENSOR_OUTPUT_NORM ,"weight" ), {n_embd },0 ); 113// try to load output.weight, if not found, use token_embd (tied embeddings) 114output = create_tensor (tn (LLM_TENSOR_OUTPUT ,"weight" ), {n_embd ,n_vocab },TENSOR_NOT_REQUIRED ); 115if (!output ) { 116output = create_tensor (tn (LLM_TENSOR_TOKEN_EMBD ,"weight" ), {n_embd ,n_vocab },TENSOR_DUPLICATED ); 117 } 118 119for (int i = 0 ;i < n_layer_all ;++ i ) { 120// NextN/MTP layers (i >= n_layer) are full decoder blocks used by the 121// LLM_GRAPH_TYPE_DECODER_MTP draft head; load them like qwen35moe/step35/hy_v3. 122const int flags = (i >=n_layer ) ?mtp_flags :trunk_flags ; 123 124auto & layer = layers [i ]; 125 126layer .attn_norm = create_tensor (tn (LLM_TENSOR_ATTN_NORM ,"weight" ,i ), {n_embd },flags ); 127layer .attn_q_a_norm = create_tensor (tn (LLM_TENSOR_ATTN_Q_A_NORM ,"weight" ,i ), {q_lora_rank },flags ); 128layer .attn_kv_a_norm = create_tensor (tn (LLM_TENSOR_ATTN_KV_A_NORM ,"weight" ,i ), {kv_lora_rank },flags ); 129 130layer .wq_a = create_tensor (tn (LLM_TENSOR_ATTN_Q_A ,"weight" ,i ), {n_embd ,q_lora_rank },flags ); 131layer .wq_b = create_tensor (tn (LLM_TENSOR_ATTN_Q_B ,"weight" ,i ), {q_lora_rank ,n_head * n_embd_head_k_mla },flags ); 132 133layer .wkv_a_mqa = create_tensor (tn (LLM_TENSOR_ATTN_KV_A_MQA ,"weight" ,i ), {n_embd ,kv_lora_rank + n_embd_head_qk_rope },flags ); 134 135// note: only old legacy GGUF files will have the unsplit wkv_b tensor in 136layer .wk_b = create_tensor (tn (LLM_TENSOR_ATTN_K_B ,"weight" ,i ), {n_embd_head_qk_nope ,kv_lora_rank ,n_head },flags ); 137layer .wv_b = create_tensor (tn (LLM_TENSOR_ATTN_V_B ,"weight" ,i ), {kv_lora_rank ,n_embd_head_v_mla ,n_head },flags ); 138 139layer .wo = create_tensor (tn (LLM_TENSOR_ATTN_OUT ,"weight" ,i ), {n_head * n_embd_head_v_mla ,n_embd },flags ); 140 141layer .ffn_norm = create_tensor (tn (LLM_TENSOR_FFN_NORM ,"weight" ,i ), {n_embd },flags ); 142 143// DSA indexer 144layer .indexer_k_norm = create_tensor (tn (LLM_TENSOR_INDEXER_K_NORM ,"weight" ,i ), {hparams .indexer_head_size },flags |TENSOR_NOT_REQUIRED ); 145layer .indexer_k_norm_b = create_tensor (tn (LLM_TENSOR_INDEXER_K_NORM ,"bias" ,i ), {hparams .indexer_head_size },flags |TENSOR_NOT_REQUIRED ); 146layer .indexer_proj = create_tensor (tn (LLM_TENSOR_INDEXER_PROJ ,"weight" ,i ), {n_embd ,hparams .indexer_n_head },flags |TENSOR_NOT_REQUIRED ); 147layer .indexer_attn_k = create_tensor (tn (LLM_TENSOR_INDEXER_ATTN_K ,"weight" ,i ), {n_embd ,hparams .indexer_head_size },flags |TENSOR_NOT_REQUIRED ); 148layer .indexer_attn_q_b = create_tensor (tn (LLM_TENSOR_INDEXER_ATTN_Q_B ,"weight" ,i ), {q_lora_rank ,hparams .indexer_n_head * hparams .indexer_head_size },flags |TENSOR_NOT_REQUIRED ); 149if (i < (int )hparams .n_layer_dense_lead ) { 150layer .ffn_gate = create_tensor (tn (LLM_TENSOR_FFN_GATE ,"weight" ,i ), {n_embd ,n_ff },flags ); 151layer .ffn_down = create_tensor (tn (LLM_TENSOR_FFN_DOWN ,"weight" ,i ), {n_ff ,n_embd },flags ); 152layer .ffn_up = create_tensor (tn (LLM_TENSOR_FFN_UP ,"weight" ,i ), {n_embd ,n_ff },flags ); 153 }else { 154layer .ffn_gate_inp = create_tensor (tn (LLM_TENSOR_FFN_GATE_INP ,"weight" ,i ), {n_embd ,n_expert },flags ); 155layer .ffn_exp_probs_b = create_tensor (tn (LLM_TENSOR_FFN_EXP_PROBS_B ,"bias" ,i ), {n_expert },TENSOR_NOT_REQUIRED ); 156 157if (n_expert == 0 ) { 158throw std::runtime_error ("n_expert must be > 0" ); 159 } 160if (n_expert_used == 0 ) { 161throw std::runtime_error ("n_expert_used must be > 0" ); 162 } 163 164// MoE branch 165layer .ffn_gate_exps = create_tensor (tn (LLM_TENSOR_FFN_GATE_EXPS ,"weight" ,i ), {n_embd ,n_ff_exp ,n_expert },flags ); 166layer .ffn_down_exps = create_tensor (tn (LLM_TENSOR_FFN_DOWN_EXPS ,"weight" ,i ), {n_ff_exp ,n_embd ,n_expert },flags ); 167layer .ffn_up_exps = create_tensor (tn (LLM_TENSOR_FFN_UP_EXPS ,"weight" ,i ), {n_embd ,n_ff_exp ,n_expert },flags ); 168 169// Shared expert branch 170layer .ffn_gate_shexp = create_tensor (tn (LLM_TENSOR_FFN_GATE_SHEXP ,"weight" ,i ), {n_embd ,n_ff_exp * n_expert_shared },flags ); 171layer .ffn_down_shexp = create_tensor (tn (LLM_TENSOR_FFN_DOWN_SHEXP ,"weight" ,i ), {n_ff_exp * n_expert_shared ,n_embd },flags ); 172layer .ffn_up_shexp = create_tensor (tn (LLM_TENSOR_FFN_UP_SHEXP ,"weight" ,i ), {n_embd ,n_ff_exp * n_expert_shared },flags ); 173 } 174 175// NextN/MTP tensors - the NextN-specific wiring around the extra decoder block 176if (i >=n_layer ) { 177layer .nextn .eh_proj = create_tensor (tn (LLM_TENSOR_NEXTN_EH_PROJ ,"weight" ,i ), {2 * n_embd ,n_embd },flags ); 178layer .nextn .enorm = create_tensor (tn (LLM_TENSOR_NEXTN_ENORM ,"weight" ,i ), {n_embd },flags ); 179layer .nextn .hnorm = create_tensor (tn (LLM_TENSOR_NEXTN_HNORM ,"weight" ,i ), {n_embd },flags ); 180 181// Optional tensors 182layer .nextn .embed_tokens = create_tensor (tn (LLM_TENSOR_NEXTN_EMBED_TOKENS ,"weight" ,i ), {n_embd ,n_vocab },flags |TENSOR_NOT_REQUIRED ); 183layer .nextn .shared_head_head = create_tensor (tn (LLM_TENSOR_NEXTN_SHARED_HEAD_HEAD ,"weight" ,i ), {n_embd ,n_vocab },flags |TENSOR_NOT_REQUIRED ); 184layer .nextn .shared_head_norm = create_tensor (tn (LLM_TENSOR_NEXTN_SHARED_HEAD_NORM ,"weight" ,i ), {n_embd },flags |TENSOR_NOT_REQUIRED ); 185 } 186 } 187} 188 189std::unique_ptr < llm_graph_context > llama_model_glm_dsa::build_arch_graph (const llm_graph_params & params )const { 190if (params .gtype == LLM_GRAPH_TYPE_DECODER_MTP ) { 191return std::make_unique < graph_mtp > (* this ,params ); 192 } 193return std::make_unique < graph > (* this ,params ); 194} 195 196llama_model_glm_dsa::graph::graph (const llama_model & model ,const llm_graph_params & params ) : 197llm_graph_context (params ) { 198const bool is_mla = hparams .is_mla (); 199GGML_ASSERT (is_mla ); 200 201// note: these are the actual head sizes you get when treating as MHA or after "decompression" using wv_b for MLA 202const int64_t n_embd_head_k = hparams .n_embd_head_k_mla (); 203const int64_t n_embd_head_v = hparams .n_embd_head_v_mla (); 204GGML_UNUSED (n_embd_head_v ); 205 206const int64_t n_embd_head_qk_rope = hparams .n_rot (); 207const int64_t n_embd_head_qk_nope = n_embd_head_k - n_embd_head_qk_rope ; 208 209const int64_t n_indexer_head = hparams .indexer_n_head ; 210const int64_t n_embd_indexer_head = hparams .indexer_head_size ; 211const uint32_t n_indexer_top_k = hparams .indexer_top_k ; 212 213// the indexer head layout is [rope | nope] 214GGML_ASSERT (hparams .n_rot () <=n_embd_indexer_head ); 215 216const uint32_t kv_lora_rank = hparams .n_lora_kv ; 217 218// We have to pre-scale kq_scale and attn_factor to make the YaRN RoPE work correctly. 219// See https://github.com/ggml-org/llama.cpp/discussions/7416 for detailed explanation. 220// And also: https://github.com/ggml-org/llama.cpp/pull/17945 [TAG_DEEPSEEK2_YARN_LOG_MUL_FIX] 221 222// first cancel the adjustment from llama_hparams::yarn_attn_factor_adjust to get the original attn_factor 223GGML_ASSERT (ext_factor >=0.0f ); 224const float attn_factor_org = attn_factor * (1.0f + 0.1f * logf (1.0f /freq_scale )); 225 226// use the original attn_factor to pre-scale the kq_scale 227const float mscale = attn_factor_org * (1.0f + 0.1f * hparams .rope_yarn_log_mul * logf (1.0f /freq_scale )); 228const float kq_scale = 1.0f * mscale * mscale /sqrtf (float (n_embd_head_k )); 229 230ggml_tensor * cur ; 231ggml_tensor * inpL ; 232 233// {n_embd, n_tokens} 234inpL = build_inp_embd (model .tok_embd ); 235 236// inp_pos - contains the positions 237ggml_tensor * inp_pos = build_inp_pos (); 238 239llm_graph_input_attn_k_dsa * inp_attn_dsa = build_attn_inp_k_dsa (); 240 241ggml_tensor * inp_out_ids = build_inp_out_ids (); 242 243// Difference vs Deepseek 3.2: shared indexer layers reuse the top_k from the previous full indexer layers 244// See https://huggingface.co/zai-org/GLM-5.2/blob/main/config.json#L30 245ggml_tensor * prev_top_k = nullptr ; 246for (int il = 0 ;il < n_layer ;++ il ) { 247ggml_tensor * inpSA = inpL ; 248 249// norm 250cur = build_norm (inpL ,model .layers [il ].attn_norm ,NULL ,LLM_NORM_RMS ,il ); 251cb (cur ,"attn_norm" ,il ); 252 253// self_attention 254 { 255ggml_tensor * qr = ggml_mul_mat (ctx0 ,model .layers [il ].wq_a ,cur ); 256cb (qr ,"qr" ,il ); 257 258qr = build_norm (qr ,model .layers [il ].attn_q_a_norm ,nullptr ,LLM_NORM_RMS ,il ); 259cb (qr ,"qr" ,il ); 260 261ggml_tensor * top_k = nullptr ; 262 263// lightning indexer 264if (hparams .is_indexer_full (il )) { 265// "full" layer 266ggml_tensor * indexer_q = ggml_mul_mat (ctx0 ,model .layers [il ].indexer_attn_q_b ,qr ); 267cb (indexer_q ,"indexer_q" ,il ); 268 269// {n_embd_indexer_head, n_indexer_head, n_tokens} 270indexer_q = ggml_reshape_3d (ctx0 ,indexer_q ,n_embd_indexer_head ,n_indexer_head ,n_tokens ); 271indexer_q = ggml_rope_ext (ctx0 ,indexer_q ,inp_pos ,nullptr ,n_rot , 272LLAMA_ROPE_TYPE_NORM ,n_ctx_orig ,freq_base ,freq_scale , 273ext_factor ,attn_factor ,beta_fast ,beta_slow ); 274cb (indexer_q ,"indexer_q" ,il ); 275 276ggml_tensor * indexer_k = ggml_mul_mat (ctx0 ,model .layers [il ].indexer_attn_k ,cur ); 277cb (indexer_k ,"indexer_k" ,il ); 278 279indexer_k = build_norm (indexer_k ,model .layers [il ].indexer_k_norm ,model .layers [il ].indexer_k_norm_b ,LLM_NORM ,il ); 280cb (indexer_k ,"indexer_k" ,il ); 281 282// {n_embd_indexer_head, 1, n_tokens} 283indexer_k = ggml_reshape_3d (ctx0 ,indexer_k ,n_embd_indexer_head ,1 ,n_tokens ); 284indexer_k = ggml_rope_ext (ctx0 ,indexer_k ,inp_pos ,nullptr ,n_rot , 285LLAMA_ROPE_TYPE_NORM ,n_ctx_orig ,freq_base ,freq_scale , 286ext_factor ,attn_factor ,beta_fast ,beta_slow ); 287cb (indexer_k ,"indexer_k" ,il ); 288 289// perform Hadamard transform on indexer q and k 290indexer_q = ggml_mul_mat (ctx0 ,inp_attn_dsa -> self_k_rot_lid ,indexer_q ); 291cb (indexer_q ,"indexer_q" ,il ); 292indexer_k = ggml_mul_mat (ctx0 ,inp_attn_dsa -> self_k_rot_lid ,indexer_k ); 293cb (indexer_k ,"indexer_k" ,il ); 294 295// store indexer keys to KV cache 296const auto * mctx_lid = inp_attn_dsa -> mctx -> get_lid (); 297const auto & k_idxs_lid = inp_attn_dsa -> get_k_idxs_lid (); 298ggml_build_forward_expand (gf ,mctx_lid -> cpy_k (ctx0 ,indexer_k ,k_idxs_lid ,il )); 299 300// prepare indexer weights 301ggml_tensor * indexer_weights = ggml_mul_mat (ctx0 ,model .layers [il ].indexer_proj ,cur ); 302cb (indexer_weights ,"indexer_weights" ,il ); 303 304// get cached indexer keys 305indexer_k = mctx_lid -> get_k (ctx0 ,il ); 306 307// split the batch into streams if needed 308const auto n_stream = indexer_k -> ne [3 ]; 309indexer_q = ggml_view_4d (ctx0 ,indexer_q ,indexer_q -> ne [0 ],indexer_q -> ne [1 ],indexer_q -> ne [2 ]/n_stream ,n_stream ,indexer_q -> nb [1 ],indexer_q -> nb [2 ],indexer_q -> nb [3 ]/n_stream ,0 ); 310indexer_weights = ggml_view_4d (ctx0 ,indexer_weights ,indexer_weights -> ne [0 ],indexer_weights -> ne [1 ]/n_stream ,indexer_weights -> ne [2 ],n_stream ,indexer_weights -> nb [1 ],indexer_weights -> nb [2 ]/n_stream ,indexer_weights -> nb [3 ]/n_stream ,0 ); 311 312// pre-scale weights to avoid scaling operations on huge indexer_score tensor 313indexer_weights = ggml_scale (ctx0 ,indexer_weights ,1.0f /sqrtf (float (n_embd_indexer_head * n_indexer_head ))); 314cb (indexer_weights ,"indexer_weights" ,il ); 315 316ggml_tensor * indexer_score = nullptr ; 317if (cparams .fused_lid ) { 318indexer_score = ggml_lightning_indexer (ctx0 ,indexer_q ,indexer_k ,indexer_weights ,inp_attn_dsa -> get_kq_mask_lid ()); 319cb (indexer_score ,"indexer_score" ,il ); 320res -> add_fused_node ({LLM_FUSED_OP_LIGHTNING_INDEXER ,indexer_score ,il }); 321 }else { 322// calculate indexer kq 323indexer_q = ggml_permute (ctx0 ,indexer_q ,0 ,2 ,1 ,3 ); 324cb (indexer_q ,"indexer_q" ,il ); 325indexer_k = ggml_permute (ctx0 ,indexer_k ,0 ,2 ,1 ,3 ); 326cb (indexer_k ,"indexer_k" ,il ); 327 328ggml_tensor * indexer_kq = ggml_mul_mat (ctx0 ,indexer_k ,indexer_q ); 329cb (indexer_kq ,"indexer_kq" ,il ); 330 331// ReLU requires contiguous tensors 332indexer_kq = ggml_cont (ctx0 ,ggml_permute (ctx0 ,indexer_kq ,2 ,1 ,0 ,3 )); 333cb (indexer_kq ,"indexer_kq" ,il ); 334 335// apply ReLU 336indexer_score = ggml_relu (ctx0 ,indexer_kq ); 337cb (indexer_score ,"indexer_score" ,il ); 338 339// multiply scores by indexer weights 340indexer_score = ggml_mul (ctx0 ,indexer_score ,indexer_weights ); 341cb (indexer_score ,"indexer_score" ,il ); 342 343// sum by q n_indexer_head dimension 344indexer_score = ggml_sum_rows (ctx0 ,indexer_score ); 345cb (indexer_score ,"indexer_score" ,il ); 346 347// permute result to match KQ mask 348indexer_score = ggml_cont (ctx0 ,ggml_permute (ctx0 ,indexer_score ,2 ,1 ,0 ,3 )); 349cb (indexer_score ,"indexer_score" ,il ); 350 351// mask indexer scores 352ggml_tensor * indexer_kq_mask = inp_attn_dsa -> get_kq_mask_lid (); 353indexer_score = ggml_add (ctx0 ,indexer_score ,indexer_kq_mask ); 354cb (indexer_score ,"indexer_score" ,il ); 355 } 356 357// get indices of top k indexer scores 358uint32_t n_top_k = indexer_score -> ne [0 ]< n_indexer_top_k ?indexer_score -> ne [0 ] :n_indexer_top_k ; 359top_k = ggml_cont (ctx0 ,ggml_top_k (ctx0 ,indexer_score ,n_top_k )); 360prev_top_k = top_k ; 361cb (top_k ,"top_k" ,il ); 362 }else { 363// "shared" indexer layer - reuse top-k from a previous full layer 364GGML_ASSERT (prev_top_k != nullptr && "shared indexer layer must follow a previous full indexer layer" ); 365top_k = prev_top_k ; 366cb (top_k ,"top_k" ,il ); 367 } 368 369ggml_tensor * q = ggml_mul_mat (ctx0 ,model .layers [il ].wq_b ,qr ); 370cb (q ,"q" ,il ); 371 372// split into {n_embd_head_qk_nope, n_head, n_tokens} 373ggml_tensor * q_nope = 374ggml_view_3d (ctx0 ,q ,n_embd_head_qk_nope ,n_head ,n_tokens ,ggml_row_size (q -> type ,n_embd_head_k ), 375ggml_row_size (q -> type ,n_embd_head_k )* n_head ,0 ); 376cb (q_nope ,"q_nope" ,il ); 377 378// and {n_embd_head_qk_rope, n_head, n_tokens} 379ggml_tensor * q_pe = ggml_view_3d ( 380ctx0 ,q ,n_embd_head_qk_rope ,n_head ,n_tokens ,ggml_row_size (q -> type ,n_embd_head_k ), 381ggml_row_size (q -> type ,n_embd_head_k )* n_head ,ggml_row_size (q -> type ,n_embd_head_qk_nope )); 382cb (q_pe ,"q_pe" ,il ); 383 384ggml_tensor * kv_cmpr_pe = ggml_mul_mat (ctx0 ,model .layers [il ].wkv_a_mqa ,cur ); 385cb (kv_cmpr_pe ,"kv_cmpr_pe" ,il ); 386 387// split into {kv_lora_rank, n_tokens} 388ggml_tensor * kv_cmpr = 389ggml_view_2d (ctx0 ,kv_cmpr_pe ,kv_lora_rank ,n_tokens , 390ggml_row_size (kv_cmpr_pe -> type ,kv_lora_rank + n_embd_head_qk_rope ),0 ); 391cb (kv_cmpr ,"kv_cmpr" ,il ); 392 393// and {n_embd_head_qk_rope, 1, n_tokens} 394ggml_tensor * k_pe = ggml_view_3d (ctx0 ,kv_cmpr_pe ,n_embd_head_qk_rope ,1 ,n_tokens , 395ggml_row_size (kv_cmpr_pe -> type ,kv_lora_rank + n_embd_head_qk_rope ), 396ggml_row_size (kv_cmpr_pe -> type ,kv_lora_rank + n_embd_head_qk_rope ), 397ggml_row_size (kv_cmpr_pe -> type ,kv_lora_rank )); 398cb (k_pe ,"k_pe" ,il ); 399 400q_pe = ggml_rope_ext (ctx0 ,q_pe ,inp_pos ,nullptr ,n_rot ,rope_type ,n_ctx_orig ,freq_base ,freq_scale , 401ext_factor ,attn_factor ,beta_fast ,beta_slow ); 402cb (q_pe ,"q_pe" ,il ); 403 404k_pe = ggml_rope_ext (ctx0 ,k_pe ,inp_pos ,nullptr ,n_rot ,rope_type ,n_ctx_orig ,freq_base ,freq_scale , 405ext_factor ,attn_factor ,beta_fast ,beta_slow ); 406cb (k_pe ,"k_pe" ,il ); 407 408kv_cmpr = build_norm (kv_cmpr ,model .layers [il ].attn_kv_a_norm ,nullptr ,LLM_NORM_RMS ,il ); 409cb (kv_cmpr ,"kv_cmpr" ,il ); 410 411// MLA attention 412 { 413// {n_embd_head_qk_nope, n_tokens, n_head} 414q_nope = ggml_permute (ctx0 ,q_nope ,0 ,2 ,1 ,3 ); 415cb (q_nope ,"q_nope_perm" ,il ); 416 417// {n_embd_head_qk_nope, kv_lora_rank, n_head} x {n_embd_head_qk_nope, n_tokens, n_head} 418ggml_tensor * q_nope_absorbed = ggml_mul_mat (ctx0 ,model .layers [il ].wk_b ,q_nope ); 419cb (q_nope_absorbed ,"q_nope_absorbed" ,il ); 420 421// {kv_lora_rank, n_head, n_tokens} 422q_nope_absorbed = ggml_permute (ctx0 ,q_nope_absorbed ,0 ,2 ,1 ,3 ); 423cb (q_nope_absorbed ,"q_nope_absorbed_perm" ,il ); 424 425// {n_embd_head_qk_rope + kv_lora_rank, n_head, n_tokens} 426// note: rope must go first for in-place context shifting in build_rope_shift() 427ggml_tensor * Qcur = ggml_concat (ctx0 ,q_nope_absorbed ,q_pe ,0 ); 428cb (Qcur ,"Qcur" ,il ); 429 430kv_cmpr = ggml_reshape_3d (ctx0 ,kv_cmpr ,kv_lora_rank ,1 ,n_tokens ); 431cb (kv_cmpr ,"kv_cmpr_reshape" ,il ); 432 433// {n_embd_head_qk_rope + kv_lora_rank, 1, n_tokens} 434ggml_tensor * Kcur = ggml_concat (ctx0 ,kv_cmpr ,k_pe ,0 ); 435cb (Kcur ,"Kcur" ,il ); 436 437// {kv_lora_rank, 1, n_tokens} 438ggml_tensor * Vcur = kv_cmpr ; 439cb (Vcur ,"Vcur" ,il ); 440 441// note: MLA with the absorption optimization converts into MQA (ie: GQA with 1 group) 442cur = build_attn (inp_attn_dsa , 443model .layers [il ].wo ,NULL ,model .layers [il ].wo_s , 444Qcur ,Kcur ,Vcur ,nullptr ,nullptr ,model .layers [il ].wv_b ,top_k ,kq_scale ,il ); 445 } 446 } 447// when unmasked nextn embeddings are requested, t_h_nextn must keep all rows, 448// so the early output masking has to be skipped (it is applied after the final norm instead) 449if (il == n_layer - 1 && inp_out_ids && (!cparams .embeddings_nextn || cparams .embeddings_nextn_masked )) { 450cur = ggml_get_rows (ctx0 ,cur ,inp_out_ids ); 451inpSA = ggml_get_rows (ctx0 ,inpSA ,inp_out_ids ); 452 } 453ggml_tensor * ffn_inp = ggml_add (ctx0 ,cur ,inpSA ); 454cb (ffn_inp ,"ffn_inp" ,il ); 455 456cur = build_norm (ffn_inp ,model .layers [il ].ffn_norm ,NULL ,LLM_NORM_RMS ,il ); 457cb (cur ,"ffn_norm" ,il ); 458 459if ((uint32_t )il < hparams .n_layer_dense_lead ) { 460cur = build_ffn (cur , 461model .layers [il ].ffn_up ,NULL ,model .layers [il ].ffn_up_s , 462model .layers [il ].ffn_gate ,NULL ,model .layers [il ].ffn_gate_s , 463model .layers [il ].ffn_down ,NULL ,model .layers [il ].ffn_down_s , 464NULL ,LLM_FFN_SILU ,LLM_FFN_PAR ,il ); 465cb (cur ,"ffn_out" ,il ); 466 }else { 467// MoE branch 468ggml_tensor * moe_out = build_moe_ffn (cur , 469model .layers [il ].ffn_gate_inp , 470model .layers [il ].ffn_up_exps , 471model .layers [il ].ffn_gate_exps , 472model .layers [il ].ffn_down_exps , 473model .layers [il ].ffn_exp_probs_b , 474n_expert ,n_expert_used , 475LLM_FFN_SILU ,hparams .expert_weights_norm , 476hparams .expert_weights_scale , 477 (llama_expert_gating_func_type )hparams .expert_gating_func , 478il , 479nullptr , 480model .layers [il ].ffn_gate_up_exps , 481model .layers [il ].ffn_up_exps_s , 482model .layers [il ].ffn_gate_exps_s , 483model .layers [il ].ffn_down_exps_s ); 484cb (moe_out ,"ffn_moe_out" ,il ); 485 486// FFN shared expert 487 { 488ggml_tensor * ffn_shexp = 489build_ffn (cur , 490model .layers [il ].ffn_up_shexp ,NULL ,model .layers [il ].ffn_up_shexp_s , 491model .layers [il ].ffn_gate_shexp ,NULL ,model .layers [il ].ffn_gate_shexp_s , 492model .layers [il ].ffn_down_shexp ,NULL ,model .layers [il ].ffn_down_shexp_s , 493NULL ,LLM_FFN_SILU ,LLM_FFN_PAR ,il ); 494cb (ffn_shexp ,"ffn_shexp" ,il ); 495 496cur = ggml_add (ctx0 ,moe_out ,ffn_shexp ); 497cb (cur ,"ffn_out" ,il ); 498 } 499 } 500cur = ggml_add (ctx0 ,cur ,ffn_inp ); 501 502cur = build_cvec (cur ,il ); 503cb (cur ,"l_out" ,il ); 504 505// input for next layer 506inpL = cur ; 507 } 508cur = inpL ; 509 510cur = build_norm (cur ,model .output_norm ,NULL ,LLM_NORM_RMS ,-1 ); 511 512// post-norm hidden state feeds the NextN/MTP draft head 513cb (cur ,"h_nextn" ,-1 ); 514res -> t_h_nextn = cur ; 515 516if (cparams .embeddings_nextn && !cparams .embeddings_nextn_masked && inp_out_ids ) { 517cur = ggml_get_rows (ctx0 ,cur ,inp_out_ids ); 518 } 519 520cb (cur ,"result_norm" ,-1 ); 521res -> t_embd = cur ; 522 523// lm_head 524cur = ggml_mul_mat (ctx0 ,model .output ,cur ); 525 526cb (cur ,"result_output" ,-1 ); 527res -> t_logits = cur ; 528 529ggml_build_forward_expand (gf ,cur ); 530} 531 532// LLM_GRAPH_TYPE_DECODER_MTP draft head for GLM-5.2 (GLM_DSA). 533// Semantics mirror the deepseek-family NextN/MTP layer: 534// enorm(embed) + hnorm(prev_hidden) -> concat(e, h) -> eh_proj -> 535// full glm_dsa decoder block (dense MLA attention + sigmoid-gated MoE FFN 536// with shared expert, exactly as the trunk deepseek2 graph builds it) -> 537// shared_head_norm (fallback output_norm) -> shared LM head. 538// The DSA indexer is not used at runtime (same as the trunk graph). 539llama_model_glm_dsa::graph_mtp::graph_mtp (const llama_model & model ,const llm_graph_params & params ) 540 :llm_graph_context (params ) { 541GGML_ASSERT (hparams .n_layer_nextn > 0 && "GLM_DSA MTP requires n_layer_nextn > 0" ); 542GGML_ASSERT (hparams .n_layer_nextn == 1 && "GLM_DSA MTP currently only supports a single MTP block" ); 543GGML_ASSERT (hparams .is_mla ()&& "GLM_DSA MTP requires MLA" ); 544 545const int il = hparams .n_layer ()+ cparams .nextn_layer_offset ; 546GGML_ASSERT (cparams .nextn_layer_offset >=0 && 547cparams .nextn_layer_offset < (int )hparams .n_layer_nextn && 548"nextn_layer_offset out of range [0, n_layer_nextn)" ); 549const auto & layer = model .layers [il ]; 550 551GGML_ASSERT (layer .nextn .eh_proj && "MTP block missing nextn.eh_proj" ); 552GGML_ASSERT (layer .nextn .enorm && "MTP block missing nextn.enorm" ); 553GGML_ASSERT (layer .nextn .hnorm && "MTP block missing nextn.hnorm" ); 554GGML_ASSERT (layer .ffn_gate_inp && "MTP block missing ffn_gate_inp" ); 555 556// note: these are the actual head sizes you get when treating as MHA or after "decompression" using wv_b for MLA 557const int64_t n_embd_head_k = hparams .n_embd_head_k_mla (); 558 559const int64_t n_embd_head_qk_rope = hparams .n_rot (); 560const int64_t n_embd_head_qk_nope = n_embd_head_k - n_embd_head_qk_rope ; 561 562const uint32_t kv_lora_rank = hparams .n_lora_kv ; 563 564// We have to pre-scale kq_scale and attn_factor to make the YaRN RoPE work correctly. 565// See the deepseek2 trunk graph for the detailed explanation - this must match it EXACTLY. 566GGML_ASSERT (ext_factor >=0.0f ); 567const float attn_factor_org = attn_factor * (1.0f + 0.1f * logf (1.0f /freq_scale )); 568 569const float mscale = attn_factor_org * (1.0f + 0.1f * hparams .rope_yarn_log_mul * logf (1.0f /freq_scale )); 570const float kq_scale = 1.0f * mscale * mscale /sqrtf (float (n_embd_head_k )); 571 572// TODO: extract in a common llm_graph_context::build_inp_embd_h() 573auto inp = std::make_unique < llm_graph_input_embd_h > (hparams .n_embd ); 574 575inp -> tokens = ggml_new_tensor_1d (ctx0 ,GGML_TYPE_I32 ,n_tokens ); 576ggml_set_input (inp -> tokens ); 577 578inp -> embd = ggml_new_tensor_2d (ctx0 ,GGML_TYPE_F32 ,hparams .n_embd_inp (),n_tokens ); 579ggml_set_input (inp -> embd ); 580 581ggml_tensor * tok_embd ; 582if (ubatch .token ) { 583ggml_tensor * tok_embd_w = layer .nextn .embed_tokens ?layer .nextn .embed_tokens :model .tok_embd ; 584 585tok_embd = ggml_get_rows (ctx0 ,tok_embd_w ,inp -> tokens ); 586 }else { 587tok_embd = inp -> embd ; 588 } 589cb (tok_embd ,"mtp_tok_embd" ,il ); 590 591inp -> h = ggml_new_tensor_2d (ctx0 ,GGML_TYPE_F32 ,hparams .n_embd ,n_tokens ); 592ggml_set_input (inp -> h ); 593ggml_set_name (inp -> h ,"mtp_h_input" ); 594 595ggml_tensor * h_embd = inp -> h ; 596 597res -> add_input (std::move (inp )); 598 599ggml_tensor * inp_pos = build_inp_pos (); 600ggml_tensor * inp_out_ids = build_inp_out_ids (); 601 602// MLA with the absorption optimization uses a K-only cache (V is a view of K) 603auto * inp_attn = build_attn_inp_k (); 604 605ggml_tensor * h_norm = build_norm (h_embd ,layer .nextn .hnorm ,nullptr ,LLM_NORM_RMS ,il ); 606cb (h_norm ,"mtp_hnorm" ,il ); 607 608ggml_tensor * e_norm = build_norm (tok_embd ,layer .nextn .enorm ,nullptr ,LLM_NORM_RMS ,il ); 609cb (e_norm ,"mtp_enorm" ,il ); 610 611ggml_tensor * concat = ggml_concat (ctx0 ,e_norm ,h_norm ,/*dim=*/ 0 ); 612cb (concat ,"mtp_concat" ,il ); 613 614ggml_tensor * cur = build_lora_mm (layer .nextn .eh_proj ,concat ,layer .nextn .eh_proj_s ); 615cb (cur ,"mtp_eh_proj" ,il ); 616 617ggml_tensor * inpSA = cur ; 618 619cur = build_norm (cur ,layer .attn_norm ,nullptr ,LLM_NORM_RMS ,il ); 620cb (cur ,"mtp_attn_norm" ,il ); 621 622// self-attention: dense MLA, same construction as the deepseek2 trunk graph 623 { 624ggml_tensor * q = ggml_mul_mat (ctx0 ,layer .wq_a ,cur ); 625cb (q ,"mtp_q" ,il ); 626 627q = build_norm (q ,layer .attn_q_a_norm ,nullptr ,LLM_NORM_RMS ,il ); 628cb (q ,"mtp_q" ,il ); 629 630q = ggml_mul_mat (ctx0 ,layer .wq_b ,q ); 631cb (q ,"mtp_q" ,il ); 632 633// split into {n_embd_head_qk_nope, n_head, n_tokens} 634ggml_tensor * q_nope = 635ggml_view_3d (ctx0 ,q ,n_embd_head_qk_nope ,n_head ,n_tokens ,ggml_row_size (q -> type ,n_embd_head_k ), 636ggml_row_size (q -> type ,n_embd_head_k )* n_head ,0 ); 637cb (q_nope ,"mtp_q_nope" ,il ); 638 639// and {n_embd_head_qk_rope, n_head, n_tokens} 640ggml_tensor * q_pe = ggml_view_3d ( 641ctx0 ,q ,n_embd_head_qk_rope ,n_head ,n_tokens ,ggml_row_size (q -> type ,n_embd_head_k ), 642ggml_row_size (q -> type ,n_embd_head_k )* n_head ,ggml_row_size (q -> type ,n_embd_head_qk_nope )); 643cb (q_pe ,"mtp_q_pe" ,il ); 644 645ggml_tensor * kv_cmpr_pe = ggml_mul_mat (ctx0 ,layer .wkv_a_mqa ,cur ); 646cb (kv_cmpr_pe ,"mtp_kv_cmpr_pe" ,il ); 647 648// split into {kv_lora_rank, n_tokens} 649ggml_tensor * kv_cmpr = 650ggml_view_2d (ctx0 ,kv_cmpr_pe ,kv_lora_rank ,n_tokens , 651ggml_row_size (kv_cmpr_pe -> type ,kv_lora_rank + n_embd_head_qk_rope ),0 ); 652cb (kv_cmpr ,"mtp_kv_cmpr" ,il ); 653 654// and {n_embd_head_qk_rope, 1, n_tokens} 655ggml_tensor * k_pe = ggml_view_3d (ctx0 ,kv_cmpr_pe ,n_embd_head_qk_rope ,1 ,n_tokens , 656ggml_row_size (kv_cmpr_pe -> type ,kv_lora_rank + n_embd_head_qk_rope ), 657ggml_row_size (kv_cmpr_pe -> type ,kv_lora_rank + n_embd_head_qk_rope ), 658ggml_row_size (kv_cmpr_pe -> type ,kv_lora_rank )); 659cb (k_pe ,"mtp_k_pe" ,il ); 660 661q_pe = ggml_rope_ext (ctx0 ,q_pe ,inp_pos ,nullptr ,n_rot ,rope_type ,n_ctx_orig ,freq_base ,freq_scale , 662ext_factor ,attn_factor ,beta_fast ,beta_slow ); 663cb (q_pe ,"mtp_q_pe" ,il ); 664 665k_pe = ggml_rope_ext (ctx0 ,k_pe ,inp_pos ,nullptr ,n_rot ,rope_type ,n_ctx_orig ,freq_base ,freq_scale , 666ext_factor ,attn_factor ,beta_fast ,beta_slow ); 667cb (k_pe ,"mtp_k_pe" ,il ); 668 669kv_cmpr = build_norm (kv_cmpr ,layer .attn_kv_a_norm ,nullptr ,LLM_NORM_RMS ,il ); 670cb (kv_cmpr ,"mtp_kv_cmpr" ,il ); 671 672// {n_embd_head_qk_nope, n_tokens, n_head} 673q_nope = ggml_permute (ctx0 ,q_nope ,0 ,2 ,1 ,3 ); 674cb (q_nope ,"mtp_q_nope_perm" ,il ); 675 676// {n_embd_head_qk_nope, kv_lora_rank, n_head} x {n_embd_head_qk_nope, n_tokens, n_head} 677ggml_tensor * q_nope_absorbed = ggml_mul_mat (ctx0 ,layer .wk_b ,q_nope ); 678cb (q_nope_absorbed ,"mtp_q_nope_absorbed" ,il ); 679 680// {kv_lora_rank, n_head, n_tokens} 681q_nope_absorbed = ggml_permute (ctx0 ,q_nope_absorbed ,0 ,2 ,1 ,3 ); 682cb (q_nope_absorbed ,"mtp_q_nope_absorbed_perm" ,il ); 683 684// {n_embd_head_qk_rope + kv_lora_rank, n_head, n_tokens} 685// note: rope must go first for in-place context shifting in build_rope_shift() 686ggml_tensor * Qcur = ggml_concat (ctx0 ,q_nope_absorbed ,q_pe ,0 ); 687cb (Qcur ,"mtp_Qcur" ,il ); 688 689kv_cmpr = ggml_reshape_3d (ctx0 ,kv_cmpr ,kv_lora_rank ,1 ,n_tokens ); 690cb (kv_cmpr ,"mtp_kv_cmpr_reshape" ,il ); 691 692// {n_embd_head_qk_rope + kv_lora_rank, 1, n_tokens} 693ggml_tensor * Kcur = ggml_concat (ctx0 ,kv_cmpr ,k_pe ,0 ); 694cb (Kcur ,"mtp_Kcur" ,il ); 695 696// {kv_lora_rank, 1, n_tokens} 697ggml_tensor * Vcur = kv_cmpr ; 698cb (Vcur ,"mtp_Vcur" ,il ); 699 700// note: MLA with the absorption optimization converts into MQA (ie: GQA with 1 group) 701cur = build_attn (inp_attn , 702layer .wo ,NULL ,layer .wo_s , 703Qcur ,Kcur ,Vcur ,nullptr ,nullptr ,layer .wv_b ,kq_scale ,il ); 704cb (cur ,"mtp_attn_out" ,il ); 705 } 706 707ggml_tensor * ffn_inp = ggml_add (ctx0 ,cur ,inpSA ); 708cb (ffn_inp ,"mtp_ffn_inp" ,il ); 709 710cur = build_norm (ffn_inp ,layer .ffn_norm ,NULL ,LLM_NORM_RMS ,il ); 711cb (cur ,"mtp_ffn_norm" ,il ); 712 713// MoE FFN with shared expert - same construction as the deepseek2 trunk graph 714ggml_tensor * moe_out = build_moe_ffn (cur , 715layer .ffn_gate_inp , 716layer .ffn_up_exps , 717layer .ffn_gate_exps , 718layer .ffn_down_exps , 719layer .ffn_exp_probs_b , 720n_expert ,n_expert_used , 721LLM_FFN_SILU ,hparams .expert_weights_norm , 722hparams .expert_weights_scale , 723 (llama_expert_gating_func_type )hparams .expert_gating_func , 724il , 725nullptr , 726layer .ffn_gate_up_exps , 727layer .ffn_up_exps_s , 728layer .ffn_gate_exps_s , 729layer .ffn_down_exps_s ); 730cb (moe_out ,"mtp_ffn_moe_out" ,il ); 731 732// FFN shared expert 733ggml_tensor * ffn_shexp = 734build_ffn (cur , 735layer .ffn_up_shexp ,NULL ,layer .ffn_up_shexp_s , 736layer .ffn_gate_shexp ,NULL ,layer .ffn_gate_shexp_s , 737layer .ffn_down_shexp ,NULL ,layer .ffn_down_shexp_s , 738NULL ,LLM_FFN_SILU ,LLM_FFN_PAR ,il ); 739cb (ffn_shexp ,"mtp_ffn_shexp" ,il ); 740 741cur = ggml_add (ctx0 ,moe_out ,ffn_shexp ); 742cb (cur ,"mtp_ffn_out" ,il ); 743 744cur = ggml_add (ctx0 ,cur ,ffn_inp ); 745cb (cur ,"mtp_post_ffn" ,il ); 746 747// shared_head_norm applied after the decoder block, before the shared LM head. 748// The post-norm hidden state seeds the next MTP step. 749ggml_tensor * head_norm_w = layer .nextn .shared_head_norm 750 ?layer .nextn .shared_head_norm 751 :model .output_norm ; 752GGML_ASSERT (head_norm_w && "GLM_DSA MTP: missing both nextn.shared_head_norm and output_norm" ); 753cur = build_norm (cur ,head_norm_w ,nullptr ,LLM_NORM_RMS ,-1 ); 754 755cb (cur ,"h_nextn" ,-1 ); 756res -> t_h_nextn = cur ; 757 758cur = ggml_get_rows (ctx0 ,cur ,inp_out_ids ); 759cb (cur ,"mtp_shared_head_norm" ,-1 ); 760 761ggml_tensor * head_w = layer .nextn .shared_head_head ?layer .nextn .shared_head_head :model .output ; 762ggml_tensor * head_s = layer .nextn .shared_head_head ?layer .nextn .shared_head_head_s :model .output_s ; 763GGML_ASSERT (head_w && "GLM_DSA MTP: missing LM head (nextn.shared_head_head or model.output)" ); 764cur = build_lora_mm (head_w ,cur ,head_s ); 765cb (cur ,"result_output" ,-1 ); 766 767res -> t_logits = cur ; 768ggml_build_forward_expand (gf ,cur ); 769}