Middle block for WanVAE encoder and decoder. Args: dim (int): Number of input/output channels. dropout (float): Dropout rate. non_linearity (str): Type of non-linearity to use.
| 428 | |
| 429 | |
| 430 | class WanMidBlock(nn.Module): |
| 431 | """ |
| 432 | Middle block for WanVAE encoder and decoder. |
| 433 | |
| 434 | Args: |
| 435 | dim (int): Number of input/output channels. |
| 436 | dropout (float): Dropout rate. |
| 437 | non_linearity (str): Type of non-linearity to use. |
| 438 | """ |
| 439 | |
| 440 | def __init__(self, dim: int, dropout: float = 0.0, non_linearity: str = "silu", num_layers: int = 1): |
| 441 | super().__init__() |
| 442 | self.dim = dim |
| 443 | |
| 444 | # Create the components |
| 445 | resnets = [WanResidualBlock(dim, dim, dropout, non_linearity)] |
| 446 | attentions = [] |
| 447 | for _ in range(num_layers): |
| 448 | attentions.append(WanAttentionBlock(dim)) |
| 449 | resnets.append(WanResidualBlock(dim, dim, dropout, non_linearity)) |
| 450 | self.attentions = nn.ModuleList(attentions) |
| 451 | self.resnets = nn.ModuleList(resnets) |
| 452 | |
| 453 | self.gradient_checkpointing = False |
| 454 | |
| 455 | def forward(self, x, feat_cache=None, feat_idx=[0]): |
| 456 | # First residual block |
| 457 | x = self.resnets[0](x, feat_cache, feat_idx) |
| 458 | |
| 459 | # Process through attention and residual blocks |
| 460 | for attn, resnet in zip(self.attentions, self.resnets[1:]): |
| 461 | if attn is not None: |
| 462 | x = attn(x) |
| 463 | |
| 464 | x = resnet(x, feat_cache, feat_idx) |
| 465 | |
| 466 | return x |
| 467 | |
| 468 | |
| 469 | class WanResidualDownBlock(nn.Module): |