| 347 | }; |
| 348 | } |
| 349 | |
| 350 | std::shared_ptr<const Qwen3SpeechTokenizerDecoderWeights> load_weights( |
| 351 | const Qwen3TTSAssets & assets, |
| 352 | ggml_backend_t backend, |
| 353 | core::BackendType backend_type, |
| 354 | assets::TensorStorageType linear_weight_storage_type, |
| 355 | assets::TensorStorageType conv_weight_storage_type) { |
| 356 | const auto & source = *assets.speech_tokenizer_weights; |
| 357 | auto weights = std::make_shared<Qwen3SpeechTokenizerDecoderWeights>(); |
| 358 | weights->store = std::make_shared<core::BackendWeightStore>( |
| 359 | backend, |
| 360 | backend_type, |
| 361 | "qwen3_tts.speech_tokenizer_decoder.weights", |
| 362 | 32ull * 1024ull * 1024ull); |
| 363 | weights->config = load_decoder_config(assets); |
| 364 | const auto & config = weights->config; |
| 365 | const int64_t split_dim = config.codebook_dim / 2; |
| 366 | |
| 367 | for (int64_t layer = 0; layer < config.num_semantic_quantizers; ++layer) { |
| 368 | const std::string prefix = "decoder.quantizer.rvq_first.vq.layers." + std::to_string(layer) + "._codebook."; |
| 369 | weights->semantic_codebooks.push_back({normalized_codebook(source, prefix, config.codebook_size, split_dim)}); |
| 370 | } |
| 371 | for (int64_t layer = 0; layer < config.num_quantizers - config.num_semantic_quantizers; ++layer) { |
| 372 | const std::string prefix = "decoder.quantizer.rvq_rest.vq.layers." + std::to_string(layer) + "._codebook."; |
| 373 | weights->acoustic_codebooks.push_back({normalized_codebook(source, prefix, config.codebook_size, split_dim)}); |
| 374 | } |
| 375 | weights->semantic_output_proj = load_conv1x1_as_linear( |
| 376 | *weights->store, |
| 377 | source, |
| 378 | "decoder.quantizer.rvq_first.output_proj", |
| 379 | linear_weight_storage_type, |
| 380 | split_dim, |
| 381 | config.hidden_size); |
| 382 | weights->acoustic_output_proj = load_conv1x1_as_linear( |
| 383 | *weights->store, |
| 384 | source, |
| 385 | "decoder.quantizer.rvq_rest.output_proj", |
| 386 | linear_weight_storage_type, |
| 387 | split_dim, |
| 388 | config.hidden_size); |
| 389 | weights->pre_conv = load_conv(*weights->store, source, "decoder.pre_conv.conv", conv_weight_storage_type, config.hidden_size, config.latent_dim, 3); |
| 390 | weights->transformer_input_proj = load_linear( |
| 391 | *weights->store, |
| 392 | source, |
| 393 | "decoder.pre_transformer.input_proj", |
| 394 | linear_weight_storage_type, |
| 395 | config.latent_dim, |
| 396 | config.hidden_size); |
| 397 | for (int64_t layer = 0; layer < config.num_layers; ++layer) { |
| 398 | const std::string prefix = "decoder.pre_transformer.layers." + std::to_string(layer); |
| 399 | TransformerLayerWeights block; |
| 400 | block.input_norm = load_rms_norm(source, prefix + ".input_layernorm", config.hidden_size, config.rms_norm_eps); |
| 401 | block.post_norm = load_rms_norm(source, prefix + ".post_attention_layernorm", config.hidden_size, config.rms_norm_eps); |
| 402 | block.attention.q = load_linear(*weights->store, source, prefix + ".self_attn.q_proj", linear_weight_storage_type, config.hidden_size, config.num_heads * config.head_dim, false); |
| 403 | block.attention.k = load_linear(*weights->store, source, prefix + ".self_attn.k_proj", linear_weight_storage_type, config.hidden_size, config.num_kv_heads * config.head_dim, false); |
| 404 | block.attention.v = load_linear(*weights->store, source, prefix + ".self_attn.v_proj", linear_weight_storage_type, config.hidden_size, config.num_kv_heads * config.head_dim, false); |
| 405 | block.attention.o = load_linear(*weights->store, source, prefix + ".self_attn.o_proj", linear_weight_storage_type, config.num_heads * config.head_dim, config.hidden_size, false); |
| 406 | block.mlp.gate = load_linear(*weights->store, source, prefix + ".mlp.gate_proj", linear_weight_storage_type, config.hidden_size, config.intermediate_size, false); |
no test coverage detected