char-fork/llama.cpp

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

Xuan-Son Nguyenmtmd: support "frame merge" for qwen-vl-based models (#21858)31e82494c

char/aliceai-t5-moe
7.6 KiB205 linesraw
1#include "models.h"
2
3ggml_tensor * clip_graph_qwen2vl::build_inp_with_temporal_merge() {
4    ggml_tensor * inp_raw = build_inp_raw();
5
6    GGML_ASSERT(img.nx() % (patch_size * 2) == 0);
7    GGML_ASSERT(img.ny() % (patch_size * 2) == 0);
8
9    const size_t nb1 = ggml_row_size(inp_raw->type, img.nx());
10    const size_t nb2 = ggml_row_size(inp_raw->type, img.nx() * img.ny());
11
12    if (n_batch == 1) {
13        // still image input
14        return ggml_add(ctx0,
15            ggml_conv_2d(ctx0, model.patch_embeddings_0, inp_raw, patch_size, patch_size, 0, 0, 1, 1),
16            ggml_conv_2d(ctx0, model.patch_embeddings_1, inp_raw, patch_size, patch_size, 0, 0, 1, 1));
17    } else if (n_batch == 2) {
18        // 2 frames input (video input)
19        ggml_tensor * inp_0 = ggml_view_3d(ctx0, inp_raw,
20                                    img.nx(), img.ny(), 3, nb1, nb2, 0);
21        ggml_tensor * inp_1 = ggml_view_3d(ctx0, inp_raw,
22                                    img.nx(), img.ny(), 3, nb1, nb2,
23                                    nb2 * 3); // move to the second frame
24        return ggml_add(ctx0,
25            ggml_conv_2d(ctx0, model.patch_embeddings_0, inp_0, patch_size, patch_size, 0, 0, 1, 1),
26            ggml_conv_2d(ctx0, model.patch_embeddings_1, inp_1, patch_size, patch_size, 0, 0, 1, 1));
27    } else {
28        GGML_ASSERT(false && "n_batch > 2 is not supported");
29    }
30}
31
32ggml_cgraph * clip_graph_qwen2vl::build() {
33    GGML_ASSERT(model.patch_bias == nullptr);
34    GGML_ASSERT(model.class_embedding == nullptr);
35
36    const int batch_size       = 1;
37    const bool use_window_attn = hparams.n_wa_pattern > 0;
38    const int n_wa_pattern     = hparams.n_wa_pattern;
39    const int n_pos            = n_patches;
40    const int num_position_ids = n_pos * 4; // m-rope requires 4 dim per position
41
42    norm_type norm_t = proj_type == PROJECTOR_TYPE_QWEN25VL
43        ? NORM_TYPE_RMS // qwen 2.5 vl
44        : NORM_TYPE_NORMAL; // qwen 2 vl
45
46    int mrope_sections[4] = {d_head/4, d_head/4, d_head/4, d_head/4};
47
48    ggml_tensor * inp = build_inp_with_temporal_merge();
49
50    // second conv dimension
51    {
52        inp = ggml_permute(ctx0, inp, 1, 2, 0, 3);  // [w, h, c, b] -> [c, w, h, b]
53        inp = ggml_cont_4d(
54            ctx0, inp,
55            n_embd * 2, n_patches_x / 2, n_patches_y, batch_size);
56        inp = ggml_reshape_4d(
57            ctx0, inp,
58            n_embd * 2, n_patches_x / 2, 2, batch_size * (n_patches_y / 2));
59        inp = ggml_permute(ctx0, inp, 0, 2, 1, 3);
60        inp = ggml_cont_3d(
61            ctx0, inp,
62            n_embd, n_patches_x * n_patches_y, batch_size);
63    }
64
65    ggml_tensor * inpL           = inp;
66    ggml_tensor * window_mask    = nullptr;
67    ggml_tensor * window_idx     = nullptr;
68    ggml_tensor * inv_window_idx = nullptr;
69
70    ggml_tensor * positions = ggml_new_tensor_1d(ctx0, GGML_TYPE_I32, num_position_ids);
71    ggml_set_name(positions, "positions");
72    ggml_set_input(positions);
73
74    // pre-layernorm
75    if (model.pre_ln_w) {
76        inpL = build_norm(inpL, model.pre_ln_w, model.pre_ln_b, norm_t, eps, -1);
77    }
78
79    if (use_window_attn) {
80        // handle window attention inputs
81        inv_window_idx = ggml_new_tensor_1d(ctx0, GGML_TYPE_I32, n_pos / 4);
82        ggml_set_name(inv_window_idx, "inv_window_idx");
83        ggml_set_input(inv_window_idx);
84        // mask for window attention
85        window_mask = ggml_new_tensor_2d(ctx0, GGML_TYPE_F32, n_pos, n_pos);
86        ggml_set_name(window_mask, "window_mask");
87        ggml_set_input(window_mask);
88
89        // if flash attn is used, we need to pad the mask and cast to f16
90        if (flash_attn_type == CLIP_FLASH_ATTN_TYPE_ENABLED) {
91            window_mask = ggml_cast(ctx0, window_mask, GGML_TYPE_F16);
92        }
93
94        // inpL shape: [n_embd, n_patches_x * n_patches_y, batch_size]
95        GGML_ASSERT(batch_size == 1);
96        inpL = ggml_reshape_2d(ctx0, inpL, n_embd * 4, n_patches_x * n_patches_y * batch_size / 4);
97        inpL = ggml_get_rows(ctx0, inpL, inv_window_idx);
98        inpL = ggml_reshape_3d(ctx0, inpL, n_embd, n_patches_x * n_patches_y, batch_size);
99    }
100
101    // loop over layers
102    for (int il = 0; il < n_layer; il++) {
103        const auto & layer = model.layers[il];
104        const bool full_attn = use_window_attn ? (il + 1) % n_wa_pattern == 0 : true;
105
106        ggml_tensor * cur = inpL; // inpL = residual, cur = hidden_states
107
108        // layernorm1
109        cur = build_norm(cur, layer.ln_1_w, layer.ln_1_b, norm_t, eps, il);
110        cb(cur, "ln1", il);
111
112        // self-attention
113        {
114            ggml_tensor * Qcur = ggml_add(ctx0,
115                build_mm(layer.q_w, cur), layer.q_b);
116            ggml_tensor * Kcur = ggml_add(ctx0,
117                build_mm(layer.k_w, cur), layer.k_b);
118            ggml_tensor * Vcur = ggml_add(ctx0,
119                build_mm(layer.v_w, cur), layer.v_b);
120
121            Qcur = ggml_reshape_3d(ctx0, Qcur, d_head, n_head, n_patches);
122            Kcur = ggml_reshape_3d(ctx0, Kcur, d_head, n_head, n_patches);
123            Vcur = ggml_reshape_3d(ctx0, Vcur, d_head, n_head, n_patches);
124
125            cb(Qcur, "Qcur", il);
126            cb(Kcur, "Kcur", il);
127            cb(Vcur, "Vcur", il);
128
129            // apply M-RoPE
130            Qcur = ggml_rope_multi(
131                ctx0, Qcur, positions, nullptr,
132                d_head/2, mrope_sections, GGML_ROPE_TYPE_VISION, 32768, 10000, 1, 0, 1, 32, 1);
133            Kcur = ggml_rope_multi(
134                ctx0, Kcur, positions, nullptr,
135                d_head/2, mrope_sections, GGML_ROPE_TYPE_VISION, 32768, 10000, 1, 0, 1, 32, 1);
136
137            cb(Qcur, "Qcur_rope", il);
138            cb(Kcur, "Kcur_rope", il);
139
140            ggml_tensor * attn_mask = full_attn ? nullptr : window_mask;
141
142            cur = build_attn(layer.o_w, layer.o_b,
143                Qcur, Kcur, Vcur, attn_mask, kq_scale, il);
144            cb(cur, "attn_out", il);
145        }
146
147        // re-add the layer input, e.g., residual
148        cur = ggml_add(ctx0, cur, inpL);
149
150        inpL = cur; // inpL = residual, cur = hidden_states
151
152        cb(cur, "ffn_inp", il);
153
154        // layernorm2
155        cur = build_norm(cur, layer.ln_2_w, layer.ln_2_b, norm_t, eps, il);
156        cb(cur, "ffn_inp_normed", il);
157
158        // ffn
159        cur = build_ffn(cur,
160            layer.ff_up_w, layer.ff_up_b,
161            layer.ff_gate_w, layer.ff_gate_b,
162            layer.ff_down_w, layer.ff_down_b,
163            hparams.ffn_op, il);
164
165        cb(cur, "ffn_out", il);
166
167        // residual 2
168        cur = ggml_add(ctx0, inpL, cur);
169        cb(cur, "layer_out", il);
170
171        inpL = cur;
172    }
173
174    // post-layernorm
175    if (model.post_ln_w) {
176        inpL = build_norm(inpL, model.post_ln_w, model.post_ln_b, norm_t, eps, n_layer);
177    }
178
179    // multimodal projection
180    ggml_tensor * embeddings = inpL;
181    embeddings = ggml_reshape_3d(ctx0, embeddings, n_embd * 4, n_pos / 4, batch_size);
182    embeddings = build_ffn(embeddings,
183                        model.mm_0_w, model.mm_0_b,
184                        nullptr, nullptr,
185                        model.mm_1_w, model.mm_1_b,
186                        FFN_GELU,
187                        -1);
188
189    if (use_window_attn) {
190        window_idx = ggml_new_tensor_1d(ctx0, GGML_TYPE_I32, n_pos / 4);
191        ggml_set_name(window_idx, "window_idx");
192        ggml_set_input(window_idx);
193
194        // embeddings shape: [n_embd, n_patches_x * n_patches_y, batch_size]
195        GGML_ASSERT(batch_size == 1);
196        embeddings = ggml_reshape_2d(ctx0, embeddings, hparams.projection_dim, n_patches_x * n_patches_y / 4);
197        embeddings = ggml_get_rows(ctx0, embeddings, window_idx);
198        embeddings = ggml_reshape_3d(ctx0, embeddings, hparams.projection_dim, n_patches_x * n_patches_y / 4, batch_size);
199    }
200
201    // build the graph
202    ggml_build_forward_expand(gf, embeddings);
203
204    return gf;
205}