| 119 | } |
| 120 | |
| 121 | ConvSubsamplingOutputs ConvSubsamplingModule::build( |
| 122 | core::ModuleBuildContext & ctx, |
| 123 | const core::TensorValue & input, |
| 124 | const core::TensorValue & lengths, |
| 125 | const ConvSubsamplingWeights & weights) const { |
| 126 | core::validate_rank_between(input, 3, 3, "input"); |
| 127 | core::validate_last_dim(input, config_.input_features, "input"); |
| 128 | |
| 129 | const int64_t batch = input.shape.dims[0]; |
| 130 | const int64_t frames = input.shape.dims[1]; |
| 131 | const int64_t total_padding = config_.kernel_size - 1; |
| 132 | const int64_t feat_after = calc_subsampled_dim(config_.input_features, total_padding, config_.kernel_size, 2, config_.stride); |
| 133 | const int64_t frames_after = calc_subsampled_dim(frames, total_padding, config_.kernel_size, 2, config_.stride); |
| 134 | auto current_lengths = lengths; |
| 135 | |
| 136 | auto x4 = core::reshape_tensor(ctx, input, core::TensorShape::from_dims({batch, 1, frames, config_.input_features})); |
| 137 | x4 = apply_lengths_time_mask_4d(ctx, x4, current_lengths); |
| 138 | x4 = Conv2dModule({ |
| 139 | 1, |
| 140 | config_.conv_channels, |
| 141 | config_.kernel_size, |
| 142 | config_.kernel_size, |
| 143 | config_.stride, |
| 144 | config_.stride, |
| 145 | static_cast<int>(total_padding / 2), |
| 146 | static_cast<int>(total_padding / 2), |
| 147 | 1, |
| 148 | 1, |
| 149 | config_.use_bias, |
| 150 | }).build(ctx, x4, weights.conv0); |
| 151 | x4 = ReluModule().build(ctx, x4); |
| 152 | current_lengths = calc_subsampled_lengths(ctx, current_lengths, total_padding, config_.kernel_size, 1, config_.stride); |
| 153 | x4 = apply_lengths_time_mask_4d(ctx, x4, current_lengths); |
| 154 | x4 = Conv2dModule({ |
| 155 | config_.conv_channels, |
| 156 | config_.conv_channels, |
| 157 | config_.kernel_size, |
| 158 | config_.kernel_size, |
| 159 | config_.stride, |
| 160 | config_.stride, |
| 161 | static_cast<int>(total_padding / 2), |
| 162 | static_cast<int>(total_padding / 2), |
| 163 | 1, |
| 164 | 1, |
| 165 | config_.use_bias, |
| 166 | }).build(ctx, x4, weights.conv1); |
| 167 | x4 = ReluModule().build(ctx, x4); |
| 168 | current_lengths = calc_subsampled_lengths(ctx, current_lengths, total_padding, config_.kernel_size, 1, config_.stride); |
| 169 | x4 = apply_lengths_time_mask_4d(ctx, x4, current_lengths); |
| 170 | x4 = tensor_layout::swap_channel_time_axes_4d(ctx, x4); |
| 171 | x4 = core::wrap_tensor(ggml_cont(ctx.ggml, x4.tensor), x4.shape, x4.type); |
| 172 | auto flat = core::reshape_tensor(ctx, x4, core::TensorShape::from_dims({batch, frames_after, config_.conv_channels * feat_after})); |
| 173 | auto output = LinearModule({config_.conv_channels * feat_after, config_.output_features, config_.use_bias}).build(ctx, flat, weights.linear); |
| 174 | return { |
| 175 | output, |
| 176 | current_lengths, |
| 177 | }; |
| 178 | } |
no test coverage detected