| |
| |
| |
| |
|
|
| import mlx.nn as nn |
| import mlx.core as mx |
|
|
| from .simplefold.mlx.layers import modulate, SwiGLUFeedForward |
|
|
|
|
| class DiTBlock(nn.Module): |
| """ |
| A DiT block with adaptive layer norm zero (adaLN-Zero) conditioning. |
| """ |
|
|
| def __init__( |
| self, |
| self_attention_layer, |
| hidden_size, |
| mlp_ratio=4.0, |
| use_swiglu=True, |
| ): |
| super().__init__() |
| self.norm1 = nn.LayerNorm(hidden_size, affine=False, eps=1e-6) |
| self.attn = self_attention_layer() |
| self.norm2 = nn.LayerNorm(hidden_size, affine=False, eps=1e-6) |
| mlp_hidden_dim = int(hidden_size * mlp_ratio) |
|
|
| assert use_swiglu, "Need use_swiglu=True for MLX" |
| self.mlp = SwiGLUFeedForward(hidden_size, mlp_hidden_dim) |
|
|
| self.adaLN_modulation = nn.Sequential( |
| nn.SiLU(), nn.Linear(hidden_size, 6 * hidden_size, bias=True) |
| ) |
|
|
| def __call__( |
| self, |
| latents, |
| c, |
| **kwargs, |
| ): |
| shift_msa, scale_msa, gate_msa, shift_mlp, scale_mlp, gate_mlp = ( |
| self.adaLN_modulation(c).split(6, axis=1) |
| ) |
|
|
| _latents, _ = self.attn( |
| modulate(self.norm1(latents), shift_msa, scale_msa), **kwargs |
| ) |
| latents = latents + mx.expand_dims(gate_msa, axis=1) * _latents |
|
|
| latents = latents + mx.expand_dims(gate_mlp, axis=1) * self.mlp( |
| modulate(self.norm2(latents), shift_mlp, scale_mlp) |
| ) |
| return latents |
|
|
|
|
| class TransformerBlock(nn.Module): |
| """ |
| A DiT block with adaptive layer norm zero (adaLN-Zero) conditioning. |
| """ |
|
|
| def __init__( |
| self, |
| self_attention_layer, |
| hidden_size, |
| mlp_ratio=4.0, |
| use_swiglu=False, |
| ): |
| super().__init__() |
| self.norm1 = nn.LayerNorm(hidden_size, affine=False, eps=1e-6) |
| self.attn = self_attention_layer() |
| self.norm2 = nn.LayerNorm(hidden_size, affine=False, eps=1e-6) |
| mlp_hidden_dim = int(hidden_size * mlp_ratio) |
|
|
| assert use_swiglu, "Need use_swiglu=True for MLX" |
| self.mlp = SwiGLUFeedForward(hidden_size, mlp_hidden_dim) |
|
|
| def __call__( |
| self, |
| latents, |
| **kwargs, |
| ): |
| _latents, _ = self.attn(self.norm1(latents), **kwargs) |
| latents = latents + _latents |
| latents = latents + self.mlp(self.norm2(latents)) |
| return latents |
|
|
|
|
| |
| class HomogenTrunk(nn.Module): |
| def __init__(self, block, depth): |
| super().__init__() |
| self.blocks = [block() for _ in range(depth)] |
|
|
| def __call__(self, latents, c, **kwargs): |
| for i, block in enumerate(self.blocks): |
| kwargs["layer_idx"] = i |
| latents = block(latents=latents, c=c, **kwargs) |
| return latents |
|
|