CoolFace
Datasetpublic

echodict/llama.cpp

version https://git-lfs.github.com/spec/v1 oid sha256:cfc44b7ba25614df70e6b65e3341cae0310163bd32fd31a6b928a542df433faf size 30786

sourceHugging Faceupdated 5mo agoView on Hugging Face
0likes765downloads
mtmd.h333 linesDownload Raw Back to mtmd
1#ifndef MTMD_H2#define MTMD_H3 4#include "ggml.h"5#include "llama.h"6 7#include <stddef.h>8#include <stdint.h>9#include <stdbool.h>10 11#ifdef __cplusplus12#include <string>13#include <vector>14#include <cinttypes>15#include <memory>16#endif17 18/**19 * libmtmd: A library for multimodal support in llama.cpp.20 *21 * WARNING: This API is experimental and subject to many BREAKING CHANGES.22 *          Issues related to API usage may receive lower priority support.23 *24 * For the usage, see an example in mtmd-cli.cpp25 *26 * For contributors:27 * - Make sure the C API is aligned with the libllama C API (as in llama.h)28 * - Do not include model name (e.g., qwen, gemma) in the API, use generic terms instead29 * - Keep the API minimal, do not expose internal details unless necessary30 *31 * IMPORTANT: The mtmd module does NOT accept pull requests that are fully or predominantly AI-generated.32 * We encourage human contributors to ensure the quality and reliability of the codebase.33 */34 35#ifdef LLAMA_SHARED36#    if defined(_WIN32) && !defined(__MINGW32__)37#        ifdef LLAMA_BUILD38#            define MTMD_API __declspec(dllexport)39#        else40#            define MTMD_API __declspec(dllimport)41#        endif42#    else43#        define MTMD_API __attribute__ ((visibility ("default")))44#    endif45#else46#    define MTMD_API47#endif48 49#ifdef __cplusplus50extern "C" {51#endif52 53enum mtmd_input_chunk_type {54    MTMD_INPUT_CHUNK_TYPE_TEXT,55    MTMD_INPUT_CHUNK_TYPE_IMAGE,56    MTMD_INPUT_CHUNK_TYPE_AUDIO,57};58 59// opaque types60struct mtmd_context;61struct mtmd_bitmap;62struct mtmd_image_tokens;63struct mtmd_input_chunk;64struct mtmd_input_chunks;65 66struct mtmd_input_text {67    const char * text;68    bool add_special;69    bool parse_special;70};71 72//73// C API74//75 76typedef struct mtmd_context      mtmd_context;77typedef struct mtmd_bitmap       mtmd_bitmap;78typedef struct mtmd_image_tokens mtmd_image_tokens;79typedef struct mtmd_input_chunk  mtmd_input_chunk;80typedef struct mtmd_input_chunks mtmd_input_chunks;81typedef struct mtmd_input_text   mtmd_input_text;82 83struct mtmd_context_params {84    bool use_gpu;85    bool print_timings;86    int n_threads;87    const char * image_marker; // deprecated, use media_marker instead88    const char * media_marker;89    enum llama_flash_attn_type flash_attn_type;90    bool warmup; // whether to run a warmup encode pass after initialization91 92    // limit number of image tokens, only for vision models with dynamic resolution93    int image_min_tokens; // minimum number of tokens for image input (default: read from metadata)94    int image_max_tokens; // maximum number of tokens for image input (default: read from metadata)95 96    // callback function passed over to mtmd proper97    ggml_backend_sched_eval_callback cb_eval;98    void * cb_eval_user_data;99};100 101MTMD_API const char * mtmd_default_marker(void);102 103MTMD_API struct mtmd_context_params mtmd_context_params_default(void);104 105// initialize the mtmd context106// return nullptr on failure107MTMD_API mtmd_context * mtmd_init_from_file(const char * mmproj_fname,108                                            const struct llama_model * text_model,109                                            const struct mtmd_context_params ctx_params);110 111MTMD_API void mtmd_free(mtmd_context * ctx);112 113// whether we need to set non-causal mask before llama_decode114// if chunk is nullptr, we assume the default case where chunk is an image chunk115MTMD_API bool mtmd_decode_use_non_causal(const mtmd_context * ctx, const mtmd_input_chunk * chunk);116 117// whether the current model use M-RoPE for llama_decode118MTMD_API bool mtmd_decode_use_mrope(const mtmd_context * ctx);119 120// whether the current model supports vision input121MTMD_API bool mtmd_support_vision(const mtmd_context * ctx);122 123// whether the current model supports audio input124MTMD_API bool mtmd_support_audio(const mtmd_context * ctx);125 126// get audio sample rate in Hz, for example 16000 for Whisper127// return -1 if audio is not supported128MTMD_API int mtmd_get_audio_sample_rate(const mtmd_context * ctx);129 130// mtmd_bitmap131//132// if bitmap is image:133//     length of data must be nx * ny * 3134//     the data is in RGBRGBRGB... format135// if bitmap is audio:136//     length of data must be n_samples * sizeof(float)137//     the data is in float format (PCM F32)138MTMD_API mtmd_bitmap *         mtmd_bitmap_init           (uint32_t nx, uint32_t ny, const unsigned char * data);139MTMD_API mtmd_bitmap *         mtmd_bitmap_init_from_audio(size_t n_samples,         const float         * data);140MTMD_API uint32_t              mtmd_bitmap_get_nx     (const mtmd_bitmap * bitmap);141MTMD_API uint32_t              mtmd_bitmap_get_ny     (const mtmd_bitmap * bitmap);142MTMD_API const unsigned char * mtmd_bitmap_get_data   (const mtmd_bitmap * bitmap);143MTMD_API size_t                mtmd_bitmap_get_n_bytes(const mtmd_bitmap * bitmap);144MTMD_API bool                  mtmd_bitmap_is_audio   (const mtmd_bitmap * bitmap);145MTMD_API void                  mtmd_bitmap_free       (mtmd_bitmap * bitmap);146// bitmap ID is optional, but useful for KV cache tracking147// these getters/setters are dedicated functions, so you can for example calculate the hash of the image based on mtmd_bitmap_get_data()148MTMD_API const char * mtmd_bitmap_get_id(const mtmd_bitmap * bitmap);149MTMD_API void         mtmd_bitmap_set_id(mtmd_bitmap * bitmap, const char * id);150 151 152// mtmd_input_chunks153//154// this is simply a list of mtmd_input_chunk155// the elements can only be populated via mtmd_tokenize()156MTMD_API mtmd_input_chunks *      mtmd_input_chunks_init(void);157MTMD_API size_t                   mtmd_input_chunks_size(const mtmd_input_chunks * chunks);158MTMD_API const mtmd_input_chunk * mtmd_input_chunks_get (const mtmd_input_chunks * chunks, size_t idx);159MTMD_API void                     mtmd_input_chunks_free(mtmd_input_chunks * chunks);160 161// mtmd_input_chunk162//163// the instance will be constructed via mtmd_tokenize()164// it will be freed along with mtmd_input_chunks165MTMD_API enum mtmd_input_chunk_type mtmd_input_chunk_get_type        (const mtmd_input_chunk * chunk);166MTMD_API const llama_token *        mtmd_input_chunk_get_tokens_text (const mtmd_input_chunk * chunk, size_t * n_tokens_output);167MTMD_API const mtmd_image_tokens *  mtmd_input_chunk_get_tokens_image(const mtmd_input_chunk * chunk);168MTMD_API size_t                     mtmd_input_chunk_get_n_tokens    (const mtmd_input_chunk * chunk);169// returns nullptr for ID on text chunk170MTMD_API const char *               mtmd_input_chunk_get_id          (const mtmd_input_chunk * chunk);171// number of temporal positions (equals to max(t,h,w) for M-RoPE; equals to n_tokens otherwise)172MTMD_API llama_pos                  mtmd_input_chunk_get_n_pos       (const mtmd_input_chunk * chunk);173 174// in case you want to use custom logic to handle the chunk (i.e. KV cache management)175// you can move the chunk ownership to your own code by copying it176// remember to free the chunk when you are done with it177MTMD_API mtmd_input_chunk * mtmd_input_chunk_copy(const mtmd_input_chunk * chunk);178MTMD_API void               mtmd_input_chunk_free(mtmd_input_chunk * chunk);179 180 181// mtmd_image_tokens182//183// the instance will be constructed via mtmd_tokenize()184// it will be freed along with mtmd_input_chunk185MTMD_API size_t       mtmd_image_tokens_get_n_tokens(const mtmd_image_tokens * image_tokens); // TODO: deprecate186MTMD_API const char * mtmd_image_tokens_get_id      (const mtmd_image_tokens * image_tokens); // TODO: deprecate187// number of temporal positions (equals to max(t,h,w) for M-RoPE; equals to n_tokens otherwise)188MTMD_API llama_pos    mtmd_image_tokens_get_n_pos   (const mtmd_image_tokens * image_tokens); // TODO: deprecate189 190DEPRECATED(MTMD_API size_t mtmd_image_tokens_get_nx(const mtmd_image_tokens * image_tokens),191           "use mtmd_image_tokens_get_decoder_pos() instead");192DEPRECATED(MTMD_API size_t mtmd_image_tokens_get_ny(const mtmd_image_tokens * image_tokens),193           "use mtmd_image_tokens_get_decoder_pos() instead");194 195struct mtmd_decoder_pos {196    uint32_t t;197    uint32_t x;198    uint32_t y;199    uint32_t z; // unused for now, reserved for future use200};201// get position for decoder attention, to be used by M-RoPE models202// i is the index of the embedding token, ranging from 0 to mtmd_image_tokens_get_n_tokens() - 1203// pos_0 is the absolute position of the first token204// return relative position (for example, embedding 0 will have position (0, 0, 0); remember to adjust it to the current absolute position)205MTMD_API struct mtmd_decoder_pos mtmd_image_tokens_get_decoder_pos(const mtmd_image_tokens * image_tokens, llama_pos pos_0, size_t i);206 207// tokenize an input text prompt and a list of bitmaps (images/audio)208// the prompt must have the input image marker (default: "<__media__>") in it209// the default marker is defined by mtmd_default_marker()210// the marker will be replaced with the image/audio chunk211// for example:212//   "here is an image: <__media__>\ndescribe it in detail."213//   this will gives 3 chunks:214//   1. "here is an image: <start_of_image>"215//   2. (image/audio tokens)216//   3. "<end_of_image>\ndescribe it in detail."217// number of bitmaps must be equal to the number of markers in the prompt218// this function is thread-safe (shared ctx)219// return values:220//   0 on success221//   1 on number of bitmaps not matching the number of markers222//   2 on image preprocessing error223MTMD_API int32_t mtmd_tokenize(mtmd_context * ctx,224                               mtmd_input_chunks * output,225                               const mtmd_input_text * text,226                               const mtmd_bitmap ** bitmaps,227                               size_t n_bitmaps);228 229// returns 0 on success230// TODO: deprecate231MTMD_API int32_t mtmd_encode(mtmd_context * ctx,232                             const mtmd_image_tokens * image_tokens);233 234// returns 0 on success235MTMD_API int32_t mtmd_encode_chunk(mtmd_context * ctx,236                                   const mtmd_input_chunk * chunk);237 238// get output embeddings from the last encode pass239// the reading size (in bytes) is equal to:240// llama_model_n_embd_inp(model) * mtmd_input_chunk_get_n_tokens(chunk) * sizeof(float)241MTMD_API float * mtmd_get_output_embd(mtmd_context * ctx);242 243// Set callback for all future logging events.244// If this is not called, or NULL is supplied, everything is output on stderr.245MTMD_API void mtmd_log_set(ggml_log_callback log_callback, void * user_data);246 247/////////////////////////////////////////248 249// test function, to be used in test-mtmd-c-api.c250MTMD_API mtmd_input_chunks * mtmd_test_create_input_chunks(void);251 252#ifdef __cplusplus253} // extern "C"254#endif255 256//257// C++ wrappers258//259 260#ifdef __cplusplus261 262namespace mtmd {263 264struct mtmd_context_deleter {265    void operator()(mtmd_context * val) { mtmd_free(val); }266};267using context_ptr = std::unique_ptr<mtmd_context, mtmd_context_deleter>;268 269struct mtmd_bitmap_deleter {270    void operator()(mtmd_bitmap * val) { mtmd_bitmap_free(val); }271};272using bitmap_ptr = std::unique_ptr<mtmd_bitmap, mtmd_bitmap_deleter>;273 274struct mtmd_input_chunks_deleter {275    void operator()(mtmd_input_chunks * val) { mtmd_input_chunks_free(val); }276};277using input_chunks_ptr = std::unique_ptr<mtmd_input_chunks, mtmd_input_chunks_deleter>;278 279struct mtmd_input_chunk_deleter {280    void operator()(mtmd_input_chunk * val) { mtmd_input_chunk_free(val); }281};282using input_chunk_ptr = std::unique_ptr<mtmd_input_chunk, mtmd_input_chunk_deleter>;283 284struct bitmap {285    bitmap_ptr ptr;286    bitmap() : ptr(nullptr) {}287    bitmap(mtmd_bitmap * bitmap) : ptr(bitmap) {}288    bitmap(bitmap && other) noexcept : ptr(std::move(other.ptr)) {}289    bitmap(uint32_t nx, uint32_t ny, const unsigned char * data) {290        ptr.reset(mtmd_bitmap_init(nx, ny, data));291    }292    ~bitmap() = default;293    uint32_t nx() const { return mtmd_bitmap_get_nx(ptr.get()); }294    uint32_t ny() const { return mtmd_bitmap_get_ny(ptr.get()); }295    const unsigned char * data() const { return mtmd_bitmap_get_data(ptr.get()); }296    size_t n_bytes() const { return mtmd_bitmap_get_n_bytes(ptr.get()); }297    std::string id() const { return mtmd_bitmap_get_id(ptr.get()); }298    void set_id(const char * id) const { mtmd_bitmap_set_id(ptr.get(), id); }299};300 301struct bitmaps {302    std::vector<bitmap> entries;303    ~bitmaps() = default;304    // return list of pointers to mtmd_bitmap305    // example:306    //   auto bitmaps_c_ptr = bitmaps.c_ptr();307    //   int32_t res = mtmd_tokenize(... bitmaps_c_ptr.data(), bitmaps_c_ptr.size());308    std::vector<const mtmd_bitmap *> c_ptr() {309        std::vector<const mtmd_bitmap *> res(entries.size());310        for (size_t i = 0; i < entries.size(); i++) {311            res[i] = entries[i].ptr.get();312        }313        return res;314    }315};316 317struct input_chunks {318    input_chunks_ptr ptr;319    input_chunks() = default;320    input_chunks(mtmd_input_chunks * chunks) : ptr(chunks) {}321    ~input_chunks() = default;322    size_t size() const { return mtmd_input_chunks_size(ptr.get()); }323    const mtmd_input_chunk * operator[](size_t idx) const {324        return mtmd_input_chunks_get(ptr.get(), idx);325    }326};327 328} // namespace mtmd329 330#endif331 332#endif333