use candle_core::DType;
use candle_core::Module;
use candle_core::Tensor;
use candle_nn::Embedding;
use candle_nn::VarBuilder;
use candle_nn::embedding;
use super::config::XlmRobertaFlashConfig;
use super::position::PositionScheme;
use crate::error::Result;
use crate::layers::layer_norm::LayerNorm;
use crate::models::xlm_roberta::embeddings::position_ids;
pub struct XlmRobertaFlashEmbeddings {
word: Embedding,
position: Option<Embedding>,
token_type: Embedding,
layer_norm: LayerNorm,
pad: u32,
}
impl XlmRobertaFlashEmbeddings {
pub fn load(
config: &XlmRobertaFlashConfig,
vb: VarBuilder,
scheme: PositionScheme,
) -> Result<Self> {
let position = match scheme {
PositionScheme::Rotary => None,
PositionScheme::Absolute => Some(embedding(
config.max_position_embeddings,
config.hidden_size,
vb.pp("embeddings").pp("position_embeddings"),
)?),
};
Ok(Self {
word: embedding(
config.vocab_size,
config.hidden_size,
vb.pp("embeddings").pp("word_embeddings"),
)?,
position,
token_type: embedding(
config.type_vocab_size,
config.hidden_size,
vb.pp("embeddings").pp("token_type_embeddings"),
)?,
layer_norm: LayerNorm::load(vb.pp("emb_ln"), config.hidden_size, config.layer_norm_eps)?,
pad: config.pad_token_id as u32,
})
}
pub(super) fn weights_dtype(&self) -> DType {
self.word.embeddings().dtype()
}
pub fn forward(&self, input_ids: &Tensor, token_type_ids: &Tensor) -> Result<Tensor> {
let mut summed = self.word.forward(input_ids)?;
if let Some(position) = &self.position {
let ids = position_ids(input_ids, self.pad)?;
summed = (summed + position.forward(&ids)?)?;
}
let summed = (summed + self.token_type.forward(token_type_ids)?)?;
Ok(self.layer_norm.forward(&summed)?)
}
}