use std::ops::Range;
use burn::tensor::{Int, Tensor, backend::Backend, Device};
use combs_formats::{ModelMetadata, ModelSource};
use crate::Result;
use crate::kv::{CacheConfig, KVCache};
pub trait GenerativeModel<B: Backend>: Send {
fn metadata(&self) -> &ModelMetadata;
fn load(source: &dyn ModelSource, device: &Device<B>) -> Result<Self>
where
Self: Sized;
fn create_kv_cache(&self, config: &CacheConfig) -> Box<dyn KVCache<B>>;
fn embed(&self, tokens: Tensor<B, 2, Int>) -> Tensor<B, 3>;
fn embed_multimodal(
&self,
tokens: Tensor<B, 2, Int>,
images: &[Tensor<B, 4>],
) -> Result<Tensor<B, 3>> {
if !images.is_empty() {
return Err(crate::ModelError::UnsupportedMedia(format!(
"{} image(s) passed to a text-only model",
images.len()
)));
}
Ok(self.embed(tokens))
}
fn prefill(
&mut self,
input: Tensor<B, 3>,
cache: &mut dyn KVCache<B>,
pos: Range<u32>,
) -> Tensor<B, 2>;
fn decode(&mut self, input: Tensor<B, 3>, cache: &mut dyn KVCache<B>) -> Tensor<B, 2>;
}