char-fork/llama.cpp

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

Saba Fallahmtmd: deepseek-ocr SAM ggml_conv_2d with the im2col kept in F32 (#26727)9731ad3f2

char/aliceai-t5-moe
18.2 KiB415 linesraw
1#include "models.h"
2
3// Implementation based on approach suggested by Acly
4// See: https://github.com/ggml-org/llama.cpp/pull/17383#issuecomment-3554227091
5static ggml_tensor * window_partition(ggml_context * ctx0, ggml_tensor * x, const int window) {
6    auto [c, w, h, b] = x->ne;
7    // same as
8    // x = ggml_win_part(m, x, window);
9    // x = ggml_reshape_3d(m, x, c, window * window, x->ne[3]);
10
11    const int64_t px  = (window - w % window) % window;
12    const int64_t py  = (window - h % window) % window;
13    const int64_t npw = (w + px) / window;
14    const int64_t nph = (h + py) / window;
15
16    ggml_tensor * cur = x;
17    if (px > 0 || py > 0) {
18        cur = ggml_pad(ctx0, cur, 0, static_cast<int>(px), static_cast<int>(py), 0);
19    }
20    cur = ggml_reshape_4d(ctx0, cur, c * window, npw, window, nph * b);
21    cur = ggml_cont(ctx0, ggml_permute(ctx0, cur, 0, 2, 1, 3));
22    cur = ggml_reshape_4d(ctx0, cur, c, window, window, npw * nph * b);
23    return cur;
24}
25
26// Implementation based on approach suggested by Acly
27// See: https://github.com/ggml-org/llama.cpp/pull/17383#issuecomment-3554227091
28static ggml_tensor * window_unpartition(ggml_context * ctx0,
29                                        ggml_tensor *  x,
30                                        const int      w,
31                                        const int      h,
32                                        const int      window) {
33    const int64_t c = x->ne[0];
34    // same as
35    // x = ggml_reshape_4d(m, x, c, window, window, x->ne[2]);
36    // x = ggml_win_unpart(m, x, w, h, window);
37
38    const int64_t px  = (window - w % window) % window;
39    const int64_t py  = (window - h % window) % window;
40    const int64_t npw = (w + px) / window;
41    const int64_t nph = (h + py) / window;
42
43    const int64_t b = x->ne[3] / (npw * nph);
44    ggml_tensor * cur = x;
45    cur = ggml_reshape_4d(ctx0, cur, c * window, window, npw, nph * b);
46    cur = ggml_cont(ctx0, ggml_permute(ctx0, cur, 0, 2, 1, 3));
47    cur = ggml_reshape_4d(ctx0, cur, c, w + px, h + py, b);
48    cur = ggml_view_4d(ctx0, cur, cur->ne[0], w, h, cur->ne[3], cur->nb[1], cur->nb[2], cur->nb[3], 0);
49    cur = ggml_cont(ctx0, cur);
50    return cur;
51}
52
53static ggml_tensor * get_rel_pos(ggml_context * ctx0,
54                                 ggml_tensor *  rel_pos,  // [L, C]
55                                 ggml_tensor *  indices,  // [q_size, k_size]
56                                 const int      q_size,
57                                 const int      k_size) {
58    const int64_t C = rel_pos->ne[0];  // channels
59    const int64_t L = rel_pos->ne[1];  // length
60
61    GGML_ASSERT(indices != nullptr);
62    GGML_ASSERT(indices->type == GGML_TYPE_I32);
63    GGML_ASSERT(indices->ne[0] == k_size);
64    GGML_ASSERT(indices->ne[1] == q_size);
65
66    const auto    max_rel_dist = 2 * std::max(q_size, k_size) - 1;
67    ggml_tensor * cur          = rel_pos;
68
69    if (max_rel_dist != L) {
70        // Linear interpolation
71        const int64_t ne0 = cur->ne[0];
72        const int64_t ne1 = cur->ne[1];
73        const int64_t ne2 = cur->ne[2];
74        const int64_t ne3 = cur->ne[3];
75
76        cur = ggml_reshape_3d(ctx0, ggml_cont(ctx0, ggml_permute(ctx0, cur, 1, 0, 2, 3)), ne1, 1, ne0 * ne2 * ne3);
77        cur = ggml_reshape_4d(
78            ctx0, ggml_interpolate(ctx0, cur, max_rel_dist, 1, ne0 * ne2 * ne3, 1, GGML_SCALE_MODE_BILINEAR),
79            max_rel_dist, ne0, ne2, ne3);
80        cur = ggml_cont(ctx0, ggml_permute(ctx0, cur, 1, 0, 2, 3));
81    }
82
83    // Flatten indices to 1D for ggml_get_rows
84    const int qk = q_size * k_size;
85
86    cur = ggml_reshape_3d(ctx0, ggml_get_rows(ctx0, cur, ggml_reshape_1d(ctx0, indices, qk)), C, k_size, q_size);
87
88    return cur;  // [C, k_size, q_size]
89}
90
91// ggml_conv_2d with the im2col kept in F32: the F16 im2col it emits since #23660 degrades OCR
92static ggml_tensor * conv_2d_f32(ggml_context * ctx0, ggml_tensor * a, ggml_tensor * b,
93                                 int s0, int s1, int p0, int p1, int d0, int d1) {
94    const ggml_type im2col_type = a->type == GGML_TYPE_F16 ? GGML_TYPE_F16 : GGML_TYPE_F32;
95    ggml_tensor * im2col = ggml_im2col(ctx0, a, b, s0, s1, p0, p1, d0, d1, true, im2col_type); // [N, OH, OW, IC * KH * KW]
96
97    ggml_tensor * result = ggml_mul_mat(ctx0,
98        ggml_reshape_2d(ctx0, im2col, im2col->ne[0], im2col->ne[3] * im2col->ne[2] * im2col->ne[1]),
99        ggml_reshape_2d(ctx0, a, (a->ne[0] * a->ne[1] * a->ne[2]), a->ne[3]));
100
101    result = ggml_reshape_4d(ctx0, result, im2col->ne[1], im2col->ne[2], im2col->ne[3], a->ne[3]); // [OC, N, OH, OW]
102    result = ggml_cont(ctx0, ggml_permute(ctx0, result, 0, 1, 3, 2)); // [N, OC, OH, OW]
103
104    return result;
105}
106
107
108ggml_tensor * clip_graph_deepseekocr::build_sam(ggml_tensor * inp_raw) {
109    // Building SAM
110    const int n_embd  = hparams.sam_n_embd;
111    const int n_layer = hparams.sam_n_layer;
112    const int n_heads = hparams.sam_n_head;
113    const int d_heads = n_embd / n_heads;
114    const int window  = hparams.attn_window_size;
115    // SAM stage runs its layernorms at 1e-6
116    const float sam_eps = 1e-6f;
117
118    ggml_tensor * inpL;
119
120    inpL = conv_2d_f32(ctx0, model.patch_embed_proj_w, inp_raw,
121                       (int) model.patch_embed_proj_w->ne[0], (int) model.patch_embed_proj_w->ne[1], 0, 0, 1, 1);
122    inpL = ggml_add(ctx0, inpL, ggml_reshape_3d(ctx0, model.patch_embed_proj_b, 1, 1, n_embd));
123    inpL = ggml_cont(ctx0, ggml_permute(ctx0, inpL, 1, 2, 0, 3));
124
125    ggml_tensor * rel_pos_indices_local;
126    ggml_tensor * rel_pos_indices_global;
127
128    rel_pos_indices_local  = ggml_new_tensor_2d(ctx0, GGML_TYPE_I32, window, window);
129    rel_pos_indices_global = ggml_new_tensor_2d(ctx0, GGML_TYPE_I32, inpL->ne[1], inpL->ne[2]);
130    ggml_set_name(rel_pos_indices_local, "rel_pos_indices_local");
131    ggml_set_name(rel_pos_indices_global, "rel_pos_indices_global");
132    ggml_set_input(rel_pos_indices_local);
133    ggml_set_input(rel_pos_indices_global);
134
135    ggml_tensor * cur;
136    const auto    tgt_size = inpL->ne[1];
137    const auto    str_size = model.pos_embed->ne[1];
138
139    if (str_size != tgt_size) {
140        ggml_tensor * old_pos_embed = nullptr;
141        old_pos_embed               = ggml_cont(ctx0, ggml_permute(ctx0, model.pos_embed, 2, 0, 1, 3));
142        ggml_tensor * new_pos_embed =
143            ggml_interpolate(ctx0, old_pos_embed, tgt_size, tgt_size, n_embd, 1, GGML_SCALE_MODE_BICUBIC);
144        new_pos_embed = ggml_cont(ctx0, ggml_permute(ctx0, new_pos_embed, 1, 2, 0, 3));
145        cur           = ggml_add(ctx0, inpL, new_pos_embed);
146    } else {
147        cur = ggml_add(ctx0, inpL, model.pos_embed);
148    }
149
150    // loop over layers
151    for (int il = 0; il < n_layer; il++) {
152        auto &        layer    = model.sam_layers[il];
153        ggml_tensor * shortcut = cur;
154
155        // layernorm1
156        cur = build_norm(cur, layer.ln_1_w, layer.ln_1_b, NORM_TYPE_NORMAL, sam_eps, il);
157
158        const int64_t w0 = cur->ne[1];
159        const int64_t h0 = cur->ne[2];
160
161        ggml_tensor * indices;
162
163        if (hparams.is_global_attn(il)) {
164            indices = rel_pos_indices_global;
165        } else {
166            // local attention layer - apply window partition
167            cur     = window_partition(ctx0, cur, window);
168            indices = rel_pos_indices_local;
169        }
170
171        const int64_t W = cur->ne[1];
172        const int64_t H = cur->ne[2];
173        // self-attention
174        {
175            const int B = cur->ne[3];
176
177            cur = ggml_mul_mat(ctx0, layer.qkv_w, cur);
178            cur = ggml_add(ctx0, cur, layer.qkv_b);
179            cur = ggml_reshape_4d(ctx0, cur, n_embd, 3, W * H, B);
180
181            ggml_tensor * Q;
182            ggml_tensor * K;
183            ggml_tensor * V;
184
185            Q = ggml_view_3d(ctx0, cur, n_embd, W * H, B, cur->nb[2], cur->nb[3], 0 * cur->nb[1]);
186            Q = ggml_reshape_4d(ctx0, ggml_cont(ctx0, Q), d_heads, n_heads, W * H, B);
187
188            K = ggml_view_3d(ctx0, cur, n_embd, W * H, B, cur->nb[2], cur->nb[3], 1 * cur->nb[1]);
189            K = ggml_reshape_4d(ctx0, ggml_cont(ctx0, K), d_heads, n_heads, W * H, B);
190
191            V = ggml_view_3d(ctx0, cur, n_embd, W * H, B, cur->nb[2], cur->nb[3], 2 * cur->nb[1]);
192            V = ggml_reshape_4d(ctx0, ggml_cont(ctx0, V), d_heads, n_heads, W * H, B);
193
194            ggml_tensor * mask;
195            ggml_tensor * rw;
196            ggml_tensor * rh;
197            ggml_tensor * qr;
198
199            rw = get_rel_pos(ctx0, layer.rel_pos_w, indices, W, W); // [W, W, C]
200            rh = get_rel_pos(ctx0, layer.rel_pos_h, indices, H, H); // [H, H, C]
201            qr = ggml_permute(ctx0, Q, 0, 2, 1, 3);
202            qr = ggml_reshape_4d(ctx0, ggml_cont(ctx0, qr), d_heads, W, H, B * n_heads);
203
204            rw = ggml_mul_mat(ctx0, rw,
205                              ggml_cont(ctx0, ggml_permute(ctx0, qr, 0, 2, 1, 3))); // [B*n_heads, W, H, W]
206            rw   = ggml_cont(ctx0, ggml_permute(ctx0, rw, 0, 2, 1, 3)); // [B*n_heads, H, W, W]
207            rw   = ggml_reshape_4d(ctx0, rw, W, 1, W * H, n_heads * B);
208            rw   = ggml_repeat_4d(ctx0, rw, W, H, W * H, n_heads * B);
209            rh   = ggml_mul_mat(ctx0, rh, qr); // [B*n_heads, H, W, H]
210            rh   = ggml_reshape_4d(ctx0, rh, 1, H, W * H, n_heads * B);
211            mask = ggml_add(ctx0, rw, rh); // [B*n_heads, H*W, H, W]
212            mask = ggml_reshape_4d(ctx0, mask, W * H, W * H, n_heads, B);
213            // casting mask to F16 only required when flash-attn is enabled
214            if (flash_attn_type == CLIP_FLASH_ATTN_TYPE_ENABLED) {
215                mask = ggml_cast(ctx0, mask, GGML_TYPE_F16);
216            }
217
218            const float scale = 1.0f / sqrtf(static_cast<float>(d_heads));
219
220            cur = build_attn(layer.o_w, layer.o_b, Q, K, V, mask, scale,
221                             il); // [B, H*W, n_embd]
222            cur = ggml_reshape_4d(ctx0, ggml_cont(ctx0, cur), n_embd, W, H, B);
223        }
224
225        if (hparams.is_global_attn(il) == false) {
226            // local attention layer - reverse window partition
227            cur = window_unpartition(ctx0, cur, w0, h0, window);
228        }
229
230        // re-add the layer input, e.g., residual
231        cur = ggml_add(ctx0, cur, shortcut);
232
233        ggml_tensor * inpFF = cur;
234
235        // layernorm2
236        cur = build_norm(inpFF, layer.ln_2_w, layer.ln_2_b, NORM_TYPE_NORMAL, sam_eps, il);
237
238        // ffn
239        cur = build_ffn(cur, layer.ff_up_w, layer.ff_up_b, nullptr, nullptr, layer.ff_down_w, layer.ff_down_b,
240                        hparams.ffn_op, il);
241
242        // residual 2
243        cur = ggml_add(ctx0, cur, inpFF);
244        cb(cur, "sam_layer_out", il);
245    }
246
247    cur = ggml_cont(ctx0, ggml_permute(ctx0, cur, 2, 0, 1, 3));
248
249    cur = conv_2d_f32(ctx0, model.neck_0_w, cur, 1, 1, 0, 0, 1, 1);
250    cur = ggml_cont(ctx0, ggml_permute(ctx0, cur, 1, 2, 0, 3));
251    cur = build_norm(cur, model.neck_1_w, model.neck_1_b, NORM_TYPE_NORMAL, sam_eps, -1);
252    cur = ggml_cont(ctx0, ggml_permute(ctx0, cur, 2, 0, 1, 3));
253
254    cur = conv_2d_f32(ctx0, model.neck_2_w, cur, 1, 1, 1, 1, 1, 1);
255    cur = ggml_cont(ctx0, ggml_permute(ctx0, cur, 1, 2, 0, 3));
256    cur = build_norm(cur, model.neck_3_w, model.neck_3_b, NORM_TYPE_NORMAL, sam_eps, -1);
257    cur = ggml_cont(ctx0, ggml_permute(ctx0, cur, 2, 0, 1, 3));
258
259    cur = conv_2d_f32(ctx0, model.net_2, cur, 2, 2, 1, 1, 1, 1);
260    cur = conv_2d_f32(ctx0, model.net_3, cur, 2, 2, 1, 1, 1, 1);
261    cb(cur, "sam_output", -1);
262
263    ggml_build_forward_expand(gf, cur);
264    return cur;
265}
266
267ggml_cgraph * clip_graph_deepseekocr::build() {
268    // patch embedding
269    ggml_tensor * inp_raw = build_inp_raw();
270
271    bool is_overview = img.add_viewsep;
272    int n_tiles_per_row = 0;
273    // number of separate "row" images batched together in this graph call
274    // (captured now, before n_batch below gets repurposed as the SAM/ViT batch size)
275    const int n_rows_batch = n_batch;
276
277    // note: we expect either a batch of rows or a batch of overviews, but not a mix of both
278
279    if (!is_overview) {
280        // handle the case where we have a batch of rows
281        // sanity check
282        for (auto & entry : img_batch->entries) {
283            if (entry.add_viewsep) {
284                throw std::runtime_error("DeepSeek-OCR: mixed overview and non-overview images in batch");
285            }
286            if (entry.nx() != img.nx() || entry.ny() != img.ny()) {
287                throw std::runtime_error("DeepSeek-OCR: mixed image sizes in batch");
288            }
289        }
290
291        GGML_ASSERT(img.ny() >= img.nx());
292        GGML_ASSERT(img.ny() % img.nx() == 0);
293        n_tiles_per_row = img.ny() / img.nx();
294
295        // each entry is one "row" image of shape [tile_size, tile_size * n_tiles_per_row, 3];
296        // merge the tile axis into the batch axis, giving a combined SAM input of shape
297        // [tile_size, tile_size, 3, n_tiles_per_row * n_rows_batch] (tile fast, row slow)
298        inp_raw = ggml_reshape_4d(ctx0, inp_raw, img.nx() * img.nx(), n_tiles_per_row, 3, n_rows_batch);
299        inp_raw = ggml_cont(ctx0, ggml_permute(ctx0, inp_raw, 0, 2, 1, 3));
300        inp_raw = ggml_reshape_4d(ctx0, inp_raw, img.nx(), img.nx(), 3, n_tiles_per_row * n_rows_batch);
301    }
302
303    ggml_tensor * sam_out = build_sam(inp_raw);
304
305    if (!is_overview) {
306        n_batch = n_tiles_per_row * n_rows_batch;
307    }
308
309    const int clip_n_patches = sam_out->ne[0] * sam_out->ne[1];
310
311    ggml_tensor * clip_out;
312    // Building DS-OCR CLIP
313    {
314        ggml_tensor * inp;
315
316        // sam_out: [patch_h, patch_w, n_embd, n_batch]
317        // -> [n_embd, clip_n_patches, n_batch]
318        inp = ggml_reshape_3d(ctx0, sam_out, clip_n_patches, sam_out->ne[2], sam_out->ne[3]);
319        inp = ggml_cont(ctx0, ggml_permute(ctx0, inp, 1, 0, 2, 3));
320
321        ggml_tensor * new_pos_embd = model.position_embeddings;
322
323        int        n_pos    = new_pos_embd->ne[1];  // +1 for [CLS]
324        const auto tgt_size = static_cast<int>(std::sqrt(inp->ne[1]));
325        const auto src_size = static_cast<int>(std::sqrt(n_pos - 1));
326
327        if (tgt_size != src_size) {
328            ggml_tensor * old_pos_embd;
329            ggml_tensor * cls_tok;
330
331            old_pos_embd = ggml_view_2d(ctx0, new_pos_embd, new_pos_embd->ne[0], src_size * src_size,
332                                        ggml_row_size(new_pos_embd->type, new_pos_embd->ne[0]), 0);
333            cls_tok      = ggml_view_2d(ctx0, new_pos_embd, new_pos_embd->ne[0], 1,
334                                        ggml_row_size(new_pos_embd->type, new_pos_embd->ne[0]), src_size * src_size);
335            new_pos_embd = ggml_interpolate(ctx0, old_pos_embd, tgt_size, tgt_size, new_pos_embd->ne[0], 1,
336                                            GGML_SCALE_MODE_BICUBIC);
337            new_pos_embd = ggml_reshape_3d(ctx0, new_pos_embd, n_embd, tgt_size * tgt_size, 1);
338            new_pos_embd = ggml_concat(ctx0, new_pos_embd, cls_tok, 1);
339            n_pos        = tgt_size * tgt_size + 1;
340        }
341
342        // add CLS token per batch item
343        // inp: [n_embd, clip_n_patches, n_batch]
344        // class_embedding: [n_embd] -> [n_embd, 1, n_batch]
345        ggml_tensor * cls_embd = ggml_repeat_4d(ctx0, model.class_embedding, n_embd, 1, n_batch, 1);
346        inp = ggml_concat(ctx0, cls_embd, inp, 1);
347
348        // for selecting learned pos embd, used by ViT
349        ggml_tensor * positions        = ggml_cast(ctx0, ggml_arange(ctx0, 0, n_pos, 1), GGML_TYPE_I32);
350        ggml_tensor * learned_pos_embd = ggml_get_rows(ctx0, new_pos_embd, positions);
351
352        ggml_tensor * cur = build_vit(inp, n_pos, NORM_TYPE_NORMAL, FFN_GELU_QUICK, learned_pos_embd, nullptr);
353
354        ggml_build_forward_expand(gf, cur);
355        clip_out = cur;
356    }
357
358    // sam_out: [patch_h, patch_w, n_embd, n_batch]
359    // -> [n_embd, clip_n_patches, n_batch]
360    sam_out  = ggml_cont(ctx0, ggml_permute(ctx0, sam_out, 1, 2, 0, 3));
361    sam_out  = ggml_reshape_3d(ctx0, sam_out, sam_out->ne[0], clip_n_patches, n_batch);
362
363    // clip_out: [n_embd, n_pos, n_batch] where n_pos = clip_n_patches + 1 (CLS)
364    // strip CLS token: skip first position, view only the patch tokens
365    clip_out = ggml_view_3d(ctx0, clip_out, n_embd, clip_n_patches, n_batch,
366                            clip_out->nb[1], clip_out->nb[2], clip_out->nb[1]);
367
368    ggml_tensor * cur;
369    cur = ggml_concat(ctx0, clip_out, sam_out, 0);
370    cur = ggml_mul_mat(ctx0, model.mm_fc_w, cur);
371    cur = ggml_add(ctx0, cur, model.mm_fc_b);
372
373    if (is_overview) {
374        // global view: weave one newline per row + trailing view separator
375        const auto h     = static_cast<int>(std::sqrt(static_cast<float>(cur->ne[1])));
376        const auto w     = h;
377        const auto n_dim = cur->ne[0];
378
379        ggml_tensor * imgnl = ggml_repeat_4d(ctx0, model.image_newline, n_dim, 1, h, n_batch);
380        cur = ggml_reshape_4d(ctx0, cur, n_dim, w, h, n_batch);
381        cur = ggml_reshape_3d(ctx0, ggml_concat(ctx0, cur, imgnl, 1), n_dim, (w + 1) * h, n_batch);
382        ggml_tensor * vs = ggml_repeat_4d(ctx0, model.view_seperator, n_dim, 1, n_batch, 1);
383        cur = ggml_concat(ctx0, cur, vs, 1);  // (n_dim, h*(w+1) + 1, n_batch)
384    } else {
385        // tile row: interleave tiles within each row, add newline per row
386        const int  grid_x = static_cast<int>(std::sqrt(static_cast<float>(clip_n_patches)));
387        const int  grid_y = grid_x;
388        const auto n_dim  = cur->ne[0];
389
390        // merge n_dim into the grid_x axis, freeing the 4th axis for n_rows_batch
391        // (n_dim, clip_n_patches, n_tiles_per_row * n_rows_batch) -> (n_dim*grid_x, grid_y, n_tiles_per_row, n_rows_batch)
392        cur = ggml_reshape_4d(ctx0, cur, n_dim * grid_x, grid_y, n_tiles_per_row, n_rows_batch);
393
394        // tiles: re-order from A.row0 A.row1 B.row0 B.row1 ...
395        //        to A.row0 B.row0 A.row1 B.row1 ...
396        //        then add nl: A.row0 B.row0 [nl] A.row1 B.row1 [nl] ...
397        // interleave tiles: -> (n_dim*grid_x, n_tiles_per_row, grid_y, n_rows_batch)
398        cur = ggml_cont(ctx0, ggml_permute(ctx0, cur, 0, 2, 1, 3));
399
400        // merge: -> (n_dim, grid_x*n_tiles_per_row, grid_y, n_rows_batch)
401        cur = ggml_reshape_4d(ctx0, cur, n_dim, grid_x * n_tiles_per_row, grid_y, n_rows_batch);
402
403        // append newline per row: (n_dim, grid_x*n_tiles_per_row+1, grid_y, n_rows_batch)
404        ggml_tensor * imgnl = ggml_repeat_4d(ctx0, model.image_newline, n_dim, 1, grid_y, n_rows_batch);
405        cur = ggml_concat(ctx0, cur, imgnl, 1);
406
407        // flatten: (n_dim, (grid_x*n_tiles_per_row+1)*grid_y, n_rows_batch)
408        cur = ggml_reshape_3d(ctx0, cur, n_dim, (grid_x * n_tiles_per_row + 1) * grid_y, n_rows_batch);
409    }
410
411    cb(cur, "dsocr_output", -1);
412
413    ggml_build_forward_expand(gf, cur);
414    return gf;
415}