| 157 | const core::TensorValue & input_bct, |
| 158 | const Conv1dWeights & weights, |
| 159 | const HubertEncoderConfig & config) { |
| 160 | const int64_t groups = config.num_conv_pos_embedding_groups; |
| 161 | const int64_t channels_per_group = config.hidden_size / groups; |
| 162 | const auto input_contiguous = contiguous(ctx, input_bct); |
| 163 | core::TensorValue out; |
| 164 | for (int64_t group = 0; group < groups; ++group) { |
| 165 | auto input_group = SliceModule({1, group * channels_per_group, channels_per_group}).build(ctx, input_contiguous); |
| 166 | auto weight_group = SliceModule({0, group * channels_per_group, channels_per_group}).build(ctx, weights.weight); |
| 167 | Conv1dWeights group_weights{weight_group, std::nullopt}; |
| 168 | if (weights.bias.has_value()) { |
| 169 | group_weights.bias = SliceModule({0, group * channels_per_group, channels_per_group}).build(ctx, *weights.bias); |
| 170 | } |
| 171 | auto group_out = Conv1dModule({ |
| 172 | channels_per_group, |
| 173 | channels_per_group, |
| 174 | config.num_conv_pos_embeddings, |
| 175 | 1, |
| 176 | static_cast<int>(config.num_conv_pos_embeddings / 2), |
| 177 | 1, |
| 178 | weights.bias.has_value()}).build(ctx, input_group, group_weights); |
| 179 | out = out.valid() ? ConcatModule({1}).build(ctx, out, group_out) : group_out; |
| 180 | } |
| 181 | if (config.num_conv_pos_embeddings % 2 == 0) { |
| 182 | out = SliceModule({2, 0, input_bct.shape.dims[2]}).build(ctx, out); |
| 183 | } |
| 184 | return GeluModule({GeluApproximation::ExactErf}).build(ctx, out); |
| 185 | } |
| 186 | |
| 187 | core::TensorValue build_self_attention( |
| 188 | core::ModuleBuildContext & ctx, |
| 189 | const core::TensorValue & hidden_btc, |
| 190 | const HubertEncoderWeights & weights, |
| 191 | int64_t layer_index) { |
| 192 | const auto & config = weights.config; |
no test coverage detected