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_kimi_linear::load_arch_hparams (llama_model_loader & ml ) { 5ml .get_key (LLM_KV_ATTENTION_LAYERNORM_RMS_EPS ,hparams .f_norm_rms_eps ); 6ml .get_key (LLM_KV_ATTENTION_KEY_LENGTH_MLA ,hparams .n_embd_head_k_mla_impl ); 7ml .get_key (LLM_KV_ATTENTION_VALUE_LENGTH_MLA ,hparams .n_embd_head_v_mla_impl ); 8ml .get_key (LLM_KV_ATTENTION_KV_LORA_RANK ,hparams .n_lora_kv ); 9ml .get_key (LLM_KV_SSM_CONV_KERNEL ,hparams .ssm_d_conv ); 10ml .get_key (LLM_KV_KDA_HEAD_DIM ,hparams .n_embd_head_kda ); 11 12// MLA qk_rope_head_dim (for reference) 13// qk_rope_head_dim = 64, qk_nope_head_dim = 128, qk_head_dim = 192 14 15// Mark KDA layers as recurrent using n_head_kv pattern (like Jamba) 16// Set n_head_kv = 0 for KDA layers (recurrent), n_head_kv = n_head for MLA layers (attention) 17for (uint32_t i = 0 ;i < hparams .n_layer ();++ i ) { 18hparams .is_recr_impl [i ]= hparams .n_head_kv (i )== 0 ;// KDA layers are recurrent 19 } 20 21// MoE parameters - Kimi uses moe_intermediate_size = 1024 22ml .get_key_or_arr (LLM_KV_EXPERT_FEED_FORWARD_LENGTH ,hparams .n_ff_exp_arr ,hparams .n_layer_all ); 23ml .get_key (LLM_KV_EXPERT_SHARED_COUNT ,hparams .n_expert_shared ); 24ml .get_key (LLM_KV_LEADING_DENSE_BLOCK_COUNT ,hparams .n_layer_dense_lead , false); 25ml .get_key (LLM_KV_EXPERT_WEIGHTS_SCALE ,hparams .expert_weights_scale , false); 26ml .get_key (LLM_KV_EXPERT_GATING_FUNC ,hparams .expert_gating_func ); 27 28switch (hparams .n_layer ()) { 29case 27 :type = LLM_TYPE_48B_A3B ;break ;// Kimi-Linear-48B-A3B 30default :type = LLM_TYPE_UNKNOWN ; 31 } 32} 33 34void llama_model_kimi_linear::load_arch_tensors (llama_model_loader & ) { 35LLAMA_LOAD_LOCALS ; 36 37tok_embd = create_tensor (tn (LLM_TENSOR_TOKEN_EMBD ,"weight" ), {n_embd ,n_vocab },0 ); 38 39// output 40output_norm = create_tensor (tn (LLM_TENSOR_OUTPUT_NORM ,"weight" ), {n_embd },0 ); 41output = create_tensor (tn (LLM_TENSOR_OUTPUT ,"weight" ), {n_embd ,n_vocab },0 ); 42 43for (int i = 0 ;i < n_layer ;++ i ) { 44auto & layer = layers [i ]; 45 46layer .attn_norm = create_tensor (tn (LLM_TENSOR_ATTN_NORM ,"weight" ,i ), {n_embd },0 ); 47 48// Check for KDA specific tensors to determine layer type or if it's a mixed model 49// Assuming KDA layer if KDA tensors are present 50 51// KDA uses head_dim = 128 (from linear_attn_config.head_dim) 52const int64_t n_embd_head_k_kda = hparams .n_embd_head_kda ; 53const int64_t n_embd_head_v_kda = hparams .n_embd_head_kda ; 54const int64_t ssm_d_conv = hparams .ssm_d_conv ; 55 56if (hparams .is_recr (i )) { 57// Conv1d weights: try 4D first, then 3D (quantization may remove trailing 1) 58// 4D: [d_conv, 1, d_inner, 1], 3D: [d_conv, 1, d_inner] 59layer .ssm_q_conv = create_tensor (tn (LLM_TENSOR_SSM_CONV1D_Q ,"weight" ,i ), {ssm_d_conv ,1 ,n_embd_head_k_kda * n_head ,1 },TENSOR_NOT_REQUIRED ); 60if (!layer .ssm_q_conv ) { 61layer .ssm_q_conv = create_tensor (tn (LLM_TENSOR_SSM_CONV1D_Q ,"weight" ,i ), {ssm_d_conv ,1 ,n_embd_head_k_kda * n_head },0 ); 62 } 63 64// KDA Layer - Conv1d weights may be 3D or 4D 65layer .ssm_k_conv = create_tensor (tn (LLM_TENSOR_SSM_CONV1D_K ,"weight" ,i ), {ssm_d_conv ,1 ,n_embd_head_k_kda * n_head ,1 },TENSOR_NOT_REQUIRED ); 66if (!layer .ssm_k_conv ) { 67layer .ssm_k_conv = create_tensor (tn (LLM_TENSOR_SSM_CONV1D_K ,"weight" ,i ), {ssm_d_conv ,1 ,n_embd_head_k_kda * n_head },0 ); 68 } 69layer .ssm_v_conv = create_tensor (tn (LLM_TENSOR_SSM_CONV1D_V ,"weight" ,i ), {ssm_d_conv ,1 ,n_embd_head_v_kda * n_head ,1 },TENSOR_NOT_REQUIRED ); 70if (!layer .ssm_v_conv ) { 71layer .ssm_v_conv = create_tensor (tn (LLM_TENSOR_SSM_CONV1D_V ,"weight" ,i ), {ssm_d_conv ,1 ,n_embd_head_v_kda * n_head },0 ); 72 } 73 74// q, k, v projections 75// Python: q_proj, k_proj, v_proj 76create_tensor_qkv (layer ,i ,n_embd ,n_embd_head_k_kda * n_head ,n_embd_head_k_kda * n_head ,n_embd_head_v_kda * n_head ,0 ); 77 78// KDA specific projections 79// f_a_proj, f_b_proj 80layer .ssm_f_a = create_tensor (tn (LLM_TENSOR_SSM_F_A ,"weight" ,i ), {n_embd ,n_embd_head_k_kda },0 );// head_dim 81layer .ssm_f_b = create_tensor (tn (LLM_TENSOR_SSM_F_B ,"weight" ,i ), {n_embd_head_k_kda ,n_embd_head_k_kda * n_head },0 );// projection_size 82 83// b_proj (beta mixing coefficient) 84layer .ssm_beta = create_tensor (tn (LLM_TENSOR_SSM_BETA ,"weight" ,i ), {n_embd ,n_head },0 ); 85 86// A_log - Shape in GGUF: [1, num_heads, 1, 1] (4D) or [1, num_heads] (2D after quantization) Note: -exp(A_log) is applied in convert_hf_to_gguf.py 87layer .ssm_a = create_tensor (tn (LLM_TENSOR_SSM_A_NOSCAN ,i ), {1 ,n_head ,1 ,1 },TENSOR_NOT_REQUIRED ); 88if (!layer .ssm_a ) { 89layer .ssm_a = create_tensor (tn (LLM_TENSOR_SSM_A_NOSCAN ,i ), {1 ,n_head },0 ); 90 } 91 92// dt_bias - shape [n_embd_head_k_kda * n_head] = [4096] 93layer .ssm_dt_b = create_tensor (tn (LLM_TENSOR_SSM_DT ,"bias" ,i ), {n_embd_head_k_kda * n_head },0 ); 94 95// g_a_proj, g_b_proj (output gate) 96layer .ssm_g_a = create_tensor (tn (LLM_TENSOR_SSM_G_A ,"weight" ,i ), {n_embd ,n_embd_head_k_kda },0 ); 97layer .ssm_g_b = create_tensor (tn (LLM_TENSOR_SSM_G_B ,"weight" ,i ), {n_embd_head_k_kda ,n_embd_head_k_kda * n_head },0 ); 98 99// o_norm (reusing SSM_NORM) 100layer .ssm_o_norm = create_tensor (tn (LLM_TENSOR_SSM_NORM ,"weight" ,i ), {n_embd_head_k_kda },0 );// FusedRMSNormGated 101 102// o_proj 103layer .wo = create_tensor (tn (LLM_TENSOR_ATTN_OUT ,"weight" ,i ), {n_embd_head_v_kda * n_head ,n_embd },0 ); 104 105 }else { 106// MLA Layer - use MLA-specific head dimensions 107const int64_t q_lora_rank = hparams .n_lora_q ; 108const int64_t kv_lora_rank = hparams .n_lora_kv ; 109const int64_t n_embd_head_k_mla = hparams .n_embd_head_k_mla (); 110const int64_t n_embd_head_v_mla = hparams .n_embd_head_v_mla (); 111 112layer .attn_q_a_norm = create_tensor (tn (LLM_TENSOR_ATTN_Q_A_NORM ,"weight" ,i ), {q_lora_rank },TENSOR_NOT_REQUIRED ); 113layer .attn_kv_a_norm = create_tensor (tn (LLM_TENSOR_ATTN_KV_A_NORM ,"weight" ,i ), {kv_lora_rank },0 ); 114 115if (layer .attn_q_a_norm ) { 116layer .wq_a = create_tensor (tn (LLM_TENSOR_ATTN_Q_A ,"weight" ,i ), {n_embd ,q_lora_rank },0 ); 117layer .wq_b = create_tensor (tn (LLM_TENSOR_ATTN_Q_B ,"weight" ,i ), {q_lora_rank ,n_head * n_embd_head_k_mla },0 ); 118 }else { 119// Kimi MLA without Q compression: wq = [n_embd, n_head * n_embd_head_k_mla] 120layer .wq = create_tensor (tn (LLM_TENSOR_ATTN_Q ,"weight" ,i ), {n_embd ,n_head * n_embd_head_k_mla },0 ); 121 } 122 123// Kimi: qk_rope_head_dim = 64 (actual RoPE dimension for MLA) 124// Note: hparams.n_rot may be 72 (from conversion) but actual is 64 125const int64_t qk_rope_head_dim = hparams .n_rot ();// From config: qk_rope_head_dim 126layer .wkv_a_mqa = create_tensor (tn (LLM_TENSOR_ATTN_KV_A_MQA ,"weight" ,i ), {n_embd ,kv_lora_rank + qk_rope_head_dim },0 ); 127// Support Legacy GGUFs that don't split wkv_b (MLA KV cache disabled) 128layer .wkv_b = create_tensor (tn (LLM_TENSOR_ATTN_KV_B ,"weight" ,i ), 129 {kv_lora_rank ,n_head * (n_embd_head_k_mla - qk_rope_head_dim + n_embd_head_v_mla )},TENSOR_NOT_REQUIRED |TENSOR_SKIP_IF_VIRTUAL ); 130if (!layer .wkv_b ) {// MLA KV cache enabled 131layer .wk_b = create_tensor (tn (LLM_TENSOR_ATTN_K_B ,"weight" ,i ), {n_embd_head_k_mla - qk_rope_head_dim ,kv_lora_rank ,n_head },0 ); 132layer .wv_b = create_tensor (tn (LLM_TENSOR_ATTN_V_B ,"weight" ,i ), {kv_lora_rank ,n_embd_head_v_mla ,n_head },0 ); 133 } 134layer .wo = create_tensor (tn (LLM_TENSOR_ATTN_OUT ,"weight" ,i ), {n_head * n_embd_head_v_mla ,n_embd },0 ); 135 } 136 137layer .ffn_norm = create_tensor (tn (LLM_TENSOR_FFN_NORM ,"weight" ,i ), {n_embd },0 ); 138 139// MoE intermediate size (different from dense FFN) 140const int64_t n_ff_exp = hparams .n_ff_exp (); 141 142// Kimi uses n_layer_dense_lead to determine which layers use dense FFN vs MoE 143// first_k_dense_replace = 1 means layer 0 uses dense FFN, layers 1+ use MoE 144if (i < (int )hparams .n_layer_dense_lead ) { 145// Dense FFN layer - use normal n_ff 146layer .ffn_gate = create_tensor (tn (LLM_TENSOR_FFN_GATE ,"weight" ,i ), {n_embd ,n_ff },0 ); 147layer .ffn_down = create_tensor (tn (LLM_TENSOR_FFN_DOWN ,"weight" ,i ), {n_ff ,n_embd },0 ); 148layer .ffn_up = create_tensor (tn (LLM_TENSOR_FFN_UP ,"weight" ,i ), {n_embd ,n_ff },0 ); 149 }else { 150// MoE layer - use n_ff_exp (1024) instead of n_ff (9216) 151layer .ffn_gate_inp = create_tensor (tn (LLM_TENSOR_FFN_GATE_INP ,"weight" ,i ), {n_embd ,n_expert },0 ); 152layer .ffn_gate_exps = create_tensor (tn (LLM_TENSOR_FFN_GATE_EXPS ,"weight" ,i ), {n_embd ,n_ff_exp ,n_expert },0 ); 153layer .ffn_down_exps = create_tensor (tn (LLM_TENSOR_FFN_DOWN_EXPS ,"weight" ,i ), {n_ff_exp ,n_embd ,n_expert },0 ); 154layer .ffn_up_exps = create_tensor (tn (LLM_TENSOR_FFN_UP_EXPS ,"weight" ,i ), {n_embd ,n_ff_exp ,n_expert },0 ); 155 156// Shared experts use moe_intermediate_size * num_shared_experts 157// Kimi: shared_expert_intermediate_size = 1024 * 1 = 1024 158// Tensors are 2D: [n_embd, n_ff_shexp] or [n_ff_shexp, n_embd] 159const int64_t n_ff_shexp_actual = n_ff_exp * (hparams .n_expert_shared > 0 ?hparams .n_expert_shared :1 ); 160layer .ffn_gate_shexp = create_tensor (tn (LLM_TENSOR_FFN_GATE_SHEXP ,"weight" ,i ), {n_embd ,n_ff_shexp_actual },TENSOR_NOT_REQUIRED ); 161layer .ffn_down_shexp = create_tensor (tn (LLM_TENSOR_FFN_DOWN_SHEXP ,"weight" ,i ), {n_ff_shexp_actual ,n_embd },TENSOR_NOT_REQUIRED ); 162layer .ffn_up_shexp = create_tensor (tn (LLM_TENSOR_FFN_UP_SHEXP ,"weight" ,i ), {n_embd ,n_ff_shexp_actual },TENSOR_NOT_REQUIRED ); 163 164layer .ffn_exp_probs_b = create_tensor (tn (LLM_TENSOR_FFN_EXP_PROBS_B ,"bias" ,i ), {n_expert },0 ); 165 } 166 } 167} 168 169std::unique_ptr < llm_graph_context > llama_model_kimi_linear::build_arch_graph (const llm_graph_params & params )const { 170return std::make_unique < graph > (* this ,params ); 171} 172 173// Causal Conv1d function for Q,K,V 174// When qkv is 0, it is Q, 1 is K, 2 is V 175static ggml_tensor * causal_conv1d (ggml_cgraph * gf ,ggml_context * ctx0 ,ggml_tensor * conv_states_all ,ggml_tensor * conv_state_all ,int64_t qkv ,ggml_tensor * x ,ggml_tensor * proj_w ,ggml_tensor * conv_w ,int64_t d_conv ,int64_t head_dim ,int64_t n_head ,int64_t n_seq_tokens ,int64_t n_seqs ,int64_t n_tokens ,int64_t kv_head ) { 176const int64_t d_inner = head_dim * n_head ; 177const int64_t conv_state_size = (d_conv - 1 )* d_inner ; 178const int64_t n_embd_r_total = 3 * conv_state_size ;// Q + K + V 179 180// conv_state_all is [n_embd_r_total, n_seqs], split into Q, K, V 181// Each conv state is [(d_conv-1) * d_inner] per sequence, need to reshape to [d_conv-1, d_inner, n_seqs] 182// Memory layout: for each seq, Q state is first conv_state_size elements, then K, then V 183// conv_state_all has stride: nb[0] = element_size, nb[1] = n_embd_r_total * element_size 184// View Q conv state: offset 0, size conv_state_size per seq 185// conv_state_all is [n_embd_r_total, n_seqs] with memory layout: 186// state[i + seq * n_embd_r_total] where i = conv_step + channel * (d_conv-1) + {0, conv_state_size, 2*conv_state_size} for Q/K/V 187// We want [d_conv-1, d_inner, n_seqs] view: 188// nb1 = (d_conv-1) * element_size (stride between channels) 189// nb2 = n_embd_r_total * element_size (stride between seqs) 190ggml_tensor * conv_state_x = ggml_view_3d (ctx0 ,conv_state_all ,d_conv - 1 ,d_inner ,n_seqs , 191 (d_conv - 1 )* ggml_element_size (conv_state_all ),// nb1: stride between channels 192n_embd_r_total * ggml_element_size (conv_state_all ),// nb2: stride between seqs 193qkv * conv_state_size * ggml_element_size (conv_state_all )); 194 195// Causal Conv1d function for Q,K,V 196// When qkv is 0, it is Q, 1 is K, 2 is V 197// Step 1: Q, K, V projections -> [d_inner, n_tokens] 198ggml_tensor * x_proj = proj_w ?ggml_mul_mat (ctx0 ,proj_w ,x ) :x ; 199 200// Reshape input: {d_inner, n_tokens} -> {d_inner, n_seq_tokens, n_seqs} 201ggml_tensor * x_3d = ggml_reshape_3d (ctx0 ,x_proj ,d_inner ,n_seq_tokens ,n_seqs ); 202 203// Concat Q conv state and current input: {d_conv-1 + n_seq_tokens, d_inner, n_seqs} 204ggml_tensor * conv_x = ggml_concat (ctx0 ,conv_state_x ,ggml_transpose (ctx0 ,x_3d ),0 ); 205 206// Save last (d_conv-1) columns back to Q conv state 207ggml_tensor * last_conv_x = ggml_view_3d (ctx0 ,conv_x ,d_conv - 1 ,d_inner ,n_seqs , 208conv_x -> nb [1 ],conv_x -> nb [2 ],n_seq_tokens * conv_x -> nb [0 ]); 209ggml_build_forward_expand (gf , 210ggml_cpy (ctx0 ,last_conv_x , 211ggml_view_3d (ctx0 ,conv_states_all , 212d_conv - 1 ,d_inner ,n_seqs , 213 (d_conv - 1 )* ggml_element_size (conv_states_all ),// nb1: contiguous within one channel's conv taps 214n_embd_r_total * ggml_element_size (conv_states_all ),// nb2: stride between sequences (skip over K,V states) 215 (kv_head * n_embd_r_total + qkv * conv_state_size )* ggml_element_size (conv_states_all ))));// offset to first seq's Q/K/V state 216// Reshape conv weight: GGUF [d_conv, 1, d_inner, 1] -> ggml_ssm_conv expects [d_conv, d_inner] 217// GGUF stores as [d_conv, 1, d_inner, 1] with memory layout w[conv_step + channel * d_conv] 218// vLLM stores as [d_inner, d_conv] with memory layout w[channel * d_conv + conv_step] 219// ggml_ssm_conv computes: c[conv_step + channel * d_conv] 220// GGUF layout: [d_conv, 1, d_inner] or [d_conv, 1, d_inner, 1] -> reshape to [d_conv, d_inner] 221// Reshape conv weight from [d_conv, 1, d_inner, 1] to [d_conv, d_inner] for ggml_ssm_conv 222ggml_tensor * conv_weight = ggml_reshape_2d (ctx0 ,conv_w ,d_conv ,d_inner ); 223 224// Apply conv1d 225// ggml_ssm_conv output: {d_inner, n_seq_tokens, n_seqs} 226ggml_tensor * Xcur = ggml_ssm_conv (ctx0 ,conv_x ,conv_weight ); 227// Reshape to 2D for bias add: {d_inner, n_tokens} 228Xcur = ggml_reshape_2d (ctx0 ,Xcur ,d_inner ,n_tokens ); 229Xcur = ggml_silu (ctx0 ,Xcur ); 230 231return ggml_reshape_4d (ctx0 ,Xcur ,head_dim ,n_head ,n_seq_tokens ,n_seqs ); 232} 233 234llama_model_kimi_linear::graph::graph (const llama_model & model ,const llm_graph_params & params ) : 235llm_build_delta_net_base (params ),model (model ) { 236ggml_tensor * cur ; 237ggml_tensor * inpL ; 238 239inpL = build_inp_embd (model .tok_embd ); 240cb (inpL ,"model.embed_tokens" ,-1 ); 241 242// Note: Kimi MLA does NOT use RoPE (rotary_emb=None in vLLM) 243// So we don't need inp_pos 244 245auto * inp_kv = !hparams .is_mla () ?build_inp_mem_hybrid () :nullptr ; 246auto * inp_k = hparams .is_mla () ?build_inp_mem_hybrid_k () :nullptr ; 247auto * inp_rs = hparams .is_mla () ?inp_k -> get_recr () :inp_kv -> get_recr (); 248auto * inp_attn_kv = !hparams .is_mla () ?inp_kv -> get_attn () :nullptr ; 249auto * inp_attn_k = hparams .is_mla () ?inp_k -> get_attn () :nullptr ; 250 251// Output ids for selecting which tokens to output 252ggml_tensor * inp_out_ids = build_inp_out_ids (); 253 254// Kimi dimension constants 255const int64_t n_head = hparams .n_head (); 256const int64_t head_dim = hparams .n_embd_head_kda ; 257const int64_t d_conv = hparams .ssm_d_conv ; 258const int64_t d_inner = n_head * head_dim ;// 32 * 128 = 4096 259const int64_t n_seqs = ubatch .n_seqs ; 260const int64_t n_seq_tokens = ubatch .n_seq_tokens ; 261 262// Verify batch consistency for recurrent layers 263GGML_ASSERT (n_seqs != 0 ); 264GGML_ASSERT (ubatch .equal_seqs ()); 265GGML_ASSERT (ubatch .n_tokens == n_seq_tokens * n_seqs ); 266 267// MLA params 268const int64_t n_embd_head_k_mla = hparams .n_embd_head_k_mla (); 269const int64_t n_embd_head_v_mla = hparams .n_embd_head_v_mla (); 270const int64_t kv_lora_rank = hparams .n_lora_kv ; 271// qk_rope_head_dim = 64 (from Kimi config) which is hparams.n_rot 272// Confirmed from tensor shape: wkv_a_mqa [2304, 576] = [n_embd, kv_lora_rank + qk_rope_head_dim] 273const int64_t n_embd_head_qk_rope = hparams .n_rot ();// config.qk_rope_head_dim 274const int64_t n_embd_head_qk_nope = n_embd_head_k_mla - n_embd_head_qk_rope ;// 192 - 64 = 128 275// Attention scale for MLA 276const float kq_scale_mla = 1.0f /sqrtf ((float )n_embd_head_k_mla ); 277 278for (int il = 0 ;il < n_layer ;++ il ) { 279const auto & layer = model .layers [il ]; 280ggml_tensor * inpSA = inpL ; 281 282// Attention Norm 283cur = build_norm (inpL ,layer .attn_norm ,NULL ,LLM_NORM_RMS ,il ); 284cb (cur ,"attn_norm" ,il ); 285 286ggml_build_forward_expand (gf ,cur ); 287 288if (hparams .is_recr (il )) { 289// === KDA Layer (Kimi Delta Attention) with Recurrent State === 290// Reference: vLLM kda.py 291const auto * mctx_cur = inp_rs -> mctx ; 292const auto kv_head = mctx_cur -> get_head (); 293 294// Get conv states from r_l tensor (Q, K, V each have separate state) 295ggml_tensor * conv_states_all = mctx_cur -> get_r_l (il ); 296cb (conv_states_all ,"conv_states_all" ,il ); 297ggml_tensor * conv_state_all = build_rs (inp_rs ,conv_states_all ,hparams .n_embd_r (),n_seqs ); 298ggml_tensor * q_in = cur ,* k_in = cur ,* v_in = cur ; 299ggml_tensor * q_w = layer .wq ,* k_w = layer .wk ,* v_w = layer .wv ; 300if (layer .wqkv ) { 301ggml_tensor * qkv = ggml_mul_mat (ctx0 ,layer .wqkv ,cur ); 302const int64_t d_inner = head_dim * n_head ; 303const size_t esize = ggml_element_size (qkv ); 304q_in = ggml_cont (ctx0 ,ggml_view_2d (ctx0 ,qkv ,d_inner ,n_tokens ,qkv -> nb [1 ],0 )); 305k_in = ggml_cont (ctx0 ,ggml_view_2d (ctx0 ,qkv ,d_inner ,n_tokens ,qkv -> nb [1 ],d_inner * esize )); 306v_in = ggml_cont (ctx0 ,ggml_view_2d (ctx0 ,qkv ,d_inner ,n_tokens ,qkv -> nb [1 ],2 * d_inner * esize )); 307q_w = nullptr ;k_w = nullptr ;v_w = nullptr ; 308 } 309ggml_tensor * Qcur = causal_conv1d (gf ,ctx0 ,conv_states_all ,conv_state_all ,0 ,q_in ,q_w ,layer .ssm_q_conv ,d_conv ,head_dim ,n_head ,n_seq_tokens ,n_seqs ,n_tokens ,kv_head ); 310ggml_tensor * Kcur = causal_conv1d (gf ,ctx0 ,conv_states_all ,conv_state_all ,1 ,k_in ,k_w ,layer .ssm_k_conv ,d_conv ,head_dim ,n_head ,n_seq_tokens ,n_seqs ,n_tokens ,kv_head ); 311ggml_tensor * Vcur = causal_conv1d (gf ,ctx0 ,conv_states_all ,conv_state_all ,2 ,v_in ,v_w ,layer .ssm_v_conv ,d_conv ,head_dim ,n_head ,n_seq_tokens ,n_seqs ,n_tokens ,kv_head ); 312 313// g1 = -exp(A_log) * softplus(f_b(f_a(x)) + dt_bias) 314ggml_tensor * f_a = ggml_mul_mat (ctx0 ,layer .ssm_f_a ,cur ); 315ggml_tensor * g1 = ggml_mul_mat (ctx0 ,layer .ssm_f_b ,f_a ); 316cb (g1 ,"g1 f_b(f_a(cur))" ,il ); 317g1 = ggml_add (ctx0 ,g1 ,layer .ssm_dt_b ); 318g1 = ggml_softplus (ctx0 ,g1 ); 319g1 = ggml_reshape_3d (ctx0 ,g1 ,head_dim ,n_head ,n_tokens ); 320 321// A_log shape is [1, n_head] or [1, n_head, 1, 1], need to broadcast to [head_dim, n_head, n_tokens]. No need to -exp(a_log) because it was done in convert_hf_to_gguf.py 322// Reshape to [1, n_head, 1] for broadcasting with g1 [head_dim, n_head, n_tokens] 323ggml_tensor * A = ggml_reshape_3d (ctx0 ,layer .ssm_a ,1 ,n_head ,1 ); 324g1 = ggml_mul (ctx0 ,g1 ,A ); 325cb (g1 ,"kda_g1" ,il ); 326 327g1 = ggml_reshape_4d (ctx0 ,g1 ,head_dim ,n_head ,n_seq_tokens ,n_seqs ); 328 329// Compute beta (mixing coefficient) 330ggml_tensor * beta = ggml_mul_mat (ctx0 ,layer .ssm_beta ,cur ); 331beta = ggml_reshape_4d (ctx0 ,beta ,1 ,n_head ,n_seq_tokens ,n_seqs ); 332cb (beta ,"kda_beta" ,il ); 333 334beta = ggml_sigmoid (ctx0 ,beta ); 335 336// Reshape for KDA recurrence 337// {n_embd, n_tokens} -> {n_embd, n_seq_tokens, n_seqs} 338cur = ggml_reshape_3d (ctx0 ,cur ,cur -> ne [0 ],n_seq_tokens ,n_seqs ); 339 340// Get SSM state and compute KDA recurrence using ggml_kda_scan 341ggml_tensor * ssm_states_all = mctx_cur -> get_s_l (il ); 342ggml_tensor * state = build_rs (inp_rs ,ssm_states_all ,hparams .n_embd_s (),n_seqs ); 343state = ggml_reshape_4d (ctx0 ,state ,head_dim ,head_dim ,n_head ,n_seqs ); 344 345 346const float eps_norm = hparams .f_norm_rms_eps ; 347 348Qcur = build_gdn_l2_norm (ctx0 ,Qcur ,eps_norm ); 349Kcur = build_gdn_l2_norm (ctx0 ,Kcur ,eps_norm ); 350 351// Choose between build_delta_net_chunking and build_delta_net_recurrent based on n_tokens 352auto attn_out = build_delta_net (Qcur ,Kcur ,Vcur ,g1 ,beta ,state ,il ); 353 354ggml_tensor * output = ggml_cont (ctx0 ,attn_out .first ); 355ggml_tensor * new_state = attn_out .second ; 356cb (output ,"attn_output" ,il ); 357cb (new_state ,"new_state" ,il ); 358 359// Update the recurrent states 360ggml_build_forward_expand (gf , 361ggml_cpy (ctx0 ,new_state , 362ggml_view_1d (ctx0 ,ssm_states_all ,hparams .n_embd_s ()* n_seqs , 363kv_head * hparams .n_embd_s ()* ggml_element_size (ssm_states_all )))); 364 365// Output gating g2 = g_b(g_a(x)) 366ggml_tensor * cur_2d = ggml_reshape_2d (ctx0 ,cur ,cur -> ne [0 ],n_seq_tokens * n_seqs ); 367ggml_tensor * g_a = ggml_mul_mat (ctx0 ,layer .ssm_g_a ,cur_2d ); 368ggml_tensor * g2 = ggml_mul_mat (ctx0 ,layer .ssm_g_b ,g_a ); 369cb (g2 ,"g2 g_b(g_a(cur_2d))" ,il ); 370g2 = ggml_reshape_3d (ctx0 ,g2 ,head_dim ,n_head ,n_seq_tokens * n_seqs ); 371 372// Apply o_norm with sigmoid gating 373// Note: Kimi model uses sigmoid gating, not SiLU (despite FusedRMSNormGated default being swish) 374// Formula: output = RMSNorm(x) * sigmoid(g) 375ggml_tensor * attn_out_final = ggml_reshape_3d (ctx0 ,output ,head_dim ,n_head ,n_seq_tokens * n_seqs ); 376ggml_tensor * normed = build_norm (attn_out_final ,layer .ssm_o_norm ,nullptr ,LLM_NORM_RMS ,il ); 377cb (normed ,"kda_normed" ,il ); 378ggml_tensor * gate = ggml_sigmoid (ctx0 ,g2 ); 379ggml_tensor * gated = ggml_mul (ctx0 ,normed ,gate ); 380 381// Output projection 382gated = ggml_cont_2d (ctx0 ,gated ,d_inner ,n_tokens ); 383cur = ggml_mul_mat (ctx0 ,layer .wo ,gated ); 384cb (cur ,"kda_out" ,il ); 385 386 }else { 387// === MLA Layer (Multi-head Latent Attention) without KV Cache === 388// Reference: vLLM mla.py 389// Step 1: Q projection and reshape 390// vLLM Kimi: q = q_proj(hidden_states), then view as [n_tokens, n_head, qk_head_dim] 391// Note: Kimi MLA does NOT use RoPE (rotary_emb=None in vLLM) 392ggml_tensor * Qcur = ggml_mul_mat (ctx0 ,layer .wq ,cur ); 393 394// Step 2: KV compression 395// kv_cmpr_pe = kv_a_proj_with_mqa(hidden_states) -> [kv_lora_rank + qk_rope_head_dim, n_tokens] 396ggml_tensor * kv_cmpr_pe = ggml_mul_mat (ctx0 ,layer .wkv_a_mqa ,cur ); 397 398// Split: kv_cmpr = kv_lora[:kv_lora_rank], k_pe = kv_lora[kv_lora_rank:] 399ggml_tensor * kv_cmpr = ggml_view_2d (ctx0 ,kv_cmpr_pe ,kv_lora_rank ,n_tokens , 400ggml_row_size (kv_cmpr_pe -> type ,kv_lora_rank + n_embd_head_qk_rope ),0 ); 401ggml_tensor * k_pe = ggml_view_3d (ctx0 ,kv_cmpr_pe ,n_embd_head_qk_rope ,1 ,n_tokens , 402ggml_row_size (kv_cmpr_pe -> type ,kv_lora_rank + n_embd_head_qk_rope ), 403ggml_row_size (kv_cmpr_pe -> type ,kv_lora_rank + n_embd_head_qk_rope ), 404ggml_row_size (kv_cmpr_pe -> type ,kv_lora_rank )); 405// Note: Kimi MLA does NOT apply RoPE (rotary_emb=None in vLLM) 406// k_pe is used directly without RoPE 407// Normalize kv_c 408kv_cmpr = build_norm (kv_cmpr ,layer .attn_kv_a_norm ,nullptr ,LLM_NORM_RMS ,il ); 409 410if (layer .wk_b && layer .wv_b ) {// MLA KV cache enabled 411// extract q_nope 412ggml_tensor * q_nope = 413ggml_view_3d (ctx0 ,Qcur ,n_embd_head_qk_nope ,n_head ,n_tokens ,ggml_row_size (Qcur -> type ,n_embd_head_k_mla ), 414ggml_row_size (Qcur -> type ,n_embd_head_k_mla )* n_head ,0 ); 415cb (q_nope ,"q_nope" ,il ); 416 417// and {n_embd_head_qk_rope, n_head, n_tokens} 418ggml_tensor * q_pe = ggml_view_3d ( 419ctx0 ,Qcur ,n_embd_head_qk_rope ,n_head ,n_tokens ,ggml_row_size (Qcur -> type ,n_embd_head_k_mla ), 420ggml_row_size (Qcur -> type ,n_embd_head_k_mla )* n_head ,ggml_row_size (Qcur -> type ,n_embd_head_qk_nope )); 421cb (q_pe ,"q_pe" ,il ); 422 423// {n_embd_head_qk_nope, n_tokens, n_head} 424q_nope = ggml_permute (ctx0 ,q_nope ,0 ,2 ,1 ,3 ); 425cb (q_nope ,"q_nope_perm" ,il ); 426 427// {n_embd_head_qk_nope, kv_lora_rank, n_head} x {n_embd_head_qk_nope, n_tokens, n_head} 428ggml_tensor * q_nope_absorbed = ggml_mul_mat (ctx0 ,layer .wk_b ,q_nope ); 429cb (q_nope_absorbed ,"q_nope_absorbed" ,il ); 430 431// {kv_lora_rank, n_head, n_tokens} 432q_nope_absorbed = ggml_permute (ctx0 ,q_nope_absorbed ,0 ,2 ,1 ,3 ); 433cb (q_nope_absorbed ,"q_nope_absorbed_perm" ,il ); 434 435// {n_embd_head_qk_rope + kv_lora_rank, n_head, n_tokens} 436// note: rope must go first for in-place context shifting in build_rope_shift() 437Qcur = ggml_concat (ctx0 ,q_nope_absorbed ,q_pe ,0 ); 438cb (Qcur ,"Qcur" ,il ); 439 440kv_cmpr = ggml_reshape_3d (ctx0 ,kv_cmpr ,kv_lora_rank ,1 ,n_tokens ); 441cb (kv_cmpr ,"kv_cmpr_reshape" ,il ); 442 443// {n_embd_head_qk_rope + kv_lora_rank, 1, n_tokens} 444ggml_tensor * Kcur = ggml_concat (ctx0 ,kv_cmpr ,k_pe ,0 ); 445cb (Kcur ,"Kcur" ,il ); 446 447// {kv_lora_rank, 1, n_tokens} 448ggml_tensor * Vcur = kv_cmpr ; 449cb (Vcur ,"Vcur" ,il ); 450 451cur = build_attn (inp_attn_k ,layer .wo ,NULL ,layer .wo_s ,Qcur ,Kcur ,Vcur ,nullptr ,nullptr ,layer .wv_b ,kq_scale_mla ,il ); 452cb (cur ,"mla_out" ,il ); 453 }else {// MLA KV cache disabled. Fall back to MHA KV cache. 454Qcur = ggml_reshape_3d (ctx0 ,Qcur ,n_embd_head_k_mla ,n_head ,n_tokens ); 455cb (Qcur ,"mla_Q" ,il ); 456// KV decompression: kv = kv_b_proj(kv_c_normed) 457ggml_tensor * kv = ggml_mul_mat (ctx0 ,layer .wkv_b ,kv_cmpr ); 458const int64_t kv_per_head = n_embd_head_qk_nope + n_embd_head_v_mla ; 459 460// Split kv into k_nope and v 461ggml_tensor * k_nope = ggml_view_3d (ctx0 ,kv ,n_embd_head_qk_nope ,n_head ,n_tokens , 462ggml_row_size (kv -> type ,kv_per_head ), 463ggml_row_size (kv -> type ,kv_per_head * n_head ),0 ); 464ggml_tensor * Vcur = ggml_view_3d (ctx0 ,kv ,n_embd_head_v_mla ,n_head ,n_tokens , 465ggml_row_size (kv -> type ,kv_per_head ), 466ggml_row_size (kv -> type ,kv_per_head * n_head ), 467ggml_row_size (kv -> type ,n_embd_head_qk_nope )); 468Vcur = ggml_cont (ctx0 ,Vcur ); 469cb (Vcur ,"mla_V" ,il ); 470 471// Concatenate k_nope + k_pe (broadcast k_pe to all heads) 472// K = [k_nope, k_pe] where k_nope is [qk_nope_head_dim, n_head, n_tokens] 473// and k_pe is [qk_rope_head_dim, 1, n_tokens] broadcast to all heads 474// Need to broadcast k_pe from [qk_rope, 1, n_tokens] to [qk_rope, n_head, n_tokens] 475ggml_tensor * k_pe_target = ggml_new_tensor_3d (ctx0 ,k_pe -> type ,n_embd_head_qk_rope ,n_head ,n_tokens ); 476ggml_tensor * k_pe_repeated = ggml_repeat (ctx0 ,k_pe ,k_pe_target ); 477ggml_tensor * Kcur = ggml_concat (ctx0 ,k_pe_repeated ,k_nope ,0 ); 478cb (Kcur ,"mla_K" ,il ); 479 480// Direct softmax attention (with MHA KV cache) 481// Use build_attn with inp_attn for proper mask handling 482cur = build_attn (inp_attn_kv ,layer .wo ,NULL ,layer .wo_s ,Qcur ,Kcur ,Vcur ,nullptr ,nullptr ,nullptr ,kq_scale_mla ,il ); 483cb (cur ,"mla_out" ,il ); 484 } 485 } 486 487// On last layer, select only the output tokens 488if (il == n_layer - 1 && inp_out_ids ) { 489cur = ggml_get_rows (ctx0 ,cur ,inp_out_ids ); 490inpSA = ggml_get_rows (ctx0 ,inpSA ,inp_out_ids ); 491 } 492 493// Residual 494ggml_tensor * ffn_inp = ggml_add (ctx0 ,cur ,inpSA ); 495cb (ffn_inp ,"ffn_inp" ,il ); 496 497// FFN Norm 498cur = build_norm (ffn_inp ,layer .ffn_norm ,NULL ,LLM_NORM_RMS ,il ); 499cb (cur ,"ffn_norm" ,il ); 500 501if ((uint32_t )il < hparams .n_layer_dense_lead ) { 502// Dense FFN layer 503cur = build_ffn (cur , 504layer .ffn_up ,NULL ,NULL , 505layer .ffn_gate ,NULL ,NULL , 506layer .ffn_down ,NULL ,NULL , 507NULL ,LLM_FFN_SILU ,LLM_FFN_PAR ,il ); 508cb (cur ,"ffn_out" ,il ); 509 }else { 510// MoE layer 511// Kimi uses moe_renormalize=True and routed_scaling_factor (stored as expert_weights_scale) = 2.446 512ggml_tensor * moe_out = build_moe_ffn (cur , 513layer .ffn_gate_inp , 514layer .ffn_up_exps , 515layer .ffn_gate_exps , 516layer .ffn_down_exps , 517layer .ffn_exp_probs_b , 518hparams .n_expert , 519hparams .n_expert_used (), 520LLM_FFN_SILU , true, 521hparams .expert_weights_scale , 522 (llama_expert_gating_func_type )hparams .expert_gating_func , 523il ); 524cb (moe_out ,"ffn_moe_out" ,il ); 525 526// Shared expert 527 { 528ggml_tensor * ffn_shexp = build_ffn (cur , 529layer .ffn_up_shexp ,NULL ,NULL , 530layer .ffn_gate_shexp ,NULL ,NULL , 531layer .ffn_down_shexp ,NULL ,NULL , 532NULL ,LLM_FFN_SILU ,LLM_FFN_PAR ,il ); 533cb (ffn_shexp ,"ffn_shexp" ,il ); 534 535cur = ggml_add (ctx0 ,moe_out ,ffn_shexp ); 536cb (cur ,"ffn_out" ,il ); 537 } 538 } 539// Residual 540cur = ggml_add (ctx0 ,cur ,ffn_inp ); 541 542cur = build_cvec (cur ,il ); 543cb (cur ,"l_out" ,il ); 544 545// input for next layer 546inpL = cur ; 547 } 548cur = inpL ; 549 550// Final Norm 551cur = build_norm (cur ,model .output_norm ,NULL ,LLM_NORM_RMS ,-1 ); 552 553cb (cur ,"result_norm" ,-1 ); 554res -> t_embd = cur ; 555 556// Output 557cur = ggml_mul_mat (ctx0 ,model .output ,cur ); 558cb (cur ,"result_output" ,-1 ); 559res -> t_logits = cur ; 560 561ggml_build_forward_expand (gf ,cur ); 562}