char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
465e49b9c
char/aliceai-t5-moe
1#include "models.h" 2#include "llama-memory-recurrent.h" 3 4void llama_model_qwen3next::load_arch_hparams (llama_model_loader & ml ) { 5ml .get_key_or_arr (LLM_KV_EXPERT_FEED_FORWARD_LENGTH ,hparams .n_ff_exp_arr ,hparams .n_layer_all , false); 6ml .get_key (LLM_KV_EXPERT_SHARED_FEED_FORWARD_LENGTH ,hparams .n_ff_shexp , false); 7ml .get_key (LLM_KV_ATTENTION_LAYERNORM_RMS_EPS ,hparams .f_norm_rms_eps ); 8 9// Load linear attention (gated delta net) parameters 10ml .get_key (LLM_KV_SSM_CONV_KERNEL ,hparams .ssm_d_conv ); 11ml .get_key (LLM_KV_SSM_INNER_SIZE ,hparams .ssm_d_inner ); 12ml .get_key (LLM_KV_SSM_STATE_SIZE ,hparams .ssm_d_state ); 13ml .get_key (LLM_KV_SSM_TIME_STEP_RANK ,hparams .ssm_dt_rank ); 14ml .get_key (LLM_KV_SSM_GROUP_COUNT ,hparams .ssm_n_group ); 15 16// Mark recurrent layers (linear attention layers). 17if (!ml .get_key_or_arr (LLM_KV_ATTENTION_RECURRENT_LAYERS ,hparams .is_recr_impl ,hparams .n_layer_all , false)) { 18uint32_t full_attn_interval = 4 ; 19ml .get_key (LLM_KV_FULL_ATTENTION_INTERVAL ,full_attn_interval , false); 20for (uint32_t i = 0 ;i < hparams .n_layer_all ;++ i ) { 21hparams .is_recr_impl [i ]= (i < hparams .n_layer ())&& ((i + 1 ) %full_attn_interval != 0 ); 22 } 23 } 24 25switch (hparams .n_layer ()) { 26case 48 :type = LLM_TYPE_80B_A3B ;break ; 27default :type = LLM_TYPE_UNKNOWN ; 28 } 29} 30 31void llama_model_qwen3next::load_arch_tensors (llama_model_loader & ml ) { 32LLAMA_LOAD_LOCALS ; 33 34if (n_expert == 0 ) { 35throw std::runtime_error (arch_name ()+ " model cannot have zero experts" ); 36 } 37 38const bool mtp_only = (hparams .n_layer_nextn > 0 )&& (ml .get_weight ("blk.0.attn_norm.weight" )== nullptr ); 39const int trunk_flags = mtp_only ?TENSOR_NOT_REQUIRED :0 ; 40int mtp_flags = !ml .load_mtp ?TENSOR_SKIP :0 ; 41 42tok_embd = create_tensor (tn (LLM_TENSOR_TOKEN_EMBD ,"weight" ), {n_embd ,n_vocab },0 ); 43 44// output 45output_norm = create_tensor (tn (LLM_TENSOR_OUTPUT_NORM ,"weight" ), {n_embd },0 ); 46output = create_tensor (tn (LLM_TENSOR_OUTPUT ,"weight" ), {n_embd ,n_vocab },TENSOR_NOT_REQUIRED ); 47 48// if output is NULL, init from the input tok embed 49if (output == NULL ) { 50output = create_tensor (tn (LLM_TENSOR_TOKEN_EMBD ,"weight" ), {n_embd ,n_vocab },TENSOR_DUPLICATED ); 51 } 52 53const int64_t n_ff_exp = hparams .n_ff_exp () ?hparams .n_ff_exp () :n_ff /n_expert_used ; 54 55// Calculate dimensions from hyperparameters 56const int64_t head_k_dim = hparams .ssm_d_state ; 57const int64_t head_v_dim = hparams .ssm_d_state ; 58const int64_t n_k_heads = hparams .ssm_n_group ; 59const int64_t n_v_heads = hparams .ssm_dt_rank ; 60const int64_t key_dim = head_k_dim * n_k_heads ; 61const int64_t value_dim = head_v_dim * n_v_heads ; 62const int64_t conv_dim = key_dim * 2 + value_dim ; 63 64// Calculate projection sizes 65const int64_t qkvz_dim = key_dim * 2 + value_dim * 2 ; 66const int64_t ba_dim = n_v_heads * 2 ; 67 68auto load_block_trunk = [& ](int il ,int flags ) { 69auto & layer = layers [il ]; 70const uint32_t n_ff_shexp = hparams .n_ff_shexp > 0 ?hparams .n_ff_shexp :hparams .n_ff (il ); 71 72layer .attn_norm = create_tensor (tn (LLM_TENSOR_ATTN_NORM ,"weight" ,il ), {n_embd },flags ); 73layer .attn_post_norm = create_tensor (tn (LLM_TENSOR_ATTN_POST_NORM ,"weight" ,il ), {n_embd },flags ); 74 75if (!hparams .is_recr (il )) { 76// Attention layers 77create_tensor_qkv (layer ,il ,n_embd ,n_embd_head_k * n_head * 2 ,n_embd_k_gqa ,n_embd_v_gqa ,flags ); 78layer .wo = create_tensor (tn (LLM_TENSOR_ATTN_OUT ,"weight" ,il ), {n_embd_head_k * n_head ,n_embd },flags ); 79// Q/K normalization for attention layers 80layer .attn_q_norm = create_tensor (tn (LLM_TENSOR_ATTN_Q_NORM ,"weight" ,il ), {n_embd_head_k },flags ); 81layer .attn_k_norm = create_tensor (tn (LLM_TENSOR_ATTN_K_NORM ,"weight" ,il ), {n_embd_head_k },flags ); 82 }else { 83// Linear attention (gated delta net) specific tensors 84// Create tensors with calculated dimensions 85// note: ssm_in is used by legacy GGUF 86layer .ssm_in = create_tensor (tn (LLM_TENSOR_SSM_IN ,"weight" ,il ), {n_embd ,qkvz_dim },TENSOR_NOT_REQUIRED |flags ); 87layer .wqkv = create_tensor (tn (LLM_TENSOR_ATTN_QKV ,"weight" ,il ), {n_embd ,key_dim * 2 + value_dim },TENSOR_NOT_REQUIRED |flags ); 88layer .wqkv_gate = create_tensor (tn (LLM_TENSOR_ATTN_GATE ,"weight" ,il ), {n_embd ,value_dim },TENSOR_NOT_REQUIRED |flags ); 89layer .ssm_conv1d = create_tensor (tn (LLM_TENSOR_SSM_CONV1D ,"weight" ,il ), {hparams .ssm_d_conv ,conv_dim },flags ); 90layer .ssm_dt = create_tensor (tn (LLM_TENSOR_SSM_DT ,"bias" ,il ), {hparams .ssm_dt_rank },flags ); 91layer .ssm_a = create_tensor (tn (LLM_TENSOR_SSM_A_NOSCAN ,il ), {hparams .ssm_dt_rank },flags ); 92layer .ssm_beta_alpha = create_tensor (tn (LLM_TENSOR_SSM_BETA_ALPHA ,"weight" ,il ), {n_embd ,ba_dim },flags ); 93layer .ssm_norm = create_tensor (tn (LLM_TENSOR_SSM_NORM ,"weight" ,il ), {head_v_dim },flags ); 94layer .ssm_out = create_tensor (tn (LLM_TENSOR_SSM_OUT ,"weight" ,il ), {value_dim ,n_embd },flags ); 95 } 96 97layer .ffn_gate_inp = create_tensor (tn (LLM_TENSOR_FFN_GATE_INP ,"weight" ,il ), {n_embd ,n_expert },flags ); 98layer .ffn_down_exps = create_tensor (tn (LLM_TENSOR_FFN_DOWN_EXPS ,"weight" ,il ), {n_ff_exp ,n_embd ,n_expert },flags ); 99create_tensor_gate_up_exps (layer ,il ,n_embd ,n_ff_exp ,n_expert ,flags ); 100 101// Shared experts 102layer .ffn_gate_inp_shexp = create_tensor (tn (LLM_TENSOR_FFN_GATE_INP_SHEXP ,"weight" ,il ), {n_embd },flags ); 103layer .ffn_gate_shexp = create_tensor (tn (LLM_TENSOR_FFN_GATE_SHEXP ,"weight" ,il ), {n_embd ,n_ff_shexp },flags ); 104layer .ffn_up_shexp = create_tensor (tn (LLM_TENSOR_FFN_UP_SHEXP ,"weight" ,il ), {n_embd ,n_ff_shexp },flags ); 105layer .ffn_down_shexp = create_tensor (tn (LLM_TENSOR_FFN_DOWN_SHEXP ,"weight" ,il ), {n_ff_shexp ,n_embd },flags ); 106 }; 107 108auto load_block_mtp = [& ](int il ) { 109// MTP head is identical to the trunk block (full attention + FFN) 110load_block_trunk (il ,mtp_flags ); 111 112auto & layer = layers [il ]; 113 114// NextN-specific tensors that define the MTP block. 115layer .nextn .eh_proj = create_tensor (tn (LLM_TENSOR_NEXTN_EH_PROJ ,"weight" ,il ), {2 * n_embd ,n_embd },mtp_flags ); 116layer .nextn .enorm = create_tensor (tn (LLM_TENSOR_NEXTN_ENORM ,"weight" ,il ), {n_embd },mtp_flags ); 117layer .nextn .hnorm = create_tensor (tn (LLM_TENSOR_NEXTN_HNORM ,"weight" ,il ), {n_embd },mtp_flags ); 118layer .nextn .embed_tokens = create_tensor (tn (LLM_TENSOR_NEXTN_EMBED_TOKENS ,"weight" ,il ), {n_embd ,n_vocab },mtp_flags |TENSOR_NOT_REQUIRED ); 119layer .nextn .shared_head_head = create_tensor (tn (LLM_TENSOR_NEXTN_SHARED_HEAD_HEAD ,"weight" ,il ), {n_embd ,n_vocab },mtp_flags |TENSOR_NOT_REQUIRED ); 120layer .nextn .shared_head_norm = create_tensor (tn (LLM_TENSOR_NEXTN_SHARED_HEAD_NORM ,"weight" ,il ), {n_embd },mtp_flags |TENSOR_NOT_REQUIRED ); 121 }; 122 123for (int i = 0 ;i < n_layer ;i ++ ) { 124load_block_trunk (i ,trunk_flags ); 125 } 126for (int i = n_layer ;i < n_layer_all ;i ++ ) { 127load_block_mtp (i ); 128 } 129} 130 131std::unique_ptr < llm_graph_context > llama_model_qwen3next::build_arch_graph (const llm_graph_params & params )const { 132if (params .gtype == LLM_GRAPH_TYPE_DECODER_MTP ) { 133return std::make_unique < graph_mtp > (* this ,params ); 134 } 135return std::make_unique < graph > (* this ,params ); 136} 137 138llama_model_qwen3next::graph::graph (const llama_model & model ,const llm_graph_params & params ) : 139llm_build_delta_net_base (params ),model (model ) { 140ggml_tensor * cur ; 141ggml_tensor * inpL ; 142 143inpL = build_inp_embd (model .tok_embd ); 144cb (inpL ,"model.embed_tokens" ,-1 ); 145 146auto * inp = build_inp_mem_hybrid (); 147 148ggml_tensor * inp_pos = build_inp_pos (); 149ggml_tensor * inp_out_ids = build_inp_out_ids (); 150 151// MTP/NextN layers are loaded as extra decoder blocks but not executed in the main pass. 152for (int il = 0 ;il < n_layer ;++ il ) { 153res -> t_layer_inp [il ]= inpL ; 154 155ggml_tensor * inpSA = inpL ; 156 157cur = build_norm (inpL ,model .layers [il ].attn_norm ,nullptr ,LLM_NORM_RMS ,il ); 158cb (cur ,"attn_norm" ,il ); 159 160ggml_build_forward_expand (gf ,cur ); 161 162// Determine layer type and build appropriate attention mechanism 163if (hparams .is_recr (il )) { 164// Linear attention layer (gated delta net) 165cur = build_layer_attn_linear (inp -> get_recr (),cur ,il ); 166 }else { 167// Full attention layer 168cur = build_layer_attn (inp -> get_attn (),cur ,inp_pos ,il ); 169 } 170 171if (il == n_layer - 1 && inp_out_ids && cparams .embeddings_nextn_masked ) { 172cur = ggml_get_rows (ctx0 ,cur ,inp_out_ids ); 173inpSA = ggml_get_rows (ctx0 ,inpSA ,inp_out_ids ); 174 } 175 176// Residual connection 177cur = ggml_add (ctx0 ,cur ,inpSA ); 178cb (cur ,"attn_residual" ,il ); 179 180// Save the tensor before post-attention norm for residual connection 181ggml_tensor * ffn_residual = cur ; 182 183// Post-attention norm 184ggml_tensor * attn_post_norm = build_norm (cur ,model .layers [il ].attn_post_norm ,nullptr ,LLM_NORM_RMS ,il ); 185cb (attn_post_norm ,"attn_post_norm" ,il ); 186 187// FFN layer (MoE or dense) - without residual connection 188cur = build_layer_ffn (attn_post_norm ,il ); 189cb (cur ,"ffn_out" ,il ); 190 191// Residual connection for FFN - add to the tensor from before post_attention_layernorm 192cur = ggml_add (ctx0 ,cur ,ffn_residual ); 193cb (cur ,"post_moe" ,il ); 194 195cur = build_cvec (cur ,il ); 196cb (cur ,"l_out" ,il ); 197 198// Input for next layer 199inpL = cur ; 200 } 201cur = inpL ; 202 203// post-norm hidden state is input to both the LM head and the MTP head 204cur = build_norm (cur ,model .output_norm ,nullptr ,LLM_NORM_RMS ,-1 ); 205 206cb (cur ,"h_nextn" ,-1 ); 207res -> t_h_nextn = cur ; 208 209if (!cparams .embeddings_nextn_masked && inp_out_ids ) { 210cur = ggml_get_rows (ctx0 ,cur ,inp_out_ids ); 211 } 212 213cb (cur ,"result_norm" ,-1 ); 214res -> t_embd = cur ; 215 216// LM head 217cur = build_lora_mm (model .output ,cur ,model .output_s ); 218 219cb (cur ,"result_output" ,-1 ); 220res -> t_logits = cur ; 221 222ggml_build_forward_expand (gf ,cur ); 223} 224 225ggml_tensor * llama_model_qwen3next::graph::build_norm_gated ( 226ggml_tensor * input , 227ggml_tensor * weights , 228ggml_tensor * gate , 229int layer ) { 230ggml_tensor * normalized = build_norm (input ,weights ,nullptr ,LLM_NORM_RMS ,layer ); 231ggml_tensor * gated_silu = ggml_silu (ctx0 ,gate ); 232 233return ggml_mul (ctx0 ,normalized ,gated_silu ); 234} 235 236ggml_tensor * llama_model_qwen3next::graph::build_layer_attn ( 237llm_graph_input_attn_kv * inp , 238ggml_tensor * cur , 239ggml_tensor * inp_pos , 240int il ) { 241const int64_t n_embd_head = hparams .n_embd_head_v (); 242GGML_ASSERT (n_embd_head == hparams .n_embd_head_k ()); 243 244// Order: joint QG projection, QG split, Q norm, KV projection, K norm, RoPE, attention 245 246// Qwen3Next uses a single Q projection that outputs query + gate 247auto [Qcur_full ,Kcur ,Vcur ]= build_qkv (model .layers [il ],cur , 248n_embd_head * 2 ,n_head , 249n_embd_head ,n_head_kv , 250n_embd_head ,n_head_kv , 251il , false); 252cb (Qcur_full ,"Qcur_full" ,il ); 253cb (Kcur ,"Kcur" ,il ); 254cb (Vcur ,"Vcur" ,il ); 255 256Qcur_full = ggml_reshape_4d (ctx0 ,Qcur_full ,n_embd_head * 2 ,n_head ,n_tokens ,1 ); 257 258// Split Q projection into query and gate 259// The split should be along dimension 0 (the feature dimension) 260ggml_tensor * Qcur = ggml_view_4d (ctx0 ,Qcur_full ,n_embd_head ,n_head ,n_tokens ,1 , 261Qcur_full -> nb [1 ],Qcur_full -> nb [2 ],Qcur_full -> nb [3 ],0 ); 262cb (Qcur ,"Qcur_view" ,il ); 263 264ggml_tensor * gate = 265ggml_view_4d (ctx0 ,Qcur_full ,n_embd_head ,n_head ,n_tokens ,1 , 266Qcur_full -> nb [1 ],Qcur_full -> nb [2 ],Qcur_full -> nb [3 ],n_embd_head * ggml_element_size (Qcur_full )); 267cb (gate ,"gate" ,il ); 268 269Kcur = ggml_reshape_3d (ctx0 ,Kcur ,n_embd_head ,n_head_kv ,n_tokens ); 270Vcur = ggml_reshape_3d (ctx0 ,Vcur ,n_embd_head ,n_head_kv ,n_tokens ); 271 272Qcur = build_norm (Qcur ,model .layers [il ].attn_q_norm ,nullptr ,LLM_NORM_RMS ,il ); 273cb (Qcur ,"Qcur_normed" ,il ); 274 275Kcur = build_norm (Kcur ,model .layers [il ].attn_k_norm ,nullptr ,LLM_NORM_RMS ,il ); 276cb (Kcur ,"Kcur_normed" ,il ); 277 278Qcur = ggml_rope_ext ( 279ctx0 ,Qcur ,inp_pos ,nullptr , 280n_rot ,rope_type ,n_ctx_orig ,freq_base ,freq_scale , 281ext_factor ,attn_factor ,beta_fast ,beta_slow ); 282 283Kcur = ggml_rope_ext ( 284ctx0 ,Kcur ,inp_pos ,nullptr , 285n_rot ,rope_type ,n_ctx_orig ,freq_base , 286freq_scale ,ext_factor ,attn_factor ,beta_fast ,beta_slow ); 287 288cb (Qcur ,"Qcur" ,il ); 289cb (Kcur ,"Kcur" ,il ); 290cb (Vcur ,"Vcur" ,il ); 291 292const float kq_scale = hparams .f_attention_scale == 0.0f ?1.0f /sqrtf (float (n_embd_head )) :hparams .f_attention_scale ; 293 294cur = build_attn (inp , 295nullptr ,nullptr ,nullptr , 296Qcur ,Kcur ,Vcur ,nullptr ,nullptr ,nullptr ,kq_scale ,il ); 297cb (cur ,"attn_pregate" ,il ); 298 299// TODO: CUDA is missing non-contiguous unary ops. when implemented: remove this cont 300gate = ggml_cont_2d (ctx0 ,gate ,n_embd_head * n_head ,n_tokens ); 301 302gate = ggml_sigmoid (ctx0 ,gate ); 303cb (gate ,"gate_sigmoid" ,il ); 304 305cur = ggml_mul (ctx0 ,cur ,gate ); 306cb (cur ,"attn_gated" ,il ); 307 308cur = build_lora_mm (model .layers [il ].wo ,cur ,model .layers [il ].wo_s ); 309cb (cur ,"attn_output" ,il ); 310 311return cur ; 312} 313 314std::pair < ggml_tensor * ,ggml_tensor *> llama_model_qwen3next::graph::build_qkvz ( 315ggml_tensor * input , 316int il ) { 317const int64_t d_inner = hparams .ssm_d_inner ; 318const int64_t n_seqs = ubatch .n_seqs ; 319const int64_t head_k_dim = hparams .ssm_d_state ; 320const int64_t num_k_heads = hparams .ssm_n_group ; 321const int64_t num_v_heads = hparams .ssm_dt_rank ; 322const int64_t head_v_dim = d_inner /num_v_heads ; 323const int64_t n_seq_tokens = ubatch .n_seq_tokens ; 324 325if (model .layers [il ].wqkv ) { 326// optimized path 327ggml_tensor * qkv_mixed = build_lora_mm (model .layers [il ].wqkv ,input ); 328qkv_mixed = ggml_reshape_3d (ctx0 ,qkv_mixed ,qkv_mixed -> ne [0 ],n_seq_tokens ,n_seqs ); 329cb (qkv_mixed ,"linear_attn_qkv_mixed" ,il ); 330 331ggml_tensor * z = build_lora_mm (model .layers [il ].wqkv_gate ,input ); 332cb (z ,"z" ,il ); 333 334return {qkv_mixed ,z }; 335 }else { 336// legacy (slower) path 337ggml_tensor * mixed_qkvz = build_lora_mm (model .layers [il ].ssm_in ,input ); 338cb (mixed_qkvz ,"linear_attn_mixed_qkvz" ,il ); 339 340int64_t qkvz_new_dim = 2 * head_k_dim + 2 * head_v_dim * (num_v_heads /num_k_heads ); 341ggml_tensor * mixed_qkvz_reshaped = ggml_reshape_4d (ctx0 ,mixed_qkvz ,qkvz_new_dim ,num_k_heads ,n_seq_tokens ,n_seqs ); 342 343// Split mixed_qkvz into query, key, value, z 344int64_t split_sizes_qkvz [4 ]= { 345head_k_dim ,// query size 346head_k_dim ,// key size 347head_v_dim * num_v_heads /num_k_heads ,// value size 348head_v_dim * num_v_heads /num_k_heads // z size 349 }; 350 351ggml_tensor * query = 352ggml_view_4d (ctx0 ,mixed_qkvz_reshaped ,split_sizes_qkvz [0 ],num_k_heads ,n_seq_tokens ,n_seqs , 353mixed_qkvz_reshaped -> nb [1 ],mixed_qkvz_reshaped -> nb [2 ],mixed_qkvz_reshaped -> nb [3 ],0 ); 354cb (query ,"q" ,il ); 355 356ggml_tensor * key = ggml_view_4d (ctx0 ,mixed_qkvz_reshaped ,split_sizes_qkvz [1 ],num_k_heads ,n_seq_tokens ,n_seqs , 357mixed_qkvz_reshaped -> nb [1 ],mixed_qkvz_reshaped -> nb [2 ],mixed_qkvz_reshaped -> nb [3 ], 358split_sizes_qkvz [0 ]* ggml_element_size (mixed_qkvz_reshaped )); 359cb (key ,"k" ,il ); 360 361ggml_tensor * value = 362ggml_view_4d (ctx0 ,mixed_qkvz_reshaped ,split_sizes_qkvz [2 ],num_k_heads ,n_seq_tokens ,n_seqs , 363mixed_qkvz_reshaped -> nb [1 ],mixed_qkvz_reshaped -> nb [2 ],mixed_qkvz_reshaped -> nb [3 ], 364 (split_sizes_qkvz [0 ]+ split_sizes_qkvz [1 ])* ggml_element_size (mixed_qkvz_reshaped )); 365cb (value ,"v" ,il ); 366 367ggml_tensor * z = ggml_view_4d (ctx0 ,mixed_qkvz_reshaped ,split_sizes_qkvz [3 ],num_k_heads ,n_seq_tokens ,n_seqs , 368mixed_qkvz_reshaped -> nb [1 ],mixed_qkvz_reshaped -> nb [2 ],mixed_qkvz_reshaped -> nb [3 ], 369 (split_sizes_qkvz [0 ]+ split_sizes_qkvz [1 ]+ split_sizes_qkvz [2 ])* ggml_element_size (mixed_qkvz_reshaped )); 370z = ggml_cont (ctx0 ,z ); 371cb (z ,"z" ,il ); 372 373// After creating query, key, and value_reshaped, reshape each to flatten the head dimensions 374// query: [head_k_dim, num_k_heads, n_tokens, n_seqs] -> [head_k_dim * num_k_heads, n_tokens, n_seqs] 375ggml_tensor * query_flat = ggml_cont_3d (ctx0 ,query ,head_k_dim * num_k_heads ,n_seq_tokens ,n_seqs ); 376cb (query_flat ,"query_flat" ,il ); 377 378// key: [head_k_dim, num_k_heads, n_tokens, n_seqs] -> [head_k_dim * num_k_heads, n_tokens, n_seqs] 379ggml_tensor * key_flat = ggml_cont_3d (ctx0 ,key ,head_k_dim * num_k_heads ,n_seq_tokens ,n_seqs ); 380cb (key_flat ,"key_flat" ,il ); 381 382// value_reshaped: [head_v_dim, num_v_heads, n_tokens, n_seqs] -> [head_v_dim * num_v_heads, n_tokens, n_seqs] 383ggml_tensor * value_flat = ggml_cont_3d (ctx0 ,value ,head_v_dim * num_v_heads ,n_seq_tokens ,n_seqs ); 384cb (value_flat ,"value_flat" ,il ); 385 386// Now concatenate along the feature dimension (dim 0) to get [conv_dim, n_tokens, n_seqs] 387ggml_tensor * qkv_mixed = ggml_concat (ctx0 ,query_flat ,key_flat ,0 ); 388qkv_mixed = ggml_concat (ctx0 ,qkv_mixed ,value_flat ,0 ); 389cb (qkv_mixed ,"qkv_mixed" ,il ); 390 391return {qkv_mixed ,z }; 392 } 393} 394 395ggml_tensor * llama_model_qwen3next::graph::build_layer_attn_linear ( 396llm_graph_input_rs * inp , 397ggml_tensor * cur , 398int il ) { 399const auto * mctx_cur = inp -> mctx ; 400 401const int64_t d_inner = hparams .ssm_d_inner ; 402const int64_t n_seqs = ubatch .n_seqs ; 403const int64_t head_k_dim = hparams .ssm_d_state ; 404const int64_t num_k_heads = hparams .ssm_n_group ; 405const int64_t num_v_heads = hparams .ssm_dt_rank ; 406const int64_t head_v_dim = d_inner /num_v_heads ; 407const int64_t n_seq_tokens = ubatch .n_seq_tokens ; 408 409GGML_ASSERT (n_seqs != 0 ); 410GGML_ASSERT (ubatch .equal_seqs ()); 411GGML_ASSERT (ubatch .n_tokens == n_seq_tokens * n_seqs ); 412 413// Input projections 414auto qkvz = build_qkvz (cur ,il ); 415ggml_tensor * qkv_mixed = qkvz .first ; 416ggml_tensor * z = qkvz .second ; 417 418ggml_tensor * mixed_ba = build_lora_mm (model .layers [il ].ssm_beta_alpha ,cur ); 419cb (mixed_ba ,"linear_attn_mixed_ba" ,il ); 420 421// Reshape mixed_ba: [batch, seq_len, hidden_size] -> [batch, seq_len, num_k_heads, 2*num_v_heads/num_k_heads] 422int64_t ba_new_dim = 2 * num_v_heads /num_k_heads ; 423ggml_tensor * mixed_ba_reshaped = ggml_reshape_4d (ctx0 ,mixed_ba ,ba_new_dim ,num_k_heads ,n_seq_tokens ,n_seqs ); 424 425// Split mixed_ba into b and a (beta and alpha parameters) 426int64_t split_sizes_ba [2 ]= { 427num_v_heads /num_k_heads ,// beta size 428num_v_heads /num_k_heads // alpha size 429 }; 430 431ggml_tensor * b = ggml_view_4d (ctx0 ,mixed_ba_reshaped ,split_sizes_ba [0 ],num_k_heads ,n_seq_tokens ,n_seqs , 432mixed_ba_reshaped -> nb [1 ],mixed_ba_reshaped -> nb [2 ],mixed_ba_reshaped -> nb [3 ],0 ); 433cb (b ,"b" ,il ); 434 435ggml_tensor * a = ggml_view_4d (ctx0 ,mixed_ba_reshaped ,split_sizes_ba [1 ],num_k_heads ,n_seq_tokens ,n_seqs , 436mixed_ba_reshaped -> nb [1 ],mixed_ba_reshaped -> nb [2 ],mixed_ba_reshaped -> nb [3 ], 437split_sizes_ba [0 ]* ggml_element_size (mixed_ba_reshaped )); 438cb (a ,"a" ,il ); 439 440// TODO: CUDA is missing non-contiguous unary ops. when implemented: remove this cont 441b = ggml_cont (ctx0 ,b ); 442 443ggml_tensor * beta = ggml_sigmoid (ctx0 ,b ); 444 445// Reshape a to merge head dimensions: [batch, seq_len, num_k_heads, num_v_heads/num_k_heads] -> [batch, seq_len, num_v_heads] 446ggml_tensor * alpha = ggml_cont_3d (ctx0 ,a ,num_v_heads ,n_seq_tokens ,n_seqs ); 447 448ggml_tensor * alpha_biased = ggml_add (ctx0 ,alpha ,model .layers [il ].ssm_dt ); 449ggml_tensor * alpha_softplus = ggml_softplus (ctx0 ,alpha_biased ); 450cb (alpha_softplus ,"a_softplus" ,il ); 451 452ggml_tensor * gate = ggml_mul (ctx0 ,alpha_softplus ,model .layers [il ].ssm_a );// -A_log.exp() * softplus 453cb (gate ,"gate" ,il ); 454 455beta = ggml_reshape_4d (ctx0 ,beta ,1 ,num_v_heads ,n_seq_tokens ,n_seqs ); 456gate = ggml_reshape_4d (ctx0 ,gate ,1 ,num_v_heads ,n_seq_tokens ,n_seqs ); 457 458ggml_tensor * conv_states_all = mctx_cur -> get_r_l (il ); 459ggml_tensor * ssm_states_all = mctx_cur -> get_s_l (il ); 460 461ggml_tensor * conv_kernel = model .layers [il ].ssm_conv1d ; 462const int64_t conv_kernel_size = conv_kernel -> ne [0 ]; 463const int64_t conv_channels = d_inner + 2 * hparams .ssm_n_group * hparams .ssm_d_state ; 464 465ggml_tensor * conv_input = build_conv_state (inp ,conv_states_all ,qkv_mixed ,conv_kernel_size ,conv_channels ,il ); 466 467ggml_tensor * state = build_rs (inp ,ssm_states_all ,hparams .n_embd_s (),n_seqs ); 468state = ggml_reshape_4d (ctx0 ,state ,head_v_dim ,head_v_dim ,num_v_heads ,n_seqs ); 469cb (state ,"state_predelta" ,il ); 470 471ggml_tensor * conv_output_proper = ggml_ssm_conv (ctx0 ,conv_input ,conv_kernel ); 472cb (conv_output_proper ,"conv_output_raw" ,il ); 473 474ggml_tensor * conv_output_silu = ggml_silu (ctx0 ,conv_output_proper ); 475cb (conv_output_silu ,"conv_output_silu" ,il ); 476 477ggml_tensor * conv_qkv_mix = conv_output_silu ; 478 479// Calculate the total conv dimension 480int64_t qkv_dim = head_k_dim * num_k_heads * 2 + head_v_dim * num_v_heads ; 481int64_t nb1_qkv = ggml_row_size (conv_qkv_mix -> type ,qkv_dim ); 482 483// Extract the convolved Q, K, V from conv_output 484ggml_tensor * q_conv = ggml_view_4d (ctx0 ,conv_qkv_mix ,head_k_dim ,num_k_heads ,n_seq_tokens ,n_seqs , 485ggml_row_size (conv_qkv_mix -> type ,head_k_dim ), 486nb1_qkv , 487nb1_qkv * n_seq_tokens , 4880 ); 489 490ggml_tensor * k_conv = ggml_view_4d (ctx0 ,conv_qkv_mix ,head_k_dim ,num_k_heads ,n_seq_tokens ,n_seqs , 491ggml_row_size (conv_qkv_mix -> type ,head_k_dim ), 492nb1_qkv , 493nb1_qkv * n_seq_tokens , 494head_k_dim * num_k_heads * ggml_element_size (conv_qkv_mix )); 495 496ggml_tensor * v_conv = ggml_view_4d (ctx0 ,conv_qkv_mix ,head_v_dim ,num_v_heads ,n_seq_tokens ,n_seqs , 497ggml_row_size (conv_qkv_mix -> type ,head_v_dim ), 498nb1_qkv , 499nb1_qkv * n_seq_tokens , 500ggml_row_size (conv_qkv_mix -> type ,2 * head_k_dim * num_k_heads )); 501 502cb (q_conv ,"q_conv" ,il ); 503cb (k_conv ,"k_conv" ,il ); 504cb (v_conv ,"v_conv" ,il ); 505 506 507const float eps_norm = hparams .f_norm_rms_eps ; 508 509q_conv = build_gdn_l2_norm (ctx0 ,q_conv ,eps_norm ); 510k_conv = build_gdn_l2_norm (ctx0 ,k_conv ,eps_norm ); 511 512//q_conv = ggml_cont_4d(ctx0, q_conv, head_k_dim, num_k_heads, n_seq_tokens, n_seqs); 513//k_conv = ggml_cont_4d(ctx0, k_conv, head_k_dim, num_k_heads, n_seq_tokens, n_seqs); 514//v_conv = ggml_cont_4d(ctx0, v_conv, head_v_dim, num_v_heads, n_seq_tokens, n_seqs); 515 516// if head keys and value keys are different, repeat to force tensors into matching shapes 517// TODO: avoid repeats for fused GDN, needs broadcast configuration for GDN op [TAG_GGML_GDN_BCAST] 518if (num_k_heads != num_v_heads ) { 519GGML_ASSERT (num_v_heads %num_k_heads == 0 ); 520int64_t repeat_factor = num_v_heads /num_k_heads ; 521 522// repeat interleave: reshape to (repeat part, 1, remaining part...), do repeat, then reshape back 523ggml_tensor * q_reshaped = ggml_reshape_4d (ctx0 ,q_conv ,head_k_dim ,1 ,num_k_heads ,n_seq_tokens * n_seqs ); 524ggml_tensor * k_reshaped = ggml_reshape_4d (ctx0 ,k_conv ,head_k_dim ,1 ,num_k_heads ,n_seq_tokens * n_seqs ); 525 526// Repeat along the third dimension (the new dimension with size 1) 527ggml_tensor * q_repeated = 528ggml_repeat_4d (ctx0 ,q_reshaped ,head_k_dim ,repeat_factor ,num_k_heads ,n_seq_tokens * n_seqs ); 529ggml_tensor * k_repeated = 530ggml_repeat_4d (ctx0 ,k_reshaped ,head_k_dim ,repeat_factor ,num_k_heads ,n_seq_tokens * n_seqs ); 531 532// Reshape back to merge the head and repeat dimensions 533// From [head_dim, repeat_factor, num_k_heads, n_seq_tokens * n_seqs] 534// Back to [head_dim, repeat_factor * num_k_heads, n_seq_tokens, n_seqs] 535q_conv = ggml_reshape_4d (ctx0 ,q_repeated ,head_k_dim ,num_k_heads * repeat_factor ,n_seq_tokens ,n_seqs ); 536k_conv = ggml_reshape_4d (ctx0 ,k_repeated ,head_k_dim ,num_k_heads * repeat_factor ,n_seq_tokens ,n_seqs ); 537 } 538 539cb (q_conv ,"q_conv_predelta" ,il ); 540cb (k_conv ,"k_conv_predelta" ,il ); 541cb (v_conv ,"v_conv_predelta" ,il ); 542 543ggml_tensor * output = build_recurrent_attn (inp ,ssm_states_all ,q_conv ,k_conv ,v_conv ,gate ,beta ,state ,il ); 544 545// z: [head_dim, n_heads, n_tokens, n_seqs] -> [n_heads * n_tokens * n_seqs, head_dim] 546ggml_tensor * z_2d = ggml_reshape_4d (ctx0 ,z ,head_v_dim ,num_v_heads ,n_seq_tokens ,n_seqs ); 547 548// Apply gated normalization: self.norm(core_attn_out, z) 549ggml_tensor * attn_out_norm = build_norm_gated (output ,model .layers [il ].ssm_norm ,z_2d ,il ); 550 551// Final reshape: [head_dim, n_heads, n_tokens, n_seqs] -> [n_tokens, n_seqs, n_heads * head_dim] 552ggml_tensor * final_output = ggml_reshape_3d (ctx0 ,attn_out_norm ,head_v_dim * num_v_heads ,n_seq_tokens ,n_seqs ); 553cb (final_output ,"final_output" ,il ); 554 555// Output projection 556cur = build_lora_mm (model .layers [il ].ssm_out ,final_output ); 557cb (cur ,"linear_attn_out" ,il ); 558 559// Reshape back to original dimensions 560cur = ggml_reshape_2d (ctx0 ,cur ,n_embd ,n_seq_tokens * n_seqs ); 561 562return cur ; 563} 564 565ggml_tensor * llama_model_qwen3next::graph::build_layer_ffn (ggml_tensor * cur ,const int il ) { 566// Check if this is an MoE layer 567if (model .layers [il ].ffn_gate_inp != nullptr ) { 568// MoE branch 569ggml_tensor * moe_out = 570build_moe_ffn (cur , 571model .layers [il ].ffn_gate_inp , 572model .layers [il ].ffn_up_exps , 573model .layers [il ].ffn_gate_exps , 574model .layers [il ].ffn_down_exps , 575nullptr , 576n_expert ,n_expert_used , 577LLM_FFN_SILU , true, 578hparams .expert_weights_scale , 579LLAMA_EXPERT_GATING_FUNC_TYPE_SOFTMAX ,il , 580nullptr ,model .layers [il ].ffn_gate_up_exps , 581model .layers [il ].ffn_up_exps_s , 582model .layers [il ].ffn_gate_exps_s , 583model .layers [il ].ffn_down_exps_s ); 584cb (moe_out ,"ffn_moe_out" ,il ); 585 586// Add shared experts if present - following Qwen3Next reference implementation 587if (model .layers [il ].ffn_up_shexp != nullptr ) { 588ggml_tensor * ffn_shexp = 589build_ffn (cur , 590model .layers [il ].ffn_up_shexp ,NULL ,model .layers [il ].ffn_up_shexp_s , 591model .layers [il ].ffn_gate_shexp ,NULL ,model .layers [il ].ffn_gate_shexp_s , 592model .layers [il ].ffn_down_shexp ,NULL ,model .layers [il ].ffn_down_shexp_s , 593NULL , 594LLM_FFN_SILU ,LLM_FFN_PAR ,il ); 595cb (ffn_shexp ,"ffn_shexp" ,il ); 596 597// Apply shared expert gating as in the reference implementation 598// The shared expert has its own gate that is sigmoided 599// Note: ffn_gate_inp_shexp is the shared expert gate (outputs 1 value per token) 600ggml_tensor * shared_gate = build_lora_mm (model .layers [il ].ffn_gate_inp_shexp ,cur ); 601cb (shared_gate ,"shared_expert_gate" ,il ); 602 603shared_gate = ggml_sigmoid (ctx0 ,shared_gate ); 604cb (shared_gate ,"shared_expert_gate_sigmoid" ,il ); 605 606ffn_shexp = ggml_mul (ctx0 ,ffn_shexp ,shared_gate ); 607cb (ffn_shexp ,"ffn_shexp_gated" ,il ); 608 609cur = ggml_add (ctx0 ,moe_out ,ffn_shexp ); 610cb (cur ,"ffn_out" ,il ); 611 }else { 612cur = moe_out ; 613 } 614 }else { 615// Dense FFN branch (not currently used I believe) 616cur = build_ffn (cur , 617model .layers [il ].ffn_up ,NULL ,NULL , 618model .layers [il ].ffn_gate ,NULL ,NULL , 619model .layers [il ].ffn_down ,NULL ,NULL , 620NULL , 621LLM_FFN_SILU ,LLM_FFN_PAR ,il ); 622cb (cur ,"ffn_out" ,il ); 623 } 624return cur ; 625} 626 627// LLM_GRAPH_TYPE_DECODER_MTP draft head for Qwen3-Next 628llama_model_qwen3next::graph_mtp::graph_mtp (const llama_model & model ,const llm_graph_params & params ) 629 :llm_graph_context (params ) { 630GGML_ASSERT (hparams .n_layer_nextn > 0 && "QWEN3NEXT MTP requires n_layer_nextn > 0" ); 631GGML_ASSERT (hparams .n_layer_nextn == 1 && "QWEN3NEXT MTP currently only supports a single MTP block" ); 632 633const int64_t n_embd_head = hparams .n_embd_head_v (); 634GGML_ASSERT (n_embd_head == hparams .n_embd_head_k ()); 635 636const int il = hparams .n_layer (); 637const auto & layer = model .layers [il ]; 638 639GGML_ASSERT (layer .nextn .eh_proj && "MTP block missing nextn.eh_proj" ); 640GGML_ASSERT (layer .nextn .enorm && "MTP block missing nextn.enorm" ); 641GGML_ASSERT (layer .nextn .hnorm && "MTP block missing nextn.hnorm" ); 642GGML_ASSERT (layer .ffn_gate_inp && "MTP block missing ffn_gate_inp" ); 643 644// TODO: extract in a common llm_graph_context::build_inp_embd_h() 645auto inp = std::make_unique < llm_graph_input_embd_h > (hparams .n_embd ); 646 647inp -> tokens = ggml_new_tensor_1d (ctx0 ,GGML_TYPE_I32 ,n_tokens ); 648ggml_set_input (inp -> tokens ); 649 650inp -> embd = ggml_new_tensor_2d (ctx0 ,GGML_TYPE_F32 ,hparams .n_embd_inp (),n_tokens ); 651ggml_set_input (inp -> embd ); 652 653// TODO: make static using `ggml_build_forward_select()` 654// see llm_graph_context::build_inp_embd() for reference 655ggml_tensor * tok_embd ; 656if (ubatch .token ) { 657ggml_tensor * tok_embd_w = layer .nextn .embed_tokens ?layer .nextn .embed_tokens :model .tok_embd ; 658 659tok_embd = ggml_get_rows (ctx0 ,tok_embd_w ,inp -> tokens ); 660 }else { 661tok_embd = inp -> embd ; 662 } 663cb (tok_embd ,"mtp_tok_embd" ,il ); 664 665inp -> h = ggml_new_tensor_2d (ctx0 ,GGML_TYPE_F32 ,hparams .n_embd ,n_tokens ); 666ggml_set_input (inp -> h ); 667ggml_set_name (inp -> h ,"mtp_h_input" ); 668 669ggml_tensor * h_embd = inp -> h ; 670 671res -> add_input (std::move (inp )); 672 673ggml_tensor * inp_pos = build_inp_pos (); 674ggml_tensor * inp_out_ids = build_inp_out_ids (); 675 676auto * inp_attn = build_attn_inp_kv (); 677 678ggml_tensor * h_norm = build_norm (h_embd ,layer .nextn .hnorm ,nullptr ,LLM_NORM_RMS ,il ); 679cb (h_norm ,"mtp_hnorm" ,il ); 680 681ggml_tensor * e_norm = build_norm (tok_embd ,layer .nextn .enorm ,nullptr ,LLM_NORM_RMS ,il ); 682cb (e_norm ,"mtp_enorm" ,il ); 683 684ggml_tensor * concat = ggml_concat (ctx0 ,e_norm ,h_norm ,/*dim=*/ 0 ); 685cb (concat ,"mtp_concat" ,il ); 686 687ggml_tensor * cur = build_lora_mm (layer .nextn .eh_proj ,concat ,layer .nextn .eh_proj_s ); 688cb (cur ,"mtp_eh_proj" ,il ); 689 690ggml_tensor * inpSA = cur ; 691 692cur = build_norm (cur ,layer .attn_norm ,nullptr ,LLM_NORM_RMS ,il ); 693cb (cur ,"mtp_attn_norm" ,il ); 694 695auto [Qcur_full ,Kcur ,Vcur ]= build_qkv (layer ,cur , 696n_embd_head * 2 ,n_head , 697n_embd_head ,n_head_kv , 698n_embd_head ,n_head_kv , 699il , false); 700cb (Qcur_full ,"mtp_Qcur_full" ,il ); 701 702ggml_tensor * Qcur = ggml_view_3d (ctx0 ,Qcur_full , 703n_embd_head ,n_head ,n_tokens , 704ggml_element_size (Qcur_full )* n_embd_head * 2 , 705ggml_element_size (Qcur_full )* n_embd_head * 2 * n_head , 7060 ); 707Qcur = build_norm (Qcur ,layer .attn_q_norm ,nullptr ,LLM_NORM_RMS ,il ); 708cb (Qcur ,"mtp_Qcur_normed" ,il ); 709 710Kcur = ggml_reshape_3d (ctx0 ,Kcur ,n_embd_head ,n_head_kv ,n_tokens ); 711Kcur = build_norm (Kcur ,layer .attn_k_norm ,nullptr ,LLM_NORM_RMS ,il ); 712cb (Kcur ,"mtp_Kcur_normed" ,il ); 713 714Vcur = ggml_reshape_3d (ctx0 ,Vcur ,n_embd_head ,n_head_kv ,n_tokens ); 715 716Qcur = ggml_rope_ext (ctx0 ,Qcur ,inp_pos ,nullptr , 717n_rot ,rope_type ,n_ctx_orig ,freq_base ,freq_scale , 718ext_factor ,attn_factor ,beta_fast ,beta_slow ); 719Kcur = ggml_rope_ext (ctx0 ,Kcur ,inp_pos ,nullptr , 720n_rot ,rope_type ,n_ctx_orig ,freq_base ,freq_scale , 721ext_factor ,attn_factor ,beta_fast ,beta_slow ); 722 723cb (Qcur ,"mtp_Qcur" ,il ); 724cb (Kcur ,"mtp_Kcur" ,il ); 725cb (Vcur ,"mtp_Vcur" ,il ); 726 727const float kq_scale = hparams .f_attention_scale == 0.0f 728 ?1.0f /sqrtf (float (n_embd_head )) :hparams .f_attention_scale ; 729 730cur = build_attn (inp_attn , 731nullptr ,nullptr ,nullptr , 732Qcur ,Kcur ,Vcur ,nullptr ,nullptr ,nullptr ,kq_scale ,il ); 733cb (cur ,"mtp_attn_pregate" ,il ); 734 735ggml_tensor * gate = ggml_view_3d (ctx0 ,Qcur_full , 736n_embd_head ,n_head ,n_tokens , 737ggml_element_size (Qcur_full )* n_embd_head * 2 , 738ggml_element_size (Qcur_full )* n_embd_head * 2 * n_head , 739ggml_element_size (Qcur_full )* n_embd_head ); 740 741// TODO: CUDA is missing non-contiguous unary ops. when implemented: remove this cont 742gate = ggml_cont_2d (ctx0 ,gate ,n_embd_head * n_head ,n_tokens ); 743cb (gate ,"mtp_gate" ,il ); 744 745cur = ggml_mul (ctx0 ,cur ,ggml_sigmoid (ctx0 ,gate )); 746cur = build_lora_mm (layer .wo ,cur ,layer .wo_s ); 747cb (cur ,"mtp_attn_out" ,il ); 748 749if (inp_out_ids ) { 750cur = ggml_get_rows (ctx0 ,cur ,inp_out_ids ); 751inpSA = ggml_get_rows (ctx0 ,inpSA ,inp_out_ids ); 752 } 753 754cur = ggml_add (ctx0 ,cur ,inpSA ); 755cb (cur ,"mtp_attn_residual" ,il ); 756 757ggml_tensor * ffn_residual = cur ; 758cur = build_norm (cur ,layer .attn_post_norm ,nullptr ,LLM_NORM_RMS ,il ); 759cb (cur ,"mtp_attn_post_norm" ,il ); 760 761// MoE FFN — routed experts plus gated shared expert (mirrors the trunk). 762ggml_tensor * moe_out = 763build_moe_ffn (cur , 764layer .ffn_gate_inp , 765layer .ffn_up_exps , 766layer .ffn_gate_exps , 767layer .ffn_down_exps , 768nullptr , 769n_expert ,n_expert_used , 770LLM_FFN_SILU , true, 771hparams .expert_weights_scale , 772LLAMA_EXPERT_GATING_FUNC_TYPE_SOFTMAX ,il , 773nullptr ,layer .ffn_gate_up_exps , 774layer .ffn_up_exps_s , 775layer .ffn_gate_exps_s , 776layer .ffn_down_exps_s ); 777cb (moe_out ,"mtp_ffn_moe_out" ,il ); 778 779if (layer .ffn_up_shexp != nullptr ) { 780ggml_tensor * ffn_shexp = 781build_ffn (cur , 782layer .ffn_up_shexp ,nullptr ,layer .ffn_up_shexp_s , 783layer .ffn_gate_shexp ,nullptr ,layer .ffn_gate_shexp_s , 784layer .ffn_down_shexp ,nullptr ,layer .ffn_down_shexp_s , 785nullptr , 786LLM_FFN_SILU ,LLM_FFN_PAR ,il ); 787cb (ffn_shexp ,"mtp_ffn_shexp" ,il ); 788 789ggml_tensor * shared_gate = build_lora_mm (layer .ffn_gate_inp_shexp ,cur ); 790shared_gate = ggml_sigmoid (ctx0 ,shared_gate ); 791cb (shared_gate ,"mtp_shared_expert_gate_sigmoid" ,il ); 792 793ffn_shexp = ggml_mul (ctx0 ,ffn_shexp ,shared_gate ); 794cb (ffn_shexp ,"mtp_ffn_shexp_gated" ,il ); 795 796cur = ggml_add (ctx0 ,moe_out ,ffn_shexp ); 797 }else { 798cur = moe_out ; 799 } 800cb (cur ,"mtp_ffn_out" ,il ); 801 802cur = ggml_add (ctx0 ,cur ,ffn_residual ); 803cb (cur ,"mtp_post_ffn" ,il ); 804 805ggml_tensor * head_norm_w = layer .nextn .shared_head_norm 806 ?layer .nextn .shared_head_norm 807 :model .output_norm ; 808GGML_ASSERT (head_norm_w && "QWEN3NEXT MTP: missing both nextn.shared_head_norm and output_norm" ); 809cur = build_norm (cur ,head_norm_w ,nullptr ,LLM_NORM_RMS ,-1 ); 810 811cb (cur ,"h_nextn" ,-1 ); 812res -> t_h_nextn = cur ; 813 814ggml_tensor * head_w = layer .nextn .shared_head_head ?layer .nextn .shared_head_head :model .output ; 815ggml_tensor * head_s = layer .nextn .shared_head_head ?layer .nextn .shared_head_head_s :model .output_s ; 816GGML_ASSERT (head_w && "QWEN3NEXT MTP: missing LM head (nextn.shared_head_head or model.output)" ); 817cur = build_lora_mm (head_w ,cur ,head_s ); 818cb (cur ,"result_output" ,-1 ); 819 820res -> t_logits = cur ; 821ggml_build_forward_expand (gf ,cur ); 822}