#include "models.h"
ggml_cgraph * clip_graph_qwen3a::build() {
ggml_tensor * inp = build_inp_raw(1);
const int64_t n_frames = inp->ne[0]; const int64_t n_mel = inp->ne[1]; const int64_t chunk_size = 100; const int64_t n_chunks = n_frames / chunk_size;
GGML_ASSERT(n_frames % chunk_size == 0); GGML_ASSERT(inp->type == GGML_TYPE_F32);
inp = ggml_view_4d(ctx0, inp,
chunk_size, n_mel, 1, n_chunks,
n_frames * (int64_t)sizeof(float), chunk_size * (int64_t)sizeof(float), chunk_size * (int64_t)sizeof(float), 0);
inp = ggml_cont(ctx0, inp);
cb(inp, "inp_chunks", -1);
{
auto conv_block = [&](ggml_tensor * x, ggml_tensor * w, ggml_tensor * b) {
x = ggml_conv_2d(ctx0, w, x, 2, 2, 1, 1, 1, 1);
if (b) {
x = ggml_add(ctx0, x, ggml_reshape_4d(ctx0, b, 1, 1, x->ne[2], 1));
}
return ggml_gelu_erf(ctx0, x);
};
inp = conv_block(inp, model.conv2d_1_w, model.conv2d_1_b);
inp = conv_block(inp, model.conv2d_2_w, model.conv2d_2_b);
inp = conv_block(inp, model.conv2d_3_w, model.conv2d_3_b);
cb(inp, "after_conv_blocks", -1);
}
inp = ggml_cont(ctx0, ggml_permute(ctx0, inp, 2, 0, 1, 3));
inp = ggml_reshape_2d(ctx0, inp, inp->ne[0] * inp->ne[1], inp->ne[2] * inp->ne[3]);
inp = ggml_mul_mat(ctx0, model.conv_out_w, inp);
if (model.conv_out_b) {
inp = ggml_add(ctx0, inp, model.conv_out_b);
}
cb(inp, "after_conv_out", -1);
const int64_t n_pos = inp->ne[1];
{
const int64_t tokens_per_chunk = n_pos / n_chunks; ggml_tensor * pos_tmp = ggml_view_2d(ctx0, model.position_embeddings,
model.position_embeddings->ne[0], tokens_per_chunk,
model.position_embeddings->nb[1], 0);
ggml_tensor * tgt = ggml_new_tensor_2d(ctx0, GGML_TYPE_F32,
model.position_embeddings->ne[0], n_pos);
inp = ggml_add(ctx0, inp, ggml_repeat(ctx0, pos_tmp, tgt));
}
ggml_tensor * cur = build_vit(inp, n_pos,
NORM_TYPE_NORMAL, hparams.ffn_op,
nullptr, nullptr);
cb(cur, "after_transformer", -1);
cur = build_ffn(cur,
model.mm_1_w, model.mm_1_b,
nullptr, nullptr,
model.mm_2_w, model.mm_2_b,
FFN_GELU_ERF, -1);
cb(cur, "projected", -1);
ggml_build_forward_expand(gf, cur);
return gf;
}