| 125 | const std::string & prefix, |
| 126 | int64_t out_channels, |
| 127 | int64_t in_channels, |
| 128 | int64_t kernel_size) { |
| 129 | const auto g = source.require_f32(prefix + ".weight_g", {1, 1, kernel_size}); |
| 130 | const auto v = source.require_f32(prefix + ".weight_v", {out_channels, in_channels, kernel_size}); |
| 131 | std::vector<float> weight(v.size()); |
| 132 | for (int64_t k = 0; k < kernel_size; ++k) { |
| 133 | double sum = 0.0; |
| 134 | for (int64_t out = 0; out < out_channels; ++out) { |
| 135 | for (int64_t in = 0; in < in_channels; ++in) { |
| 136 | const size_t index = static_cast<size_t>((out * in_channels + in) * kernel_size + k); |
| 137 | sum += static_cast<double>(v[index]) * static_cast<double>(v[index]); |
| 138 | } |
| 139 | } |
| 140 | const double norm = std::sqrt(sum); |
| 141 | if (norm == 0.0) { |
| 142 | throw std::runtime_error("HuBERT positional-conv weight norm is zero"); |
| 143 | } |
| 144 | const float scale_value = static_cast<float>(static_cast<double>(g[static_cast<size_t>(k)]) / norm); |
| 145 | for (int64_t out = 0; out < out_channels; ++out) { |
| 146 | for (int64_t in = 0; in < in_channels; ++in) { |
| 147 | const size_t index = static_cast<size_t>((out * in_channels + in) * kernel_size + k); |
| 148 | weight[index] = v[index] * scale_value; |
| 149 | } |
| 150 | } |
| 151 | } |
| 152 | return weight; |
| 153 | } |
| 154 | |
| 155 | core::TensorValue grouped_pos_conv( |
| 156 | core::ModuleBuildContext & ctx, |
| 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; |
no test coverage detected