| 279 | } |
| 280 | |
| 281 | core::TensorValue grouped_pos_conv( |
| 282 | core::ModuleBuildContext & ctx, |
| 283 | const core::TensorValue & input_bct, |
| 284 | const Conv1dWeights & weights, |
| 285 | const WavlmEncoderConfig & config) { |
| 286 | const int64_t groups = config.num_conv_pos_embedding_groups; |
| 287 | const int64_t channels_per_group = config.hidden_size / groups; |
| 288 | const auto input_contiguous = contiguous(ctx, input_bct); |
| 289 | core::TensorValue out; |
| 290 | for (int64_t group = 0; group < groups; ++group) { |
| 291 | auto input_group = SliceModule({1, group * channels_per_group, channels_per_group}).build(ctx, input_contiguous); |
| 292 | auto weight_group = SliceModule({0, group * channels_per_group, channels_per_group}).build(ctx, weights.weight); |
| 293 | Conv1dWeights group_weights{weight_group, std::nullopt}; |
| 294 | if (weights.bias.has_value()) { |
| 295 | group_weights.bias = SliceModule({0, group * channels_per_group, channels_per_group}).build(ctx, *weights.bias); |
| 296 | } |
| 297 | auto group_out = Conv1dModule({ |
| 298 | channels_per_group, |
| 299 | channels_per_group, |
| 300 | config.num_conv_pos_embeddings, |
| 301 | 1, |
| 302 | static_cast<int>(config.num_conv_pos_embeddings / 2), |
| 303 | 1, |
| 304 | weights.bias.has_value()}).build(ctx, input_group, group_weights); |
| 305 | out = out.valid() ? ConcatModule({1}).build(ctx, out, group_out) : group_out; |
| 306 | } |
| 307 | if (config.num_conv_pos_embeddings % 2 == 0) { |
| 308 | out = SliceModule({2, 0, input_bct.shape.dims[2]}).build(ctx, out); |
| 309 | } |
| 310 | return GeluModule({GeluApproximation::ExactErf}).build(ctx, out); |
| 311 | } |
| 312 | |
| 313 | int64_t relative_position_bucket(int64_t relative_position, const WavlmEncoderConfig & config) { |
| 314 | int64_t num_buckets = config.num_buckets / 2; |
no test coverage detected