| 825 | } |
| 826 | |
| 827 | int32_t mtmd_encode(mtmd_context * ctx, const mtmd_image_tokens * image_tokens) { |
| 828 | clip_ctx * ctx_clip = ctx->ctx_v; |
| 829 | if (!ctx_clip) { |
| 830 | LOG_ERR("%s: this API does not support non-vision input, please use mtmd_encode_chunk instead\n", __func__); |
| 831 | return 1; |
| 832 | } |
| 833 | int n_mmproj_embd = clip_n_mmproj_embd(ctx_clip); |
| 834 | ctx->image_embd_v.resize(image_tokens->n_tokens() * n_mmproj_embd); |
| 835 | bool ok = false; |
| 836 | |
| 837 | if (clip_is_llava(ctx_clip) |
| 838 | || clip_is_minicpmv(ctx_clip) |
| 839 | || clip_is_glm(ctx_clip)) { |
| 840 | // TODO @ngxson : llava does not support batched encoding ; this should be fixed inside clip_image_batch_encode() |
| 841 | const auto & entries = image_tokens->batch_f32.entries; |
| 842 | for (size_t i = 0; i < entries.size(); i++) { |
| 843 | int n_tokens_per_image = clip_n_output_tokens(ctx_clip, entries[i].get()); |
| 844 | ok = clip_image_encode( |
| 845 | ctx_clip, |
| 846 | ctx->n_threads, |
| 847 | entries[i].get(), |
| 848 | ctx->image_embd_v.data() + i*n_mmproj_embd*n_tokens_per_image); |
| 849 | } |
| 850 | } else { |
| 851 | ok = clip_image_batch_encode( |
| 852 | ctx_clip, |
| 853 | ctx->n_threads, |
| 854 | &image_tokens->batch_f32, |
| 855 | ctx->image_embd_v.data()); |
| 856 | } |
| 857 | |
| 858 | return ok ? 0 : 1; |
| 859 | } |
| 860 | |
| 861 | float * mtmd_get_output_embd(mtmd_context * ctx) { |
| 862 | return ctx->image_embd_v.data(); |
no test coverage detected