@@ -314,11 +314,17 @@ ggml_tensor * clip_graph::build_vit(
314314 std::function<ggml_tensor *(ggml_tensor *, const clip_layer &)> add_pos,
315315 const build_vit_opts & opts
316316 ) {
317+ // batch dim: inp is [n_embd, n_pos] (B==1) or [n_embd, n_pos, B] (multi-tile encode)
318+ const int64_t B = inp->ne [2 ];
319+
317320 if (learned_pos_embd) {
318321 inp = ggml_add (ctx0, inp, learned_pos_embd);
319322 cb (inp, " pos_embed" , -1 );
320323 }
321324
325+ // flatten batch; unflatten again in attention
326+ inp = ggml_reshape_2d (ctx0, inp, n_embd, n_pos * B);
327+
322328 ggml_tensor * inpL = inp;
323329
324330 // pre-layernorm
@@ -348,20 +354,24 @@ ggml_tensor * clip_graph::build_vit(
348354 cur = ggml_add (ctx0, cur, layer.qkv_b );
349355 }
350356
351- Qcur = ggml_view_3d (ctx0, cur, d_head, n_head, n_pos,
352- /* nb1 */ ggml_row_size (cur->type , d_head),
353- /* nb2 */ cur->nb [1 ],
354- /* offset */ 0 );
355-
356- Kcur = ggml_view_3d (ctx0, cur, d_head, n_head, n_pos,
357- /* nb1 */ ggml_row_size (cur->type , d_head),
358- /* nb2 */ cur->nb [1 ],
359- /* offset */ ggml_row_size (cur->type , n_embd));
360-
361- Vcur = ggml_view_3d (ctx0, cur, d_head, n_head, n_pos,
362- /* nb1 */ ggml_row_size (cur->type , d_head),
363- /* nb2 */ cur->nb [1 ],
364- /* offset */ ggml_row_size (cur->type , 2 * n_embd));
357+ // Q/K/V as [d_head, n_head, n_pos, B], the batch stride is cur->nb[1]*n_pos.
358+ Qcur = ggml_view_4d (ctx0, cur, d_head, n_head, n_pos, B,
359+ /* nb1 */ ggml_row_size (cur->type , d_head),
360+ /* nb2 */ cur->nb [1 ],
361+ /* nb3 */ cur->nb [1 ] * n_pos,
362+ /* offset */ 0 );
363+
364+ Kcur = ggml_view_4d (ctx0, cur, d_head, n_head, n_pos, B,
365+ /* nb1 */ ggml_row_size (cur->type , d_head),
366+ /* nb2 */ cur->nb [1 ],
367+ /* nb3 */ cur->nb [1 ] * n_pos,
368+ /* offset */ ggml_row_size (cur->type , n_embd));
369+
370+ Vcur = ggml_view_4d (ctx0, cur, d_head, n_head, n_pos, B,
371+ /* nb1 */ ggml_row_size (cur->type , d_head),
372+ /* nb2 */ cur->nb [1 ],
373+ /* nb3 */ cur->nb [1 ] * n_pos,
374+ /* offset */ ggml_row_size (cur->type , 2 * n_embd));
365375
366376 if (layer.q_norm ) {
367377 GGML_ASSERT (layer.q_norm ->ne [0 ] == Qcur->ne [0 ]);
@@ -406,9 +416,9 @@ ggml_tensor * clip_graph::build_vit(
406416 }
407417 }
408418
409- Qcur = ggml_reshape_3d (ctx0, Qcur, d_head, n_head, n_pos);
410- Kcur = ggml_reshape_3d (ctx0, Kcur, d_head, n_head_kv, n_pos);
411- Vcur = ggml_reshape_3d (ctx0, Vcur, d_head, n_head_kv, n_pos);
419+ Qcur = ggml_reshape_4d (ctx0, Qcur, d_head, n_head, n_pos, B );
420+ Kcur = ggml_reshape_4d (ctx0, Kcur, d_head, n_head_kv, n_pos, B );
421+ Vcur = ggml_reshape_4d (ctx0, Vcur, d_head, n_head_kv, n_pos, B );
412422
413423 if (norm_per_head) {
414424 if (layer.q_norm ) {
@@ -438,6 +448,7 @@ ggml_tensor * clip_graph::build_vit(
438448 cb (Vcur, " Vcur_normed" , il);
439449 }
440450
451+ // build_attn returns a flat 2D [n_embd, n_pos*B]
441452 cur = build_attn (layer.o_w , layer.o_b ,
442453 Qcur, Kcur, Vcur, opts.attn_mask , kq_scale, il);
443454 cb (cur, " attn_out" , il);
@@ -509,6 +520,10 @@ ggml_tensor * clip_graph::build_vit(
509520 if (model.post_ln_w ) {
510521 inpL = build_norm (inpL, model.post_ln_w , model.post_ln_b , norm_t , eps, -1 );
511522 }
523+
524+ // restore the batch dim
525+ GGML_ASSERT (inpL->ne [1 ] % B == 0 );
526+ inpL = ggml_reshape_3d (ctx0, inpL, n_embd, inpL->ne [1 ] / B, B);
512527 return inpL;
513528}
514529
0 commit comments