char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
b11f7c16b
char/aliceai-t5-moe
1#include "models.h" 2 3ggml_cgraph * clip_graph_pixtral::build () { 4const int n_merge = hparams .n_merge ; 5 6// 2D input positions 7ggml_tensor * pos_h = ggml_new_tensor_1d (ctx0 ,GGML_TYPE_I32 ,n_patches ); 8ggml_set_name (pos_h ,"pos_h" ); 9ggml_set_input (pos_h ); 10 11ggml_tensor * pos_w = ggml_new_tensor_1d (ctx0 ,GGML_TYPE_I32 ,n_patches ); 12ggml_set_name (pos_w ,"pos_w" ); 13ggml_set_input (pos_w ); 14 15auto add_pos = [& ](ggml_tensor * cur ,const clip_layer & ) { 16return build_rope_2d (ctx0 ,cur ,pos_h ,pos_w ,hparams .rope_theta , true); 17 }; 18 19ggml_tensor * inp = build_inp (); 20ggml_tensor * cur = build_vit ( 21inp ,n_patches , 22NORM_TYPE_RMS , 23hparams .ffn_op , 24nullptr ,// no learned pos embd 25add_pos ); 26 27// mistral small 3.1 patch merger 28// ref: https://github.com/huggingface/transformers/blob/7a3e208892c06a5e278144eaf38c8599a42f53e7/src/transformers/models/mistral3/modeling_mistral3.py#L67 29if (model .mm_patch_merger_w ) { 30GGML_ASSERT (hparams .n_merge > 0 ); 31 32cur = ggml_mul (ctx0 ,ggml_rms_norm (ctx0 ,cur ,eps ),model .mm_input_norm_w ); 33 34// reshape image tokens to 2D grid 35cur = ggml_reshape_3d (ctx0 ,cur ,n_embd ,n_patches_x ,n_patches_y ); 36cur = ggml_permute (ctx0 ,cur ,2 ,0 ,1 ,3 );// [x, y, n_embd] 37cur = ggml_cont (ctx0 ,cur ); 38 39// torch.nn.functional.unfold is just an im2col under the hood 40// we just need a dummy kernel to make it work 41ggml_tensor * kernel = ggml_view_3d (ctx0 ,cur ,n_merge ,n_merge ,cur -> ne [2 ],0 ,0 ,0 ); 42cur = ggml_im2col (ctx0 ,kernel ,cur ,n_merge ,n_merge ,0 ,0 ,1 ,1 , true,inp -> type ); 43 44// project to n_embd 45cur = ggml_reshape_2d (ctx0 ,cur ,cur -> ne [0 ],cur -> ne [1 ]* cur -> ne [2 ]); 46cur = build_mm (model .mm_patch_merger_w ,cur ); 47 } 48 49// LlavaMultiModalProjector (always using GELU activation) 50 { 51cur = build_ffn (cur , 52model .mm_1_w ,model .mm_1_b , 53nullptr ,nullptr , 54model .mm_2_w ,model .mm_2_b , 55FFN_GELU , 56-1 ); 57 } 58 59// arrangement of the [IMG_BREAK] token 60if (model .token_embd_img_break ) { 61// not efficient, but works 62// the trick is to view the embeddings as a 3D tensor with shape [n_embd, n_patches_per_row, n_rows] 63// and then concatenate the [IMG_BREAK] token to the end of each row, aka n_patches_per_row dimension 64// after the concatenation, we have a tensor with shape [n_embd, n_patches_per_row + 1, n_rows] 65 66const int p_y = n_patches_y /n_merge ; 67const int p_x = n_patches_x /n_merge ; 68const int p_total = p_x * p_y ; 69const int n_embd_text = cur -> ne [0 ]; 70const int n_tokens_output = p_total + p_y - 1 ;// one [IMG_BREAK] per row, except the last row 71 72ggml_tensor * tmp = ggml_reshape_3d (ctx0 ,cur ,n_embd_text ,p_x ,p_y ); 73ggml_tensor * tok = ggml_new_tensor_3d (ctx0 ,tmp -> type ,n_embd_text ,1 ,p_y ); 74tok = ggml_scale (ctx0 ,tok ,0.0 );// clear the tensor 75tok = ggml_add (ctx0 ,tok ,model .token_embd_img_break ); 76tmp = ggml_concat (ctx0 ,tmp ,tok ,1 ); 77cur = ggml_view_2d (ctx0 ,tmp , 78n_embd_text ,n_tokens_output , 79ggml_row_size (tmp -> type ,n_embd_text ),0 ); 80 } 81 82// build the graph 83ggml_build_forward_expand (gf ,cur ); 84 85return gf ; 86}