ferritin_plms/esm3/layers/
transformer_stack.rs1use crate::esm3::layers::blocks::UnifiedTransformerBlock;
4use crate::esm3::models::esm3::ESM3Config;
5use crate::esm3::utils::affine3d::Affine3D;
6use candle_core::{Module, Result, Tensor};
7use candle_nn::{self as nn, VarBuilder};
8
9pub struct TransformerStack {
10 blocks: Vec<UnifiedTransformerBlock>,
11 norm: nn::LayerNorm,
12}
13
14impl TransformerStack {
15 pub fn load(vb: VarBuilder, config: &ESM3Config) -> Result<Self> {
16 let mut blocks = Vec::with_capacity(config.n_layers);
17 for i in 0..config.n_layers {
18 blocks.push(UnifiedTransformerBlock::load(
19 vb.pp(format!("blocks.{}", i)),
20 config,
21 i,
22 )?);
23 }
24
25 let norm_weight = vb.pp("norm").get((config.d_model,), "weight")?;
27 let norm = nn::LayerNorm::new_no_bias(norm_weight, 1e-5);
28
29 Ok(Self { blocks, norm })
30 }
31
32 pub fn forward(
42 &self,
43 x: &Tensor,
44 sequence_id: Option<&Tensor>,
45 affine: Option<&Affine3D>,
46 affine_mask: Option<&Tensor>,
47 chain_id: Option<&Tensor>,
48 ) -> Result<(Tensor, Tensor)> {
49 let mut x = x.clone();
50
51 for block in &self.blocks {
52 x = block.forward(&x, sequence_id, affine, affine_mask, chain_id)?;
53 }
54
55 let post_norm = self.norm.forward(&x)?;
56 Ok((post_norm, x))
57 }
58}