pub(crate) mod bpe;
pub(crate) mod compile;
pub(crate) mod image;
use super::{
error::{Error, ImageField, Result, TokenizerImageDefect},
prompt::Prompt,
};
use bpe::{Encoded, TokenizerScratch};
use image::TokenizerImage;
#[derive(Debug, Clone, Copy)]
pub(crate) struct Sentinel {
pub(crate) prompt: Prompt<'static>,
pub(crate) text: &'static str,
pub(crate) split: SplitSpecialTokens,
pub(crate) ids: &'static [u32],
}
pub(crate) const UPSTREAM_SENTINELS: [Sentinel; 6] = [
Sentinel {
prompt: Prompt::Document(None),
text: "Café crème, naïve résumé",
split: SplitSpecialTokens::Recognize,
ids: &[
2, 3250, 236787, 7293, 1109, 1816, 236787, 62367, 100479, 236764, 120362, 118515, 1,
],
},
Sentinel {
prompt: Prompt::Bare,
text: "",
split: SplitSpecialTokens::Recognize,
ids: &[2, 1],
},
Sentinel {
prompt: Prompt::Bare,
text: "x\u{f0000}y",
split: SplitSpecialTokens::Recognize,
ids: &[2, 236781, 481, 414, 366, 366, 236762, 1],
},
Sentinel {
prompt: Prompt::Bare,
text: "<|image|>",
split: SplitSpecialTokens::Recognize,
ids: &[2, 258880, 1],
},
Sentinel {
prompt: Prompt::Bare,
text: "<|image|>",
split: SplitSpecialTokens::Split,
ids: &[2, 236820, 236909, 3304, 111038, 1],
},
Sentinel {
prompt: Prompt::Bare,
text: "<b> </b>",
split: SplitSpecialTokens::Recognize,
ids: &[2, 236820, 236763, 107068, 236763, 236813, 1],
},
];
impl TokenizerImage {
pub(crate) fn check_sentinels(
&self,
sentinels: &[Sentinel],
scratch: &mut TokenizerScratch,
) -> Result<()> {
let mut ids = Vec::new();
for sentinel in sentinels {
ids.clear();
self.encode_joint(
&sentinel.prompt,
sentinel.text,
sentinel.split,
scratch,
Encoded {
ids: &mut ids,
spans: None,
},
)?;
let got: Vec<u32> = ids.iter().map(|id| id.get()).collect();
if got != sentinel.ids {
return Err(Error::TokenizerImage(TokenizerImageDefect::new(
ImageField::Sentinel,
format!(
"{:?} for {:?} under {}",
sentinel.ids, sentinel.text, sentinel.split
),
format!("{got:?}"),
)));
}
}
Ok(())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, derive_more::Display)]
#[display("{}", self.as_str())]
pub enum SplitSpecialTokens {
Recognize,
Split,
}
impl SplitSpecialTokens {
#[inline]
pub const fn from_split(split: bool) -> Self {
if split { Self::Split } else { Self::Recognize }
}
#[inline]
pub const fn is_split(&self) -> bool {
matches!(self, Self::Split)
}
#[inline]
pub const fn as_str(&self) -> &'static str {
match self {
Self::Recognize => "recognize",
Self::Split => "split",
}
}
}
#[cfg(test)]
mod tests;