char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
97e4ca735
char/aliceai-t5-moe
1#include "models.h" 2 3void llama_model_gemma4::load_arch_hparams (llama_model_loader & ml ) { 4hparams .swa_type = LLAMA_SWA_TYPE_STANDARD ; 5ml .get_arr (LLM_KV_ATTENTION_SLIDING_WINDOW_PATTERN ,hparams .is_swa_impl ); 6 7uint32_t n_kv_shared_layers = 0 ; 8ml .get_key (LLM_KV_ATTENTION_SHARED_KV_LAYERS ,n_kv_shared_layers , false); 9 10hparams .n_layer_kv_from_start = hparams .n_layer_all - (int32_t )n_kv_shared_layers ; 11hparams .f_attention_scale = 1.0f ;// Gemma4 uses self.scaling = 1.0 (no pre-attn scaling) 12 13ml .get_key (LLM_KV_ROPE_FREQ_BASE_SWA ,hparams .rope_freq_base_train_swa , false); 14ml .get_key_or_arr (LLM_KV_EXPERT_FEED_FORWARD_LENGTH ,hparams .n_ff_exp_arr ,hparams .n_layer_all , false); 15ml .get_key (LLM_KV_ATTENTION_SLIDING_WINDOW ,hparams .n_swa ); 16ml .get_key (LLM_KV_ATTENTION_LAYERNORM_RMS_EPS ,hparams .f_norm_rms_eps ); 17ml .get_key (LLM_KV_EMBEDDING_LENGTH_PER_LAYER ,hparams .n_embd_per_layer ); 18ml .get_key (LLM_KV_ATTENTION_KEY_LENGTH_SWA ,hparams .n_embd_head_k_swa ); 19ml .get_key (LLM_KV_ATTENTION_VALUE_LENGTH_SWA ,hparams .n_embd_head_v_swa ); 20ml .get_key (LLM_KV_FINAL_LOGIT_SOFTCAPPING ,hparams .f_final_logit_softcapping , false); 21 22// when non_causal is set, the model will use bidirectional attention on SWA layers only, while dense layers will remain causal 23// ref: use_bidirectional_attention == "vision" in HF config 24// note: E2B/E4B are always causal, bypassing this logic 25hparams .non_causal_type = LLAMA_NON_CAUSAL_TYPE_SWA_ONLY ; 26 27switch (hparams .n_layer ()) { 28case 30 :type = LLM_TYPE_26B_A4B ;break ; 29case 35 :type = LLM_TYPE_E2B ;break ; 30case 42 :type = LLM_TYPE_E4B ;break ; 31case 60 :type = LLM_TYPE_31B ;break ; 32default :type = LLM_TYPE_UNKNOWN ; 33 } 34} 35 36void llama_model_gemma4::load_arch_tensors (llama_model_loader & ) { 37LLAMA_LOAD_LOCALS ; 38 39const uint32_t n_embd_per_layer = hparams .n_embd_per_layer ; 40const int64_t n_ff_exp = hparams .n_ff_exp (); 41 42if (n_embd_head_k != n_embd_head_v ) { 43throw std::runtime_error ("Gemma 4 requires n_embd_head_k == n_embd_head_v" ); 44 } 45if (hparams .n_embd_head_k_swa != hparams .n_embd_head_v_swa ) { 46throw std::runtime_error ("Gemma 4 requires n_embd_head_k_swa == n_embd_head_v_swa" ); 47 } 48 49output = create_tensor (tn (LLM_TENSOR_OUTPUT ,"weight" ), {n_embd ,n_vocab },TENSOR_NOT_REQUIRED ); 50// if output is NULL, init from the input tok embed 51if (output == NULL ) { 52output = create_tensor (tn (LLM_TENSOR_TOKEN_EMBD ,"weight" ), {n_embd ,n_vocab },TENSOR_DUPLICATED ); 53 } 54 55tok_embd = create_tensor (tn (LLM_TENSOR_TOKEN_EMBD ,"weight" ), {n_embd ,n_vocab },0 ); 56 57if (n_embd_per_layer > 0 ) { 58per_layer_tok_embd = create_tensor (tn (LLM_TENSOR_PER_LAYER_TOKEN_EMBD ,"weight" ), {n_embd_per_layer * n_layer ,n_vocab },TENSOR_READ_LAZY ); 59per_layer_model_proj = create_tensor (tn (LLM_TENSOR_PER_LAYER_MODEL_PROJ ,"weight" ,0 ), {n_embd ,n_embd_per_layer * n_layer },0 ); 60per_layer_proj_norm = create_tensor (tn (LLM_TENSOR_PER_LAYER_PROJ_NORM ,"weight" ,0 ), {n_embd_per_layer },0 ); 61 } 62 63output_norm = create_tensor (tn (LLM_TENSOR_OUTPUT_NORM ,"weight" ), {n_embd },0 ); 64 65int rope_freqs_flag = 0 ; 66 67for (int i = 0 ;i < n_layer ;++ i ) { 68auto & layer = layers [i ]; 69const int64_t n_head = hparams .n_head (i ); 70const int64_t n_embd_head = hparams .n_embd_head_k (i ); 71const int64_t n_embd_k = hparams .n_embd_k_gqa (i ); 72const int64_t n_embd_v = hparams .n_embd_v_gqa (i ); 73const int kv_flags = hparams .has_kv (i ) ?0 :TENSOR_NOT_REQUIRED ; 74 75layer .attn_norm = create_tensor (tn (LLM_TENSOR_ATTN_NORM ,"weight" ,i ), {n_embd },0 ); 76 77// note: use_alternative_attention (v_proj is optional, if it's not present, use k_proj) 78layer .wqkv = create_tensor (tn (LLM_TENSOR_ATTN_QKV ,"weight" ,i ), 79 {n_embd ,n_embd_head * n_head + n_embd_k + n_embd_v },TENSOR_NOT_REQUIRED |TENSOR_SKIP_IF_VIRTUAL ); 80if (!layer .wqkv ) { 81layer .wq = create_tensor (tn (LLM_TENSOR_ATTN_Q ,"weight" ,i ), {n_embd ,n_embd_head * n_head },0 ); 82layer .wk = create_tensor (tn (LLM_TENSOR_ATTN_K ,"weight" ,i ), {n_embd ,n_embd_k },kv_flags ); 83layer .wv = create_tensor (tn (LLM_TENSOR_ATTN_V ,"weight" ,i ), {n_embd ,n_embd_v },TENSOR_NOT_REQUIRED ); 84 } 85layer .wo = create_tensor (tn (LLM_TENSOR_ATTN_OUT ,"weight" ,i ), {n_embd_head * n_head ,n_embd },0 ); 86 87layer .attn_q_norm = create_tensor (tn (LLM_TENSOR_ATTN_Q_NORM ,"weight" ,i ), {n_embd_head },0 ); 88layer .attn_k_norm = create_tensor (tn (LLM_TENSOR_ATTN_K_NORM ,"weight" ,i ), {n_embd_head },kv_flags ); 89layer .attn_post_norm = create_tensor (tn (LLM_TENSOR_ATTN_POST_NORM ,"weight" ,i ), {n_embd },0 ); 90 91layer .out_scale = create_tensor (tn (LLM_TENSOR_LAYER_OUT_SCALE ,"weight" ,i ), {1u },TENSOR_NOT_REQUIRED ); 92 93if (!hparams .is_swa (i )) { 94// full_attention layers use rope_freqs for proportional rope 95layer .rope_freqs = create_tensor (tn (LLM_TENSOR_ROPE_FREQS ,"weight" ,i ), {n_embd_head /2 },rope_freqs_flag ); 96rope_freqs_flag = TENSOR_DUPLICATED ; 97 } 98 99// handle use_double_wide_mlp 100int64_t n_ff_cur = hparams .n_ff (i ); 101 102// for expert layers, we use normal FFN as shared expert (same as python code) 103layer .ffn_norm = create_tensor (tn (LLM_TENSOR_FFN_NORM ,"weight" ,i ), {n_embd },0 ); 104layer .ffn_gate = create_tensor (tn (LLM_TENSOR_FFN_GATE ,"weight" ,i ), {n_embd ,n_ff_cur },0 ); 105layer .ffn_up = create_tensor (tn (LLM_TENSOR_FFN_UP ,"weight" ,i ), {n_embd ,n_ff_cur },0 ); 106layer .ffn_down = create_tensor (tn (LLM_TENSOR_FFN_DOWN ,"weight" ,i ), {n_ff_cur ,n_embd },0 ); 107layer .ffn_post_norm = create_tensor (tn (LLM_TENSOR_FFN_POST_NORM ,"weight" ,i ), {n_embd },0 ); 108 109// MoE router 110layer .ffn_gate_inp = create_tensor (tn (LLM_TENSOR_FFN_GATE_INP ,"weight" ,i ), {n_embd ,n_expert },TENSOR_NOT_REQUIRED ); 111bool has_expert = layer .ffn_gate_inp != nullptr ; 112 113// norm 114if (has_expert ) { 115layer .ffn_gate_inp_s = create_tensor (tn (LLM_TENSOR_FFN_GATE_INP ,"scale" ,i ), {n_embd },0 ); 116 117layer .ffn_pre_norm_2 = create_tensor (tn (LLM_TENSOR_FFN_PRE_NORM_2 ,"weight" ,i ), {n_embd },0 ); 118layer .ffn_post_norm_1 = create_tensor (tn (LLM_TENSOR_FFN_POST_NORM_1 ,"weight" ,i ), {n_embd },0 ); 119layer .ffn_post_norm_2 = create_tensor (tn (LLM_TENSOR_FFN_POST_NORM_2 ,"weight" ,i ), {n_embd },0 ); 120 121// MoE FFN 122layer .ffn_gate_up_exps = create_tensor (tn (LLM_TENSOR_FFN_GATE_UP_EXPS ,"weight" ,i ), {n_embd ,n_ff_exp * 2 ,n_expert },TENSOR_NOT_REQUIRED ); 123 124if (layer .ffn_gate_up_exps == nullptr ) { 125layer .ffn_gate_exps = create_tensor (tn (LLM_TENSOR_FFN_GATE_EXPS ,"weight" ,i ), {n_embd ,n_ff_exp ,n_expert },0 ); 126layer .ffn_up_exps = create_tensor (tn (LLM_TENSOR_FFN_UP_EXPS ,"weight" ,i ), {n_embd ,n_ff_exp ,n_expert },0 ); 127 } 128 129layer .ffn_down_exps = create_tensor (tn (LLM_TENSOR_FFN_DOWN_EXPS ,"weight" ,i ), {n_ff_exp ,n_embd ,n_expert },0 ); 130 131// per-expert scale will be loaded as down_exps_s at the end of the current switch case 132 } 133 134// per-layer embeddings 135if (n_embd_per_layer > 0 ) { 136layer .per_layer_inp_gate = create_tensor (tn (LLM_TENSOR_PER_LAYER_INP_GATE ,"weight" ,i ), {n_embd ,n_embd_per_layer },0 ); 137layer .per_layer_proj = create_tensor (tn (LLM_TENSOR_PER_LAYER_PROJ ,"weight" ,i ), {n_embd_per_layer ,n_embd },0 ); 138layer .per_layer_post_norm = create_tensor (tn (LLM_TENSOR_PER_LAYER_POST_NORM ,"weight" ,i ), {n_embd },0 ); 139 } 140 } 141} 142 143std::unique_ptr < llm_graph_context > llama_model_gemma4::build_arch_graph (const llm_graph_params & params )const { 144return std::make_unique < graph > (* this ,params ); 145} 146 147// get 2D slice view from a 3D tensor, the idx corresponds to the 3rd dim 148static ggml_tensor * gemma4_view_2d_slice (ggml_context * ctx0 ,ggml_tensor * x ,int idx ) { 149GGML_ASSERT (idx < (int )x -> ne [2 ]); 150return ggml_view_2d (ctx0 ,x ,x -> ne [0 ],x -> ne [1 ],ggml_row_size (x -> type ,x -> ne [0 ]), 151idx * x -> ne [0 ]* x -> ne [1 ]* ggml_element_size (x )); 152} 153 154llama_model_gemma4::graph::graph (const llama_model & model ,const llm_graph_params & params ) : 155llm_graph_context (params ), 156model (model ), 157n_embd_per_layer (model .hparams .n_embd_per_layer ) { 158ggml_tensor * cur ; 159ggml_tensor * inpL ; 160 161inpL = build_inp_embd (model .tok_embd ); 162 163// important: do not normalize weights for raw embeddings input (i.e. encoded image emdeddings) 164inpL = ggml_scale (ctx0 ,inpL ,ubatch .token ?sqrtf (n_embd ) :1.0f ); 165cb (inpL ,"inp_scaled" ,-1 ); 166 167// inp_pos - contains the positions 168ggml_tensor * inp_pos = build_inp_pos (); 169 170// TODO: is causal == true correct? might need some changes 171auto * inp_attn = build_attn_inp_kv_iswa (); 172 173ggml_tensor * inp_out_ids = build_inp_out_ids (); 174 175ggml_tensor * inp_per_layer = nullptr ; 176if (model .per_layer_tok_embd ) { 177inp_per_layer = build_inp_per_layer (); 178ggml_build_forward_expand (gf ,inp_per_layer ); 179 180// inp_per_layer shape: [n_embd_per_layer, n_tokens, n_layer] 181inp_per_layer = project_per_layer_inputs (inpL ,inp_per_layer ); 182 } 183 184for (int il = 0 ;il < n_layer ;++ il ) { 185const int64_t n_embd_head = hparams .n_embd_head_k (il ); 186GGML_ASSERT (n_embd_head == hparams .n_embd_head_v (il )); 187 188const int64_t n_head = hparams .n_head (il ); 189const int64_t n_head_kv = hparams .n_head_kv (il ); 190 191const float freq_base_l = model .get_rope_freq_base (cparams ,il ); 192const float freq_scale_l = model .get_rope_freq_scale (cparams ,il ); 193const int n_rot_l = hparams .n_rot (il ); 194 195res -> t_layer_inp [il ]= inpL ; 196 197// norm 198cur = build_norm (inpL ,model .layers [il ].attn_norm ,nullptr ,LLM_NORM_RMS ,il ); 199cb (cur ,"attn_norm" ,il ); 200 201ggml_tensor * freq_factors = nullptr ; 202if (!hparams .is_swa (il )) { 203// full_attention layers use rope_freqs for proportional rope 204freq_factors = model .layers [il ].rope_freqs ; 205 } 206 207// Q projection (shared for both non-KV and KV layers) 208// this is to mirror Gemma4Attention in pytorch code 209ggml_tensor * qkv_fused = nullptr ; 210ggml_tensor * Qcur ; 211if (model .layers [il ].wqkv ) { 212qkv_fused = build_lora_mm (model .layers [il ].wqkv ,cur ,model .layers [il ].wqkv_s ); 213cb (qkv_fused ,"wqkv" ,il ); 214const int64_t q_dim = n_embd_head * n_head ; 215Qcur = ggml_cont (ctx0 ,ggml_view_2d (ctx0 ,qkv_fused ,q_dim ,n_tokens ,qkv_fused -> nb [1 ],0 )); 216 }else { 217Qcur = build_lora_mm (model .layers [il ].wq ,cur ,model .layers [il ].wq_s ); 218 } 219 { 220cb (Qcur ,"Qcur" ,il ); 221 222Qcur = ggml_reshape_3d (ctx0 ,Qcur ,n_embd_head ,n_head ,n_tokens ); 223 224Qcur = build_norm (Qcur ,model .layers [il ].attn_q_norm ,nullptr ,LLM_NORM_RMS ,il ); 225cb (Qcur ,"Qcur_normed" ,il ); 226 227Qcur = ggml_rope_ext (ctx0 ,Qcur ,inp_pos ,freq_factors ,n_rot_l ,rope_type ,n_ctx_orig ,freq_base_l ,freq_scale_l , 228ext_factor ,attn_factor ,beta_fast ,beta_slow ); 229cb (Qcur ,"Qcur_pos" ,il ); 230 } 231 232// self-attention 233if (hparams .has_kv (il )) { 234ggml_tensor * Kcur ; 235ggml_tensor * Vcur ; 236if (qkv_fused ) { 237const int64_t q_dim = n_embd_head * n_head ; 238const int64_t k_dim = n_embd_head * n_head_kv ; 239const int64_t v_dim = n_embd_head * n_head_kv ; 240const size_t esize = ggml_element_size (qkv_fused ); 241Kcur = ggml_cont (ctx0 ,ggml_view_2d (ctx0 ,qkv_fused ,k_dim ,n_tokens ,qkv_fused -> nb [1 ],q_dim * esize )); 242Vcur = ggml_cont (ctx0 ,ggml_view_2d (ctx0 ,qkv_fused ,v_dim ,n_tokens ,qkv_fused -> nb [1 ], (q_dim + k_dim )* esize )); 243 }else { 244Kcur = build_lora_mm (model .layers [il ].wk ,cur ,model .layers [il ].wk_s ); 245Vcur = model .layers [il ].wv 246 ?build_lora_mm (model .layers [il ].wv ,cur ,model .layers [il ].wv_s ) 247 :Kcur ;// if v_proj is not present, use Kcur as Vcur 248 } 249cb (Kcur ,"Kcur" ,il ); 250cb (Vcur ,"Vcur" ,il ); 251 252Kcur = ggml_reshape_3d (ctx0 ,Kcur ,n_embd_head ,n_head_kv ,n_tokens ); 253Vcur = ggml_reshape_3d (ctx0 ,Vcur ,n_embd_head ,n_head_kv ,n_tokens ); 254 255Kcur = build_norm (Kcur ,model .layers [il ].attn_k_norm ,nullptr ,LLM_NORM_RMS ,il ); 256Vcur = ggml_rms_norm (ctx0 ,Vcur ,hparams .f_norm_rms_eps ); 257 258cb (Kcur ,"Kcur_normed" ,il ); 259cb (Vcur ,"Vcur_normed" ,il ); 260 261Kcur = ggml_rope_ext (ctx0 ,Kcur ,inp_pos ,freq_factors ,n_rot_l ,rope_type ,n_ctx_orig ,freq_base_l ,freq_scale_l , 262ext_factor ,attn_factor ,beta_fast ,beta_slow ); 263 264cb (Kcur ,"Kcur_pos" ,il ); 265 266cur = build_attn (inp_attn ,model .layers [il ].wo , 267nullptr ,model .layers [il ].wo_s ,Qcur ,Kcur ,Vcur ,nullptr ,nullptr ,nullptr , 268hparams .f_attention_scale ,il ); 269 }else { 270// reuse KV cache of earlier layers 271cur = build_attn (inp_attn , 272model .layers [il ].wo ,nullptr ,model .layers [il ].wo_s , 273Qcur ,nullptr ,nullptr ,nullptr ,nullptr ,nullptr ,hparams .f_attention_scale ,il ); 274 } 275 276// TODO @ngxson : strip unused token right after the last KV layer to speed up prompt processing 277// keep all rows when extracting unmasked nextn embeddings (MTP target needs the hidden state for every token) 278if (il == n_layer - 1 && inp_out_ids && cparams .embeddings_nextn_masked ) { 279cur = ggml_get_rows (ctx0 ,cur ,inp_out_ids ); 280inpL = ggml_get_rows (ctx0 ,inpL ,inp_out_ids ); 281 } 282cur = build_norm (cur , 283model .layers [il ].attn_post_norm ,nullptr , 284LLM_NORM_RMS ,il ); 285cb (cur ,"attn_post_norm" ,il ); 286 287ggml_tensor * attn_out = ggml_add (ctx0 ,cur ,inpL ); 288cb (attn_out ,"attn_out" ,il ); 289 290// feed-forward network 291const bool is_moe_layer = model .layers [il ].ffn_gate_inp != nullptr ; 292if (is_moe_layer ) { 293// MLP (shared exp) 294ggml_tensor * cur_mlp = build_norm (attn_out , 295model .layers [il ].ffn_norm ,nullptr , 296LLM_NORM_RMS ,il ); 297cb (cur_mlp ,"ffn_norm_1" ,il ); 298 299cur_mlp = build_ffn (cur_mlp , 300model .layers [il ].ffn_up ,nullptr ,model .layers [il ].ffn_up_s , 301model .layers [il ].ffn_gate ,nullptr ,model .layers [il ].ffn_gate_s , 302model .layers [il ].ffn_down ,nullptr ,model .layers [il ].ffn_down_s , 303nullptr , 304LLM_FFN_GELU ,LLM_FFN_PAR ,il ); 305cur_mlp = build_norm (cur_mlp , 306model .layers [il ].ffn_post_norm_1 ,nullptr , 307LLM_NORM_RMS ,il ); 308cb (cur_mlp ,"ffn_mlp" ,il ); 309 310// Expert FFN 311ggml_tensor * cur_moe = build_norm (attn_out , 312model .layers [il ].ffn_pre_norm_2 ,nullptr , 313LLM_NORM_RMS ,il ); 314cb (cur_moe ,"ffn_norm_2" ,il ); 315 316// custom MoE logits calculation (router operates on attn_out, not cur) 317ggml_tensor * tmp = ggml_rms_norm (ctx0 ,attn_out ,hparams .f_norm_rms_eps ); 318tmp = ggml_scale (ctx0 ,tmp ,1.0f /sqrtf ((float )n_embd )); 319tmp = ggml_mul (ctx0 ,tmp ,model .layers [il ].ffn_gate_inp_s ); 320ggml_tensor * logits = build_lora_mm (model .layers [il ].ffn_gate_inp ,tmp );// [n_expert, n_tokens] 321cb (logits ,"ffn_moe_logits" ,il ); 322 323cur_moe = build_moe_ffn (cur_moe , 324nullptr ,// gate_inp 325model .layers [il ].ffn_up_exps , 326model .layers [il ].ffn_gate_exps , 327model .layers [il ].ffn_down_exps , 328nullptr ,// exp_probs_b (not used for gemma4) 329n_expert ,n_expert_used , 330LLM_FFN_GELU , true, 3311.0f , 332LLAMA_EXPERT_GATING_FUNC_TYPE_SOFTMAX , 333il ,logits , 334model .layers [il ].ffn_gate_up_exps , 335model .layers [il ].ffn_up_exps_s , 336model .layers [il ].ffn_gate_exps_s , 337model .layers [il ].ffn_down_exps_s ); 338cur_moe = build_norm (cur_moe , 339model .layers [il ].ffn_post_norm_2 ,nullptr , 340LLM_NORM_RMS ,il ); 341cb (cur_moe ,"ffn_moe" ,il ); 342 343cur = ggml_add (ctx0 ,cur_mlp ,cur_moe ); 344cb (cur ,"ffn_moe_combined" ,il ); 345 }else { 346cur = build_norm (attn_out , 347model .layers [il ].ffn_norm ,nullptr , 348LLM_NORM_RMS ,il ); 349cb (cur ,"ffn_norm" ,il ); 350 351cur = build_ffn (cur , 352model .layers [il ].ffn_up ,nullptr ,model .layers [il ].ffn_up_s , 353model .layers [il ].ffn_gate ,nullptr ,model .layers [il ].ffn_gate_s , 354model .layers [il ].ffn_down ,nullptr ,model .layers [il ].ffn_down_s , 355nullptr , 356LLM_FFN_GELU ,LLM_FFN_PAR ,il ); 357cb (cur ,"ffn_out" ,il ); 358 } 359cur = build_norm (cur , 360model .layers [il ].ffn_post_norm ,nullptr , 361LLM_NORM_RMS ,-1 ); 362cb (cur ,"ffn_post_norm" ,il ); 363 364// residual connection 365cur = ggml_add (ctx0 ,cur ,attn_out ); 366 367// per-layer embedding 368if (inp_per_layer ) { 369ggml_tensor * pe_in = cur ; 370cb (cur ,"pe_in" ,il ); 371 372cur = build_lora_mm (model .layers [il ].per_layer_inp_gate ,cur );// [n_embd_per_layer, n_tokens] 373cur = ggml_gelu (ctx0 ,cur ); 374 375ggml_tensor * inp_this_layer = gemma4_view_2d_slice (ctx0 ,inp_per_layer ,il );// [n_embd_per_layer, n_tokens] 376 377// TODO @ngxson : improve this 378if (il == n_layer - 1 && inp_out_ids && cparams .embeddings_nextn_masked ) { 379inp_this_layer = ggml_get_rows (ctx0 ,inp_this_layer ,inp_out_ids ); 380 } 381 382cur = ggml_mul (ctx0 ,cur ,inp_this_layer ); 383cur = build_lora_mm (model .layers [il ].per_layer_proj ,cur );// [n_embd, n_tokens] 384cur = build_norm (cur ,model .layers [il ].per_layer_post_norm ,nullptr ,LLM_NORM_RMS ,il ); 385cb (cur ,"per_layer_embd_out" ,il ); 386 387// residual connection 388cur = ggml_add (ctx0 ,pe_in ,cur ); 389 } 390 391// layer_scalar 392if (model .layers [il ].out_scale ) { 393cur = ggml_mul (ctx0 ,cur ,model .layers [il ].out_scale ); 394cb (cur ,"out_scaled" ,il ); 395 } 396 397cur = build_cvec (cur ,il ); 398cb (cur ,"l_out" ,il ); 399 400// input for next layer 401inpL = cur ; 402 } 403cur = inpL ; 404 405cur = build_norm (cur , 406model .output_norm ,nullptr , 407LLM_NORM_RMS ,-1 ); 408 409// Expose the post-output-norm hidden state (the LM-head input feature) so that 410// MTP draft contexts can read it via llama_get_embeddings_nextn_ith() as the 411// recurrent h input. This matches the reference (transformers/vLLM/SGLang), 412// which feeds the drafter the target's post-final-norm hidden state. 413cb (cur ,"h_nextn" ,-1 ); 414res -> t_h_nextn = cur ; 415 416if (!cparams .embeddings_nextn_masked && inp_out_ids ) { 417cur = ggml_get_rows (ctx0 ,cur ,inp_out_ids ); 418 } 419 420cb (cur ,"result_norm" ,-1 ); 421res -> t_embd = cur ; 422 423// lm_head 424cur = build_lora_mm (model .output ,cur ,model .output_s ); 425 426if (hparams .f_final_logit_softcapping ) { 427cur = ggml_scale (ctx0 ,cur ,1.0f /hparams .f_final_logit_softcapping ); 428cur = ggml_tanh (ctx0 ,cur ); 429cur = ggml_scale (ctx0 ,cur ,hparams .f_final_logit_softcapping ); 430 } 431 432cb (cur ,"result_output" ,-1 ); 433res -> t_logits = cur ; 434 435ggml_build_forward_expand (gf ,cur ); 436} 437 438// equivalent to get_per_layer_inputs() in python code 439// output shape: [n_embd_per_layer, n_layer, n_tokens] 440ggml_tensor * llama_model_gemma4::graph::build_inp_per_layer () { 441auto inp = std::make_unique < llm_graph_input_embd > (n_embd ); 442 443ggml_tensor * inp_per_layer ; 444float tok_embd_scale = sqrtf ((float )n_embd_per_layer ); 445if (ubatch .token ) { 446inp -> tokens = ggml_new_tensor_1d (ctx0 ,GGML_TYPE_I32 ,ubatch .n_tokens ); 447ggml_set_input (inp -> tokens ); 448res -> t_inp_tokens = inp -> tokens ; 449 450inp_per_layer = ggml_get_rows (ctx0 ,model .per_layer_tok_embd ,inp -> tokens ); 451inp_per_layer = ggml_reshape_3d (ctx0 ,inp_per_layer ,n_embd_per_layer ,n_layer ,n_tokens ); 452inp_per_layer = ggml_scale (ctx0 ,inp_per_layer ,tok_embd_scale ); 453cb (inp_per_layer ,"inp_per_layer_selected" ,-1 ); 454 455res -> add_input (std::move (inp )); 456 }else { 457// Multimodal embedding path: use padding token (ID=0) embedding 458// TODO: verify if this is the correct behavior in transformers implementation 459const int64_t embd_size = model .per_layer_tok_embd -> ne [0 ];// n_embd_per_layer * n_layer 460 461// Extract and dequantize padding token embedding (row 0) 462ggml_tensor * padding = ggml_view_1d (ctx0 ,model .per_layer_tok_embd ,embd_size ,0 ); 463inp_per_layer = ggml_cast (ctx0 ,padding ,GGML_TYPE_F32 ); 464inp_per_layer = ggml_scale (ctx0 ,inp_per_layer ,tok_embd_scale ); 465 466// Reshape to [n_embd_per_layer, n_layer, 1] 467inp_per_layer = ggml_reshape_3d (ctx0 ,inp_per_layer ,n_embd_per_layer ,n_layer ,1 ); 468cb (inp_per_layer ,"inp_per_layer_multimodal" ,-1 ); 469 } 470return inp_per_layer ; 471} 472 473// equivalent to project_per_layer_inputs() in python code 474// this calculates the per-layer inputs, so the final tensor shape will have n_layer as the last dim 475// inp_batch shape: [n_embd, n_tokens] 476// inp_per_layer shape: [n_embd_per_layer, n_layer, n_tokens] (from build_inp_per_layer) 477// output shape: [n_embd_per_layer, n_tokens, n_layer] 478ggml_tensor * llama_model_gemma4::graph::project_per_layer_inputs (ggml_tensor * inp_batch ,ggml_tensor * inp_per_layer ) { 479const float per_layer_projection_scale = 1.0f /sqrtf ((float )n_embd ); 480const float per_layer_input_scale = 1.0f /sqrtf (2.0f ); 481 482// note: this matrix multiplication will be performed in the input layer (i.e. on the CPU) 483ggml_tensor * per_layer_proj ; 484per_layer_proj = ggml_mul_mat (ctx0 ,model .per_layer_model_proj ,inp_batch ); 485per_layer_proj = ggml_scale (ctx0 ,per_layer_proj ,per_layer_projection_scale ); 486per_layer_proj = ggml_reshape_3d (ctx0 ,per_layer_proj ,n_embd_per_layer ,n_layer ,n_tokens ); 487 488per_layer_proj = build_norm (per_layer_proj ,model .per_layer_proj_norm ,nullptr ,LLM_NORM_RMS ,-1 ); 489cb (per_layer_proj ,"per_layer_proj" ,-1 ); 490 491inp_per_layer = ggml_add (ctx0 ,per_layer_proj ,inp_per_layer ); 492inp_per_layer = ggml_scale (ctx0 ,inp_per_layer ,per_layer_input_scale ); 493cb (inp_per_layer ,"inp_per_layer" ,-1 ); 494 495// permute to shape: [n_embd_per_layer, n_tokens, n_layer] 496inp_per_layer = ggml_cont (ctx0 ,ggml_permute (ctx0 ,inp_per_layer ,0 ,2 ,1 ,3 )); 497return inp_per_layer ; 498}