metrale_model_engine/traits/model/
vision.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2
3//! 2026-09-26: `ModelVision`, one of the supertraits `Model` is made of. Its methods, default
4//! bodies and docs are the ones `Model` declared before the split.
5//!
6//! Owner: model-engine.
7//! Invariants: none beyond the types.
8
9use anyhow::Result;
10
11/// 2026-09-26: Vision-encoder input for prompts with images.
12pub trait ModelVision {
13    /// 2026-09-25: Encode images with the vision encoder and keep the embeddings for the next
14    /// prefill. Call it before `prefill_chunk` for a prompt with image pad tokens. Default:
15    /// `Ok(())`.
16    fn prepare_vision_embed(&self, _images: &[metrale_model_layers::VisionItem]) -> Result<()> {
17        Ok(())
18    }
19
20    /// 2026-09-25: Give every rank the same merged vision rows for this prompt. Otherwise only
21    /// rank 0 has the encoder's rows, the other ranks keep the pad-token embedding, and the
22    /// per-layer all-reduce mixes the two. The head calls it after the prompt broadcast and the
23    /// worker at the matching point, so the collective pairs. Default: `Ok(())`.
24    fn ep_sync_vision_embeds(&self, _tokens: &[u32]) -> Result<()> {
25        Ok(())
26    }
27
28    /// 2026-09-25: Encode the images of several requests in one encoder pass. Returns, per
29    /// request in order, `(patch_row_offset, grid_index_offset, num_images, patch_row_count)`
30    /// in the shared output buffer. Default: an empty `Vec`.
31    fn prepare_vision_embed_batched(
32        &self,
33        _per_request: &[Vec<metrale_model_layers::VisionItem>],
34    ) -> Result<Vec<(usize, usize, usize, usize)>> {
35        Ok(Vec::new())
36    }
37
38    /// 2026-09-25: Where the next `prefill_chunk` reads its vision rows in the batched encoder
39    /// output: row offset, grid index offset and image count; `(0, 0, 0)` resets. Default:
40    /// no-op.
41    fn set_vision_slice_base(&self, _row_base: usize, _grid_base: usize, _owned_images: usize) {}
42
43    /// 2026-09-25: Whether `tokens` holds a vision pad token, whose KV came from image
44    /// embeddings that re-prefilling the tokens cannot reproduce. Decode preemption then does
45    /// not pick the sequence for requeue-and-re-prefill unless it can be spilled. Default
46    /// `false`.
47    fn tokens_contain_vision_pad(&self, _tokens: &[u32]) -> bool {
48        false
49    }
50}