| 846 | } |
| 847 | |
| 848 | bool clip_image_batch_encode(const clip_ctx * ctx, const int n_threads, const clip_image_f32_batch * imgs, float * vec) { |
| 849 | |
| 850 | if (!ctx->has_vision_encoder) { |
| 851 | printf("This gguf file seems to have no vision encoder\n"); |
| 852 | return false; |
| 853 | } |
| 854 | |
| 855 | int batch_size = imgs->size; |
| 856 | if(ctx->has_llava_projector) { |
| 857 | GGML_ASSERT(batch_size == 1); // TODO: support multiple images |
| 858 | } |
| 859 | |
| 860 | // reset alloc buffer to clean the memory from previous invocations |
| 861 | ggml_allocr_reset(ctx->alloc); |
| 862 | |
| 863 | // build the inference graph |
| 864 | ggml_cgraph * gf = clip_image_build_graph(ctx, imgs); |
| 865 | ggml_allocr_alloc_graph(ctx->alloc, gf); |
| 866 | |
| 867 | struct ggml_cplan plan = ggml_graph_plan(gf, n_threads); |
| 868 | if (plan.work_size > 0) { |
| 869 | plan.work_data = (uint8_t *)malloc(plan.work_size); |
| 870 | } |
| 871 | |
| 872 | ggml_graph_compute(gf, &plan); |
| 873 | |
| 874 | // the last node is the embedding tensor |
| 875 | struct ggml_tensor * embeddings = gf->nodes[gf->n_nodes - 1]; |
| 876 | |
| 877 | // copy the embeddings to the location passed by the user |
| 878 | memcpy(vec, ggml_get_data_f32(embeddings), ggml_nbytes(embeddings)); |
| 879 | |
| 880 | if (plan.work_size > 0) { |
| 881 | free(plan.work_data); |
| 882 | } |
| 883 | |
| 884 | return true; |
| 885 | } |
| 886 | |
| 887 | bool clip_model_quantize(const char * fname_inp, const char * fname_out, const int itype) { |
| 888 |
no test coverage detected