char-fork/llama.cpp

git clone https://git.t4t.associates/char-fork/llama.cpp

Gabe Goodhartmodel: Granite Speech Plus (#24818)a3900a669

char/aliceai-t5-moe
12.7 KiB309 linesraw
1#include "models.h"
2
3#include <algorithm>
4
5ggml_cgraph * clip_graph_granite_speech::build() {
6    const int n_frames     = img.nx();
7    const int context_size = hparams.audio_chunk_size;
8    const int ctc_layer    = n_layer / 2;
9    const int conv_kernel  = hparams.audio_conv_kernel_size;
10    const int conv_pad     = conv_kernel / 2;
11
12    const int num_blocks   = (n_frames + context_size - 1) / context_size;
13    const int padded_len   = num_blocks * context_size;
14    const int remainder    = n_frames % context_size;
15
16    // Calculate projector input dimension based on feature layers
17    const int proj_input_dim = n_embd * (hparams.feature_layers.size() + 1);
18    const bool use_feature_concat = !hparams.feature_layers.empty();
19
20    ggml_tensor * attn_dists = ggml_new_tensor_1d(ctx0, GGML_TYPE_I32, context_size * context_size);
21    ggml_set_name(attn_dists, "attn_dists");
22    ggml_set_input(attn_dists);
23
24    ggml_tensor * attn_mask = nullptr;
25    if (remainder > 0) {
26        attn_mask = ggml_new_tensor_4d(ctx0, GGML_TYPE_F32,
27            context_size, context_size, 1, num_blocks);
28        ggml_set_name(attn_mask, "attn_mask");
29        ggml_set_input(attn_mask);
30    }
31
32    ggml_tensor * inp = build_inp_raw(1);
33    auto * cur = ggml_cont(ctx0, ggml_transpose(ctx0, inp));
34    cb(cur, "inp_transposed", -1);
35
36    cur = build_mm(model.inp_proj_w, cur);
37    cur = ggml_add(ctx0, cur, model.inp_proj_b);
38    cb(cur, "inp_linear", -1);
39
40    // Capture layer 0 if requested (after input_linear)
41    ggml_tensor * concat_result = nullptr;
42    if (use_feature_concat) {
43        if (std::find(hparams.feature_layers.begin(), hparams.feature_layers.end(), 0) != hparams.feature_layers.end()) {
44            concat_result = cur;
45            cb(concat_result, "feature_layer_0", -1);
46        }
47    }
48
49    for (int il = 0; il < n_layer; il++) {
50        const auto & layer = model.layers[il];
51        auto * residual = cur;
52
53        // ffn1 (half-step)
54        {
55            auto * ffn1 = build_norm(cur, layer.ff_norm_w, layer.ff_norm_b,
56                                     NORM_TYPE_NORMAL, eps, il);
57            cb(ffn1, "ffn1_norm", il);
58
59            ffn1 = build_ffn(ffn1,
60                layer.ff_up_w, layer.ff_up_b,
61                nullptr, nullptr,
62                layer.ff_down_w, layer.ff_down_b,
63                FFN_SILU, il);
64            cb(ffn1, "ffn1_out", il);
65
66            residual = ggml_add(ctx0, residual, ggml_scale(ctx0, ffn1, 0.5f));
67            cb(residual, "ffn1_residual", il);
68        }
69
70        // build_attn not used here: Shaw RPE needs pos_attn = mul_mat(pos_emb, Q)
71        // injected between KQ product and softmax, which build_attn doesn't support
72        {
73            auto * normed = build_norm(residual, layer.ln_1_w, layer.ln_1_b,
74                                       NORM_TYPE_NORMAL, eps, il);
75            cb(normed, "attn_norm", il);
76
77            if (n_frames < padded_len) {
78                normed = ggml_pad(ctx0, normed, 0, padded_len - n_frames, 0, 0);
79            }
80
81            ggml_tensor * Q = build_mm(layer.q_w, normed);
82            ggml_tensor * K = build_mm(layer.k_w, normed);
83            ggml_tensor * V = build_mm(layer.v_w, normed);
84
85            Q = ggml_reshape_4d(ctx0, Q, d_head, n_head, context_size, num_blocks);
86            K = ggml_reshape_4d(ctx0, K, d_head, n_head, context_size, num_blocks);
87            V = ggml_reshape_4d(ctx0, V, d_head, n_head, context_size, num_blocks);
88
89            ggml_tensor * Q_perm = ggml_permute(ctx0, Q, 0, 2, 1, 3);
90            ggml_tensor * K_perm = ggml_cont(ctx0, ggml_permute(ctx0, K, 0, 2, 1, 3));
91
92            ggml_tensor * kq = ggml_mul_mat(ctx0, K_perm, Q_perm);
93
94            // Shaw RPE: pos_emb ne[2]=1 broadcasts against Q ne[2]=num_blocks in mul_mat
95            ggml_tensor * pos_emb = ggml_get_rows(ctx0, layer.attn_rel_pos_emb, attn_dists);
96            pos_emb = ggml_reshape_3d(ctx0, pos_emb, d_head, context_size, context_size);
97            pos_emb = ggml_reshape_4d(ctx0, pos_emb, d_head, context_size, 1, context_size);
98
99            ggml_tensor * Q_shaw = ggml_permute(ctx0, Q, 0, 1, 3, 2);
100            ggml_tensor * pos_attn = ggml_mul_mat(ctx0, pos_emb, Q_shaw);
101            pos_attn = ggml_cont(ctx0, ggml_permute(ctx0, pos_attn, 0, 2, 3, 1));
102
103            ggml_tensor * scores = ggml_add(ctx0, kq, pos_attn);
104            ggml_tensor * attn_weights = ggml_soft_max_ext(ctx0, scores, attn_mask,
105                                                            kq_scale, 0.0f);
106
107            ggml_tensor * V_perm = ggml_cont(ctx0, ggml_permute(ctx0, V, 1, 2, 0, 3));
108            ggml_tensor * attn_out = ggml_mul_mat(ctx0, V_perm, attn_weights);
109
110            attn_out = ggml_permute(ctx0, attn_out, 0, 2, 1, 3);
111            attn_out = ggml_cont_2d(ctx0, attn_out, n_embd, padded_len);
112
113            if (n_frames < padded_len) {
114                attn_out = ggml_view_2d(ctx0, attn_out,
115                    n_embd, n_frames, attn_out->nb[1], 0);
116            }
117
118            cur = build_mm(layer.o_w, attn_out);
119            cur = ggml_add(ctx0, cur, layer.o_b);
120            cb(cur, "attn_out", il);
121        }
122
123        residual = ggml_add(ctx0, residual, cur);
124
125        // conv module
126        {
127            cur = build_norm(residual, layer.norm_conv_w, layer.norm_conv_b,
128                             NORM_TYPE_NORMAL, eps, il);
129            cb(cur, "conv_norm", il);
130
131            auto * x = build_mm(layer.conv_pw1_w, cur);
132            x = ggml_add(ctx0, x, layer.conv_pw1_b);
133            cb(x, "conv_pw1", il);
134
135            // GLU: ggml has no fused op, manual split + sigmoid gate
136            {
137                int64_t d = x->ne[0] / 2;
138                ggml_tensor * gate = ggml_sigmoid(ctx0,
139                    ggml_view_2d(ctx0, x, d, x->ne[1], x->nb[1], d * x->nb[0]));
140                x = ggml_mul(ctx0,
141                    ggml_view_2d(ctx0, x, d, x->ne[1], x->nb[1], 0), gate);
142                x = ggml_cont(ctx0, ggml_transpose(ctx0, x));
143            }
144            cb(x, "conv_glu", il);
145
146            x = ggml_pad(ctx0, x, conv_pad, 0, 0, 0);
147            x = ggml_roll(ctx0, x, conv_pad, 0, 0, 0);
148            x = ggml_pad(ctx0, x, conv_pad, 0, 0, 0);
149            x = ggml_ssm_conv(ctx0, x, layer.conv_dw_w);
150            cb(x, "conv_dw", il);
151
152            // folded batch norm
153            x = ggml_add(ctx0, ggml_mul(ctx0, x, layer.conv_norm_w), layer.conv_norm_b);
154            x = ggml_silu(ctx0, x);
155            cb(x, "conv_bn_silu", il);
156
157            x = build_mm(layer.conv_pw2_w, x);
158            x = ggml_add(ctx0, x, layer.conv_pw2_b);
159            cb(x, "conv_pw2", il);
160
161            cur = x;
162        }
163
164        residual = ggml_add(ctx0, residual, cur);
165
166        // ffn2 (half-step)
167        {
168            auto * ffn2 = build_norm(residual, layer.ff_norm_1_w, layer.ff_norm_1_b,
169                                     NORM_TYPE_NORMAL, eps, il);
170            cb(ffn2, "ffn2_norm", il);
171
172            ffn2 = build_ffn(ffn2,
173                layer.ff_up_1_w, layer.ff_up_1_b,
174                nullptr, nullptr,
175                layer.ff_down_1_w, layer.ff_down_1_b,
176                FFN_SILU, il);
177            cb(ffn2, "ffn2_out", il);
178
179            residual = ggml_add(ctx0, residual, ggml_scale(ctx0, ffn2, 0.5f));
180        }
181
182        cur = build_norm(residual, layer.ln_2_w, layer.ln_2_b,
183                         NORM_TYPE_NORMAL, eps, il);
184        cb(cur, "layer_out", il);
185
186        // Capture intermediate layer (il + 1) if requested
187        if (use_feature_concat) {
188            if (hparams.is_feature_layer(il + 1)) {
189                if (concat_result == nullptr) {
190                    concat_result = cur;
191                } else {
192                    concat_result = ggml_concat(ctx0, concat_result, cur, 0);
193                }
194                cb(concat_result, string_format("feature_layer_%d", il + 1).c_str(), il);
195            }
196        }
197
198        // CTC branch
199        if (il + 1 == ctc_layer) {
200            auto * mid = build_mm(model.ctc_out_w, cur);
201            mid = ggml_add(ctx0, mid, model.ctc_out_b);
202            mid = ggml_soft_max(ctx0, mid);
203            mid = build_mm(model.ctc_out_mid_w, mid);
204            mid = ggml_add(ctx0, mid, model.ctc_out_mid_b);
205            cur = ggml_add(ctx0, cur, mid);
206            cb(cur, "ctc_branch", il);
207        }
208    }
209
210    // Append final output to concatenated features if using feature concatenation
211    if (use_feature_concat && concat_result != nullptr) {
212        concat_result = ggml_concat(ctx0, concat_result, cur, 0);
213        cb(concat_result, "concat_final", -1);
214        cur = concat_result;
215    }
216
217    cb(cur, "encoder_out", -1);
218
219    // QFormer projector
220    {
221        const int window_size     = hparams.audio_proj_window_size;
222        const int num_queries     = window_size / hparams.audio_proj_downsample_rate;
223        const int proj_n_head     = hparams.audio_proj_head_count;
224        const int proj_d_head     = n_embd / proj_n_head;
225        const float proj_kq_scale = 1.0f / sqrtf((float)proj_d_head);
226        const float proj_eps      = 1e-12f;
227        const int nblocks_proj    = (n_frames + window_size - 1) / window_size;
228        const int padded_proj     = nblocks_proj * window_size;
229
230        if (n_frames < padded_proj) {
231            cur = ggml_pad(ctx0, cur, 0, padded_proj - n_frames, 0, 0);
232        }
233
234        ggml_tensor * enc_windows = ggml_reshape_3d(ctx0, cur, proj_input_dim, window_size, nblocks_proj);
235
236        ggml_tensor * queries = build_norm(model.qf_proj_blocks[0].qf_proj_query,
237            model.qf_proj_blocks[0].qf_proj_norm_w, model.qf_proj_blocks[0].qf_proj_norm_b,
238            NORM_TYPE_NORMAL, proj_eps, -1);
239        {
240            ggml_tensor * q_3d    = ggml_reshape_3d(ctx0, queries, n_embd, num_queries, 1);
241            ggml_tensor * q_shape = ggml_new_tensor_3d(ctx0, GGML_TYPE_F32,
242                n_embd, num_queries, nblocks_proj);
243            queries = ggml_repeat(ctx0, q_3d, q_shape);
244        }
245
246        for (int il = 0; il < (int)model.qf_proj_blocks[0].qf_proj_layers.size(); il++) {
247            const auto & pl = model.qf_proj_blocks[0].qf_proj_layers[il];
248
249            // self-attention
250            {
251                ggml_tensor * Q = ggml_add(ctx0, build_mm(pl.q_w, queries), pl.q_b);
252                ggml_tensor * K = ggml_add(ctx0, build_mm(pl.k_w, queries), pl.k_b);
253                ggml_tensor * V = ggml_add(ctx0, build_mm(pl.v_w, queries), pl.v_b);
254
255                Q = ggml_reshape_4d(ctx0, Q, proj_d_head, proj_n_head, num_queries, nblocks_proj);
256                K = ggml_reshape_4d(ctx0, K, proj_d_head, proj_n_head, num_queries, nblocks_proj);
257                V = ggml_reshape_4d(ctx0, V, proj_d_head, proj_n_head, num_queries, nblocks_proj);
258
259                ggml_tensor * sa_out = build_attn(pl.o_w, pl.o_b,
260                    Q, K, V, nullptr, proj_kq_scale, il);
261                sa_out = ggml_reshape_3d(ctx0, sa_out, n_embd, num_queries, nblocks_proj);
262
263                queries = build_norm(ggml_add(ctx0, sa_out, queries),
264                    pl.ln_1_w, pl.ln_1_b,
265                    NORM_TYPE_NORMAL, proj_eps, il);
266            }
267
268            // cross-attention
269            {
270                ggml_tensor * Q = ggml_add(ctx0, build_mm(pl.cross_attn_q_w, queries), pl.cross_attn_q_b);
271                ggml_tensor * K = ggml_add(ctx0, build_mm(pl.cross_attn_k_w, enc_windows), pl.cross_attn_k_b);
272                ggml_tensor * V = ggml_add(ctx0, build_mm(pl.cross_attn_v_w, enc_windows), pl.cross_attn_v_b);
273
274                Q = ggml_reshape_4d(ctx0, Q, proj_d_head, proj_n_head, num_queries, nblocks_proj);
275                K = ggml_reshape_4d(ctx0, K, proj_d_head, proj_n_head, window_size, nblocks_proj);
276                V = ggml_reshape_4d(ctx0, V, proj_d_head, proj_n_head, window_size, nblocks_proj);
277
278                ggml_tensor * ca_out = build_attn(pl.cross_attn_o_w, pl.cross_attn_o_b,
279                    Q, K, V, nullptr, proj_kq_scale, il);
280                ca_out = ggml_reshape_3d(ctx0, ca_out, n_embd, num_queries, nblocks_proj);
281
282                queries = build_norm(ggml_add(ctx0, ca_out, queries),
283                    pl.cross_attn_norm_w, pl.cross_attn_norm_b,
284                    NORM_TYPE_NORMAL, proj_eps, il);
285            }
286
287            // ffn
288            {
289                ggml_tensor * ffn_out = build_ffn(queries,
290                    pl.ff_up_w, pl.ff_up_b,
291                    nullptr, nullptr,
292                    pl.ff_down_w, pl.ff_down_b,
293                    FFN_GELU, il);
294
295                queries = build_norm(ggml_add(ctx0, ffn_out, queries),
296                    pl.ln_2_w, pl.ln_2_b,
297                    NORM_TYPE_NORMAL, proj_eps, il);
298            }
299        }
300
301        cur = ggml_reshape_2d(ctx0, queries, n_embd, num_queries * nblocks_proj);
302        cur = ggml_add(ctx0, build_mm(model.qf_proj_blocks[0].qf_proj_linear_w, cur), model.qf_proj_blocks[0].qf_proj_linear_b);
303        cb(cur, "projector_out", -1);
304    }
305
306    ggml_build_forward_expand(gf, cur);
307
308    return gf;
309}