char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
733905474
char/aliceai-t5-moe
libmtmd dev guide
History
Please refer to multimodal.md for a broader context.
In short:
libmtmdstarted as a wrapper aroundlibllava/clip.cpp- Various components that used to be in
clip.cppare moved progressively to mtmd. For example, preprocessor is now part of mtmd
Terminologies
- mtmd: MulTiMoDal
- bitmap: representing a raw input data, for example: RGB image, PCM audio
- tiles / slices: for llava-uhd-style models, the preprocessor breaks a large input into smaller square images called tiles or slices
- chunk: a mtmd_input_chunk represents a preprocessed input that can then be passed through
mtmd_encode()
Pipeline
A typical pipeline of the core libmtmd is as follows:
- A bitmap (RGB image or PCM audio) is created
- Bitmap and the text prompt is provided to
mtmd_tokenize()that breaks the input into chunks- Alternatively,
mtmd_tokenize_from_parts()takes a list of pre-split text/media parts instead of a marker-based prompt - The tokenizer function first expands a "lazy" bitmap if it finds one. Typically, this is used by video, so that one media token corresponds to one input bitmap
- For models that support "fused" temporal frames like Qwen-VL, the tokenizer tries to merge pair of consecutive frames into one batch. Only bitmaps marked by
mtmd_bitmap_set_mergeable()are merged - The preprocessor will then be called, which produces a list of chunks
- Depending on the model itself, special tokens will be injected to separate image chunks (i.e. llava-uhd-style models)
- Alternatively,
- Multiple bitmaps may be batched together to form a larger
mtmd_batch() - Single image or batch is encoded, via
mtmd_encode()ormtmd_batch_encode() - Get the output embeddings
Helper
We provide a set of helper functions via mtmd_helper to make using libmtmd easier. The helper provides:
- Image, audio and video file decoding (for example, decode raw JPEG into RGB bitmap)
- Manage
llama_batchand calls tollama_decode
Audio generation support
Audio generation is added to mtmd in PR #26254
Currently, we support the 3-stage pipeline below which should cover most TTS models:
- Stage 1: Backbone / Semantic Stage: Backbone model accepts text prompt and reference voice as input
- Stage 2: Acoustic Detail Generator: A model takes the hidden state from backbone and generate audio details (usually as audio codes or mel-spectrogram)
- Stage 3: Waveform Reconstruction: Convert the semantic and acoustic data from previous stages to the final waveform
For example, Qwen3-TTS:
- Reference voice is encoded using ECAPA-TDNN speaker encoder (
speaker_encoder) - Text prompt and reference voice are processed via a backbone (
talker.model) - A model converts sampled semantic token and hidden state from stage 2 into a list of 15 acoustic codes (
talker.code_predictor) - 16 generated codes are converted into waveform (
code2wav)
API design constraints
Due to wide variety of audio generation pipelines, the mtmd_gen_audio system is designed to be flexible and reusable by new models.
mtmd_gen_audio is split into 2 main API:
- Core API
mtmd.h: handles main inference. Important: the API surface must be stateless; caller must handle state management and audio frame accumulation. - Helper API
mtmd-helper.h: provides a model-agnostic stateful API. Usage example can be found in thetools/ttsdirectory.
Checklist for porting new audio generation models to mtmd
- Make sure to consult merged PRs about adding new TTS models, especially reviewer comments
- Example: https://github.com/ggml-org/llama.cpp/pulls?q=is%3Apr+mtmd+tts+is%3Amerged
- Establish a list of reusable and missing components from the current mtmd implementation.
- For GGUF conversion:
- Backbone model should be converted to a normal text model (loadable via
libllama)- If model used hard-coded embedding row ID, append them to token embeddings and assign token name for them (see
qwen3tts.py) - If model have a specific output logits head for audio codes (usually semantic code), keep the head as-is and pad the logits at inference time (see
src/models/qwen3vl.cpp)
- If model used hard-coded embedding row ID, append them to token embeddings and assign token name for them (see
- Sidecar models (code2wav, bigvgan, etc) must live inside the mmproj GGUF (but can be in different
clip_contextif necessary)- Note: it should use
ggml_build_forward_selectto select graphs if multiple graphs living in the same context
- Note: it should use
- Reuse existing GGUF metadata key name and tensor name whenever possible; think twice before adding extensive changes to GGUF writer. For example, Qwen3-TTS hard-code part of the hparams to
clip.cppas they won't likely to change. - For tensor naming:
- Prefixed with
a.*for tensors used by speaker encoder pipeline - Prefixed with
a.gen.*for generation stages (code / mel-spectrogram / PCM generation)
- Prefixed with
- For GGUF metadata:
- Reuse as many existing keys as possible
- In most cases, you can hard-code model configs in the model graph class, or in
clip_hparams - If some values need to be exposed to the
mtmd_helperlayer, hard-code them inmtmd_helperand distinguish by pipeline andmtmd_gen_audio_info::model_variantif necessary - Do NOT add new GGUF metadata or new fields to
mtmd_gen_audio_infounless you can prove that you absolutely need them
- Backbone model should be converted to a normal text model (loadable via
- Make sure most of the changes happen inside
mtmd-helper-gen.cpp. A good PR looks like this:- 10-20% changes is to add new backbone (text) model and conversion
- 60% changes inside
mtmd-helper-gen.cpp - 10% changes inside
libmtmdandclip.cppsystems - The rest downstream code (CLI, server) should have no changes at all
- Update usage documentation in
tools/tts/README.md
IMPORTANT: If your model needs changes that don't fit the existing infrastructure, open an issue first for discussion.
No-go checklist (these will get the PR rejected and require discussion before proceeding):
- Violating the API design constraints stated above
- Adding a new model-specific binary: the API and binary surface must stay model-agnostic
1# libmtmd dev guide 2 3## History 4 5Please refer to [multimodal.md](../../docs/multimodal.md) for a broader context. 6 7In short: 8- `libmtmd` started as a wrapper around `libllava` / `clip.cpp` 9- Various components that used to be in `clip.cpp` are moved progressively to mtmd. For example, preprocessor is now part of mtmd 10 11## Terminologies 12 13- mtmd: **M**ul**T**i**M**o**D**al 14- bitmap: representing a raw input data, for example: RGB image, PCM audio 15- tiles / slices: for llava-uhd-style models, the preprocessor breaks a large input into smaller square images called tiles or slices 16- chunk: a mtmd_input_chunk represents a preprocessed input that can then be passed through `mtmd_encode()` 17 18## Pipeline 19 20A typical pipeline of the core libmtmd is as follows: 21- A bitmap (RGB image or PCM audio) is created 22- Bitmap and the text prompt is provided to `mtmd_tokenize()` that breaks the input into chunks 23- Alternatively, `mtmd_tokenize_from_parts()` takes a list of pre-split text/media parts instead of a marker-based prompt 24- The tokenizer function first expands a "lazy" bitmap if it finds one. Typically, this is used by video, so that one media token corresponds to one input bitmap 25- For models that support "fused" temporal frames like Qwen-VL, the tokenizer tries to merge pair of consecutive frames into one batch. Only bitmaps marked by `mtmd_bitmap_set_mergeable()` are merged 26- The preprocessor will then be called, which produces a list of chunks 27- Depending on the model itself, special tokens will be injected to separate image chunks (i.e. llava-uhd-style models) 28- Multiple bitmaps may be batched together to form a larger `mtmd_batch()` 29- Single image or batch is encoded, via `mtmd_encode()` or `mtmd_batch_encode()` 30- Get the output embeddings 31 32## Helper 33 34We provide a set of helper functions via `mtmd_helper` to make using libmtmd easier. The helper provides: 35- Image, audio and video file decoding (for example, decode raw JPEG into RGB bitmap) 36- Manage `llama_batch` and calls to `llama_decode` 37 38## Audio generation support 39 40Audio generation is added to mtmd in PR [#26254](https://github.com/ggml-org/llama.cpp/pull/26254) 41 42Currently, we support the 3-stage pipeline below which should cover most TTS models: 43- Stage 1: Backbone / Semantic Stage: Backbone model accepts text prompt and reference voice as input 44- Stage 2: Acoustic Detail Generator: A model takes the hidden state from backbone and generate audio details (usually as audio codes or mel-spectrogram) 45- Stage 3: Waveform Reconstruction: Convert the semantic and acoustic data from previous stages to the final waveform 46 47For example, Qwen3-TTS: 48- Reference voice is encoded using ECAPA-TDNN speaker encoder (`speaker_encoder`) 49- Text prompt and reference voice are processed via a backbone (`talker.model`) 50- A model converts sampled semantic token and hidden state from stage 2 into a list of 15 acoustic codes (`talker.code_predictor`) 51- 16 generated codes are converted into waveform (`code2wav`) 52 53### API design constraints 54 55Due to wide variety of audio generation pipelines, the `mtmd_gen_audio` system is designed to be flexible and reusable by new models. 56 57`mtmd_gen_audio` is split into 2 main API: 58- Core API `mtmd.h`: handles main inference. Important: the API surface must be stateless; caller must handle state management and audio frame accumulation. 59- Helper API `mtmd-helper.h`: provides a model-agnostic stateful API. Usage example can be found in the `tools/tts` directory. 60 61### Checklist for porting new audio generation models to mtmd 62 631. Make sure to consult merged PRs about adding new TTS models, especially reviewer comments 64- Example: https://github.com/ggml-org/llama.cpp/pulls?q=is%3Apr+mtmd+tts+is%3Amerged 652. Establish a list of reusable and missing components from the current mtmd implementation. 663. For GGUF conversion: 67- Backbone model should be converted to a normal text model (loadable via `libllama`) 68- If model used hard-coded embedding row ID, append them to token embeddings and assign token name for them (see `qwen3tts.py`) 69- If model have a specific output logits head for audio codes (usually semantic code), keep the head as-is and pad the logits at inference time (see `src/models/qwen3vl.cpp`) 70- Sidecar models (code2wav, bigvgan, etc) must live inside the mmproj GGUF (but can be in different `clip_context` if necessary) 71- Note: it should use `ggml_build_forward_select` to select graphs if multiple graphs living in the same context 72- Reuse existing GGUF metadata key name and tensor name whenever possible; think twice before adding extensive changes to GGUF writer. For example, Qwen3-TTS hard-code part of the hparams to `clip.cpp` as they won't likely to change. 73- For tensor naming: 74- Prefixed with `a.*` for tensors used by speaker encoder pipeline 75- Prefixed with `a.gen.*` for generation stages (code / mel-spectrogram / PCM generation) 76- For GGUF metadata: 77- Reuse as many existing keys as possible 78- In most cases, you can hard-code model configs in the model graph class, or in `clip_hparams` 79- If some values need to be exposed to the `mtmd_helper` layer, hard-code them in `mtmd_helper` and distinguish by pipeline and `mtmd_gen_audio_info::model_variant` if necessary 80- Do NOT add new GGUF metadata or new fields to `mtmd_gen_audio_info` unless you can prove that you absolutely need them 814. Make sure most of the changes happen inside `mtmd-helper-gen.cpp`. A good PR looks like this: 82- 10-20% changes is to add new backbone (text) model and conversion 83- 60% changes inside `mtmd-helper-gen.cpp` 84- 10% changes inside `libmtmd` and `clip.cpp` systems 85- The rest downstream code (CLI, server) should have no changes at all 865. Update usage documentation in `tools/tts/README.md` 87 88IMPORTANT: If your model needs changes that don't fit the existing infrastructure, **open an issue first for discussion**. 89 90No-go checklist (these will get the PR rejected and require discussion before proceeding): 91- Violating the API design constraints stated above 92- Adding a new model-specific binary: the API and binary surface must stay model-agnostic