use candle_core::Module;
use candle_core::Tensor;
use candle_nn::Linear;
use candle_nn::VarBuilder;
use candle_nn::linear;
use super::attention::MPNetAttention;
use super::config::MPNetConfig;
use crate::error::Result;
use crate::layers::activation::Activation;
use crate::layers::layer_norm::LayerNorm;
use crate::layers::mask::AttentionMask;
pub struct MPNetLayer {
attention: MPNetAttention,
intermediate: Linear,
activation: Activation,
output: Linear,
layer_norm: LayerNorm,
}
impl MPNetLayer {
pub fn load(config: &MPNetConfig, vb: VarBuilder) -> Result<Self> {
Ok(Self {
attention: MPNetAttention::load(config, vb.pp("attention"))?,
intermediate: linear(
config.hidden_size,
config.intermediate_size,
vb.pp("intermediate.dense"),
)?,
activation: config.hidden_act,
output: linear(
config.intermediate_size,
config.hidden_size,
vb.pp("output.dense"),
)?,
layer_norm: LayerNorm::load(
vb.pp("output.LayerNorm"),
config.hidden_size,
config.layer_norm_eps,
)?,
})
}
pub fn forward(&self, hidden: &Tensor, mask: &AttentionMask) -> Result<Tensor> {
let attended = self.attention.forward(hidden, mask)?;
let inner = self
.activation
.forward(&self.intermediate.forward(&attended)?)?;
let projected = self.output.forward(&inner)?;
Ok(self.layer_norm.forward(&(projected + attended)?)?)
}
}