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