Serving Multimodal Models
A text server receives token IDs. A multimodal server may first have to fetch, decode, resize, sample, encode, and project an image, a video, or an audio clip. Those stages add their own queues and failure modes before language-model prefill begins. They may also produce hundreds or thousands of features whose count depends on the media and its preprocessing policy. Prompt length alone is therefore not enough for admission control.
This chapter covers two workloads that share media formats but little else. In media-input serving, an encoder supplies evidence to a language model, which then generates text. In media-generation serving, a model produces an image or video through an iterative or autoregressive process. The first extends the serving path developed in this part; the second needs a different cost model and scheduler.
Start with the fusion contract
The architecture determines where media features live and which cache pays for them. Two common contracts illustrate why there is no universal “visual token” cost (Qiu et al. 2025).
| Fusion contract | What enters the language backbone | Persistent state during text generation | Main serving consequence |
|---|---|---|---|
| Decoder-only fusion (also called projected-prefix or early fusion) | A connector maps media features to the language-model width and inserts them among the input embeddings. LLaVA is the canonical example (Liu et al. 2023). | The inserted positions normally create self-attention keys and values in the same cache allocation as text positions. They are continuous embeddings, not tokenizer-produced vocabulary IDs. | Media length increases language-model prefill, self-attention KV memory, and the KV bytes read during every decode step. |
| Cross-attention fusion | Text remains the self-attention sequence. Selected layers read a separate media memory through cross-attention. Flamingo resamples each image to 64 features before these layers (Alayrac et al. 2022). | Text self-attention KV and media cross-attention state are separate. The number of cross-attention layers and their cache implementation determine the media cost. | Media need not consume ordinary text positions, but encoding, cross-attention computation, and persistent media keys and values still cost time and memory. |
Discrete image or audio codes add another representation choice, but they do not remove this architectural question: after lookup, code IDs also become continuous vectors, and the model must still specify whether they join self-attention or a separate memory. Chapter 15 develops these model designs. Here, the important point is operational: capacity accounting is architecture-dependent.
Account for the input after preprocessing
For decoder-only fusion, let the final input length be
Here, is media item ; is the number of media items; is the decode, resize, crop, frame-sampling, and padding policy; identifies the media encoder revision; identifies the connector, merger, or resampler; returns the number of features inserted for one item; and and count text and model-specific separator positions. Every symbol is a deployment value. Counting raw image patches without , , and is not enough to predict the sequence seen by the language model.
If all positions remain in self-attention, their KV allocation is
In this expression, is the number of language-model layers that store self-attention KV state, is the number of key-value heads, is one head's width, and is the bytes used for each cached scalar. The factor 2 represents keys and values. This formula applies to the projected-prefix contract. A cross-attention model needs a separate term for media keys and values at the layers that actually contain cross-attention; it should not be charged as though every feature were an ordinary text prefix.
The time to first token has more stages as well:
Each is elapsed time in the named stage. Some terms can overlap, so the sum is an upper-level accounting model rather than a promise that every system runs them serially. It is still more useful than a single “prefill latency” number because it reveals whether a slow request waited for an encoder, crossed a network boundary, or occupied the language backbone.
Language prefill itself is not simply linear in media length. Dense layers add work roughly proportional to , while dense self-attention has a quadratic attention term in the combined sequence length. Optimized kernels change constants and memory traffic, not this distinction. During decode, each new text query also reads the retained media state: from the self-attention KV cache in decoder-only fusion or through the model's cross-attention path.
Derive visual length from the actual policy
For a fixed grid with preprocessed height , width , and patch dimensions , the raw patch count is
Here, and are dimensions after resizing, cropping, or padding; and are the patch height and width; and the ceiling accounts for a policy that pads incomplete edge patches. A policy that rejects or center-crops non-divisible dimensions has different behavior. The language-model count may then remove a class feature, add separators or a global view, concatenate several tiles, merge neighboring features, or replace the whole grid with a fixed number of resampler queries.
For example, LLaVA-1.5 uses a 336-pixel CLIP ViT-L/14 encoder. After the class feature is removed, its patch grid contributes 576 projected image positions (Liu et al. 2024). That is a model-specific result, not a generic property of CLIP or of 336-pixel images.
The runnable below isolates that one fixed-grid contract. It assumes divisible dimensions, no class or separator positions, no tiling or merge, and insertion of every patch into all 32 language-model layers. It uses explicit GQA head dimensions and reports binary MiB.
def visual_tokens(width, height, patch=14):
if width <= 0 or height <= 0 or patch <= 0:
raise ValueError("dimensions and patch must be positive")
if width % patch or height % patch:
raise ValueError("this fixed-grid example requires divisible dimensions")
return (width // patch) * (height // patch)
def kv_mib(tokens, layers=32, n_kv_heads=8, head_dim=128, bytes_per_value=2):
if min(tokens, layers, n_kv_heads, head_dim, bytes_per_value) <= 0:
raise ValueError("KV dimensions must be positive")
kv_bytes = 2 * layers * tokens * n_kv_heads * head_dim * bytes_per_value
return kv_bytes / 2**20
for width, height in [(336, 336), (672, 672)]:
tokens = visual_tokens(width, height)
print(f"{width}x{height}: {tokens:4d} visual tokens, {kv_mib(tokens):5.1f} MiB KV")
Real systems use several mechanisms to change this count:
- A fixed grid makes cost predictable but may resize away small text or small objects.
- Tiling preserves more spatial detail by encoding multiple supported crops. It is a trained model feature, not an arbitrary server-side operation; global views, overlap, separators, and padding make the final count model-specific.
- Dynamic resolution lets count vary with aspect ratio and input size. Qwen2-VL combines this policy with a visual merger and multimodal rotary positions, so its raw patch count and language-backbone count are not the same (Wang et al. 2024).
- A spatial merge or pixel shuffle folds neighboring spatial features into channels before projection. This shortens the sequence, but it does not by itself prove that fine detail was discarded; the trained connector decides what survives. InternVL 1.5 combines such a connector with dynamic tiling (Chen et al. 2024).
- A fixed-budget resampler maps a variable encoder grid to a chosen number of features. Language-model cost becomes predictable per media item, although the encoder and resampler still process the larger input (Alayrac et al. 2022).
- Token pruning removes features after some backbone layers. FastV, for example, applies a layer-2 attention-based policy to evaluated vision-language models and reports lower FLOPs (Chen et al. 2024). Earlier layers still pay for the full sequence; only later layers become cheaper. Attention weight is not a proof of causal importance, so aggressive pruning must be tested on OCR, charts, small text, and small objects rather than accepted from an average VQA score.
Video and audio add time as another length axis. A video policy may sample frames, form spatiotemporal patches, or merge across time. An audio policy may chunk a waveform or spectrogram into encoder frames. Duration, sample rate, frame rate, temporal stride, and per-request media limits therefore belong in the same capacity model as image resolution. None of these policies can be inferred from the user's text-token count.
The trained model defines valid preprocessing and connector choices, but the serving layer still chooses limits within that contract. Its resolution, tile, frame, duration, and downsampling rules choose the visual token count or audio feature count presented to the backbone. That choice is a serving-cost decision and a quality decision at the same time.
Schedule a resource vector, not a prompt length
A useful admission record describes the work before it reaches any queue. At a minimum it contains a resource vector with media bytes, decoded pixels, image count, video frames or audio duration, estimated encoder work, projected token count, text-token count, output-token limit, required model and adapter, and the applicable latency class. Limits should be checked before allocating large decoded buffers or accelerator memory.
The request then passes through two different batching problems:
- The media side benefits from shape buckets. Grouping compatible resolutions, frame counts, or audio lengths reduces padding waste and makes encoder kernels efficient. A single large item should not force every item in the batch to pad to its shape.
- The language side batches by total prefill and KV demand. It must reserve enough cache for the projected token count and output-token limit, and may chunk a long multimodal prefill so that it does not monopolize the engine.
Separate encoder and language-model queues make their backlogs visible. They also allow admission control and fairness policies to prevent a burst of high-resolution requests from causing head-of-line blocking for short text or small-image traffic. Production traces are commonly heavy-tailed and bursty, so averages hide the requests that set tail latency (Qiu et al. 2025).
Colocation keeps media features on the same accelerator and avoids network transfer, but encoder work can interfere with prefill and decode. Disaggregation lets encoder replicas scale independently and protects the language tier from a modality burst. Its cost is explicit: feature tensors must be serialized, transferred, routed, and invalidated across another service boundary. The transfer grows with feature count and width, and an undersized encoder pool or network simply becomes the new queue.
EPD systems separate encode, prefill, and decode for this reason. An ICML 2025 study reports that the stages have different resource profiles and benefits from independent placement (Singh et al. 2025). vLLM later exposed native encoder disaggregation and reported roughly 2--2.5 times goodput in specific Qwen3-VL benchmarks on four A100 GPUs (vLLM Multimodal Workstream 2025). Those figures demonstrate the mechanism; they are not a capacity promise for another model, workload, or network.
Cache the stage you intend to skip
“Image caching” can refer to three different objects. They have different keys and save different work.
| Cache | Stored object | A hit skips | Required identity |
|---|---|---|---|
| Processor cache | Decoded and normalized media or processor outputs | Fetch, decode, resize, frame sampling, or other CPU-side processing | Canonical media identity, decode library and preprocessor revision, policy parameters |
| Encoder-output cache | Media embeddings produced by the encoder and connector boundary | Encoder execution; language-model prefill still runs unless its prefix also hits | Processor identity plus encoder revision, projector revision, precision, and layout |
| KV prefix cache | Completed language-model KV blocks | Prefill for the exact cached prefix blocks | Model and adapter revision, exact prefix order and positions, media-derived embeddings or their stable identity, cache format, and block alignment |
vLLM, for example, manages encoder outputs by multimodal-item hash and reference count, separately from its language-model prefix cache (vLLM Project 2026). This separation matters. An encoder-output hit does not imply a KV prefix-cache hit, and a changed system prompt, adapter, preprocessing rule, or projector can invalidate one cache while leaving another usable.
Cache keys also need a tenant scope, authorization decision, collision-safe comparison, retention policy, and revision-based invalidation. Reuse across a conversation can be valuable for a document or repeated video, but global reuse must not reveal that another tenant supplied the same private media. Measure hit rate and saved stage time under the real workload before reserving a large cache.
Verify media-input serving end to end
Profile the complete request path under a replay that preserves modality mix, item counts, resolution, duration, text length, output length, and arrival bursts. Report p50, p95, and p99 rather than a single average.
For language-producing requests, record at least:
- ingress/decode time, preprocessing time, encoder queue and execution time, connector or transfer time, language queue time, time to first token, and inter-token latency;
- decoded pixels or frames, projected token count, peak encoder memory, peak KV memory, rejected or downsampled requests, and accelerator utilization by stage;
- processor, encoder cache hit rate, and KV prefix-cache hit rate, including bytes retained and time actually saved;
- goodput and tail latency at matched load, both for the total workload and for each modality and size bucket;
- answer quality at each shipped resolution, frame, merge, resampler, or pruning policy on the product's OCR, chart, small-object, multi-image, video, and audio tasks, compared with a full-detail baseline.
This measurement prevents two common mistakes: calling an optimization useful because one isolated kernel is faster, and calling compression safe because an aggregate benchmark hides the detail-sensitive cases.
Media generation is a different serving path
Media output should not be forced into the input-serving model. A common latent image pipeline has a text encoder, an iterative denoiser or flow model, and a latent decoder (Rombach et al. 2022). Other systems generate discrete visual codes autoregressively or predict coarse-to-fine blocks. The scheduler must know which contract it is running.
For an iterative latent model, a useful latency decomposition is
Here, is the number of solver steps or neural-function evaluations; identifies one step; is the latent state processed at that step; is the number of denoiser evaluations required at that step, including any guidance branches that are not fused; covers text or reference-media conditioning; is measured denoiser time for the chosen shape and batch; converts the final latent to media; and covers output encoding, storage, or delivery. The sum makes clear why fewer steps help without claiming that steps are the only cost.
Resolution and duration change the latent length. For a two-dimensional latent with image size , autoencoder compression , and transformer patch size , the latent token count is
In this formula, and are output pixels; and are the autoencoder's spatial compression factors; and are the denoiser's latent-patch dimensions; and is the number of latent tokens per denoiser evaluation. Video adds a temporal factor after temporal compression and patching. Dense global attention can add a quadratic term in ; local, factorized, or sparse attention changes that term.
The runnable computes a transparent token-pass proxy for a 1024-pixel square, 8-fold latent compression on each spatial axis, latent patches, and two guidance branches. It is not a FLOPs estimate: it omits attention shape, model width, fixed stages, communication, sparsity, batching, and utilization.
def latent_tokens(width, height, compression=8, patch=2):
if min(width, height, compression, patch) <= 0:
raise ValueError("all dimensions must be positive")
stride = compression * patch
return ((width + stride - 1) // stride) * ((height + stride - 1) // stride)
def token_pass_proxy(tokens, steps, guidance_branches=2):
if min(tokens, steps, guidance_branches) <= 0:
raise ValueError("tokens, steps, and branches must be positive")
return tokens * steps * guidance_branches
tokens = latent_tokens(1024, 1024)
base = token_pass_proxy(tokens, 50)
fast = token_pass_proxy(tokens, 4)
print(f"latent tokens: {tokens}")
print(f"50-step proxy: {base} token-passes")
print(f" 4-step proxy: {fast} token-passes")
print(f"denoiser-only ratio: {base / fast:.1f}x")
Progressive distillation, consistency models, and adversarial diffusion distillation show that a trained model can reduce neural-function evaluations from many steps to a few (Salimans and Ho 2022; Song et al. 2023; Sauer et al. 2024). The result is a new quality--latency point, not a free runtime switch: sampler, guidance, and step count can all change output quality and must be evaluated together.
Repeated denoising creates other serving opportunities. Compatible requests can batch at the same model, shape, and iteration, while mismatched step counts can cause head-of-line blocking or padding-like waste. A scheduler should support cancellation between iterations so abandoned jobs stop consuming accelerator time. Within a request, DeepCache reuses selected U-Net features across nearby steps (Ma et al. 2024), and DistriFusion partitions a high-resolution sample across devices using stale context from the previous step (Li et al. 2024). Both are method-specific approximations with quality and hardware assumptions, not generic KV-cache behavior.
A conventional bidirectional denoiser updates the whole latent repeatedly, so it does not provide independent finalized tokens like autoregressive text. Services can still decode and stream a preview, but preview cadence adds decoder work and a noisy intermediate image is not a completed result. Causal video is different again: CausVid generates frame blocks left to right and uses a KV cache, demonstrating that causal media generation can expose a streaming contract (Yin et al. 2025).
For media output, measure queue time, first-preview latency, final latency, neural-function evaluations, guidance branches, accelerator-seconds per output, cancellation waste, output encoding and egress, and quality at each step count, resolution, duration, sampler, and batch policy. Compare quality with matched prompts, seeds, and settings. A cheap output that no longer meets the product's quality target is not a serving improvement.
- Fixed or variable media budgets? Fixed resampling simplifies capacity planning. Dynamic resolution and tiling preserve more input detail but create a heavier-tailed workload. Neither policy is best across documents, natural images, video, and audio.
- Colocate or disaggregate? Disaggregation protects stages from interference and allows independent scaling. Colocation avoids transfer and can use idle capacity more efficiently. The answer depends on the measured stage mix and network, not the architecture diagram alone.
- Compress before or after seeing the prompt? Early merging and resampling save the most language-model work but cannot use deep prompt context. Later pruning can be query-aware but pays the early layers and complicates cache shapes.
- One serving engine or two? Input VLMs, iterative image generators, and causal video can share kernels and fleet management, but their admission units, batching constraints, progress semantics, and service objectives remain different.
The operating rule
Treat media policy as part of the service contract. Publish accepted formats, byte and dimension limits, image and frame counts, duration, resize or sampling behavior, token or feature ceilings, downsampling and rejection behavior, and output quality tiers. Then make the scheduler enforce the same contract used by capacity tests.
The point is not that every extra pixel is bad. It is that media capability has an explicit path through preprocessing, encoder work, persistent state, queueing, and quality. Once those terms are visible, encoder placement, image prefix caching, resolution limits, pruning, and step reduction become testable engineering choices instead of slogans.
Further reading
- Dosovitskiy et al., “An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale,” 2021. arXiv:2010.11929ViT shows that a pure Transformer applied directly to sequences of image patches matches or beats CNNs on image classification when pre-trained at sufficient scale.
- Alayrac et al., “Flamingo: a Visual Language Model for Few-Shot Learning” (the Perceiver Resampler and the fixed visual-token budget), 2022. arXiv:2204.14198Flamingo is a Visual Language Model (VLM) family that bridges frozen vision and language models with a Perceiver Resampler and gated cross-attention, enabling few-shot learning across 16 image and video understanding tasks.
- Liu et al., “Visual Instruction Tuning” (direct projection into the sequence), 2023. arXiv:2304.08485LLaVA connects a CLIP visual encoder to an LLM via a linear projection and applies visual instruction tuning on GPT-4-generated multimodal data to produce a general-purpose vision-language assistant.
- Wang et al., “Qwen2-VL: Enhancing Vision-Language Model's Perception of the World at Any Resolution” (naive dynamic resolution and multimodal rotary position embedding), 2024. arXiv:2409.12191Qwen2-VL introduces dynamic-resolution visual sequences and multimodal rotary position encoding across text, image, and video axes.
- Chen et al., “InternVL: Scaling up Vision Foundation Models and Aligning for Generic Visual-Linguistic Tasks” (scaling the vision encoder to six billion parameters), 2024. arXiv:2312.14238InternVL scales a vision transformer encoder to 6 billion parameters and progressively aligns it with language models through a learned middleware.
- Chen et al., “An Image is Worth 1/2 Tokens After Layer 2: Plug-and-Play Inference Acceleration for Large Vision-Language Models” (FastV), 2024. arXiv:2403.06764FastV prunes visual tokens in large vision-language models after layer 2 based on attention scores, achieving 45% FLOPs reduction with negligible performance loss.
- Qiu et al., “ModServe: Modality- and Stage-Aware Resource Disaggregation for Scalable Multimodal Model Serving” (systems analysis of decoder-only and cross-attention multimodal serving under production traces), 2025. arXiv:2502.00937ModServe measures heterogeneous multimodal inference stages and heavy-tailed production requests, then independently scales and places stages to meet tail-latency objectives.
- vLLM Multimodal Workstream, “Encoder Disaggregation for Scalable Multimodal Model Serving,” 2025. vllm.aivLLM's native encode-prefill-decode disaggregation, available since v0.11.1, independently scales a vision-encoder pool and reports about 2–2.5x goodput in its four-A100 Qwen3-VL benchmarks.
- Li et al., “DistriFusion: Distributed Parallel Inference for High-Resolution Diffusion Models” (one image split across GPUs by tolerating stale patch context), 2024. arXiv:2402.19481Splits a single high-resolution diffusion sample across GPUs via displaced patch parallelism, reusing the previous step's feature maps so workers communicate asynchronously, up to 6.1x lower latency with no quality loss.
- Ma et al., “DeepCache: Accelerating Diffusion Models for Free” (the diffusion counterpart of a KV cache: features reused across steps), 2024. arXiv:2312.00858A training-free method that caches high-level U-Net features across adjacent denoising steps and recomputes only the fast-changing parts, 2-4x faster with negligible quality loss.
- Salimans & Ho, “Progressive Distillation for Fast Sampling of Diffusion Models” (thousands of steps distilled down to single digits), 2022. arXiv:2202.00512Repeatedly distills a diffusion sampler into a student that needs half the steps, taking generation from thousands of steps down to as few as four at no more than the original training cost.
- Song et al., “Consistency Models” (map any trajectory point straight to the result: one-step generation), 2023. arXiv:2303.01469Models that map any point on the denoising trajectory directly to its origin, enabling one-step generation with optional multi-step refinement, trainable by distillation or from scratch.
- Sauer et al., “Adversarial Diffusion Distillation” (the method behind SDXL-Turbo: one-to-four-step synthesis), 2024. arXiv:2311.17042Combines score distillation with an adversarial loss for one-to-four-step sampling, the method behind SDXL-Turbo, reaching real-time synthesis that matches its teacher within four steps.
- Black Forest Labs, “Announcing Black Forest Labs” (FLUX.1 flow-matching model family, including a few-step distilled variant), 2024. bfl.aiBlack Forest Labs introduced the FLUX.1 flow-matching model family with a full model, an open-weight distilled model, and a faster hosted variant.
- Brooks et al., “Video generation models as world simulators” (a diffusion transformer over spacetime patches), 2024. openai.comThe Sora technical report: a diffusion transformer over spatiotemporal patches of video latents, with compute as the axis along which sample quality scales, up to a minute of generated video.
- Polyak & others, “Movie Gen: A Cast of Media Foundation Models” (a 73K-token context for sixteen seconds of HD video), 2024. arXiv:2410.13720Meta's media foundation models, whose video model carries a 73,000-token context for sixteen seconds of high-definition footage, against roughly four thousand latent tokens for one megapixel image.
- Yin et al., “From Slow Bidirectional to Fast Autoregressive Video Diffusion Models” (video generation rediscovers decode and the KV cache), 2025. arXiv:2412.07772CausVid distills a fifty-step bidirectional video diffusion model into a four-step causal generator and reports 9.4 FPS on one GPU after 1.3 seconds of initial latency using KV caching.
- Google DeepMind, “Genie 3: A New Frontier for World Models” (a request becomes a stateful per-user session with a frame deadline), 2025. deepmind.googleA real-time interactive world model generating 720p at 24fps with a short visual memory, turning a request from a batch job into a stateful per-user session with a tens-of-milliseconds frame deadline.
Comments
Log in to comment