}
};
+// Helper class to set non-causal attention via RAII
+class scope_non_causal {
+public:
+ scope_non_causal(llama_context * context, bool enabled) : context_(context), enabled_(enabled) {
+ if (enabled_) {
+ // TODO @ngxson : need to make sure only one image is processed at a time, and n_ubatch must be enough to hold the image
+ llama_set_causal_attn(context_, false);
+ }
+ }
+ ~scope_non_causal() {
+ if (enabled_) {
+ llama_set_causal_attn(context_, true);
+ }
+ }
+
+ scope_non_causal(const scope_non_causal &) = delete;
+ scope_non_causal & operator=(const scope_non_causal &) = delete;
+
+private:
+ llama_context * context_;
+ bool enabled_;
+};
+
// Helper function for decoding an image whose embeddings have already been calculated
int32_t mtmd_helper_decode_image_chunk(
mtmd_context * ctx,
}
const bool use_non_causal = mtmd_decode_use_non_causal(ctx, chunk);
- if (use_non_causal) {
- llama_set_causal_attn(lctx, false);
- // TODO @ngxson : need to make sure only one image is processed at a time, and n_ubatch must be enough to hold the image
- }
+ const scope_non_causal non_causal(lctx, use_non_causal);
while (i_batch < n_img_batches) { // split into batches
int pos_offset = i_batch*n_batch;
int32_t ret = llama_decode(lctx, batch_embd_view);
if (ret != 0) {
LOG_ERR("failed to decode %s\n", name);
- if (use_non_causal) {
- llama_set_causal_attn(lctx, true);
- }
return ret;
}
ret = callback(batch_embd_view, user_data);
if (ret != 0) {
LOG_ERR("post-decode callback failed\n");
- if (use_non_causal) {
- llama_set_causal_attn(lctx, true);
- }
return ret;
}
}
n_past += mtmd_input_chunk_get_n_pos(chunk);
*new_n_past = n_past;
- if (use_non_causal) {
- llama_set_causal_attn(lctx, true);
- }
return 0;
}