char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
c61b98b87
char/aliceai-t5-moe
1// Laguna (poolside): sigmoid-routed MoE with a score-correction bias, one shared 2// expert, a softplus attention output gate, QK-norm, and per-layer-type RoPE 3// (YaRN on full-attention layers, plain RoPE on sliding-window layers). XS.2 is 4// hybrid full/SWA with a per-head gate; M.1 is full-attention with a per-element 5// gate. Shares the MoE/gate structure with afmoe. 6 7#include "models.h" 8 9void llama_model_laguna::load_arch_hparams (llama_model_loader & ml ) { 10ml .get_key (LLM_KV_ATTENTION_LAYERNORM_RMS_EPS ,hparams .f_norm_rms_eps ); 11ml .get_key (LLM_KV_LEADING_DENSE_BLOCK_COUNT ,hparams .n_layer_dense_lead ); 12ml .get_key_or_arr (LLM_KV_EXPERT_FEED_FORWARD_LENGTH ,hparams .n_ff_exp_arr ,hparams .n_layer_all ); 13ml .get_key (LLM_KV_EXPERT_GATING_FUNC ,hparams .expert_gating_func , false); 14ml .get_key (LLM_KV_EXPERT_WEIGHTS_SCALE ,hparams .expert_weights_scale , false); 15ml .get_key (LLM_KV_EXPERT_WEIGHTS_NORM ,hparams .expert_weights_norm , false); 16 17// Laguna ships one shared expert and stores its size directly (routed and 18// shared experts may differ), so read the size from expert_shared_feed_forward_length. 19// The count is not in the config; default to 1 but read the key if present. 20hparams .n_expert_shared = 1 ; 21ml .get_key (LLM_KV_EXPERT_SHARED_COUNT ,hparams .n_expert_shared , false); 22ml .get_key (LLM_KV_EXPERT_SHARED_FEED_FORWARD_LENGTH ,hparams .n_ff_shexp , false); 23if (hparams .n_ff_shexp == 0 ) { 24// Weightless fixtures (test-llama-archs) omit this key; derive a nonzero 25// size so the shared expert is still built. Real GGUFs always carry the 26// exact value (routed and shared FF lengths may differ). 27hparams .n_ff_shexp = hparams .n_ff_exp ()* hparams .n_expert_shared ; 28 } 29 30// Sliding-window attention is OPTIONAL. XS.2 is hybrid (full / SWA / SWA / 31// SWA repeating, period 4 starting with full); M.1 has no sliding window 32// (all layers full attention). When sliding_window is absent or zero we 33// leave swa_type = NONE and skip the SWA-specific per-layer-type RoPE. 34hparams .n_swa = 0 ; 35ml .get_key (LLM_KV_ATTENTION_SLIDING_WINDOW ,hparams .n_swa , false); 36if (hparams .n_swa > 0 ) { 37hparams .swa_type = LLAMA_SWA_TYPE_STANDARD ; 38 39uint32_t swa_period = 4 ; 40ml .get_key_or_arr (LLM_KV_ATTENTION_SLIDING_WINDOW_PATTERN ,swa_period , false); 41hparams .set_swa_pattern (swa_period ,/*dense_first=*/ true);// XS.2: FULL at il%4==0 42 43// Per-layer-type RoPE: full layers use YaRN θ=500000 over 64 dims; 44// SWA layers use default RoPE θ=10000 over 128 dims. Base load_hparams 45// already reads ROPE_FREQ_BASE and ROPE_DIMENSION_COUNT into the 46// non-SWA fields; we explicitly pull the SWA mirrors here. 47hparams .rope_freq_base_train_swa = hparams .rope_freq_base_train ; 48hparams .rope_freq_scale_train_swa = 1.0f ;// SWA uses plain RoPE (no YaRN scaling); do NOT inherit full layers 1/factor 49ml .get_key (LLM_KV_ROPE_FREQ_BASE_SWA ,hparams .rope_freq_base_train_swa , false); 50ml .get_key (LLM_KV_ROPE_DIMENSION_COUNT_SWA ,hparams .n_rot_swa , false); 51 } 52 53// Default the expert gating function to SIGMOID when the key is absent 54// (matches the HF reference). 55if (hparams .expert_gating_func == LLAMA_EXPERT_GATING_FUNC_TYPE_NONE ) { 56hparams .expert_gating_func = LLAMA_EXPERT_GATING_FUNC_TYPE_SIGMOID ; 57 } 58 59switch (hparams .n_layer ()) { 60case 40 :type = LLM_TYPE_30B_A3B ;break ;// Laguna-XS.2 61case 48 :type = LLM_TYPE_118B_A8B ;break ;// Laguna-S.2 62case 70 :type = LLM_TYPE_230B_A10B ;break ;// Laguna-M.1 63default :type = LLM_TYPE_UNKNOWN ; 64 } 65} 66 67void llama_model_laguna::load_arch_tensors (llama_model_loader & ml ) { 68LLAMA_LOAD_LOCALS ; 69 70tok_embd = create_tensor (tn (LLM_TENSOR_TOKEN_EMBD ,"weight" ), {n_embd ,n_vocab },0 ); 71 72output_norm = create_tensor (tn (LLM_TENSOR_OUTPUT_NORM ,"weight" ), {n_embd },0 ); 73output = create_tensor (tn (LLM_TENSOR_OUTPUT ,"weight" ), {n_embd ,n_vocab },TENSOR_NOT_REQUIRED ); 74if (output == NULL ) { 75// tied embeddings fallback 76output = create_tensor (tn (LLM_TENSOR_TOKEN_EMBD ,"weight" ), {n_embd ,n_vocab },TENSOR_DUPLICATED ); 77 } 78 79const int64_t n_ff_exp = hparams .n_ff_exp (); 80const int64_t n_ff_shexp = hparams .n_ff_shexp ; 81 82for (int i = 0 ;i < n_layer ;++ i ) { 83auto & layer = layers [i ]; 84 85// Per-layer head count — Laguna varies n_head between full and SWA 86// layers (48 vs 64 in XS.2). KV head count is uniform. 87const int64_t n_head_il = hparams .n_head (i ); 88const int64_t n_head_kv_il = hparams .n_head_kv (i ); 89const int64_t n_embd_q_il = n_embd_head_k * n_head_il ; 90const int64_t n_embd_k_il = n_embd_head_k * n_head_kv_il ; 91const int64_t n_embd_v_il = n_embd_head_v * n_head_kv_il ; 92 93layer .attn_norm = create_tensor (tn (LLM_TENSOR_ATTN_NORM ,"weight" ,i ), {n_embd },0 ); 94 95create_tensor_qkv (layer ,i ,n_embd ,n_embd_q_il ,n_embd_k_il ,n_embd_v_il ,0 ); 96layer .wo = create_tensor (tn (LLM_TENSOR_ATTN_OUT ,"weight" ,i ), {n_embd_q_il ,n_embd },0 ); 97 98layer .attn_q_norm = create_tensor (tn (LLM_TENSOR_ATTN_Q_NORM ,"weight" ,i ), {n_embd_head_k },0 ); 99layer .attn_k_norm = create_tensor (tn (LLM_TENSOR_ATTN_K_NORM ,"weight" ,i ), {n_embd_head_k },0 ); 100 101// Attention output gate. XS.2 is per-head (g_proj -> n_head, one scalar 102// per head broadcast over head_dim at multiply time); M.1 is per-element 103// (g_proj -> n_head*head_dim, like afmoe). Detect from the stored tensor 104// shape so a single arch handles both; the graph mirrors this check. 105// Gate width selects per-head vs per-element. Real GGUFs always carry the 106// gate tensor, so read the width from it and require EXACTLY one of the two 107// valid widths -- never guess between them. Weightless fixtures 108// (test-llama-archs) have no gate tensor; fall back to the per-head layout so 109// the per-head reshape path is still exercised. 110const int64_t n_gate_per_head = n_head_il ; 111const int64_t n_gate_per_elem = n_embd_head_k * n_head_il ; 112const ggml_tensor * gate_meta = ml .get_tensor_meta (tn (LLM_TENSOR_ATTN_GATE ,"weight" ,i ).str ().c_str ()); 113int64_t n_gate_out ; 114if (gate_meta != nullptr ) { 115n_gate_out = gate_meta -> ne [1 ]; 116if (n_gate_out != n_gate_per_head && n_gate_out != n_gate_per_elem ) { 117GGML_ABORT ("Laguna: unexpected attention gate width %lld at layer %d " 118"(expected %lld per-head or %lld per-element)" , 119 (long long )n_gate_out ,i , (long long )n_gate_per_head , (long long )n_gate_per_elem ); 120 } 121 }else { 122n_gate_out = n_gate_per_head ; 123 } 124layer .wqkv_gate = create_tensor (tn (LLM_TENSOR_ATTN_GATE ,"weight" ,i ), {n_embd ,n_gate_out },0 ); 125 126layer .ffn_norm = create_tensor (tn (LLM_TENSOR_FFN_NORM ,"weight" ,i ), {n_embd },0 ); 127 128if ((uint32_t )i >=hparams .n_layer_dense_lead ) { 129// MoE layer 130layer .ffn_gate_inp = create_tensor (tn (LLM_TENSOR_FFN_GATE_INP ,"weight" ,i ), {n_embd ,n_expert },0 ); 131layer .ffn_exp_probs_b = create_tensor (tn (LLM_TENSOR_FFN_EXP_PROBS_B ,"bias" ,i ), {n_expert },0 ); 132 133layer .ffn_gate_exps = create_tensor (tn (LLM_TENSOR_FFN_GATE_EXPS ,"weight" ,i ), {n_embd ,n_ff_exp ,n_expert },0 ); 134layer .ffn_up_exps = create_tensor (tn (LLM_TENSOR_FFN_UP_EXPS ,"weight" ,i ), {n_embd ,n_ff_exp ,n_expert },0 ); 135layer .ffn_down_exps = create_tensor (tn (LLM_TENSOR_FFN_DOWN_EXPS ,"weight" ,i ), {n_ff_exp ,n_embd ,n_expert },0 ); 136 137// Always-on shared expert. 138layer .ffn_gate_shexp = create_tensor (tn (LLM_TENSOR_FFN_GATE_SHEXP ,"weight" ,i ), {n_embd ,n_ff_shexp },0 ); 139layer .ffn_up_shexp = create_tensor (tn (LLM_TENSOR_FFN_UP_SHEXP ,"weight" ,i ), {n_embd ,n_ff_shexp },0 ); 140layer .ffn_down_shexp = create_tensor (tn (LLM_TENSOR_FFN_DOWN_SHEXP ,"weight" ,i ), {n_ff_shexp ,n_embd },0 ); 141 }else { 142// Dense layer (the leading n_layer_dense_lead layers) 143layer .ffn_gate = create_tensor (tn (LLM_TENSOR_FFN_GATE ,"weight" ,i ), {n_embd ,n_ff },0 ); 144layer .ffn_up = create_tensor (tn (LLM_TENSOR_FFN_UP ,"weight" ,i ), {n_embd ,n_ff },0 ); 145layer .ffn_down = create_tensor (tn (LLM_TENSOR_FFN_DOWN ,"weight" ,i ), {n_ff ,n_embd },0 ); 146 } 147 } 148} 149 150std::unique_ptr < llm_graph_context > llama_model_laguna::build_arch_graph (const llm_graph_params & params )const { 151return std::make_unique < graph > (* this ,params ); 152} 153 154llama_model_laguna::graph::graph (const llama_model & model ,const llm_graph_params & params ) :llm_graph_context (params ) { 155const int64_t n_embd_head = hparams .n_embd_head_v (); 156GGML_ASSERT (n_embd_head == hparams .n_embd_head_k ()); 157 158ggml_tensor * cur ; 159ggml_tensor * inpL ; 160 161inpL = build_inp_embd (model .tok_embd ); 162// No MuP embedding scale (laguna omits this; afmoe scales by sqrt(hidden)). 163 164ggml_tensor * inp_pos = build_inp_pos (); 165// XS.2 is hybrid SWA -> interleaved-SWA KV input; M.1 is all-full -> plain 166// KV input. Pick the matching input (and build_attn overload) per swa_type. 167const bool has_swa = hparams .swa_type != LLAMA_SWA_TYPE_NONE ; 168llm_graph_input_attn_kv * inp_attn_kv = has_swa ?nullptr :build_attn_inp_kv (); 169llm_graph_input_attn_kv_iswa * inp_attn_iswa = has_swa ?build_attn_inp_kv_iswa () :nullptr ; 170ggml_tensor * inp_out_ids = build_inp_out_ids (); 171 172const float kq_scale = 1.0f /sqrtf (float (n_embd_head )); 173 174for (int il = 0 ;il < n_layer ;++ il ) { 175const bool is_swa_il = hparams .is_swa (il ); 176const int64_t n_head_il = hparams .n_head (il ); 177const int64_t n_head_kv_il = hparams .n_head_kv (il ); 178 179// Per-layer-type RoPE config. SWA layers run plain rope (no YaRN), 180// achieved by zeroing the YaRN ext/beta params for those layers. 181const int n_rot_l = is_swa_il ?hparams .n_rot_swa :n_rot ; 182const float freq_base_l = is_swa_il ?hparams .rope_freq_base_train_swa :freq_base ; 183const float freq_scale_l = is_swa_il ?hparams .rope_freq_scale_train_swa :freq_scale ; 184const float ext_factor_l = is_swa_il ?0.0f :ext_factor ; 185// YaRN magnitude scaling (mscale) is already handled by the framework: 186// llama_context pre-divides cparams.yarn_attn_factor by (1 + 0.1*ln(factor)) 187// to cancel ggml rope_yarn's internal mscale *= 1 + 0.1*ln(1/freq_scale). 188// Pass attn_factor straight through (like every other arch); SWA layers run 189// plain RoPE (ext_factor 0, no mscale) so force 1.0 there. 190const float attn_factor_l = is_swa_il ?1.0f :attn_factor ; 191const float beta_fast_l = is_swa_il ?0.0f :beta_fast ; 192const float beta_slow_l = is_swa_il ?0.0f :beta_slow ; 193const int n_ctx_orig_l = is_swa_il ?hparams .n_ctx_train :n_ctx_orig ; 194 195ggml_tensor * inpSA = inpL ; 196 197// Pre-norm 198cur = build_norm (inpL ,model .layers [il ].attn_norm ,NULL ,LLM_NORM_RMS ,il ); 199cb (cur ,"attn_norm" ,il ); 200 201// Self-attention 202 { 203ggml_tensor * attn_inp = cur ;// saved for the gate projection 204 205auto [Qcur ,Kcur ,Vcur ]= build_qkv (model .layers [il ],cur , 206n_embd_head ,n_head_il ,n_head_kv_il ,il ); 207 208// g_proj on the *pre-attention* hidden state (matches HF 209// reference: gate is computed from the same `hidden_states` 210// input as q/k/v, not from the attn output). 211ggml_tensor * gate = build_lora_mm (model .layers [il ].wqkv_gate ,attn_inp ); 212cb (gate ,"attn_gate_proj" ,il ); 213 214// QK RMSNorm at head_dim level (Qwen3 style) 215Qcur = build_norm (Qcur ,model .layers [il ].attn_q_norm ,NULL ,LLM_NORM_RMS ,il ); 216Kcur = build_norm (Kcur ,model .layers [il ].attn_k_norm ,NULL ,LLM_NORM_RMS ,il ); 217cb (Qcur ,"Qcur_normed" ,il ); 218cb (Kcur ,"Kcur_normed" ,il ); 219 220Qcur = ggml_rope_ext (ctx0 ,Qcur ,inp_pos ,nullptr , 221n_rot_l ,rope_type ,n_ctx_orig_l ,freq_base_l ,freq_scale_l , 222ext_factor_l ,attn_factor_l ,beta_fast_l ,beta_slow_l ); 223Kcur = ggml_rope_ext (ctx0 ,Kcur ,inp_pos ,nullptr , 224n_rot_l ,rope_type ,n_ctx_orig_l ,freq_base_l ,freq_scale_l , 225ext_factor_l ,attn_factor_l ,beta_fast_l ,beta_slow_l ); 226cb (Qcur ,"Qcur_rope" ,il ); 227cb (Kcur ,"Kcur_rope" ,il ); 228 229cur = has_swa 230 ?build_attn (inp_attn_iswa , 231NULL ,NULL ,NULL ,// o_proj deferred until after gating 232Qcur ,Kcur ,Vcur ,nullptr ,nullptr ,nullptr ,kq_scale ,il ) 233 :build_attn (inp_attn_kv , 234NULL ,NULL ,NULL , 235Qcur ,Kcur ,Vcur ,nullptr ,nullptr ,nullptr ,kq_scale ,il ); 236cb (cur ,"attn_out" ,il ); 237 238// Softplus output gate (the unary kernel computes softplus in fp32 239// and casts back). Two shapes, distinguished by the g_proj output 240// dim (matching the load-time detection): 241// XS.2 per-head : gate [n_head_il, n_tokens] -> reshape to 242// [1, n_head_il, n_tokens] and broadcast over 243// head_dim against cur [head_dim, n_head, T]. 244// M.1 per-element : gate [n_head_il*head_dim, n_tokens] spans the 245// full attention output -> direct ggml_mul. 246gate = ggml_softplus (ctx0 ,gate ); 247cb (gate ,"attn_gate_softplus" ,il ); 248 249const int64_t n_tokens = cur -> ne [1 ]; 250if (model .layers [il ].wqkv_gate -> ne [1 ]== n_head_il ) { 251cur = ggml_reshape_3d (ctx0 ,cur ,n_embd_head ,n_head_il ,n_tokens ); 252gate = ggml_reshape_3d (ctx0 ,gate ,1 ,n_head_il ,n_tokens ); 253cur = ggml_mul (ctx0 ,cur ,gate ); 254cur = ggml_reshape_2d (ctx0 ,cur ,n_embd_head * n_head_il ,n_tokens ); 255 }else { 256cur = ggml_mul (ctx0 ,cur ,gate ); 257 } 258cb (cur ,"attn_gated" ,il ); 259 260cur = build_lora_mm (model .layers [il ].wo ,cur ,model .layers [il ].wo_s ); 261cb (cur ,"attn_o_proj" ,il ); 262 } 263 264if (il == n_layer - 1 && inp_out_ids ) { 265cur = ggml_get_rows (ctx0 ,cur ,inp_out_ids ); 266inpSA = ggml_get_rows (ctx0 ,inpSA ,inp_out_ids ); 267 } 268 269ggml_tensor * ffn_inp = ggml_add (ctx0 ,cur ,inpSA ); 270cb (ffn_inp ,"ffn_inp" ,il ); 271 272// Pre-norm only (no post-attn norm) 273cur = build_norm (ffn_inp ,model .layers [il ].ffn_norm ,NULL ,LLM_NORM_RMS ,il ); 274cb (cur ,"ffn_norm" ,il ); 275 276if ((uint32_t )il >=hparams .n_layer_dense_lead ) { 277// MoE: sigmoid routing + score-correction bias + sum-norm + 278// routed_scaling_factor (all handled by build_moe_ffn). 279ggml_tensor * moe_out = build_moe_ffn (cur , 280model .layers [il ].ffn_gate_inp , 281model .layers [il ].ffn_up_exps , 282model .layers [il ].ffn_gate_exps , 283model .layers [il ].ffn_down_exps , 284model .layers [il ].ffn_exp_probs_b , 285n_expert ,n_expert_used , 286LLM_FFN_SILU , 287hparams .expert_weights_norm , 288hparams .expert_weights_scale , 289 (llama_expert_gating_func_type )hparams .expert_gating_func , 290il ); 291cb (moe_out ,"ffn_moe_out" ,il ); 292 293// Always-on shared expert, summed in parallel. 294ggml_tensor * ffn_shexp = build_ffn (cur , 295model .layers [il ].ffn_up_shexp ,NULL ,NULL , 296model .layers [il ].ffn_gate_shexp ,NULL ,NULL , 297model .layers [il ].ffn_down_shexp ,NULL ,NULL , 298NULL , 299LLM_FFN_SILU ,LLM_FFN_PAR ,il ); 300cb (ffn_shexp ,"ffn_shexp" ,il ); 301 302cur = ggml_add (ctx0 ,moe_out ,ffn_shexp ); 303cb (cur ,"ffn_out" ,il ); 304 }else { 305// Dense FFN for the leading n_layer_dense_lead layers (XS.2: 1, M.1: 3) 306cur = build_ffn (cur , 307model .layers [il ].ffn_up ,NULL ,NULL , 308model .layers [il ].ffn_gate ,NULL ,NULL , 309model .layers [il ].ffn_down ,NULL ,NULL , 310NULL , 311LLM_FFN_SILU ,LLM_FFN_PAR ,il ); 312cb (cur ,"ffn_out" ,il ); 313 } 314 315// No post-ffn norm 316cur = ggml_add (ctx0 ,cur ,ffn_inp ); 317cur = build_cvec (cur ,il ); 318cb (cur ,"l_out" ,il ); 319 320inpL = cur ; 321 } 322 323cur = inpL ; 324cur = build_norm (cur ,model .output_norm ,NULL ,LLM_NORM_RMS ,-1 ); 325cb (cur ,"result_norm" ,-1 ); 326res -> t_embd = cur ; 327 328cur = build_lora_mm (model .output ,cur ); 329cb (cur ,"result_output" ,-1 ); 330res -> t_logits = cur ; 331 332ggml_build_forward_expand (gf ,cur ); 333}