| 650 | return modules::CodebookLookupModule({size, dim}).build(build_ctx, indices, table); |
| 651 | } |
| 652 | |
| 653 | core::TensorValue quantizer_decode( |
| 654 | ggml_context * ctx, |
| 655 | core::ModuleBuildContext & build_ctx, |
| 656 | ggml_tensor * codes_t_q_b, |
| 657 | const Qwen3SpeechTokenizerDecoderWeights & weights, |
| 658 | core::ConstantTensorCache & constants) { |
| 659 | const auto & config = weights.config; |
| 660 | const int64_t split_dim = config.codebook_dim / 2; |
| 661 | core::TensorValue semantic_sum; |
| 662 | for (int64_t group = 0; group < config.num_semantic_quantizers; ++group) { |
| 663 | auto * code_slice = ggml_view_2d( |
| 664 | ctx, |
| 665 | codes_t_q_b, |
| 666 | codes_t_q_b->ne[0], |
| 667 | codes_t_q_b->ne[2], |
| 668 | codes_t_q_b->nb[2], |
| 669 | static_cast<size_t>(group) * codes_t_q_b->nb[1]); |
| 670 | auto decoded = codebook_decode( |
| 671 | build_ctx, |
| 672 | code_slice, |
| 673 | weights.semantic_codebooks[static_cast<size_t>(group)], |
| 674 | split_dim, |
| 675 | config.codebook_size, |
| 676 | constants); |
| 677 | semantic_sum = semantic_sum.valid() ? modules::AddModule{}.build(build_ctx, semantic_sum, decoded) : decoded; |
| 678 | } |
| 679 | semantic_sum = modules::LinearModule(binding::linear_config( |
| 680 | weights.semantic_output_proj.input_dim, |
| 681 | weights.semantic_output_proj.output_dim, |
| 682 | weights.semantic_output_proj.use_bias)) |
| 683 | .build(build_ctx, semantic_sum, binding::linear_data(constants, weights.semantic_output_proj.weight, weights.semantic_output_proj.bias)); |
| 684 | |
| 685 | core::TensorValue acoustic_sum; |
| 686 | for (int64_t group = 0; group < config.num_quantizers - config.num_semantic_quantizers; ++group) { |
| 687 | const int64_t source_group = config.num_semantic_quantizers + group; |
| 688 | auto * code_slice = ggml_view_2d( |
| 689 | ctx, |
| 690 | codes_t_q_b, |
| 691 | codes_t_q_b->ne[0], |
| 692 | codes_t_q_b->ne[2], |
| 693 | codes_t_q_b->nb[2], |
| 694 | static_cast<size_t>(source_group) * codes_t_q_b->nb[1]); |
| 695 | auto decoded = codebook_decode( |
| 696 | build_ctx, |
| 697 | code_slice, |
| 698 | weights.acoustic_codebooks[static_cast<size_t>(group)], |
| 699 | split_dim, |
| 700 | config.codebook_size, |
| 701 | constants); |
| 702 | acoustic_sum = acoustic_sum.valid() ? modules::AddModule{}.build(build_ctx, acoustic_sum, decoded) : decoded; |
| 703 | } |
| 704 | acoustic_sum = modules::LinearModule(binding::linear_config( |
| 705 | weights.acoustic_output_proj.input_dim, |
| 706 | weights.acoustic_output_proj.output_dim, |
| 707 | weights.acoustic_output_proj.use_bias)) |
| 708 | .build(build_ctx, acoustic_sum, binding::linear_data(constants, weights.acoustic_output_proj.weight, weights.acoustic_output_proj.bias)); |
| 709 | return modules::AddModule{}.build(build_ctx, semantic_sum, acoustic_sum); |
no test coverage detected