Models / modernbert-base

ModernBERT-base

Answer.AI's 2024 redesign of the BERT encoder: 22 pre-norm layers of width 768, rotary positions, GeGLU, no biases, and a sliding attention window that opens up every third layer.

149M parametersmodernbertApache-2.0fill-maskfeature-extractionencoder-onlyrotary-embeddingssliding-window-attention

The forward entry with one level of blocks expanded. Every edge carries the tensor type the compiler inferred at that point, in the model's own generics.

ModernBERT-base: forwardModernBERT-base: forward

Entries ​

EntrySignature
forwardforward<B: Dim, S: Dim>(tokens: Tensor[B, S; i32]) -> Tensor[B, S, D; T]

Generics ​

The root block's generics as this checkpoint binds them.

Vocab50368
D768
Heads12
Inner1152
Layers22
Window128
Period3
Tf32

Blocks ​

Every block of the program with its members and functions, as linnet inspect prints them.

Attention ​

text
modernbert::Attention<D: Dim, Heads: Dim, T: Float>
  sub qkv: Dense<D, 3 * D, T>
  sub out: Dense<D, D, T>
  pub fn forward<B: Dim, S: Dim>(x: Tensor[B, S, D; T], theta: f32, window: Tensor[S, S; bool]?) -> Tensor[B, S, D; T]

Dense ​

text
modernbert::Dense<In: Dim, Out: Dim, T: Float>
  param weight: Tensor[Out, In; T]
  pub fn forward<*S: Shape>(x: Tensor[*S, In; T]) -> Tensor[*S, Out; T]

Embedding ​

text
std.nn.embedding::Embedding<Vocab: Dim, H: Dim, T: Float = bf16>
  param weight: Tensor[Vocab, H; T]
  pub fn forward<*S: Shape>(ids: Tensor[*S; i32]) -> Tensor[*S, H; T]

Embeddings ​

text
modernbert::Embeddings<Vocab: Dim, D: Dim, T: Float>
  sub tok_embeddings: Embedding<Vocab, D, T>
  sub norm: Norm<D, T>
  pub fn forward<*S: Shape>(ids: Tensor[*S; i32]) -> Tensor[*S, D; T]

EncoderLayer ​

text
modernbert::EncoderLayer<D: Dim, Heads: Dim, Inner: Dim, T: Float>
  sub attn_norm: Norm<D, T>
  sub attn: Attention<D, Heads, T>
  sub mlp_norm: Norm<D, T>
  sub mlp: GeGlu<D, Inner, T>
  pub fn forward<B: Dim, S: Dim>(x: Tensor[B, S, D; T], theta: f32, window: Tensor[S, S; bool]?) -> Tensor[B, S, D; T]

FirstLayer ​

text
modernbert::FirstLayer<D: Dim, Heads: Dim, Inner: Dim, T: Float>
  sub attn: Attention<D, Heads, T>
  sub mlp_norm: Norm<D, T>
  sub mlp: GeGlu<D, Inner, T>
  pub fn forward<B: Dim, S: Dim>(x: Tensor[B, S, D; T], theta: f32, window: Tensor[S, S; bool]?) -> Tensor[B, S, D; T]

GeGlu ​

text
modernbert::GeGlu<D: Dim, Inner: Dim, T: Float>
  sub up: Dense<D, 2 * Inner, T>
  sub down: Dense<Inner, D, T>
  pub fn forward<*S: Shape>(x: Tensor[*S, D; T]) -> Tensor[*S, D; T]

LayerCycle ​

text
modernbert::LayerCycle<D: Dim, Heads: Dim, Inner: Dim, Period: Dim, T: Float>
  sub local: [EncoderLayer<D, Heads, Inner, T>; -1 + Period]
  sub global: EncoderLayer<D, Heads, Inner, T>
  pub fn forward<B: Dim, S: Dim>(x: Tensor[B, S, D; T], window: Tensor[S, S; bool]) -> Tensor[B, S, D; T]

Linear ​

text
std.nn.linear::Linear<In: Dim, Out: Dim, T: Float = bf16>
  param weight: Tensor[Out, In; T]
  param bias: Tensor[Out; T]?
  pub fn forward<*S: Shape>(x: Tensor[*S, In; T]) -> Tensor[*S, Out; T]

Model ​

text
modernbert::Model<Vocab: Dim, D: Dim, Heads: Dim, Inner: Dim, Layers: Dim, Window: Dim, Period: Dim, T: Float = f32>
  sub embeddings: Embeddings<Vocab, D, T>
  sub first: FirstLayer<D, Heads, Inner, T>
  sub cycles: [LayerCycle<D, Heads, Inner, Period, T>; (-1 + Layers) / Period]
  sub final_norm: Norm<D, T>
  pub entry forward<B: Dim, S: Dim>(tokens: Tensor[B, S; i32]) -> Tensor[B, S, D; T]

Norm ​

text
modernbert::Norm<D: Dim, T: Float>
  param weight: Tensor[D; T]
  pub fn forward<*S: Shape>(x: Tensor[*S, D; T]) -> Tensor[*S, D; T]

RmsNorm ​

text
std.nn.norm::RmsNorm<H: Dim, T: Float = bf16>
  param weight: Tensor[H; T]
  pub fn forward<*S: Shape>(x: Tensor[*S, H; T]) -> Tensor[*S, H; T]