use crate::common::Tokenizer as TokTrait;
use crate::error::{LayaError, Result};
use std::path::Path;
use tokenizers::Tokenizer as HfTokenizer;
const FB_CLS: u32 = 50281;
const FB_SEP: u32 = 50282;
const FB_MASK: u32 = 50284;
const FB_PAD: u32 = 50283;
const FB_UNK: u32 = 50280;
const CLS_ALIASES: &[&str] = &["[CLS]", "<bos>", "<s>"];
const SEP_ALIASES: &[&str] = &["[SEP]", "<eos>", "</s>"];
const PAD_ALIASES: &[&str] = &["[PAD]", "<pad>"];
const MASK_ALIASES: &[&str] = &["[MASK]", "<mask>"];
const UNK_ALIASES: &[&str] = &["[UNK]", "<unk>"];
pub struct LayaTokenizer {
inner: HfTokenizer,
cls: u32,
sep: u32,
mask: u32,
pad: u32,
#[allow(dead_code)]
unk: u32,
mask_token: String,
}
impl LayaTokenizer {
pub fn from_file<P: AsRef<Path>>(path: P) -> Result<Self> {
let inner = HfTokenizer::from_file(path.as_ref())
.map_err(|e| LayaError::Tokenizer(e.to_string()))?;
Ok(Self::from_hf(inner))
}
pub fn encode_with_special(&self, text: &str, max_length: usize) -> Vec<u32> {
match self.inner.encode(text, true) {
Ok(enc) => {
let mut ids = enc.get_ids().to_vec();
ids.truncate(max_length);
ids
}
Err(_) => Vec::new(),
}
}
fn from_hf(inner: HfTokenizer) -> Self {
let (cls, _) = resolve(&inner, CLS_ALIASES, FB_CLS);
let (sep, _) = resolve(&inner, SEP_ALIASES, FB_SEP);
let (pad, _) = resolve(&inner, PAD_ALIASES, FB_PAD);
let (mask, mask_token) = resolve(&inner, MASK_ALIASES, FB_MASK);
let (unk, _) = resolve(&inner, UNK_ALIASES, FB_UNK);
LayaTokenizer {
inner,
cls,
sep,
mask,
pad,
unk,
mask_token,
}
}
}
fn resolve(tok: &HfTokenizer, aliases: &[&str], fallback: u32) -> (u32, String) {
for a in aliases {
if let Some(id) = tok.token_to_id(a) {
return (id, (*a).to_string());
}
}
(fallback, aliases[0].to_string())
}
impl TokTrait for LayaTokenizer {
fn cls_id(&self) -> u32 {
self.cls
}
fn sep_id(&self) -> u32 {
self.sep
}
fn mask_id(&self) -> u32 {
self.mask
}
fn pad_id(&self) -> u32 {
self.pad
}
fn mask_token(&self) -> &str {
&self.mask_token
}
fn encode(&self, text: &str) -> Vec<u32> {
match self.inner.encode(text, false) {
Ok(enc) => enc.get_ids().to_vec(),
Err(_) => Vec::new(),
}
}
}