char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
3bcfeb700
char/aliceai-t5-moe
1#include "models.h" 2 3void llama_model_gemma3n::load_arch_hparams (llama_model_loader & ml ) { 4uint32_t swa_period = 5 ; 5ml .get_key_or_arr (LLM_KV_ATTENTION_SLIDING_WINDOW_PATTERN ,swa_period , false); 6hparams .swa_type = LLAMA_SWA_TYPE_STANDARD ; 7hparams .set_swa_pattern (swa_period ); 8 9hparams .n_layer_kv_from_start = 20 ; 10hparams .f_attention_scale = 1.0f ; 11 12ml .get_key (LLM_KV_ROPE_FREQ_BASE_SWA ,hparams .rope_freq_base_train_swa , false); 13ml .get_key (LLM_KV_ATTENTION_SLIDING_WINDOW ,hparams .n_swa ); 14ml .get_key (LLM_KV_ATTENTION_LAYERNORM_RMS_EPS ,hparams .f_norm_rms_eps ); 15 16switch (hparams .n_layer ()) { 17case 30 :type = LLM_TYPE_E2B ;break ; 18case 35 :type = LLM_TYPE_E4B ;break ; 19default :type = LLM_TYPE_UNKNOWN ; 20 } 21} 22 23void llama_model_gemma3n::load_arch_tensors (llama_model_loader & ) { 24LLAMA_LOAD_LOCALS ; 25 26const int64_t n_altup = hparams .n_altup ; 27const int64_t laurel_rank = hparams .laurel_rank ; 28const int64_t n_embd_altup = hparams .n_embd_altup ; 29 30output = create_tensor (tn (LLM_TENSOR_OUTPUT ,"weight" ), {n_embd ,n_vocab },TENSOR_NOT_REQUIRED ); 31// if output is NULL, init from the input tok embed 32if (output == NULL ) { 33output = create_tensor (tn (LLM_TENSOR_TOKEN_EMBD ,"weight" ), {n_embd ,n_vocab },TENSOR_DUPLICATED ); 34 } 35 36tok_embd = create_tensor (tn (LLM_TENSOR_TOKEN_EMBD ,"weight" ), {n_embd ,n_vocab },0 ); 37 38altup_proj = create_tensor (tn (LLM_TENSOR_ALTUP_PROJ ,"weight" ), {n_embd ,n_embd ,n_altup - 1 },0 ); 39altup_unembd_proj = create_tensor (tn (LLM_TENSOR_ALTUP_UNEMBD_PROJ ,"weight" ), {n_embd ,n_embd ,n_altup - 1 },0 ); 40 41per_layer_tok_embd = create_tensor (tn (LLM_TENSOR_PER_LAYER_TOKEN_EMBD ,"weight" ), {n_embd_altup * n_layer ,n_vocab },0 ); 42per_layer_model_proj = create_tensor (tn (LLM_TENSOR_PER_LAYER_MODEL_PROJ ,"weight" ,0 ), {n_embd ,n_embd_altup * n_layer },0 ); 43per_layer_proj_norm = create_tensor (tn (LLM_TENSOR_PER_LAYER_PROJ_NORM ,"weight" ,0 ), {n_embd_altup },0 ); 44 45output_norm = create_tensor (tn (LLM_TENSOR_OUTPUT_NORM ,"weight" ), {n_embd },0 ); 46 47for (int i = 0 ;i < n_layer ;++ i ) { 48auto & layer = layers [i ]; 49 50layer .attn_norm = create_tensor (tn (LLM_TENSOR_ATTN_NORM ,"weight" ,i ), {n_embd },0 ); 51 52create_tensor_qkv (layer ,i ,n_embd ,n_embd_head_k * n_head ,n_embd_k_gqa ,n_embd_v_gqa ,0 ); 53layer .wo = create_tensor (tn (LLM_TENSOR_ATTN_OUT ,"weight" ,i ), {n_embd_head_k * n_head ,n_embd },0 ); 54 55layer .attn_q_norm = create_tensor (tn (LLM_TENSOR_ATTN_Q_NORM ,"weight" ,i ), {n_embd_head_k },0 ); 56layer .attn_k_norm = create_tensor (tn (LLM_TENSOR_ATTN_K_NORM ,"weight" ,i ), {n_embd_head_k },0 ); 57layer .attn_post_norm = create_tensor (tn (LLM_TENSOR_ATTN_POST_NORM ,"weight" ,i ), {n_embd },0 ); 58 59layer .ffn_norm = create_tensor (tn (LLM_TENSOR_FFN_NORM ,"weight" ,i ), {n_embd },0 ); 60layer .ffn_gate = create_tensor (tn (LLM_TENSOR_FFN_GATE ,"weight" ,i ), {n_embd ,n_ff },0 ); 61layer .ffn_up = create_tensor (tn (LLM_TENSOR_FFN_UP ,"weight" ,i ), {n_embd ,n_ff },0 ); 62layer .ffn_down = create_tensor (tn (LLM_TENSOR_FFN_DOWN ,"weight" ,i ), {n_ff ,n_embd },0 ); 63layer .ffn_post_norm = create_tensor (tn (LLM_TENSOR_FFN_POST_NORM ,"weight" ,i ), {n_embd },0 ); 64 65// altup & laurel 66layer .per_layer_inp_gate = create_tensor (tn (LLM_TENSOR_PER_LAYER_INP_GATE ,"weight" ,i ), {n_embd ,n_embd_altup },0 ); 67layer .per_layer_proj = create_tensor (tn (LLM_TENSOR_PER_LAYER_PROJ ,"weight" ,i ), {n_embd_altup ,n_embd },0 ); 68layer .per_layer_post_norm = create_tensor (tn (LLM_TENSOR_PER_LAYER_POST_NORM ,"weight" ,i ), {n_embd },0 ); 69layer .altup_correct_coef = create_tensor (tn (LLM_TENSOR_ALTUP_CORRECT_COEF ,"weight" ,i ), {n_altup ,n_altup },0 ); 70layer .altup_correct_scale = create_tensor (tn (LLM_TENSOR_ALTUP_CORRECT_SCALE ,"weight" ,i ), {n_embd },0 ); 71layer .altup_predict_coef = create_tensor (tn (LLM_TENSOR_ALTUP_PREDICT_COEF ,"weight" ,i ), {n_altup ,n_altup * n_altup },0 ); 72layer .altup_router = create_tensor (tn (LLM_TENSOR_ALTUP_ROUTER ,"weight" ,i ), {n_embd ,n_altup },0 ); 73layer .altup_router_norm = create_tensor (tn (LLM_TENSOR_ALTUP_ROUTER_NORM ,"weight" ,i ), {n_embd },0 ); 74layer .laurel_l = create_tensor (tn (LLM_TENSOR_LAUREL_L ,"weight" ,i ), {n_embd ,laurel_rank },0 ); 75layer .laurel_r = create_tensor (tn (LLM_TENSOR_LAUREL_R ,"weight" ,i ), {laurel_rank ,n_embd },0 ); 76layer .laurel_post_norm = create_tensor (tn (LLM_TENSOR_LAUREL_POST_NORM ,"weight" ,i ), {n_embd },0 ); 77 } 78} 79 80std::unique_ptr < llm_graph_context > llama_model_gemma3n::build_arch_graph (const llm_graph_params & params )const { 81return std::make_unique < graph > (* this ,params ); 82} 83 84// get 2D slice view from a 3D tensor, the idx corresponds to the 3rd dim 85static ggml_tensor * gemma3n_view_2d_slice (ggml_context * ctx0 ,ggml_tensor * x ,int idx ) { 86GGML_ASSERT (idx < (int )x -> ne [2 ]); 87return ggml_view_2d (ctx0 ,x ,x -> ne [0 ],x -> ne [1 ],ggml_row_size (x -> type ,x -> ne [0 ]), 88idx * x -> ne [0 ]* x -> ne [1 ]* ggml_element_size (x )); 89} 90 91llama_model_gemma3n::graph::graph (const llama_model & model ,const llm_graph_params & params ) : 92llm_graph_context (params ), 93model (model ), 94n_embd_head (model .hparams .n_embd_head_k ()), 95n_embd_altup (model .hparams .n_embd_altup ), 96n_altup (model .hparams .n_altup ), 97i_altup_act (model .hparams .i_altup_act ) { 98ggml_tensor * cur ; 99ggml_tensor * inpL ; 100 101inpL = build_inp_embd (model .tok_embd ); 102 103// important: do not normalize weights for raw embeddings input (i.e. encoded image embeddings) 104inpL = ggml_scale (ctx0 ,inpL ,ubatch .token ?sqrtf (n_embd ) :1.0f ); 105cb (inpL ,"inp_scaled" ,-1 ); 106 107// inp_pos - contains the positions 108ggml_tensor * inp_pos = build_inp_pos (); 109 110// TODO: is causal == true correct? might need some changes 111auto * inp_attn = build_attn_inp_kv_iswa (); 112 113ggml_tensor * inp_per_layer = build_inp_per_layer (); 114ggml_build_forward_expand (gf ,inp_per_layer ); 115 116// inp_per_layer now has shape: [n_embd_altup, n_tokens, n_layer] 117inp_per_layer = project_per_layer_inputs (inpL ,inp_per_layer ); 118 119// inpL now has only 1 altup, project it to the rest of the altups 120// these "added" altups will be concat to the last dim of inpL 121 { 122ggml_tensor * target_magnitude = calc_magnitude (inpL ); 123ggml_tensor * inp_repeated = ggml_repeat_4d (ctx0 ,inpL ,n_embd ,n_tokens ,n_altup - 1 ,1 ); 124ggml_tensor * altup_added = 125ggml_mul_mat (ctx0 ,model .altup_proj ,inp_repeated );// shape: [n_embd, n_tokens, n_altup - 1] 126ggml_tensor * new_magnitude = calc_magnitude (altup_added ); 127altup_added = ggml_div (ctx0 ,ggml_mul (ctx0 ,altup_added ,target_magnitude ),new_magnitude ); 128inpL = ggml_concat (ctx0 ,inpL ,altup_added ,2 );// shape: [n_embd, n_tokens, n_altup] 129cb (inpL ,"inp_stacked" ,-1 ); 130 } 131// inpL now has shape: [n_embd, n_tokens, n_altup] 132 133for (int il = 0 ;il < n_layer ;++ il ) { 134// this block is made to be closely resemble Gemma3p5DecoderLayer on python code 135const float freq_base_l = model .get_rope_freq_base (cparams ,il ); 136const float freq_scale_l = model .get_rope_freq_scale (cparams ,il ); 137 138ggml_tensor * cur = inpL ;// [n_embd, n_tokens, n_altup] 139ggml_tensor * predictions = altup_predict (cur ,il );// [n_embd, n_tokens, n_altup] 140 141// predicted value will go through self-attention and laurel 142ggml_tensor * active_prediction = gemma3n_view_2d_slice (ctx0 ,predictions ,i_altup_act );// [n_embd, n_tokens] 143cur = active_prediction ; 144cb (cur ,"active_prediction" ,il ); 145 146// norm 147cur = build_norm (cur ,model .layers [il ].attn_norm ,NULL ,LLM_NORM_RMS ,il ); 148cb (cur ,"attn_norm" ,il ); 149 150// laurel 151ggml_tensor * laurel_out = laurel (cur ,il );// [n_embd, n_tokens] 152 153// self-attention 154if (hparams .has_kv (il )) { 155auto [Qcur ,Kcur ,Vcur ]= build_qkv (model .layers [il ],cur ,n_embd_head ,n_head ,n_head_kv ,il ); 156 157Qcur = build_norm (Qcur ,model .layers [il ].attn_q_norm ,NULL ,LLM_NORM_RMS ,il ); 158Kcur = build_norm (Kcur ,model .layers [il ].attn_k_norm ,NULL ,LLM_NORM_RMS ,il ); 159Vcur = ggml_rms_norm (ctx0 ,Vcur ,hparams .f_norm_rms_eps ); 160 161cb (Qcur ,"Qcur_normed" ,il ); 162cb (Kcur ,"Kcur_normed" ,il ); 163cb (Vcur ,"Vcur_normed" ,il ); 164 165Qcur = ggml_rope_ext (ctx0 ,Qcur ,inp_pos ,nullptr ,n_rot ,rope_type ,n_ctx_orig ,freq_base_l ,freq_scale_l , 166ext_factor ,attn_factor ,beta_fast ,beta_slow ); 167 168Kcur = ggml_rope_ext (ctx0 ,Kcur ,inp_pos ,nullptr ,n_rot ,rope_type ,n_ctx_orig ,freq_base_l ,freq_scale_l , 169ext_factor ,attn_factor ,beta_fast ,beta_slow ); 170 171cb (Qcur ,"Qcur_pos" ,il ); 172cb (Kcur ,"Kcur_pos" ,il ); 173 174cur = build_attn (inp_attn ,model .layers [il ].wo , 175NULL ,model .layers [il ].wo_s ,Qcur ,Kcur ,Vcur ,nullptr ,nullptr ,nullptr , 176hparams .f_attention_scale ,il ); 177 }else { 178// reuse KV cache of earlier layers 179ggml_tensor * Qcur ; 180if (model .layers [il ].wqkv ) { 181ggml_tensor * qkv = build_lora_mm (model .layers [il ].wqkv ,cur ); 182const int64_t q_dim = n_embd_head * n_head ; 183Qcur = ggml_cont (ctx0 ,ggml_view_2d (ctx0 ,qkv ,q_dim ,n_tokens ,qkv -> nb [1 ],0 )); 184 }else { 185Qcur = build_lora_mm (model .layers [il ].wq ,cur ); 186 } 187cb (Qcur ,"Qcur" ,il ); 188Qcur = ggml_reshape_3d (ctx0 ,Qcur ,n_embd_head ,n_head ,n_tokens ); 189 190Qcur = build_norm (Qcur ,model .layers [il ].attn_q_norm ,NULL ,LLM_NORM_RMS ,il ); 191cb (Qcur ,"Qcur_normed" ,il ); 192 193Qcur = ggml_rope_ext (ctx0 ,Qcur ,inp_pos ,nullptr ,n_rot ,rope_type ,n_ctx_orig ,freq_base_l ,freq_scale_l , 194ext_factor ,attn_factor ,beta_fast ,beta_slow ); 195cb (Qcur ,"Qcur_pos" ,il ); 196 197cur = build_attn (inp_attn , 198model .layers [il ].wo ,NULL ,model .layers [il ].wo_s , 199Qcur ,nullptr ,nullptr ,nullptr ,nullptr ,nullptr ,hparams .f_attention_scale ,il ); 200 } 201cur = build_norm (cur ,model .layers [il ].attn_post_norm ,NULL ,LLM_NORM_RMS ,il ); 202cb (cur ,"attn_post_norm" ,il ); 203 204cur = ggml_add (ctx0 ,cur ,active_prediction );// [n_embd, n_tokens] 205cb (cur ,"attn_gated" ,il ); 206 207ggml_tensor * attn_laurel = ggml_scale (ctx0 ,ggml_add (ctx0 ,cur ,laurel_out ), 2081.0f /sqrtf (2.0f ));// [n_embd, n_tokens] 209cb (attn_laurel ,"attn_laurel" ,il ); 210 211cur = build_norm (attn_laurel ,model .layers [il ].ffn_norm ,NULL ,LLM_NORM_RMS ,il ); 212cb (cur ,"ffn_norm" ,il ); 213 214// feed-forward network 215 { 216ggml_tensor * up_proj = build_lora_mm (model .layers [il ].ffn_up ,cur ); 217ggml_tensor * gate_proj = build_lora_mm (model .layers [il ].ffn_gate ,cur ); 218 219if (il < n_layer_sparsity ) { 220// apply activation sparsity 221gate_proj = gaussian_topk (gate_proj ); 222 } 223gate_proj = ggml_gelu (ctx0 ,gate_proj ); 224 225cur = ggml_mul (ctx0 ,up_proj ,gate_proj ); 226cur = build_lora_mm (model .layers [il ].ffn_down ,cur ); 227cb (cur ,"ffn_out" ,il ); 228 } 229cur = build_norm (cur ,model .layers [il ].ffn_post_norm ,NULL ,LLM_NORM_RMS ,-1 ); 230cb (cur ,"ffn_post_norm" ,il ); 231 232ggml_tensor * attn_ffw_laurel_gated = ggml_add (ctx0 ,cur ,attn_laurel );// [n_embd, n_tokens] 233cb (attn_ffw_laurel_gated ,"attn_ffw_laurel_gated" ,il ); 234 235ggml_tensor * corrected = altup_correct (predictions ,attn_ffw_laurel_gated ,il );// [n_embd, n_tokens, n_altup] 236 237ggml_tensor * first_prediction ;// [n_embd, n_tokens] 238 { 239first_prediction = gemma3n_view_2d_slice (ctx0 ,corrected ,i_altup_act );// [n_embd, n_tokens] 240first_prediction = ggml_mul (ctx0 ,first_prediction ,model .layers [il ].altup_correct_scale ); 241first_prediction = build_lora_mm (model .layers [il ].per_layer_inp_gate ,first_prediction ); 242first_prediction = ggml_gelu (ctx0 ,first_prediction );// [n_embd_altup, n_tokens] 243cb (first_prediction ,"first_prediction_gated" ,il ); 244 245ggml_tensor * inp_this_layer = gemma3n_view_2d_slice (ctx0 ,inp_per_layer ,il );// [n_embd_altup, n_tokens] 246first_prediction = ggml_mul (ctx0 ,first_prediction ,inp_this_layer );// [n_embd_altup, n_tokens] 247cb (first_prediction ,"first_prediction_scaled" ,il ); 248 249first_prediction = build_lora_mm (model .layers [il ].per_layer_proj ,first_prediction );// [n_embd, n_tokens] 250first_prediction = 251build_norm (first_prediction ,model .layers [il ].per_layer_post_norm ,NULL ,LLM_NORM_RMS ,il ); 252cb (first_prediction ,"first_prediction_out" ,il ); 253 } 254// equivalent to python code: corrected_predictions[1:] += first_prediction 255 { 256ggml_tensor * slice_first = gemma3n_view_2d_slice (ctx0 ,corrected ,0 ); 257ggml_tensor * slice_rest = ggml_view_3d ( 258ctx0 ,corrected ,n_embd ,n_tokens ,n_altup - 1 ,ggml_row_size (corrected -> type ,n_embd ), 259ggml_row_size (corrected -> type ,n_embd * n_tokens ),n_embd * n_tokens * ggml_element_size (corrected )); 260ggml_tensor * tmp = ggml_add (ctx0 ,slice_rest ,first_prediction );// [n_embd, n_tokens, n_altup - 1] 261corrected = ggml_concat (ctx0 ,slice_first ,tmp ,2 );// [n_embd, n_tokens, n_altup] 262 } 263cur = corrected ;// [n_embd, n_tokens, n_altup] 264cur = build_cvec (cur ,il ); 265cb (cur ,"l_out" ,il ); 266 267// input for next layer 268inpL = cur ; 269 } 270cur = inpL ;// [n_embd, n_tokens, n_altup] 271 272// cur now has multiple altup(s), we want to merge them back to 1 altup 273 { 274ggml_tensor * target_magnitude = calc_magnitude (gemma3n_view_2d_slice (ctx0 ,cur ,i_altup_act ));// [n_embd, n_tokens] 275// do a view to skip the first slice (active altup) 276ggml_tensor * alt_slice = 277ggml_view_3d (ctx0 ,cur ,n_embd ,n_tokens ,n_altup - 1 ,ggml_row_size (cur -> type ,n_embd ), 278ggml_row_size (cur -> type ,n_embd * n_tokens ),n_embd * n_tokens * ggml_element_size (cur )); 279ggml_tensor * altup_unembd = 280ggml_mul_mat (ctx0 ,model .altup_unembd_proj ,alt_slice );// shape: [n_embd, n_tokens, n_altup - 1] 281ggml_tensor * new_magnitude = calc_magnitude (altup_unembd ); 282altup_unembd = ggml_div (ctx0 ,ggml_mul (ctx0 ,altup_unembd ,target_magnitude ),new_magnitude ); 283cb (altup_unembd ,"altup_unembd" ,-1 ); 284 285// equivalent to torch.mean(hidden_states, dim=0) 286cur = gemma3n_view_2d_slice (ctx0 ,cur ,0 );// [n_embd, n_tokens] 287for (int i = 0 ;i < n_altup - 1 ;++ i ) { 288cur = ggml_add (ctx0 ,cur ,gemma3n_view_2d_slice (ctx0 ,altup_unembd ,i )); 289 } 290cur = ggml_scale (ctx0 ,cur ,1.0f /float (n_altup ));// [n_embd, n_tokens] 291cb (cur ,"unembd_merged" ,-1 ); 292 } 293// cur now has shape: [n_embd, n_tokens] 294 295// TODO: move this to right after the last KV layer 296 { 297// skip computing output for unused tokens 298ggml_tensor * inp_out_ids = build_inp_out_ids (); 299cur = ggml_get_rows (ctx0 ,cur ,inp_out_ids ); 300 } 301cur = build_norm (cur ,model .output_norm ,NULL ,LLM_NORM_RMS ,-1 ); 302 303cb (cur ,"result_norm" ,-1 ); 304res -> t_embd = cur ; 305 306cur = build_lora_mm (model .output ,cur ,model .output_s ); 307 308 { 309// final logit soft-capping 310cur = ggml_scale (ctx0 ,cur ,1.0f /hparams .f_final_logit_softcapping ); 311cur = ggml_tanh (ctx0 ,cur ); 312cur = ggml_scale (ctx0 ,cur ,hparams .f_final_logit_softcapping ); 313 } 314cb (cur ,"result_output" ,-1 ); 315res -> t_logits = cur ; 316 317ggml_build_forward_expand (gf ,cur ); 318} 319 320ggml_tensor * llama_model_gemma3n::graph::calc_magnitude (ggml_tensor * x ) { 321return ggml_sqrt (ctx0 ,ggml_sum_rows (ctx0 ,ggml_sqr (ctx0 ,x ))); 322} 323 324// equivalent to get_per_layer_inputs() in python code 325// output shape: [n_embd_altup, n_layer, n_tokens] 326ggml_tensor * llama_model_gemma3n::graph::build_inp_per_layer () { 327auto inp = std::make_unique < llm_graph_input_embd > (n_embd ); 328ggml_tensor * inp_per_layer ; 329float tok_embd_scale = sqrtf ((float )n_embd_altup ); 330if (ubatch .token ) { 331inp -> tokens = ggml_new_tensor_1d (ctx0 ,GGML_TYPE_I32 ,ubatch .n_tokens ); 332ggml_set_input (inp -> tokens ); 333res -> t_inp_tokens = inp -> tokens ; 334inp_per_layer = ggml_get_rows (ctx0 ,model .per_layer_tok_embd ,inp -> tokens ); 335inp_per_layer = ggml_reshape_3d (ctx0 ,inp_per_layer ,n_embd_altup ,n_layer ,n_tokens ); 336inp_per_layer = ggml_scale (ctx0 ,inp_per_layer ,tok_embd_scale ); 337cb (inp_per_layer ,"inp_per_layer_selected" ,-1 ); 338res -> add_input (std::move (inp )); 339 }else { 340// Multimodal embedding path: use padding token (ID=0) embedding 341// TODO: verify if this is the correct behavior in transformers implementation 342const int64_t embd_size = model .per_layer_tok_embd -> ne [0 ];// n_embd_altup * n_layer 343 344// Extract and dequantize padding token embedding (row 0) 345ggml_tensor * padding = ggml_view_1d (ctx0 ,model .per_layer_tok_embd ,embd_size ,0 ); 346inp_per_layer = ggml_cast (ctx0 ,padding ,GGML_TYPE_F32 ); 347inp_per_layer = ggml_scale (ctx0 ,inp_per_layer ,tok_embd_scale ); 348 349// Reshape to [n_embd_altup, n_layer, 1] 350inp_per_layer = ggml_reshape_3d (ctx0 ,inp_per_layer ,n_embd_altup ,n_layer ,1 ); 351cb (inp_per_layer ,"inp_per_layer_multimodal" ,-1 ); 352 } 353return inp_per_layer ; 354} 355 356// equivalent to project_per_layer_inputs() in python code 357// this calculates the per-layer inputs, so the final tensor shape will have n_layer as the last dim 358// output shape: [n_embd_altup, n_tokens, n_layer] 359ggml_tensor * llama_model_gemma3n::graph::project_per_layer_inputs (ggml_tensor * inp_batch ,ggml_tensor * inp_per_layer ) { 360const float per_layer_projection_scale = 1.0f /sqrtf ((float )n_embd ); 361const float per_layer_input_scale = 1.0f /sqrtf (2.0f ); 362 363ggml_tensor * per_layer_proj ; 364per_layer_proj = ggml_mul_mat (ctx0 ,model .per_layer_model_proj ,inp_batch ); 365per_layer_proj = ggml_scale (ctx0 ,per_layer_proj ,per_layer_projection_scale ); 366per_layer_proj = ggml_reshape_3d (ctx0 ,per_layer_proj ,n_embd_altup ,n_layer ,n_tokens ); 367 368per_layer_proj = build_norm (per_layer_proj ,model .per_layer_proj_norm ,NULL ,LLM_NORM_RMS ,-1 ); 369cb (per_layer_proj ,"per_layer_proj" ,-1 ); 370 371inp_per_layer = ggml_add (ctx0 ,per_layer_proj ,inp_per_layer ); 372inp_per_layer = ggml_scale (ctx0 ,inp_per_layer ,per_layer_input_scale ); 373cb (inp_per_layer ,"inp_per_layer" ,-1 ); 374 375// permute to shape: [n_embd_altup, n_tokens, n_layer] 376inp_per_layer = ggml_cont (ctx0 ,ggml_permute (ctx0 ,inp_per_layer ,0 ,2 ,1 ,3 )); 377return inp_per_layer ; 378} 379 380// input cur shape: [n_altup, n_tokens] 381// output shape: [n_altup, n_tokens] 382ggml_tensor * llama_model_gemma3n::graph::laurel (ggml_tensor * cur ,int il ) { 383ggml_tensor * tmp = cur ; 384tmp = build_lora_mm (model .layers [il ].laurel_l ,tmp ); 385tmp = build_lora_mm (model .layers [il ].laurel_r ,tmp ); 386tmp = build_norm (tmp ,model .layers [il ].laurel_post_norm ,NULL ,LLM_NORM_RMS ,il ); 387tmp = ggml_add (ctx0 ,tmp ,cur ); 388cb (tmp ,"laurel_out" ,il ); 389return tmp ; 390} 391 392// input x shape: [n_embd, n_tokens] 393// output shape: [n_embd, n_tokens] 394ggml_tensor * llama_model_gemma3n::graph::gaussian_topk (ggml_tensor * x ) { 395ggml_tensor * mean = ggml_mean (ctx0 ,x ); 396ggml_tensor * std = ggml_sqrt (ctx0 ,ggml_scale (ctx0 ,ggml_sum_rows (ctx0 ,ggml_sqr (ctx0 ,ggml_sub (ctx0 ,x ,mean ))), 3971.0f / (float ) (x -> ne [0 ]- 1 ))); 398ggml_tensor * cutoff_x = ggml_add (ctx0 ,mean ,ggml_scale (ctx0 ,std ,f_sparsity_std_mul )); 399return ggml_relu (ctx0 ,ggml_sub (ctx0 ,x ,cutoff_x )); 400} 401 402// 403// altup functions 404// 405 406// equivalent to compute_router_modalities() in python code 407// input x shape: [n_embd, n_tokens] 408// output shape: [n_altup, n_tokens] 409ggml_tensor * llama_model_gemma3n::graph::altup_compute_router_modalities (ggml_tensor * x ,int il ) { 410ggml_tensor * router_inputs = build_norm (x ,model .layers [il ].altup_router_norm ,NULL ,LLM_NORM_RMS ,il ); 411 412// router_input_scale 413router_inputs = ggml_scale (ctx0 ,router_inputs ,1.0f / (float )n_embd ); 414 415ggml_tensor * output = ggml_mul_mat (ctx0 ,model .layers [il ].altup_router ,router_inputs ); 416return ggml_tanh (ctx0 ,output );// [n_altup, n_tokens] 417} 418 419// input cur shape: [n_embd, n_tokens, n_altup] 420// output shape: [n_embd, n_tokens, n_altup] 421ggml_tensor * llama_model_gemma3n::graph::altup_predict (ggml_tensor * cur ,int il ) { 422ggml_tensor * activated = gemma3n_view_2d_slice (ctx0 ,cur ,i_altup_act );// [n_embd, n_tokens] 423ggml_tensor * modalities = altup_compute_router_modalities (activated ,il );// [n_altup, n_tokens] 424cb (modalities ,"modalities" ,il ); 425 426ggml_tensor * all_coefs = build_lora_mm (model .layers [il ].altup_predict_coef ,modalities ); 427cb (all_coefs ,"all_coefs" ,il ); 428// first dim now having n_altup^2 elements, we reshape it to 2D (so we end up with 3D tensor) 429all_coefs = ggml_reshape_3d (ctx0 ,all_coefs ,n_altup ,n_altup ,n_tokens ); 430 431// permute to [n_altup, n_embd, n_tokens] 432ggml_tensor * cur_permuted = ggml_cont (ctx0 ,ggml_permute (ctx0 ,cur ,1 ,2 ,0 ,3 )); 433ggml_tensor * predictions = ggml_mul_mat (ctx0 ,cur_permuted ,all_coefs );// [n_altup, n_embd, n_tokens] 434 435// final shape must be the same as cur: [n_embd, n_tokens, n_altup] 436predictions = ggml_cont (ctx0 ,ggml_permute (ctx0 ,predictions ,0 ,2 ,1 ,3 )); 437predictions = ggml_add (ctx0 ,predictions ,cur ); 438cb (predictions ,"predictions" ,il ); 439 440return predictions ; 441} 442 443// input predictions shape: [n_embd, n_tokens, n_altup] 444// input activated shape: [n_embd, n_tokens] 445// output shape: [n_embd, n_tokens, n_altup] 446ggml_tensor * llama_model_gemma3n::graph::altup_correct (ggml_tensor * predictions ,ggml_tensor * activated ,int il ) { 447ggml_tensor * modalities = altup_compute_router_modalities (activated ,il );// [n_altup, n_tokens] 448cb (modalities ,"modalities" ,il ); 449 450ggml_tensor * active_prediction = gemma3n_view_2d_slice (ctx0 ,predictions ,i_altup_act ); 451ggml_tensor * innovation = ggml_sub (ctx0 ,activated ,active_prediction );// [n_embd, n_tokens] 452cb (innovation ,"innovation" ,il ); 453 454ggml_tensor * all_coefs = build_lora_mm (model .layers [il ].altup_correct_coef ,modalities );// [n_altup, n_tokens] 455all_coefs = ggml_scale_bias (ctx0 ,all_coefs ,1.0f ,1.0f );// + 1.0 456cb (all_coefs ,"all_coefs" ,il ); 457all_coefs = ggml_transpose (ctx0 ,all_coefs );// [n_tokens, n_altup] 458all_coefs = ggml_cont_3d (ctx0 ,all_coefs ,1 ,n_tokens ,n_altup );// [1, n_tokens, n_altup] 459 460innovation = ggml_repeat_4d (ctx0 ,innovation ,n_embd ,n_tokens ,n_altup ,1 ); 461ggml_tensor * corrected = ggml_mul (ctx0 ,innovation ,all_coefs );// [n_embd, n_tokens, n_altup] 462corrected = ggml_add (ctx0 ,corrected ,predictions );// [n_embd, n_tokens, n_altup] 463cb (corrected ,"corrected" ,il ); 464 465return corrected ; 466}