char-fork/llama.cpp

git clone https://git.t4t.associates/char-fork/llama.cpp

Mads Marquartmtmd : add `const` in various places (#28307)f45576aa8

char/aliceai-t5-moe
12.8 KiB298 linesraw
1#ifndef MTMD_HELPER_H
2#define MTMD_HELPER_H
3
4#include "ggml.h"
5#include "llama.h"
6#include "mtmd.h"
7
8#include <stddef.h>
9#include <stdint.h>
10#include <stdbool.h>
11
12#ifdef __cplusplus
13extern "C" {
14#endif
15
16//
17// libmtmd helper functions
18//
19// Please note that these helpers are not guaranteed to be stable.
20// BREAKING CHANGES are expected.
21//
22
23struct mtmd_helper_video;
24typedef struct mtmd_helper_video mtmd_helper_video;
25
26struct mtmd_helper_video_init_params {
27    float fps_target;            // desired output fps; <= 0 means use the video's native fps, defaulted to 4.0f
28    const char * ffmpeg_bin_dir; // directory containing ffmpeg/ffprobe binaries; NULL means search PATH
29    int64_t timestamp_interval_ms; // interval for adding timestamp as text chunk (example: "[10m50.5s]"); <= 0 means no timestamp, defaulted to 5000ms
30    // TODO @ngxson : allow "placeholder" bitmap output for counting tokens
31};
32
33MTMD_API struct mtmd_helper_video_init_params mtmd_helper_video_init_params_default(void);
34
35// opt for mtmd_helper_bitmap_init_from_*()
36struct mtmd_helper_init_opt {
37    struct mtmd_helper_video_init_params video_params;
38};
39typedef struct mtmd_helper_init_opt mtmd_helper_init_opt;
40
41MTMD_API struct mtmd_helper_init_opt mtmd_helper_init_opt_default(void);
42
43// Set callback for all future logging events.
44// If this is not called, or NULL is supplied, everything is output on stderr.
45// Note: this also call mtmd_log_set() internally
46MTMD_API void mtmd_helper_log_set(ggml_log_callback log_callback, void * user_data);
47
48// Returns true if this build includes video support (MTMD_VIDEO was ON at compile time).
49MTMD_API bool mtmd_helper_support_video(const mtmd_context * ctx);
50
51struct mtmd_helper_bitmap_wrapper {
52    mtmd_bitmap * bitmap;
53    mtmd_helper_video * video_ctx;
54};
55
56// helper function to construct a mtmd_bitmap from a file
57// it calls mtmd_helper_bitmap_init_from_buf() internally
58// returns nullptr on failure
59// this function is thread-safe
60MTMD_API struct mtmd_helper_bitmap_wrapper mtmd_helper_bitmap_init_from_file(
61                    const mtmd_context * ctx,
62                    const char * fname,
63                    bool placeholder,
64                    struct mtmd_helper_init_opt opt);
65
66// helper function to construct a mtmd_bitmap from a buffer containing a file
67// supported formats:
68//     image: formats supported by stb_image: jpg, png, bmp, gif, etc.
69//            webp is decoded via ffmpeg, requires MTMD_VIDEO build with ffmpeg in PATH
70//     audio: formats supported by miniaudio: wav, mp3, flac
71// note:
72//   - for now, video input is only supported via C++ helper functions
73//   - audio files will be auto-detected based on magic bytes
74//   - output bitmap will have SHA-256 hash (hex string) as the ID
75// returns nullptr on failure
76// this function is thread-safe
77MTMD_API struct mtmd_helper_bitmap_wrapper mtmd_helper_bitmap_init_from_buf(
78                    const mtmd_context * ctx,
79                    const unsigned char * buf, size_t len,
80                    bool placeholder,
81                    struct mtmd_helper_init_opt opt);
82
83// helper to count the total number of tokens from a list of chunks, useful to keep track of KV cache
84MTMD_API size_t mtmd_helper_get_n_tokens(const mtmd_input_chunks * chunks);
85
86// helper to count the total position of tokens from a list of chunks, useful to keep track of n_past
87// normally, n_pos is equal to n_tokens, but for M-RoPE it is different
88MTMD_API llama_pos mtmd_helper_get_n_pos(const mtmd_input_chunks * chunks);
89
90// helper to get the list of relative positions corresponding to the embedding tokens, to be used by M-RoPE
91// out_pos must have length == mtmd_helper_get_n_tokens(image)
92MTMD_API void mtmd_helper_image_get_decoder_pos(const mtmd_image_tokens * image, llama_pos pos_0, struct mtmd_decoder_pos * out_pos);
93
94// helper function that automatically:
95// 1. run llama_decode() on text chunks
96// 2. run mtmd_encode_chunk() on image chunks, then mtmd_get_output_embd() and then llama_decode()
97// if any of the mtmd_encode_chunk() or llama_decode() calls return non-zero, stop and forward the error
98// otherwise, returns 0 on success
99// this function is NOT thread-safe
100MTMD_API int32_t mtmd_helper_eval_chunks(mtmd_context * ctx,
101                                         struct llama_context * lctx,
102                                         const mtmd_input_chunks * chunks,
103                                         llama_pos n_past,
104                                         llama_seq_id seq_id,
105                                         int32_t n_batch,
106                                         bool logits_last,
107                                         llama_pos * new_n_past);
108
109// works like mtmd_helper_eval_chunks(), but only for a single chunk
110// this function is NOT thread-safe
111MTMD_API int32_t mtmd_helper_eval_chunk_single(mtmd_context * ctx,
112                                               struct llama_context * lctx,
113                                               const mtmd_input_chunk * chunk,
114                                               llama_pos n_past,
115                                               llama_seq_id seq_id,
116                                               int32_t n_batch,
117                                               bool logits_last,
118                                               llama_pos * new_n_past);
119
120typedef int32_t (*mtmd_helper_post_decode_callback)(struct llama_batch batch, void * user_data);
121
122// helper function to decode an image whose embeddings have already been calculated
123// this helper will handle batching and pre/post decoding setup (for ex. gemma 3 requires non-causal attention)
124// ret 0 on success, -1 on chunk not being a valid image chunk, 1 on decode failure
125MTMD_API int32_t mtmd_helper_decode_image_chunk(mtmd_context * ctx,
126                                                struct llama_context * lctx,
127                                                const mtmd_input_chunk * chunk,
128                                                float * encoded_embd,
129                                                llama_pos n_past,
130                                                llama_seq_id seq_id,
131                                                int32_t n_batch,
132                                                llama_pos * new_n_past,
133                                                mtmd_helper_post_decode_callback callback,
134                                                void * user_data);
135
136//
137// video input helpers (requires ffmpeg/ffprobe installed on the system)
138// the notion of video only exists at the helper level, it is not visible to the core mtmd library
139//
140// NOTE: this implementation is model-agnostic, it can be used with any vision-capable model
141//       however, it may not be accurate for some specific models
142//       (this is expected for now, to keep the implementation simple)
143//
144
145struct mtmd_helper_video_info {
146    uint32_t width;
147    uint32_t height;
148    float    fps;      // effective fps (fps_target if set, else original video fps)
149    int32_t  n_frames; // estimated total frames at effective fps (-1 if unknown)
150};
151
152// note: mtmd_helper_video_init_params is defined at the top, as it is part of mtmd_helper_init_opt
153
154// returns NULL on failure (ffprobe not found, file unreadable, etc.)
155MTMD_API mtmd_helper_video * mtmd_helper_video_init(
156                    const struct mtmd_context * mctx,
157                    const char * path,
158                    struct mtmd_helper_video_init_params params);
159
160// Same as mtmd_helper_video_init(), but reads from an in-memory buffer.
161// The buffer is copied internally; the caller does not need to keep it alive.
162// Note: pipe input is not seekable, so seeking will use output-side seeking
163// (ffmpeg decodes and discards frames up to the target position).
164MTMD_API mtmd_helper_video * mtmd_helper_video_init_from_buf(
165                    const struct mtmd_context * mctx,
166                    const unsigned char * buf, size_t len,
167                    struct mtmd_helper_video_init_params params);
168MTMD_API void mtmd_helper_video_free(mtmd_helper_video * ctx);
169MTMD_API struct mtmd_helper_video_info mtmd_helper_video_get_info(const mtmd_helper_video * ctx);
170
171// Read the next item from the video stream; exactly one of out_bitmap or out_text is set per call.
172// *out_bitmap - heap-allocated; caller must free with mtmd_bitmap_free()
173// *out_text   - heap-allocated (always via strdup/malloc); caller must free with free()
174// returns 0 on success, -1 on EOF, -2 on error
175MTMD_API int32_t mtmd_helper_video_read_next(mtmd_helper_video * ctx,
176            mtmd_bitmap ** out_bitmap,
177            char ** out_text);
178
179// return true if model can be used for chat
180MTMD_API bool mtmd_helper_model_can_chat(const struct llama_context * lctx, const struct mtmd_context * mctx);
181
182//
183// Audio generation helpers
184// (early-stage experimental, subjected to breaking changes)
185//
186
187// audio generation helper context
188// contains accumulator for generated audio features and PCM audio
189struct mtmd_helper_gen_audio;
190typedef struct mtmd_helper_gen_audio mtmd_helper_gen_audio;
191
192enum mtmd_helper_gen_audio_outtype {
193    MTMD_HELPER_GEN_AUDIO_OUTTYPE_PCM, // raw PCM
194    MTMD_HELPER_GEN_AUDIO_OUTTYPE_WAV, // WAV PCM 16-bit LE, mono
195};
196struct mtmd_helper_gen_audio_inp {
197    llama_seq_id seq_id;
198
199    const char * prompt;
200    size_t       prompt_len;
201
202    mtmd_bitmap * speaker_ref; // optional, can be NULL
203    const char * lang; // optional, can be NULL
204
205    int32_t  top_k;
206    float    top_p;
207    uint32_t seed; // UINT32_MAX for random (default: random)
208
209    enum mtmd_helper_gen_audio_outtype out_type;
210};
211
212MTMD_API mtmd_helper_gen_audio * mtmd_helper_gen_audio_init(
213                                    struct llama_context * lctx,
214                                    struct mtmd_context * mctx);
215
216MTMD_API void mtmd_helper_gen_audio_free(mtmd_helper_gen_audio * ctx);
217
218MTMD_API void mtmd_helper_gen_audio_reset(mtmd_helper_gen_audio * ctx);
219
220MTMD_API int32_t mtmd_helper_gen_audio_set_input(
221                        mtmd_helper_gen_audio * ctx,
222                        const struct mtmd_helper_gen_audio_inp * inp);
223
224// processes at most n_batch prompt tokens per call
225// returns: >0 = number of prompt tokens remaining, 0 = done, <0 = error
226MTMD_API int32_t mtmd_helper_gen_audio_step_prompt(
227                        mtmd_helper_gen_audio * ctx,
228                        int32_t n_batch);
229
230// generates one frame; must only be called after step_prompt() has returned 0
231// sampled can be LLAMA_TOKEN_NULL for pipelines with no discrete backbone token
232// out_stop (optional) is set on end-of-speech, the caller must then stop the loop
233// h_state_out is valid until next step_gen() or reset() call, null if no frame is generated
234MTMD_API int32_t mtmd_helper_gen_audio_step_gen(
235                        mtmd_helper_gen_audio * ctx,
236                        llama_token sampled,
237                        const float *  h_state_in,
238                        const float ** h_state_out,
239                        bool * out_stop);
240
241// out_data valid until next get_output() or reset() call
242// out_n_samples (optional, can be NULL) receives the number of generated PCM samples
243MTMD_API int32_t mtmd_helper_gen_audio_get_output(
244                        mtmd_helper_gen_audio * ctx,
245                        int32_t * out_sample_rate,
246                        const char ** out_data,
247                        size_t * out_data_len,
248                        int64_t * out_n_samples);
249
250#ifdef __cplusplus
251} // extern "C"
252#endif
253
254#ifdef __cplusplus
255#include <set>
256#include <memory>
257
258namespace mtmd_helper {
259
260//
261// C++ wrappers
262//
263
264// video-related C++ wrappers
265struct mtmd_helper_video_deleter {
266    void operator()(mtmd_helper_video * val) { mtmd_helper_video_free(val); }
267};
268using video_ptr = std::unique_ptr<mtmd_helper_video, mtmd_helper_video_deleter>;
269
270// audio generation-related C++ wrappers
271struct mtmd_helper_gen_audio_deleter {
272    void operator()(mtmd_helper_gen_audio * val) { mtmd_helper_gen_audio_free(val); }
273};
274using gen_audio_ptr = std::unique_ptr<mtmd_helper_gen_audio, mtmd_helper_gen_audio_deleter>;
275struct gen_audio {
276    gen_audio_ptr ctx;
277    gen_audio(struct llama_context * lctx, struct mtmd_context * mctx) : ctx(mtmd_helper_gen_audio_init(lctx, mctx)) {}
278    void reset() {
279        mtmd_helper_gen_audio_reset(ctx.get());
280    }
281    int32_t set_input(const struct mtmd_helper_gen_audio_inp * inp) {
282        return mtmd_helper_gen_audio_set_input(ctx.get(), inp);
283    }
284    int32_t step_prompt(int32_t n_batch) {
285        return mtmd_helper_gen_audio_step_prompt(ctx.get(), n_batch);
286    }
287    int32_t step_gen(llama_token sampled, const float * h_state, const float ** h_state_out, bool * out_stop = nullptr) {
288        return mtmd_helper_gen_audio_step_gen(ctx.get(), sampled, h_state, h_state_out, out_stop);
289    }
290    int32_t get_output(int32_t * out_sample_rate, const char ** out_data, size_t * out_data_len, int64_t * out_n_samples = nullptr) {
291        return mtmd_helper_gen_audio_get_output(ctx.get(), out_sample_rate, out_data, out_data_len, out_n_samples);
292    }
293};
294
295} // namespace mtmd_helper
296#endif
297
298#endif