| 130 | } |
| 131 | |
| 132 | MioCodecContentTokenEmbeddingTable build_content_token_embedding_table( |
| 133 | const engine::assets::TensorSource & source, |
| 134 | const MioCodecConfig & config) { |
| 135 | const int64_t quantizer_dim = static_cast<int64_t>(config.quantizer_levels.size()); |
| 136 | if (quantizer_dim <= 0 || config.quantizer_input_dim <= 0 || config.quantizer_output_dim <= 0) { |
| 137 | throw std::runtime_error("MioCodec content token embedding dimensions are invalid"); |
| 138 | } |
| 139 | if (config.quantizer_output_dim != config.wave_prenet_dim) { |
| 140 | throw std::runtime_error("MioCodec content token embedding config is inconsistent with the wave prenet"); |
| 141 | } |
| 142 | const int64_t codebook_size = product(config.quantizer_levels); |
| 143 | const int64_t output_dim = config.quantizer_output_dim; |
| 144 | const auto proj_out_weight = source.require_f32("local_quantizer.proj_out.weight", {output_dim, quantizer_dim}); |
| 145 | const auto proj_out_bias = source.require_f32("local_quantizer.proj_out.bias", {output_dim}); |
| 146 | const auto basis = quantizer_basis(config.quantizer_levels); |
| 147 | |
| 148 | MioCodecContentTokenEmbeddingTable table; |
| 149 | table.codebook_size = codebook_size; |
| 150 | table.dim = output_dim; |
| 151 | table.values.resize(static_cast<size_t>(codebook_size * output_dim), 0.0F); |
| 152 | std::vector<float> fsq_code(static_cast<size_t>(quantizer_dim), 0.0F); |
| 153 | for (int64_t token = 0; token < codebook_size; ++token) { |
| 154 | for (int64_t dim = 0; dim < quantizer_dim; ++dim) { |
| 155 | const int64_t level = config.quantizer_levels[static_cast<size_t>(dim)]; |
| 156 | const int64_t half = level / 2; |
| 157 | if (half <= 0) { |
| 158 | throw std::runtime_error("MioCodec content token embedding level is invalid"); |
| 159 | } |
| 160 | const int64_t component = (token / basis[static_cast<size_t>(dim)]) % level; |
| 161 | fsq_code[static_cast<size_t>(dim)] = |
| 162 | (static_cast<float>(component) - static_cast<float>(half)) / static_cast<float>(half); |
| 163 | } |
| 164 | float * dst = table.values.data() + static_cast<size_t>(token * output_dim); |
| 165 | for (int64_t out = 0; out < output_dim; ++out) { |
| 166 | const float * weight = proj_out_weight.data() + static_cast<size_t>(out * quantizer_dim); |
| 167 | float value = proj_out_bias[static_cast<size_t>(out)]; |
| 168 | for (int64_t dim = 0; dim < quantizer_dim; ++dim) { |
| 169 | value += fsq_code[static_cast<size_t>(dim)] * weight[dim]; |
| 170 | } |
| 171 | dst[out] = value; |
| 172 | } |
| 173 | } |
| 174 | return table; |
| 175 | } |
| 176 | |
| 177 | MioCodecLinearWeights bind_linear( |
| 178 | const MioCodecWeights & weights, |
no test coverage detected