ai00-core 0.5.1

An implementation of the RWKV language model in pure WebGPU.
Documentation
use bit_set::BitSet;
use bnf_sampler::sampler::{AcceptTokenResult, PossibleTokensResult, Sampler};

use super::Transformer;

#[derive(Debug)]
pub struct BnfSampler {
    sampler: Sampler,
    current_token_ids: BitSet,
}

impl BnfSampler {
    pub fn new(mut sampler: Sampler) -> Self {
        let current_token_ids = match sampler.all_possible_next_tokens(None) {
            Ok(PossibleTokensResult::Continue(tokens)) => tokens.clone(),
            _ => BitSet::new(),
        };
        Self {
            sampler,
            current_token_ids,
        }
    }

    #[inline]
    pub fn current_token_ids(&self) -> &BitSet {
        &self.current_token_ids
    }
}

impl std::ops::Deref for BnfSampler {
    type Target = Sampler;

    fn deref(&self) -> &Self::Target {
        &self.sampler
    }
}

impl std::ops::DerefMut for BnfSampler {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.sampler
    }
}

impl Transformer for BnfSampler {
    fn transform(&self, output: &mut [f32]) {
        output
            .iter_mut()
            .enumerate()
            .filter(|&(token, _)| !self.current_token_ids().contains(token))
            .for_each(|(_, logits)| *logits = f32::MIN)
    }

    fn update(&mut self, token: u16) -> bool {
        let token = Some(token as u32);
        let accept = self.accept_a_token(token).expect("invalid input token");
        self.current_token_ids = match self.sampler.all_possible_next_tokens(None) {
            Ok(PossibleTokensResult::Continue(tokens)) => tokens.clone(),
            _ => BitSet::new(),
        };
        match accept {
            AcceptTokenResult::Continue => false,
            AcceptTokenResult::End | AcceptTokenResult::Failed => true,
        }
    }
}