use candle_core::DType;
use serde::Deserialize;
use serde::Serialize;
use crate::models::MultiVectorHead;
use crate::models::xlm_roberta_flash::PositionScheme;
use crate::multi_vector::MaskedRowFill;
use crate::multi_vector::ScoreReduction;
use crate::registry::BackendSupport;
use crate::registry::CellException;
use crate::registry::DtypeBackendSupport;
use crate::registry::DtypeSupport;
use crate::registry::Family;
use crate::registry::Support;
use crate::registry::WeightsFormat;
use crate::registry::multi_vector::conventions::HeadConventions;
pub(crate) struct MultiVectorEntry {
pub id: &'static str,
pub family: Family,
pub head: MultiVectorHead,
pub default_max_length: usize,
pub keeps_cls_row: bool,
pub projection_in: usize,
pub projection_out: usize,
pub projection_bias: bool,
pub normalize: bool,
pub score_reduction: ScoreReduction,
pub query_marker: Option<&'static str>,
pub document_marker: Option<&'static str>,
pub query_length: Option<usize>,
pub attends_to_mask_tokens: bool,
pub masked_document_row_fill: MaskedRowFill,
pub position_scheme: Option<PositionScheme>,
pub cpu: Support,
pub metal: Support,
pub cuda: Support,
pub dtypes: DtypeSupport,
pub license: &'static str,
pub size_gb: f32,
pub phase: u8,
pub weights: WeightsFormat,
pub gated: bool,
pub accel_only_dtypes: &'static [DType],
pub cell_exceptions: &'static [CellException],
}
impl MultiVectorEntry {
pub fn descriptor(&self) -> MultiVectorDescriptor {
let backends = BackendSupport {
cpu: self.cpu,
metal: self.metal,
cuda: self.cuda,
};
MultiVectorDescriptor {
id: self.id.to_string(),
family: self.family,
head: self.head,
default_max_length: self.default_max_length,
keeps_cls_row: self.keeps_cls_row,
projection_in: self.projection_in,
projection_out: self.projection_out,
projection_bias: self.projection_bias,
normalize: self.normalize,
score_reduction: self.score_reduction,
query_marker: self.query_marker.map(str::to_string),
document_marker: self.document_marker.map(str::to_string),
query_length: self.query_length,
attends_to_mask_tokens: self.attends_to_mask_tokens,
masked_document_row_fill: self.masked_document_row_fill,
position_scheme: self.position_scheme,
backends,
dtype_backends: DtypeBackendSupport::derive(backends, self.dtypes, self.accel_only_dtypes)
.with_exceptions(self.cell_exceptions),
license: self.license.to_string(),
size_gb: self.size_gb,
phase: self.phase,
weights: self.weights,
gated: self.gated,
}
}
#[cfg(test)]
pub(crate) fn cells(&self) -> crate::registry::support::rules::Cells<'static> {
let descriptor = self.descriptor();
crate::registry::support::rules::Cells {
id: self.id,
backends: descriptor.backends,
dtypes: self.dtypes,
accel_only: self.accel_only_dtypes,
exceptions: self.cell_exceptions,
rows: descriptor.dtype_backends,
}
}
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[non_exhaustive]
pub struct MultiVectorDescriptor {
pub id: String,
pub family: Family,
pub head: MultiVectorHead,
pub default_max_length: usize,
pub keeps_cls_row: bool,
pub projection_in: usize,
pub projection_out: usize,
pub projection_bias: bool,
pub normalize: bool,
pub score_reduction: ScoreReduction,
pub query_marker: Option<String>,
pub document_marker: Option<String>,
pub query_length: Option<usize>,
pub attends_to_mask_tokens: bool,
pub masked_document_row_fill: MaskedRowFill,
pub position_scheme: Option<PositionScheme>,
pub backends: BackendSupport,
pub dtype_backends: DtypeBackendSupport,
pub license: String,
pub size_gb: f32,
pub phase: u8,
pub weights: WeightsFormat,
pub gated: bool,
}
impl MultiVectorDescriptor {
pub fn new(
id: impl Into<String>,
family: Family,
head: MultiVectorHead,
projection_in: usize,
projection_out: usize,
) -> Self {
let conventions = HeadConventions::of(head);
Self {
id: id.into(),
family,
head,
default_max_length: 512,
keeps_cls_row: conventions.keeps_cls_row,
projection_in,
projection_out,
projection_bias: conventions.projection_bias,
normalize: true,
score_reduction: conventions.score_reduction,
query_marker: conventions.query_marker.map(str::to_string),
document_marker: conventions.document_marker.map(str::to_string),
query_length: conventions.query_length,
attends_to_mask_tokens: conventions.attends_to_mask_tokens,
masked_document_row_fill: conventions.masked_document_row_fill,
position_scheme: (family == Family::XlmRobertaFlash).then_some(PositionScheme::Rotary),
backends: BackendSupport::untested(),
dtype_backends: DtypeBackendSupport::untested(),
license: "unknown".to_string(),
size_gb: 0.0,
phase: u8::MAX,
weights: conventions.weights,
gated: false,
}
}
}