use candle_core::Tensor;
use candle_nn::VarBuilder;
use super::attention::NomicBertAttention;
use super::config::NomicBertConfig;
use super::mlp::NomicBertMlp;
use crate::error::Result;
use crate::layers::layer_norm::LayerNorm;
use crate::layers::mask::AttentionMask;
use crate::layers::rope::RotaryEmbedding;
pub struct NomicBertLayer {
attention: NomicBertAttention,
mlp: NomicBertMlp,
norm1: LayerNorm,
norm2: LayerNorm,
}
impl NomicBertLayer {
pub fn load(config: &NomicBertConfig, vb: VarBuilder) -> Result<Self> {
Ok(Self {
attention: NomicBertAttention::load(config, vb.clone())?,
mlp: NomicBertMlp::load(config, vb.clone())?,
norm1: LayerNorm::load(vb.pp("norm1"), config.n_embd, config.layer_norm_epsilon)?,
norm2: LayerNorm::load(vb.pp("norm2"), config.n_embd, config.layer_norm_epsilon)?,
})
}
pub fn forward(
&self,
hidden: &Tensor,
mask: &AttentionMask,
rope: &RotaryEmbedding,
) -> Result<Tensor> {
let attended = self.attention.forward(hidden, mask, rope)?;
let hidden = self.norm1.forward(&(attended + hidden)?)?;
let projected = self.mlp.forward(&hidden)?;
Ok(self.norm2.forward(&(projected + &hidden)?)?)
}
}