返回 JoyAI-Echo
resnet.py
根目录 / ltx-core / src / ltx_core / model / audio_vae / resnet.py
1 from typing import Tuple
2
3 import torch
4
5 from ltx_core.model.audio_vae.causal_conv_2d import make_conv2d
6 from ltx_core.model.audio_vae.causality_axis import CausalityAxis
7 from ltx_core.model.common.normalization import NormType, build_normalization_layer
8
9 LRELU_SLOPE = 0.1
10
11
12 class ResBlock1(torch.nn.Module):
13 def __init__(self, channels: int, kernel_size: int = 3, dilation: Tuple[int, int, int] = (1, 3, 5)):
14 super(ResBlock1, self).__init__()
15 self.convs1 = torch.nn.ModuleList(
16 [
17 torch.nn.Conv1d(
18 channels,
19 channels,
20 kernel_size,
21 1,
22 dilation=dilation[0],
23 padding="same",
24 ),
25 torch.nn.Conv1d(
26 channels,
27 channels,
28 kernel_size,
29 1,
30 dilation=dilation[1],
31 padding="same",
32 ),
33 torch.nn.Conv1d(
34 channels,
35 channels,
36 kernel_size,
37 1,
38 dilation=dilation[2],
39 padding="same",
40 ),
41 ]
42 )
43
44 self.convs2 = torch.nn.ModuleList(
45 [
46 torch.nn.Conv1d(
47 channels,
48 channels,
49 kernel_size,
50 1,
51 dilation=1,
52 padding="same",
53 ),
54 torch.nn.Conv1d(
55 channels,
56 channels,
57 kernel_size,
58 1,
59 dilation=1,
60 padding="same",
61 ),
62 torch.nn.Conv1d(
63 channels,
64 channels,
65 kernel_size,
66 1,
67 dilation=1,
68 padding="same",
69 ),
70 ]
71 )
72
73 def forward(self, x: torch.Tensor) -> torch.Tensor:
74 for conv1, conv2 in zip(self.convs1, self.convs2, strict=True):
75 xt = torch.nn.functional.leaky_relu(x, LRELU_SLOPE)
76 xt = conv1(xt)
77 xt = torch.nn.functional.leaky_relu(xt, LRELU_SLOPE)
78 xt = conv2(xt)
79 x = xt + x
80 return x
81
82
83 class ResBlock2(torch.nn.Module):
84 def __init__(self, channels: int, kernel_size: int = 3, dilation: Tuple[int, int] = (1, 3)):
85 super(ResBlock2, self).__init__()
86 self.convs = torch.nn.ModuleList(
87 [
88 torch.nn.Conv1d(
89 channels,
90 channels,
91 kernel_size,
92 1,
93 dilation=dilation[0],
94 padding="same",
95 ),
96 torch.nn.Conv1d(
97 channels,
98 channels,
99 kernel_size,
100 1,
101 dilation=dilation[1],
102 padding="same",
103 ),
104 ]
105 )
106
107 def forward(self, x: torch.Tensor) -> torch.Tensor:
108 for conv in self.convs:
109 xt = torch.nn.functional.leaky_relu(x, LRELU_SLOPE)
110 xt = conv(xt)
111 x = xt + x
112 return x
113
114
115 class ResnetBlock(torch.nn.Module):
116 def __init__(
117 self,
118 *,
119 in_channels: int,
120 out_channels: int | None = None,
121 conv_shortcut: bool = False,
122 dropout: float = 0.0,
123 temb_channels: int = 512,
124 norm_type: NormType = NormType.GROUP,
125 causality_axis: CausalityAxis = CausalityAxis.HEIGHT,
126 ) -> None:
127 super().__init__()
128 self.causality_axis = causality_axis
129
130 if self.causality_axis != CausalityAxis.NONE and norm_type == NormType.GROUP:
131 raise ValueError("Causal ResnetBlock with GroupNorm is not supported.")
132 self.in_channels = in_channels
133 out_channels = in_channels if out_channels is None else out_channels
134 self.out_channels = out_channels
135 self.use_conv_shortcut = conv_shortcut
136
137 self.norm1 = build_normalization_layer(in_channels, normtype=norm_type)
138 self.non_linearity = torch.nn.SiLU()
139 self.conv1 = make_conv2d(in_channels, out_channels, kernel_size=3, stride=1, causality_axis=causality_axis)
140 if temb_channels > 0:
141 self.temb_proj = torch.nn.Linear(temb_channels, out_channels)
142 self.norm2 = build_normalization_layer(out_channels, normtype=norm_type)
143 self.dropout = torch.nn.Dropout(dropout)
144 self.conv2 = make_conv2d(out_channels, out_channels, kernel_size=3, stride=1, causality_axis=causality_axis)
145 if self.in_channels != self.out_channels:
146 if self.use_conv_shortcut:
147 self.conv_shortcut = make_conv2d(
148 in_channels, out_channels, kernel_size=3, stride=1, causality_axis=causality_axis
149 )
150 else:
151 self.nin_shortcut = make_conv2d(
152 in_channels, out_channels, kernel_size=1, stride=1, causality_axis=causality_axis
153 )
154
155 def forward(
156 self,
157 x: torch.Tensor,
158 temb: torch.Tensor | None = None,
159 ) -> torch.Tensor:
160 h = x
161 h = self.norm1(h)
162 h = self.non_linearity(h)
163 h = self.conv1(h)
164
165 if temb is not None:
166 h = h + self.temb_proj(self.non_linearity(temb))[:, :, None, None]
167
168 h = self.norm2(h)
169 h = self.non_linearity(h)
170 h = self.dropout(h)
171 h = self.conv2(h)
172
173 if self.in_channels != self.out_channels:
174 x = self.conv_shortcut(x) if self.use_conv_shortcut else self.nin_shortcut(x)
175
176 return x + h
177
177 lines PYTHON