MCPcopy Create free account
hub / github.com/PABannier/sam3.cpp / sam3_text_block_forward

Function sam3_text_block_forward

sam3.cpp:3957–4033  ·  view source on GitHub ↗

Single text encoder block forward pass. Input x: [E, L] where E=text_width=1024, L=seq_len (typically 32). causal_mask: [L, L] F16 additive mask for ggml_flash_attn_ext. Returns: [E, L]

Source from the content-addressed store, hash-verified

3955// causal_mask: [L, L] F16 additive mask for ggml_flash_attn_ext.
3956// Returns: [E, L]
3957static struct ggml_tensor* sam3_text_block_forward(struct ggml_context* ctx,
3958 struct ggml_tensor* x,
3959 const sam3_text_block& blk,
3960 const sam3_hparams& hp,
3961 struct ggml_tensor* causal_mask,
3962 int block_idx) {
3963 const int E = hp.text_width; // 1024
3964 const int NH = hp.text_heads; // 16
3965 const int HD = E / NH; // 64
3966 const int64_t L = x->ne[1]; // sequence length
3967
3968 auto* shortcut = x;
3969 x = sam3_layer_norm(ctx, x, blk.ln1_w, blk.ln1_b);
3970 sam3_name_tensorf(x, "text_block_%02d_after_ln1", block_idx);
3971
3972 auto* qkv = ggml_mul_mat(ctx, blk.attn_in_proj_w, x);
3973 qkv = ggml_add(ctx, qkv, blk.attn_in_proj_b);
3974 sam3_name_tensorf(qkv, "text_block_%02d_qkv", block_idx);
3975
3976 // [3*E, L] → [E, 3, L] → permute → [E, L, 3]
3977 qkv = ggml_reshape_3d(ctx, qkv, E, 3, L);
3978 qkv = ggml_cont(ctx, ggml_permute(ctx, qkv, 0, 2, 1, 3));
3979 // qkv: [E, L, 3]
3980
3981 auto* Q = ggml_view_2d(ctx, qkv, E, L, qkv->nb[1], 0);
3982 auto* K = ggml_view_2d(ctx, qkv, E, L, qkv->nb[1], 1 * qkv->nb[2]);
3983 auto* V = ggml_view_2d(ctx, qkv, E, L, qkv->nb[1], 2 * qkv->nb[2]);
3984
3985 // [E, L] → [HD, NH, L] → permute → [HD, L, NH, 1]
3986 Q = ggml_reshape_3d(ctx, Q, HD, NH, L);
3987 Q = ggml_cont(ctx, ggml_permute(ctx, Q, 0, 2, 1, 3));
3988 Q = ggml_reshape_4d(ctx, Q, HD, L, NH, 1);
3989
3990 K = ggml_reshape_3d(ctx, K, HD, NH, L);
3991 K = ggml_cont(ctx, ggml_permute(ctx, K, 0, 2, 1, 3));
3992 K = ggml_reshape_4d(ctx, K, HD, L, NH, 1);
3993
3994 V = ggml_reshape_3d(ctx, V, HD, NH, L);
3995 V = ggml_permute(ctx, V, 0, 2, 1, 3); // non-contiguous; flash_attn uses strides
3996
3997 float scale = 1.0f / sqrtf((float)HD);
3998 auto* attn_out = ggml_flash_attn_ext(ctx, Q, K, V, causal_mask, scale, 0.0f, 0.0f);
3999 x = ggml_reshape_2d(ctx, attn_out, E, L);
4000
4001 x = ggml_mul_mat(ctx, blk.attn_out_proj_w, x);
4002 x = ggml_add(ctx, x, blk.attn_out_proj_b);
4003
4004 if (blk.ls1) {
4005 x = ggml_mul(ctx, x, blk.ls1);
4006 }
4007 sam3_name_tensorf(x, "text_block_%02d_attn_out", block_idx);
4008
4009 x = ggml_add(ctx, shortcut, x);
4010 sam3_name_tensorf(x, "text_block_%02d_after_attn_residual", block_idx);
4011
4012 shortcut = x;
4013 x = sam3_layer_norm(ctx, x, blk.ln2_w, blk.ln2_b);
4014 sam3_name_tensorf(x, "text_block_%02d_after_ln2", block_idx);

Callers 1

Calls 2

sam3_layer_normFunction · 0.85
sam3_name_tensorfFunction · 0.85

Tested by

no test coverage detected