char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
547765a93
char/aliceai-t5-moe
1/** 2* Gemma 4 Audio Conformer Encoder (clip_graph_gemma4a) 3* 4* Architecture: Conformer with dual half-step FFN, full self-attention 5* with sinusoidal RPE, depthwise light conv, and output projection. 6*/ 7 8#include "models.h" 9#include <cmath> 10 11ggml_cgraph * clip_graph_gemma4a::build () { 12const float res_weight = 0.5f ; 13const float norm_eps = 1e-6f ; 14 15// 1. Input 16ggml_tensor * inp = build_inp_raw (1 ); 17auto * cur = ggml_cont (ctx0 ,ggml_transpose (ctx0 ,inp )); 18 19// 2. Subsampling Conv2D (symmetric padding=1, matching PyTorch) 20 { 21for (int i = 0 ;i < 2 ;i ++ ) { 22cur = ggml_conv_2d (ctx0 ,model .sscp_conv_w [i ],cur ,2 ,2 ,1 ,1 ,1 ,1 ); 23if (model .sscp_conv_b [i ]) { 24cur = ggml_add (ctx0 ,cur ,model .sscp_conv_b [i ]); 25 } 26// nn.LayerNorm(channels): permute ch to ne[0], normalize, permute back 27if (model .sscp_norm_w [i ]) { 28cur = ggml_cont (ctx0 ,ggml_permute (ctx0 ,cur ,1 ,2 ,0 ,3 )); 29cur = ggml_norm (ctx0 ,cur ,norm_eps ); 30cur = ggml_mul (ctx0 ,cur ,model .sscp_norm_w [i ]); 31cur = ggml_cont (ctx0 ,ggml_permute (ctx0 ,cur ,2 ,0 ,1 ,3 )); 32 } 33cur = ggml_relu (ctx0 ,cur ); 34 } 35// Flatten [freq, time, ch, 1] -> [ch*freq, time] 36cur = ggml_cont (ctx0 ,ggml_permute (ctx0 ,cur ,1 ,2 ,0 ,3 )); 37cur = ggml_reshape_2d (ctx0 ,cur ,cur -> ne [0 ]* cur -> ne [1 ],cur -> ne [2 ]); 38if (model .sscp_inp_proj_w ) { 39cur = build_mm (model .sscp_inp_proj_w ,cur ); 40if (model .sscp_inp_proj_b ) { 41cur = ggml_add (ctx0 ,cur ,model .sscp_inp_proj_b ); 42 } 43 } 44 } 45 46const int64_t n_pos = cur -> ne [1 ]; 47 48// Chunked local attention parameters 49const int64_t C = 12 ;// chunk_size 50const int64_t P = 12 ;// max_past_horizon (context_left - 1) 51const int64_t S = C + P ;// context_size = 24 52const int64_t R = P + 1 ;// RPE positions = 13 53const int64_t B = (n_pos + C - 1 ) /C ;// num_blocks 54const int64_t Np = B * C ;// padded sequence length 55const int64_t pad_seq = Np - n_pos ; 56 57// Input tensors: blocked RPE and blocked attention mask 58ggml_tensor * pos_emb = ggml_new_tensor_2d (ctx0 ,GGML_TYPE_F32 ,n_head * d_head ,R ); 59ggml_set_name (pos_emb ,"pos_emb" ); 60ggml_set_input (pos_emb ); 61 62ggml_tensor * kq_mask = ggml_new_tensor_3d (ctx0 ,GGML_TYPE_F32 ,S ,C ,B ); 63ggml_set_name (kq_mask ,"kq_mask" ); 64ggml_set_input (kq_mask ); 65 66// 3. Conformer Blocks 67for (int il = 0 ;il < hparams .n_layer ;il ++ ) { 68const auto & layer = model .layers [il ]; 69auto * residual = cur ; 70 71// FFN 1 (half-step) 72if (layer .ff_norm_w && layer .ff_up_w && layer .ff_down_w ) { 73cur = build_norm (cur ,layer .ff_norm_w ,nullptr ,NORM_TYPE_RMS ,norm_eps ,il ); 74cur = build_ffn (cur , 75layer .ff_up_w ,nullptr ,nullptr ,nullptr , 76layer .ff_down_w ,nullptr ,FFN_SILU ,il ); 77if (layer .ff_post_norm_w ) { 78cur = build_norm (cur ,layer .ff_post_norm_w ,nullptr ,NORM_TYPE_RMS ,norm_eps ,il ); 79 } 80residual = ggml_add (ctx0 ,residual ,ggml_scale (ctx0 ,cur ,res_weight )); 81 } 82 83// Chunked local self-attention with RPE 84if (layer .q_w && layer .k_w && layer .v_w && layer .o_w ) { 85const float q_scale = (1.0f /sqrtf ((float )d_head )) /logf (2.0f ); 86const float k_scale = logf (1.0f + expf (1.0f )) /logf (2.0f ); 87const float softcap = 50.0f ; 88 89ggml_tensor * attn_norm_w = layer .attn_pre_norm_w ?layer .attn_pre_norm_w :layer .ln_1_w ; 90cur = attn_norm_w 91 ?build_norm (residual ,attn_norm_w ,nullptr ,NORM_TYPE_RMS ,norm_eps ,il ) 92 :residual ; 93 94ggml_tensor * Qcur = build_mm (layer .q_w ,cur ); 95ggml_tensor * Kcur = build_mm (layer .k_w ,cur ); 96ggml_tensor * Vcur = build_mm (layer .v_w ,cur ); 97 98// [n_embd, n_pos] -> [D, H, N] 99Qcur = ggml_reshape_3d (ctx0 ,Qcur ,d_head ,n_head ,n_pos ); 100Kcur = ggml_reshape_3d (ctx0 ,Kcur ,d_head ,n_head ,n_pos ); 101Vcur = ggml_reshape_3d (ctx0 ,Vcur ,d_head ,n_head ,n_pos ); 102 103// Q/K scaling 104Qcur = ggml_scale (ctx0 ,Qcur ,q_scale ); 105if (layer .per_dim_scale_w ) { 106Qcur = ggml_mul (ctx0 ,Qcur ,ggml_reshape_3d (ctx0 ,layer .per_dim_scale_w ,d_head ,1 ,1 )); 107 } 108Kcur = ggml_scale (ctx0 ,Kcur ,k_scale ); 109if (layer .per_dim_k_scale_w ) { 110Kcur = ggml_mul (ctx0 ,Kcur ,ggml_reshape_3d (ctx0 ,layer .per_dim_k_scale_w ,d_head ,1 ,1 )); 111 } 112 113// Q blocking: [D, H, N] -> pad to Np -> reshape [D, H, C, B] 114// ggml permute: ne[ax_i] = src->ne[i], so (0,3,1,2) sends H->3, C->1, B->2 115Qcur = ggml_pad (ctx0 ,Qcur ,0 ,0 ,pad_seq ,0 );// [D, H, Np] 116Qcur = ggml_reshape_4d (ctx0 ,Qcur ,d_head ,n_head ,C ,B );// [D, H, C, B] 117Qcur = ggml_cont (ctx0 ,ggml_permute (ctx0 ,Qcur ,0 ,3 ,1 ,2 ));// [D, C, B, H] 118 119// K/V block context extraction via overlapping view: 120// Pad to S*B elements, roll right by P to create left-padding, 121// then view with stride C in the block dimension (overlapping windows). 122auto extract_blocks = [& ](ggml_tensor * t )-> ggml_tensor * { 123// [D, H, N] -> pad to S*B -> roll right by P -> cont (materialize) 124const int64_t pad_kv = S * B - n_pos ; 125t = ggml_pad (ctx0 ,t ,0 ,0 ,pad_kv ,0 );// [D, H, S*B] 126t = ggml_roll (ctx0 ,t ,0 ,0 ,P ,0 );// left-pad by P 127t = ggml_cont (ctx0 ,t );// materialize roll (removes view offset) 128// Overlapping view: stride for B dim is C positions, not S 129// ne = [D, H, S, B], data_size = D*H*S*B*sizeof = source_nbytes (exact fit) 130// nb1=D*sizeof, nb2=D*H*sizeof, nb3=C*D*H*sizeof (overlap: C < S) 131t = ggml_view_4d (ctx0 ,t ,d_head ,n_head ,S ,B , 132t -> nb [1 ],t -> nb [2 ],C * t -> nb [2 ],0 ); 133t = ggml_cont (ctx0 ,t );// materialize overlapping windows 134return t ; 135 }; 136 137ggml_tensor * Kblk = extract_blocks (Kcur ); 138// [D, H, S, B] -> [D, S, B, H] via permute(0,3,1,2) 139Kblk = ggml_cont (ctx0 ,ggml_permute (ctx0 ,Kblk ,0 ,3 ,1 ,2 )); 140 141ggml_tensor * Vblk = extract_blocks (Vcur ); 142// [D, H, S, B] -> [S, D, B, H] via permute(1,3,0,2) 143Vblk = ggml_cont (ctx0 ,ggml_permute (ctx0 ,Vblk ,1 ,3 ,0 ,2 )); 144 145// Content attention: Q @ K^T 146// Kblk=[D,S,B,H], Qcur=[D,C,B,H] -> mul_mat contracts on D -> [S,C,B,H] 147ggml_tensor * matrix_ac = ggml_mul_mat (ctx0 ,Kblk ,Qcur ); 148 149// Relative position attention 150if (layer .attn_k_rel_w ) { 151// RPE: [n_embd, R] -> project -> [D, H, R] -> [D, R, H] 152auto * p = ggml_mul_mat (ctx0 ,layer .attn_k_rel_w ,pos_emb ); 153p = ggml_reshape_3d (ctx0 ,p ,d_head ,n_head ,R ); 154p = ggml_cont (ctx0 ,ggml_permute (ctx0 ,p ,0 ,2 ,1 ,3 ));// [D, R, H] 155 156// Q_flat @ RPE^T: [D, C*B, H] @ [D, R, H] -> [R, C*B, H] 157auto * Q_flat = ggml_reshape_3d (ctx0 ,Qcur ,d_head ,C * B ,n_head ); 158auto * matrix_bd = ggml_mul_mat (ctx0 ,p ,Q_flat );// [R, C*B, H] 159matrix_bd = ggml_reshape_4d (ctx0 ,matrix_bd ,R ,C ,B ,n_head );// [R, C, B, H] 160 161// Blocked relative shift (appendix B of Transformer-XL) 162 { 163matrix_bd = ggml_pad (ctx0 ,matrix_bd ,S + 1 - R ,0 ,0 ,0 );// [S+1, C, B, H] 164matrix_bd = ggml_reshape_3d (ctx0 ,matrix_bd , (S + 1 )* C ,B ,n_head ); 165matrix_bd = ggml_view_3d (ctx0 ,matrix_bd , 166C * S ,B ,n_head , 167matrix_bd -> nb [1 ],matrix_bd -> nb [2 ],0 ); 168matrix_bd = ggml_cont (ctx0 ,matrix_bd );// [C*S, B, H] 169matrix_bd = ggml_reshape_4d (ctx0 ,matrix_bd ,S ,C ,B ,n_head );// [S, C, B, H] 170 } 171 172matrix_ac = ggml_add (ctx0 ,matrix_ac ,matrix_bd ); 173 } 174 175auto * scores = matrix_ac ;// [S, C, B, H] 176 177// Softcap 178scores = ggml_scale (ctx0 ,scores ,1.0f /softcap ); 179scores = ggml_tanh (ctx0 ,scores ); 180scores = ggml_scale (ctx0 ,scores ,softcap ); 181 182// Blocked attention mask: [S, C, B] broadcasts over H 183scores = ggml_add (ctx0 ,scores ,kq_mask ); 184 185ggml_tensor * attn = ggml_soft_max (ctx0 ,scores ); 186 187// attn @ V: [S,C,B,H] @ [S,D,B,H] -> [D,C,B,H] 188ggml_tensor * x = ggml_mul_mat (ctx0 ,Vblk ,attn ); 189 190// [D,C,B,H] -> [D,H,C,B] via permute(0,2,3,1) -> flatten -> trim 191x = ggml_cont (ctx0 ,ggml_permute (ctx0 ,x ,0 ,2 ,3 ,1 )); 192x = ggml_cont_2d (ctx0 ,x ,d_head * n_head ,C * B ); 193if (pad_seq > 0 ) { 194x = ggml_view_2d (ctx0 ,x ,d_head * n_head ,n_pos ,x -> nb [1 ],0 ); 195x = ggml_cont (ctx0 ,x ); 196 } 197 198x = build_mm (layer .o_w ,x ); 199if (layer .o_b ) {x = ggml_add (ctx0 ,x ,layer .o_b ); } 200 201if (layer .attn_post_norm_w ) { 202x = build_norm (x ,layer .attn_post_norm_w ,nullptr ,NORM_TYPE_RMS ,norm_eps ,il ); 203 } 204residual = ggml_add (ctx0 ,residual ,x ); 205 } 206 207// Convolution Module 208if (layer .norm_conv_w && layer .conv_pw1_w && layer .conv_dw_w && layer .conv_pw2_w ) { 209cur = build_norm (residual ,layer .norm_conv_w ,nullptr ,NORM_TYPE_RMS ,norm_eps ,il ); 210auto * x = build_mm (layer .conv_pw1_w ,cur ); 211 212// GLU 213 { 214int64_t d = x -> ne [0 ] /2 ; 215ggml_tensor * gate = ggml_sigmoid (ctx0 , 216ggml_cont (ctx0 ,ggml_view_2d (ctx0 ,x ,d ,x -> ne [1 ],x -> nb [1 ],d * x -> nb [0 ]))); 217x = ggml_mul (ctx0 , 218ggml_view_2d (ctx0 ,x ,d ,x -> ne [1 ],x -> nb [1 ],0 ),gate ); 219x = ggml_cont (ctx0 ,ggml_transpose (ctx0 ,x )); 220 } 221 222// Causal depthwise Conv1D via ggml_ssm_conv (pad+roll for left-only padding). 223x = ggml_pad (ctx0 ,x ,4 ,0 ,0 ,0 ); 224x = ggml_roll (ctx0 ,x ,4 ,0 ,0 ,0 ); 225x = ggml_ssm_conv (ctx0 ,x ,layer .conv_dw_w ); 226if (layer .conv_dw_b ) { 227x = ggml_add (ctx0 ,x ,layer .conv_dw_b ); 228 } 229 230if (layer .conv_norm_w ) { 231x = ggml_rms_norm (ctx0 ,x ,norm_eps ); 232x = ggml_mul (ctx0 ,x ,layer .conv_norm_w ); 233 } 234x = ggml_silu (ctx0 ,x ); 235x = build_mm (layer .conv_pw2_w ,x ); 236residual = ggml_add (ctx0 ,residual ,x ); 237 } 238 239// FFN 2 (half-step) 240if (layer .ff_norm_1_w && layer .ff_up_1_w && layer .ff_down_1_w ) { 241cur = build_norm (residual ,layer .ff_norm_1_w ,nullptr ,NORM_TYPE_RMS ,norm_eps ,il ); 242cur = build_ffn (cur , 243layer .ff_up_1_w ,nullptr ,nullptr ,nullptr , 244layer .ff_down_1_w ,nullptr ,FFN_SILU ,il ); 245if (layer .ff_post_norm_1_w ) { 246cur = build_norm (cur ,layer .ff_post_norm_1_w ,nullptr ,NORM_TYPE_RMS ,norm_eps ,il ); 247 } 248residual = ggml_add (ctx0 ,residual ,ggml_scale (ctx0 ,cur ,res_weight )); 249 } 250 251// Layer output norm 252cur = layer .ln_2_w 253 ?build_norm (residual ,layer .ln_2_w ,nullptr ,NORM_TYPE_RMS ,norm_eps ,il ) 254 :residual ; 255 256 } 257 258// 4. Output Projection 259if (model .audio_out_proj_w ) { 260cur = build_mm (model .audio_out_proj_w ,cur ); 261if (model .audio_out_proj_b ) { 262cur = ggml_add (ctx0 ,cur ,model .audio_out_proj_b ); 263 } 264 } 265 266// 5. Audio Multimodal Embedder 267cur = ggml_rms_norm (ctx0 ,cur ,norm_eps ); 268if (model .mm_soft_emb_norm_w ) { 269cur = ggml_mul (ctx0 ,cur ,model .mm_soft_emb_norm_w ); 270 } 271if (model .mm_input_proj_w ) { 272cur = build_mm (model .mm_input_proj_w ,cur ); 273 } 274 275ggml_build_forward_expand (gf ,cur ); 276return gf ; 277} 278 279ggml_tensor * clip_graph_gemma4a::build_mm (ggml_tensor * w ,ggml_tensor * x )const { 280auto it = model .clamp_info_map .find (w -> name ); 281if (it == model .clamp_info_map .end ()) { 282return ggml_mul_mat (ctx0 ,w ,x ); 283 } 284const auto & ci = it -> second ; 285ggml_tensor * clamped = ggml_clamp (ctx0 ,x ,ci .inp_min ,ci .inp_max ); 286ggml_tensor * out = ggml_mul_mat (ctx0 ,w ,clamped ); 287return ggml_clamp (ctx0 ,out ,ci .out_min ,ci .out_max ); 288}