index-tts stash save

This commit is contained in:
jhqxxx
2026-02-07 00:26:03 +08:00
parent 978b74ec13
commit 01172b1ae6
24 changed files with 1004 additions and 232 deletions
+2 -2
View File
@@ -31,7 +31,7 @@ jobs:
- name: Install make dependencies - name: Install make dependencies
run: | run: |
sudo apt-get update sudo apt-get update
sudo apt-get install -y build-essential sudo apt-get install -y build-essential cmake
- name: Install FFmpeg dependencies - name: Install FFmpeg dependencies
run: | run: |
@@ -61,7 +61,7 @@ jobs:
- name: Install make dependencies - name: Install make dependencies
run: | run: |
sudo apt-get update sudo apt-get update
sudo apt-get install -y build-essential sudo apt-get install -y build-essential cmake
- name: Install FFmpeg development packages - name: Install FFmpeg development packages
run: | run: |
Generated
+53 -2
View File
@@ -52,8 +52,10 @@ dependencies = [
"num", "num",
"rayon", "rayon",
"realfft", "realfft",
"regex",
"reqwest 0.12.24", "reqwest 0.12.24",
"rocket", "rocket",
"sentencepiece",
"serde", "serde",
"serde_json", "serde_json",
"serde_yaml", "serde_yaml",
@@ -3305,6 +3307,29 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "prost"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2ea70524a2f82d518bce41317d0fae74151505651af45faf1ffbd6fd33f0568"
dependencies = [
"bytes",
"prost-derive",
]
[[package]]
name = "prost-derive"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b"
dependencies = [
"anyhow",
"itertools 0.14.0",
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "psl-types" name = "psl-types"
version = "2.0.11" version = "2.0.11"
@@ -3667,9 +3692,9 @@ dependencies = [
[[package]] [[package]]
name = "regex" name = "regex"
version = "1.12.2" version = "1.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276"
dependencies = [ dependencies = [
"aho-corasick", "aho-corasick",
"memchr", "memchr",
@@ -4104,6 +4129,32 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "sentencepiece"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3baa1506c7718f6b70bcac5475e563176dd51bb669dae38181abbf3070517453"
dependencies = [
"libc",
"num-derive",
"num-traits",
"prost",
"prost-derive",
"sentencepiece-sys",
"thiserror 2.0.17",
]
[[package]]
name = "sentencepiece-sys"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa4f9b54dc005df8ec1c3f9e2347cea6b6657ec5460977a982e7a4e09ef49411"
dependencies = [
"cc",
"cmake",
"pkg-config",
]
[[package]] [[package]]
name = "seq-macro" name = "seq-macro"
version = "0.3.6" version = "0.3.6"
+2
View File
@@ -40,6 +40,8 @@ serde_yaml = "0.9.34"
zip = "7.2.0" zip = "7.2.0"
half = "2.7.1" half = "2.7.1"
byteorder = "1.5.0" byteorder = "1.5.0"
sentencepiece = "0.13.1"
regex = "1.12.3"
[features] [features]
flash-attn = ["candle-flash-attn"] flash-attn = ["candle-flash-attn"]
+7
View File
@@ -62,6 +62,13 @@
⭐ 如果这个项目对你有帮助,请给我们一个 Star! ⭐ 如果这个项目对你有帮助,请给我们一个 Star!
## 环境依赖 ## 环境依赖
* cmake:
* ubuntu/WSL
```bash
sudo apt-get update
sudo apt-get install cmake
```
* 启用ffmpeg的feature时: * 启用ffmpeg的feature时:
* ubuntu/WSL * ubuntu/WSL
```bash ```bash
+24 -7
View File
@@ -2,9 +2,9 @@ use anyhow::{Result, anyhow};
use candle_core::{D, IndexOp, Tensor}; use candle_core::{D, IndexOp, Tensor};
use candle_nn::{ use candle_nn::{
Activation, BatchNorm, BatchNormConfig, Conv1d, Conv1dConfig, Conv2d, Conv2dConfig, Activation, BatchNorm, BatchNormConfig, Conv1d, Conv1dConfig, Conv2d, Conv2dConfig,
ConvTranspose1d, ConvTranspose1dConfig, Embedding, LayerNorm, LayerNormConfig, Linear, Module, ConvTranspose1d, ConvTranspose1dConfig, Embedding, GroupNorm, Init, LayerNorm, LayerNormConfig,
ModuleT, RmsNorm, VarBuilder, batch_norm, conv1d, conv1d_no_bias, conv2d, conv2d_no_bias, Linear, Module, ModuleT, RmsNorm, VarBuilder, batch_norm, conv1d, conv1d_no_bias, conv2d,
embedding, layer_norm, linear_b, linear_no_bias, ops::sigmoid, rms_norm, conv2d_no_bias, embedding, layer_norm, linear_b, linear_no_bias, ops::sigmoid, rms_norm,
}; };
use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator}; use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator};
@@ -464,9 +464,10 @@ impl NaiveAttnTwoLinearMLPBlock {
linear2_pp_name, linear2_pp_name,
)?; )?;
let input_layernorm = get_layer_norm(vb.pp(input_norm_pp_name), norm_eps, hidden_size)?; let input_layernorm =
get_layer_norm(vb.pp(input_norm_pp_name), norm_eps, hidden_size, true)?;
let post_attention_layernorm = let post_attention_layernorm =
get_layer_norm(vb.pp(post_norm_pp_name), norm_eps, hidden_size)?; get_layer_norm(vb.pp(post_norm_pp_name), norm_eps, hidden_size, true)?;
Ok(Self { Ok(Self {
self_attn, self_attn,
mlp, mlp,
@@ -689,16 +690,26 @@ pub fn get_conv1d(
Ok(conv1d) Ok(conv1d)
} }
pub fn get_layer_norm(vb: VarBuilder, eps: f64, dim: usize) -> Result<LayerNorm> { pub fn get_layer_norm(vb: VarBuilder, eps: f64, dim: usize, affine: bool) -> Result<LayerNorm> {
let ln_config = LayerNormConfig { let ln_config = LayerNormConfig {
eps, eps,
remove_mean: true, // true for layernorm, false for RMSNorm remove_mean: true, // true for layernorm, false for RMSNorm
affine: true, // true for with bias, false for without bias affine, // true for with bias, false for without bias
}; };
let norm = layer_norm(dim, ln_config, vb)?; let norm = layer_norm(dim, ln_config, vb)?;
Ok(norm) Ok(norm)
} }
pub fn get_layer_norm_without_weight(
vb: VarBuilder,
eps: f64,
dim: usize,
) -> Result<LayerNorm> {
let weight = Tensor::ones(dim, vb.dtype(), vb.device())?;
let bias = Tensor::zeros(dim, vb.dtype(), vb.device())?;
Ok(LayerNorm::new(weight, bias, eps))
}
pub fn get_batch_norm(vb: VarBuilder, eps: f64, dim: usize, affine: bool) -> Result<BatchNorm> { pub fn get_batch_norm(vb: VarBuilder, eps: f64, dim: usize, affine: bool) -> Result<BatchNorm> {
let bn_config = BatchNormConfig { let bn_config = BatchNormConfig {
eps, eps,
@@ -1167,3 +1178,9 @@ impl WNLinear {
Ok(x) Ok(x)
} }
} }
pub fn mish(xs: &Tensor) -> Result<Tensor> {
let tanh = xs.exp()?.affine(1.0, 1.0)?.log()?.tanh()?;
let xs = xs.mul(&tanh)?;
Ok(xs)
}
+5 -5
View File
@@ -252,7 +252,7 @@ impl Block {
window_size: usize, window_size: usize,
input_size: Option<(usize, usize)>, input_size: Option<(usize, usize)>,
) -> Result<Self> { ) -> Result<Self> {
let norm1 = get_layer_norm(vb.pp("norm1"), eps, dim)?; let norm1 = get_layer_norm(vb.pp("norm1"), eps, dim, true)?;
let input_size = if window_size == 0 { let input_size = if window_size == 0 {
input_size input_size
} else { } else {
@@ -266,7 +266,7 @@ impl Block {
use_rel_pos, use_rel_pos,
input_size, input_size,
)?; )?;
let norm2 = get_layer_norm(vb.pp("norm2"), eps, dim)?; let norm2 = get_layer_norm(vb.pp("norm2"), eps, dim, true)?;
let mlp_dim = (dim as f32 * mlp_ratio) as usize; let mlp_dim = (dim as f32 * mlp_ratio) as usize;
let mlp = TwoLinearMLP::new(vb.pp("mlp"), dim, mlp_dim, dim, act, true, "lin1", "lin2")?; let mlp = TwoLinearMLP::new(vb.pp("mlp"), dim, mlp_dim, dim, act, true, "lin1", "lin2")?;
Ok(Self { Ok(Self {
@@ -674,8 +674,8 @@ impl NoTPTransformerBlock {
) -> Result<Self> { ) -> Result<Self> {
let self_attn = NoTPAttention::new(vb.pp("self_attn"), hidden_size, num_heads)?; let self_attn = NoTPAttention::new(vb.pp("self_attn"), hidden_size, num_heads)?;
let mlp = NoTPFeedForward::new(vb.pp("mlp"), hidden_size, ffn_hidden_size)?; let mlp = NoTPFeedForward::new(vb.pp("mlp"), hidden_size, ffn_hidden_size)?;
let layer_norm1 = get_layer_norm(vb.pp("layer_norm1"), eps, hidden_size)?; let layer_norm1 = get_layer_norm(vb.pp("layer_norm1"), eps, hidden_size, true)?;
let layer_norm2 = get_layer_norm(vb.pp("layer_norm2"), eps, hidden_size)?; let layer_norm2 = get_layer_norm(vb.pp("layer_norm2"), eps, hidden_size, true)?;
Ok(Self { Ok(Self {
self_attn, self_attn,
mlp, mlp,
@@ -764,7 +764,7 @@ impl VitModel {
ffn_hidden_size, ffn_hidden_size,
eps, eps,
)?; )?;
let pre_layrnorm = get_layer_norm(vb.pp("pre_layrnorm"), eps, hidden_size)?; let pre_layrnorm = get_layer_norm(vb.pp("pre_layrnorm"), eps, hidden_size, true)?;
Ok(Self { Ok(Self {
embeddings, embeddings,
transformer, transformer,
+6 -6
View File
@@ -227,8 +227,8 @@ impl EncoderLayerSANM {
"w_1", "w_1",
"w_2", "w_2",
)?; )?;
let norm1 = get_layer_norm(vb.pp("norm1"), 1e-5, in_dim)?; let norm1 = get_layer_norm(vb.pp("norm1"), 1e-5, in_dim, true)?;
let norm2 = get_layer_norm(vb.pp("norm2"), 1e-5, hidden_dim)?; let norm2 = get_layer_norm(vb.pp("norm2"), 1e-5, hidden_dim, true)?;
let concat_linear = if concat_after { let concat_linear = if concat_after {
let lin = linear(hidden_dim * 2, hidden_dim, vb.pp("concat_linear"))?; let lin = linear(hidden_dim * 2, hidden_dim, vb.pp("concat_linear"))?;
Some(lin) Some(lin)
@@ -400,8 +400,8 @@ impl SenseVoiceEncoderSmall {
)?; )?;
tp_encoders.push(tp_blocks_i); tp_encoders.push(tp_blocks_i);
} }
let after_norm = get_layer_norm(vb.pp("after_norm"), 1e-5, output_size)?; let after_norm = get_layer_norm(vb.pp("after_norm"), 1e-5, output_size, true)?;
let tp_norm = get_layer_norm(vb.pp("tp_norm"), 1e-5, output_size)?; let tp_norm = get_layer_norm(vb.pp("tp_norm"), 1e-5, output_size, true)?;
let scaling = (output_size as f64).powf(0.5); let scaling = (output_size as f64).powf(0.5);
Ok(Self { Ok(Self {
embed, embed,
@@ -468,8 +468,8 @@ impl AdaptorEncoderLayer {
"w_1", "w_1",
"w_2", "w_2",
)?; )?;
let norm1 = get_layer_norm(vb.pp("norm1"), 1e-5, llm_dim)?; let norm1 = get_layer_norm(vb.pp("norm1"), 1e-5, llm_dim, true)?;
let norm2 = get_layer_norm(vb.pp("norm2"), 1e-5, llm_dim)?; let norm2 = get_layer_norm(vb.pp("norm2"), 1e-5, llm_dim, true)?;
let concat_linear = if concat_after { let concat_linear = if concat_after {
let lin = linear(llm_dim * 2, llm_dim, vb.pp("concat_linear"))?; let lin = linear(llm_dim * 2, llm_dim, vb.pp("concat_linear"))?;
Some(lin) Some(lin)
+3 -2
View File
@@ -129,11 +129,12 @@ impl GlmAsrEncoderLayer {
"fc2", "fc2",
)?; )?;
let input_layernorm = let input_layernorm =
get_layer_norm(vb.pp("input_layernorm"), 1e-5, audio_cfg.hidden_size)?; get_layer_norm(vb.pp("input_layernorm"), 1e-5, audio_cfg.hidden_size, true)?;
let post_attention_layernorm = get_layer_norm( let post_attention_layernorm = get_layer_norm(
vb.pp("post_attention_layernorm"), vb.pp("post_attention_layernorm"),
1e-5, 1e-5,
audio_cfg.hidden_size, audio_cfg.hidden_size,
true,
)?; )?;
Ok(Self { Ok(Self {
self_attn, self_attn,
@@ -202,7 +203,7 @@ impl GlmAsrEncoder {
let layer_i = GlmAsrEncoderLayer::new(vb_layers.pp(i), audio_cfg)?; let layer_i = GlmAsrEncoderLayer::new(vb_layers.pp(i), audio_cfg)?;
layers.push(layer_i); layers.push(layer_i);
} }
let norm = get_layer_norm(vb.pp("norm"), 1e-5, audio_cfg.hidden_size)?; let norm = get_layer_norm(vb.pp("norm"), 1e-5, audio_cfg.hidden_size, true)?;
let dim = (audio_cfg.head_dim as f64 * audio_cfg.partial_rotary_factor) as usize; let dim = (audio_cfg.head_dim as f64 * audio_cfg.partial_rotary_factor) as usize;
let rotary_emb = RoPE::new(dim, audio_cfg.rope_parameters.rope_theta, vb.device())?; let rotary_emb = RoPE::new(dim, audio_cfg.rope_parameters.rope_theta, vb.device())?;
Ok(Self { Ok(Self {
+56 -7
View File
@@ -1,14 +1,29 @@
use aha_openai_dive::v1::resources::chat::ChatCompletionParameters; use aha_openai_dive::v1::resources::chat::ChatCompletionParameters;
use anyhow::Result; use anyhow::{Result, anyhow};
use candle_core::{DType, Device}; use candle_core::{DType, Device};
use sentencepiece::SentencePieceProcessor;
use crate::{ use crate::{
models::index_tts2::{config::IndexTTS2Config, processor::IndexTTS2Processor}, models::index_tts2::{
utils::{get_default_save_dir, get_device, get_dtype}, config::IndexTTS2Config,
model::IndexTTS2Model,
processor::IndexTTS2Processor,
utils::{TextNormalizer, tokenize_by_cjk_char},
},
tokenizer::sentencepiece_encode,
utils::{
audio_utils::extract_audio_url, extract_user_text, get_default_save_dir, get_device,
get_dtype,
},
}; };
pub struct IndexTTS2Generate { pub struct IndexTTS2Generate {
processor: IndexTTS2Processor, processor: IndexTTS2Processor,
tokenizer: SentencePieceProcessor,
config: IndexTTS2Config, config: IndexTTS2Config,
cache_spk_audio_prompt: Option<String>,
model: IndexTTS2Model,
device: Device,
} }
impl IndexTTS2Generate { impl IndexTTS2Generate {
@@ -18,12 +33,46 @@ impl IndexTTS2Generate {
let config: IndexTTS2Config = serde_yaml::from_slice(&std::fs::read(config_path)?)?; let config: IndexTTS2Config = serde_yaml::from_slice(&std::fs::read(config_path)?)?;
let device = get_device(device); let device = get_device(device);
let dtype = get_dtype(dtype, "bf16"); let dtype = get_dtype(dtype, "bf16");
let processor = IndexTTS2Processor::new(path, &save_dir, &config, &device, dtype)?; let processor = IndexTTS2Processor::new(&device)?;
let bpe_path = path.to_string() + "/bpe.model";
Ok(Self { config, processor }) let tokenizer = SentencePieceProcessor::open(bpe_path)
.map_err(|e| anyhow!(format!("load bpe,model file error:{}", e)))?;
let model = IndexTTS2Model::new(path, &save_dir, &config, &device, dtype)?;
Ok(Self {
processor,
tokenizer,
config,
cache_spk_audio_prompt: None,
model,
device,
})
} }
pub fn use_prompt(&self, mes: &ChatCompletionParameters) -> bool {
if let Some(cache) = &self.cache_spk_audio_prompt {
let audio_vec = extract_audio_url(mes);
if audio_vec.len() == 0 {
true
} else {
if cache.eq(&audio_vec[0]) { true } else { false }
}
} else {
false
}
}
pub fn generate(&mut self, mes: ChatCompletionParameters) -> Result<()> { pub fn generate(&mut self, mes: ChatCompletionParameters) -> Result<()> {
let _ = self.processor.process_info(&mes)?; let text = extract_user_text(&mes)?;
let text = tokenize_by_cjk_char(&text, true);
let input_ids = sentencepiece_encode(&text, &self.tokenizer, &self.device)?;
let (audio_22k, audio_16k) = if self.use_prompt(&mes) {
(None, None)
} else {
let (audio_22k, audio_16k, prompt) = self.processor.process_info(&mes)?;
self.cache_spk_audio_prompt = Some(prompt);
(Some(audio_22k), Some(audio_16k))
};
let _ = self.model.forward(&input_ids, audio_22k.as_ref(), audio_16k.as_ref())?;
Ok(()) Ok(())
} }
} }
+461 -19
View File
@@ -1,20 +1,33 @@
use anyhow::Result; use anyhow::{Result, anyhow};
use candle_core::{D, Tensor}; use candle_core::{D, DType, Device, IndexOp, Tensor, pickle::read_all_with_key};
use candle_nn::{ use candle_nn::{
Conv1d, Embedding, LayerNorm, Linear, Module, RmsNorm, VarBuilder, embedding, linear, linear_b, Activation, Conv1d, Embedding, GroupNorm, Init, LayerNorm, Linear, Module, RmsNorm, VarBuilder,
ops::sigmoid, rms_norm, embedding, group_norm, linear, linear_b, ops::sigmoid, rms_norm,
}; };
use crate::{ use crate::{
models::{ models::{
campplus::CAMPPlus,
common::{ common::{
GateUpDownMLP, QKVCatAttention, TwoLinearMLP, WNConv1d, WNLinear, get_conv1d, GateUpDownMLP, QKVCatAttention, TwoLinearMLP, WNConv1d, WNLinear, get_conv1d,
get_layer_norm, get_layer_norm, get_layer_norm_without_weight, mish,
}, },
index_tts2::config::{DiTModelArgs, S2MelConfig}, feature_extractor::seamless_m4t_feature_extractor::SeamlessM4TFeatureExtractor,
index_tts2::config::{DiTModelArgs, IndexTTS2Config, PreprocessParams, S2MelConfig},
mask_gct::model::RepCodec,
w2v_bert_2_0::model::W2VBert2_0Model,
}, },
position_embed::rope::RoPE, position_embed::rope::RoPE,
utils::tensor_utils::{pad_reflect_last_dim, split_tensor_with_size}, utils::{
audio_utils::{
create_hann_window, get_waveform_and_window_properties, kaldi_fbank,
kaldi_get_mel_banks, mel_filter_bank, torch_stft,
},
get_vb_model_path, read_pth_tensor_info_cycle,
tensor_utils::{
interpolate_nearest_1d, pad_reflect_last_dim, sequence_mask, split_tensor_with_size,
},
},
}; };
pub struct AdaptiveLayerNorm { pub struct AdaptiveLayerNorm {
project_layer: Linear, project_layer: Linear,
@@ -219,7 +232,7 @@ impl TimestepEmbedder {
candle_nn::Activation::Silu, candle_nn::Activation::Silu,
true, true,
"0", "0",
"1", "2",
)?; )?;
let scale = 1000.0; let scale = 1000.0;
let half = frequency_embedding_size / 2; let half = frequency_embedding_size / 2;
@@ -338,7 +351,7 @@ impl Wavenet {
let in_layer = SConv1d::new( let in_layer = SConv1d::new(
vb_layers.pp(i), vb_layers.pp(i),
hidden_c, hidden_c,
1 * hidden_c, 2 * hidden_c,
ks, ks,
1, 1,
dilation, dilation,
@@ -385,7 +398,7 @@ impl Wavenet {
Ok(acts) Ok(acts)
} }
pub fn forward(self, xs: &Tensor, x_mask: &Tensor, g: Option<&Tensor>) -> Result<Tensor> { pub fn forward(&self, xs: &Tensor, x_mask: &Tensor, g: Option<&Tensor>) -> Result<Tensor> {
let mut output = xs.zeros_like()?; let mut output = xs.zeros_like()?;
let g = if let Some(g) = g let g = if let Some(g) = g
&& let Some(cond_layer) = &self.cond_layer && let Some(cond_layer) = &self.cond_layer
@@ -432,7 +445,7 @@ impl FinalLayer {
patch_size: usize, patch_size: usize,
out_c: usize, out_c: usize,
) -> Result<Self> { ) -> Result<Self> {
let norm_final = get_layer_norm(vb.pp("norm_final"), 1e-6, hidden_size)?; let norm_final = get_layer_norm_without_weight(vb.pp("norm_final"), 1e-6, hidden_size)?;
let linear = WNLinear::new( let linear = WNLinear::new(
vb.pp("linear"), vb.pp("linear"),
hidden_size, hidden_size,
@@ -485,6 +498,8 @@ pub struct DiT {
time_as_token: bool, time_as_token: bool,
style_as_token: bool, style_as_token: bool,
uvit_skip_connection: bool, uvit_skip_connection: bool,
transformer_style_condition: bool,
long_skip_connection: bool,
} }
impl DiT { impl DiT {
@@ -594,24 +609,451 @@ impl DiT {
time_as_token, time_as_token,
style_as_token, style_as_token,
uvit_skip_connection, uvit_skip_connection,
transformer_style_condition: config.di_t.style_condition,
long_skip_connection: config.di_t.long_skip_connection,
}) })
} }
pub fn forward(
&self,
xs: &Tensor,
prompt_xs: &Tensor,
x_lens: &Tensor,
t: &Tensor,
style: Option<&Tensor>,
cond: &Tensor,
) -> Result<Tensor> {
let (_, _, t_dim) = xs.dims3()?;
let t1 = self.t_embedder.forward(t)?;
let cond = self.cond_projection.forward(cond)?;
let xs = xs.transpose(1, 2)?;
let prompt_xs = prompt_xs.transpose(1, 2)?;
let mut x_in = Tensor::cat(&[&xs, &prompt_xs, &cond], D::Minus1)?;
if self.transformer_style_condition
&& !self.style_as_token
&& let Some(style) = style
{
let style = style.unsqueeze(1)?.repeat((1, t_dim, 1))?;
x_in = Tensor::cat(&[&x_in, &style], D::Minus1)?;
}
x_in = self.cond_x_merge_linear.forward(&x_in)?;
// if self.style_as_token
// && let Some(style_in) = self.style_in.as_ref()
// {
// let style = style_in.forward(style)?.unsqueeze(1)?;
// x_in = Tensor::cat(&[&style, &x_in], 1)?;
// }
// if self.time_as_token {
// let t1 = t1.unsqueeze(1)?;
// x_in = Tensor::cat(&[&t1, &x_in], 1)?;
// }
// let mut x_lens = x_lens.clone();
// if self.style_as_token {
// x_lens = x_lens.affine(1.0, 1.0)?;
// }
// if self.time_as_token {
// x_lens = x_lens.affine(1.0, 0.0)?;
// }
let x_mask = sequence_mask(&x_lens, Some(x_in.dim(1)? as u32))?
.to_device(xs.device())?
.unsqueeze(1)?;
let mut x_res = self.transformer.forward(&x_in, &t1.unsqueeze(1)?, None)?;
// if self.time_as_token {
// let last_dim = x_res.dim(D::Minus1)?;
// x_res = x_res.narrow(D::Minus1, 1, last_dim - 1)?;
// }
// if self.style_as_token {
// let last_dim = x_res.dim(D::Minus1)?;
// x_res = x_res.narrow(D::Minus1, 1, last_dim - 1)?;
// }
if self.long_skip_connection {
x_res = self
.skip_linear
.forward(&Tensor::cat(&[&x_res, &xs], D::Minus1)?)?;
}
let xs = self.conv1.forward(&x_res)?;
let xs = xs.transpose(1, 2)?;
let t2 = self.t_embedder2.forward(t)?;
let xs = self
.wavenet
.forward(&xs, &x_mask, Some(&t2.unsqueeze(2)?))?
.transpose(1, 2)?
.broadcast_add(&self.res_projection.forward(&x_res)?)?;
let xs = self.final_layer.forward(&xs, &t1)?.transpose(1, 2)?;
let xs = self.conv2.forward(&xs)?;
Ok(xs)
}
} }
pub struct CFM { pub struct CFM {
in_channels: usize,
estimator: DiT, estimator: DiT,
// criterion: l1Loss
sigma_min: f32,
}
impl CFM {
pub fn new(vb: VarBuilder, config: &S2MelConfig) -> Result<Self> {
let in_channels = config.di_t.in_channels;
let sigma_min = 1e-6;
let estimator = DiT::new(vb.pp("estimator"), config)?;
Ok(Self {
in_channels,
estimator,
sigma_min,
})
}
}
pub struct InterpolateModule {
conv1d: Conv1d,
norm: GroupNorm,
}
impl InterpolateModule {
pub fn new(vb: &VarBuilder, index: usize, channels: usize, groups: usize) -> Result<Self> {
let start_index = index * 3;
let conv1d = get_conv1d(vb.pp(start_index), channels, channels, 3, 1, 1, 1, 1, true)?;
let norm = group_norm(groups, channels, 1e-5, vb.pp(start_index + 1))?;
Ok(Self { conv1d, norm })
}
pub fn forward(&self, xs: &Tensor) -> Result<Tensor> {
let xs = self.conv1d.forward(xs)?;
let xs = self.norm.forward(&xs)?;
let xs = mish(&xs)?;
Ok(xs)
}
}
pub struct InterpolateRegulator {
sampling_ratios: Vec<usize>,
out_channels: usize,
model0_11: Vec<InterpolateModule>,
model_12: Conv1d,
embedding: Embedding,
mask_token: Tensor,
quantizer_dropout: f32,
content_in_proj: Linear,
n_codebooks: usize,
interpolate: bool,
}
impl InterpolateRegulator {
pub fn new(
vb: VarBuilder,
channels: usize,
sampling_ratios: Vec<usize>,
is_discrete: bool,
in_channels: usize,
vector_quantize: bool,
codebook_size: usize,
out_channels: Option<usize>,
groups: usize,
n_codebooks: usize,
quantizer_dropout: f32,
f0_condition: bool,
n_f0_bins: usize,
) -> Result<Self> {
let out_channels = out_channels.unwrap_or(channels);
let vb_model = vb.pp("model");
let interpolate = true;
let mut model0_11 = vec![];
for (index, _) in sampling_ratios.iter().enumerate() {
let inter = InterpolateModule::new(&vb_model, index, channels, groups)?;
model0_11.push(inter);
}
let model_12 = get_conv1d(
vb_model.pp("12"),
channels,
out_channels,
1,
0,
1,
1,
1,
true,
)?;
let embedding = embedding(codebook_size, channels, vb.pp("embedding"))?;
let mask_token = vb.get_with_hints((1, channels), "mask_token", Init::Const(0.0))?;
let content_in_proj = linear(in_channels, channels, vb.pp("content_in_proj"))?;
Ok(Self {
sampling_ratios,
out_channels,
model0_11,
model_12,
embedding,
mask_token,
quantizer_dropout,
content_in_proj,
n_codebooks,
interpolate,
})
}
pub fn forward(&self, x: &Tensor, y_lens: &Tensor) -> Result<Tensor> {
let mut xs = self.content_in_proj.forward(x)?;
xs = xs.transpose(1, 2)?.contiguous()?;
if self.interpolate {
let size = y_lens.max_all()?.to_scalar::<u32>()? as usize;
xs = interpolate_nearest_1d(&xs, size)?;
}
for model_i in self.model0_11.iter() {
xs = model_i.forward(&xs)?;
}
xs = self.model_12.forward(&xs)?.transpose(1, 2)?.contiguous()?;
Ok(xs)
}
} }
pub struct MyModel { pub struct MyModel {
cfm: CFM, cfm: CFM,
length_regulator: InterpolateRegulator,
} }
pub struct IndexTTS2 { impl MyModel {
cache_spk_cond: Option<Tensor>, pub fn new(
cache_s2mel_style: Option<Tensor>, model_path: &str,
cache_s2mel_prompt: Option<Tensor>, config: &S2MelConfig,
cache_spk_audio_prompt: Option<String>, dtype: DType,
cache_emo_cond: Option<Tensor>, device: &Device,
cache_emo_audio_prompt: Option<Tensor>, ) -> Result<Self> {
cache_mel: Option<Tensor>, let s2mel_path = model_path.to_string() + "/s2mel.pth";
let length_regulator_dict =
read_pth_tensor_info_cycle(s2mel_path.clone(), Some("net.length_regulator"))?;
let length_regulator_vb = VarBuilder::from_tensors(length_regulator_dict, dtype, device);
let length_regulator = InterpolateRegulator::new(
length_regulator_vb,
config.length_regulator.channels,
config.length_regulator.sampling_ratios.clone(),
config.length_regulator.is_discrete,
config.length_regulator.in_channels,
config.length_regulator.vector_quantize,
config.length_regulator.content_codebook_size,
None,
1,
config.length_regulator.n_codebooks,
config.length_regulator.quantizer_dropout,
config.length_regulator.f0_condition,
config.length_regulator.n_f0_bins,
)?;
let cfm_dict = read_pth_tensor_info_cycle(s2mel_path.clone(), Some("net.cfm"))?;
let cfm_vb = VarBuilder::from_tensors(cfm_dict, dtype, device);
let cfm = CFM::new(cfm_vb, config)?;
Ok(Self {
cfm,
length_regulator,
})
}
pub fn length_regulator_forward(
&self,
s_ori: &Tensor,
target_lengths: &Tensor,
) -> Result<Tensor> {
let xs = self.length_regulator.forward(s_ori, target_lengths)?;
Ok(xs)
}
}
pub struct IndexTTS2Cache {
pub cache_spk_cond: Tensor,
pub cache_s2mel_style: Tensor,
pub cache_s2mel_prompt: Tensor,
pub cache_mel: Tensor,
// pub cache_emo_cond: Tensor,
// pub cache_emo_audio_prompt: Tensor,
}
pub struct IndexTTS2Model {
cache: Option<IndexTTS2Cache>,
feature_extractor: SeamlessM4TFeatureExtractor,
semantic_model: W2VBert2_0Model,
semantic_mean: Tensor,
semantic_std: Tensor,
semantic_codec: RepCodec,
s2mel_filters: Tensor,
s2mel_windows: Tensor,
s2mel_preprocess_params: PreprocessParams,
window_shift: usize,
window_size: usize,
padded_window_size: usize,
mel_energies: Tensor,
campplus_model: CAMPPlus,
s2mel: MyModel,
}
impl IndexTTS2Model {
pub fn new(
path: &str,
save_dir: &str,
config: &IndexTTS2Config,
device: &Device,
dtype: DType,
) -> Result<Self> {
let feature_extractor = SeamlessM4TFeatureExtractor::new(
// 80,
80,
crate::utils::tensor_utils::PaddingSide::Right,
1.0,
16000,
2,
device,
)?;
let w2vbert2_path = save_dir.to_string() + "/facebook/w2v-bert-2.0";
let semantic_model = W2VBert2_0Model::init(&w2vbert2_path, device, dtype)?;
let semantic_mean_var_path = path.to_string() + "/" + &config.w2v_stat;
let dict = read_all_with_key(semantic_mean_var_path, None)?;
let mut semantic_mean = Tensor::new(0.0, device)?.to_dtype(dtype)?;
let mut semantic_std = Tensor::new(1.0, device)?.to_dtype(dtype)?;
for (k, v) in dict {
if k.eq("mean") {
semantic_mean = v.to_device(device)?.to_dtype(dtype)?;
} else if k.eq("var") {
semantic_std = v.to_device(device)?.to_dtype(dtype)?.sqrt()?;
}
}
let semantic_codec_path =
save_dir.to_string() + "/amphion/MaskGCT/semantic_codec/model.safetensors";
let vb =
unsafe { VarBuilder::from_mmaped_safetensors(&[semantic_codec_path], dtype, &device)? };
let semantic_codec = RepCodec::new(vb, &config.semantic_codec)?;
let s2mel_filters = mel_filter_bank(
config.s2mel.preprocess_params.spect_params.n_fft / 2 + 1,
config.s2mel.preprocess_params.spect_params.n_mels,
config.s2mel.preprocess_params.spect_params.fmin as f32,
config
.s2mel
.preprocess_params
.spect_params
.fmax
.unwrap_or(config.s2mel.preprocess_params.sr / 2) as f32,
config.s2mel.preprocess_params.sr as f32,
Some("slaney"),
crate::utils::audio_utils::MelScale::Slaney,
false,
device,
)?
.t()?;
let s2mel_windows = create_hann_window(
config.s2mel.preprocess_params.spect_params.win_length,
dtype,
device,
)?;
let (window_shift, window_size, padded_window_size) =
get_waveform_and_window_properties(16000, 10.0, 25.0, true)?;
let (mel_energies, _) =
kaldi_get_mel_banks(80, padded_window_size, 16000 as f32, 20.0, 0.0, device)?;
let mel_energies = mel_energies.pad_with_zeros(D::Minus1, 0, 1)?.t()?;
let campplus_model_path = save_dir.to_string()
+ "/iic/speech_campplus_sv_zh-cn_16k-common/campplus_cn_common.bin";
let campplus_vb = get_vb_model_path(campplus_model_path, dtype, device.clone(), None)?;
let campplus_model = CAMPPlus::new(campplus_vb, 80, 192, 32, 4, 128)?;
let s2mel = MyModel::new(path, &config.s2mel, dtype, device)?;
Ok(Self {
cache: None,
feature_extractor,
semantic_model,
semantic_mean,
semantic_std,
semantic_codec,
s2mel_filters,
s2mel_windows,
s2mel_preprocess_params: config.s2mel.preprocess_params.clone(),
window_shift,
window_size,
padded_window_size,
mel_energies,
campplus_model,
s2mel,
})
}
pub fn get_emb(
&self,
input_features: &Tensor,
attention_mask: Option<&Tensor>,
) -> Result<Tensor> {
let output =
self.semantic_model
.forward(input_features, attention_mask, Some(17), false)?;
let feature = &output.specify_layer_id_hidden_state.unwrap();
let feature = feature
.broadcast_sub(&self.semantic_mean)?
.broadcast_div(&self.semantic_std)?;
Ok(feature)
}
pub fn s2mel_spectrogram(&self, waveform: &Tensor) -> Result<Tensor> {
let pad = (self.s2mel_preprocess_params.spect_params.n_fft
- self.s2mel_preprocess_params.spect_params.hop_length)
/ 2;
let pad_audio_22k = pad_reflect_last_dim(&waveform, (pad, pad))?;
let spec = torch_stft(
&pad_audio_22k,
self.s2mel_preprocess_params.spect_params.n_fft,
self.s2mel_preprocess_params.spect_params.hop_length,
&self.s2mel_windows,
)?
.transpose(1, 2)?;
let spec = self.s2mel_filters.broadcast_matmul(&spec)?;
let spec = spec.clamp(1e-5, f64::INFINITY)?.log()?;
Ok(spec)
}
pub fn forward(
&mut self,
input_ids: &Tensor,
audio_22k: Option<&Tensor>,
audio_16k: Option<&Tensor>,
) -> Result<()> {
if (audio_22k.is_none() || audio_16k.is_none()) && self.cache.is_none() {
return Err(anyhow!(
"Missing required audio input: must provide either audio_22k, audio_16k, or have cached prompt data available"
));
}
let (spk_cond_emb, style, prompt_condition, ref_mel) = if let Some(audio_22k) = audio_22k
&& let Some(audio_16k) = audio_16k
{
let (audio_16k_features, audio_16k_mask) =
self.feature_extractor.call(&audio_16k, 16000, true, true)?;
let spk_cond_emb = self.get_emb(&audio_16k_features, audio_16k_mask.as_ref())?;
let (_, s_ref) = self.semantic_codec.quantize(&spk_cond_emb)?;
let ref_mel = self.s2mel_spectrogram(&audio_22k)?;
let ref_target_lengths = Tensor::new(ref_mel.dim(2)? as u32, ref_mel.device())?;
let feat = kaldi_fbank(
&audio_16k,
&self.mel_energies,
self.window_shift,
self.window_size,
self.padded_window_size,
0.0,
)?;
let feat = feat.broadcast_sub(&feat.mean_keepdim(1)?)?;
let style = self.campplus_model.forward(&feat)?;
let prompt_condition = self
.s2mel
.length_regulator
.forward(&s_ref, &ref_target_lengths)?;
let cache = IndexTTS2Cache {
cache_spk_cond: spk_cond_emb.clone(),
cache_s2mel_style: style.clone(),
cache_s2mel_prompt: prompt_condition.clone(),
cache_mel: ref_mel.clone(),
};
self.cache = Some(cache);
(spk_cond_emb, style, prompt_condition, ref_mel)
} else {
let cache = self.cache.as_ref().unwrap();
(
cache.cache_spk_cond.clone(),
cache.cache_s2mel_style.clone(),
cache.cache_s2mel_prompt.clone(),
cache.cache_mel.clone(),
)
};
Ok(())
}
} }
+145 -141
View File
@@ -5,13 +5,16 @@ use candle_nn::VarBuilder;
use crate::{ use crate::{
models::{ models::{
campplus::CAMPPlus, feature_extractor::seamless_m4t_feature_extractor::SeamlessM4TFeatureExtractor, index_tts2::config::{IndexTTS2Config, PreprocessParams}, mask_gct::model::RepCodec, w2v_bert_2_0::model::W2VBert2_0Model campplus::CAMPPlus,
feature_extractor::seamless_m4t_feature_extractor::SeamlessM4TFeatureExtractor,
index_tts2::config::{IndexTTS2Config, PreprocessParams},
mask_gct::model::RepCodec,
w2v_bert_2_0::model::W2VBert2_0Model,
}, },
utils::{ utils::{
audio_utils::{ audio_utils::{
create_hann_window, extract_audio_url, get_waveform_and_window_properties, kaldi_fbank, create_hann_window, extract_audio_url, get_waveform_and_window_properties, kaldi_fbank,
kaldi_get_mel_banks, load_audio, mel_filter_bank, resample_simple, kaldi_get_mel_banks, load_audio, mel_filter_bank, resample_simple, torch_stft,
torch_stft,
}, },
get_vb_model_path, get_vb_model_path,
tensor_utils::pad_reflect_last_dim, tensor_utils::pad_reflect_last_dim,
@@ -21,104 +24,104 @@ use crate::{
pub struct IndexTTS2Processor { pub struct IndexTTS2Processor {
device: Device, device: Device,
max_audio_length_seconds: usize, max_audio_length_seconds: usize,
feature_extractor: SeamlessM4TFeatureExtractor, // feature_extractor: SeamlessM4TFeatureExtractor,
semantic_model: W2VBert2_0Model, // semantic_model: W2VBert2_0Model,
semantic_mean: Tensor, // semantic_mean: Tensor,
semantic_std: Tensor, // semantic_std: Tensor,
semantic_codec: RepCodec, // semantic_codec: RepCodec,
s2mel_filters: Tensor, // s2mel_filters: Tensor,
s2mel_windows: Tensor, // s2mel_windows: Tensor,
s2mel_preprocess_params: PreprocessParams, // s2mel_preprocess_params: PreprocessParams,
window_shift: usize, // window_shift: usize,
window_size: usize, // window_size: usize,
padded_window_size: usize, // padded_window_size: usize,
mel_energies: Tensor, // mel_energies: Tensor,
campplus_model: CAMPPlus, // campplus_model: CAMPPlus,
} }
impl IndexTTS2Processor { impl IndexTTS2Processor {
pub fn new( pub fn new(
path: &str, // path: &str,
save_dir: &str, // save_dir: &str,
config: &IndexTTS2Config, // config: &IndexTTS2Config,
device: &Device, device: &Device,
dtype: DType, // dtype: DType,
) -> Result<Self> { ) -> Result<Self> {
let feature_extractor = SeamlessM4TFeatureExtractor::new( // let feature_extractor = SeamlessM4TFeatureExtractor::new(
// // 80,
// 80, // 80,
80, // crate::utils::tensor_utils::PaddingSide::Right,
crate::utils::tensor_utils::PaddingSide::Right, // 1.0,
1.0, // 16000,
16000, // 2,
2, // device,
device, // )?;
)?; // let w2vbert2_path = save_dir.to_string() + "/facebook/w2v-bert-2.0";
let w2vbert2_path = save_dir.to_string() + "/facebook/w2v-bert-2.0"; // let semantic_model = W2VBert2_0Model::init(&w2vbert2_path, device, dtype)?;
let semantic_model = W2VBert2_0Model::init(&w2vbert2_path, device, dtype)?; // let semantic_mean_var_path = path.to_string() + "/" + &config.w2v_stat;
let semantic_mean_var_path = path.to_string() + "/" + &config.w2v_stat; // let dict = read_all_with_key(semantic_mean_var_path, None)?;
let dict = read_all_with_key(semantic_mean_var_path, None)?; // let mut semantic_mean = Tensor::new(0.0, device)?.to_dtype(dtype)?;
let mut semantic_mean = Tensor::new(0.0, device)?.to_dtype(dtype)?; // let mut semantic_std = Tensor::new(1.0, device)?.to_dtype(dtype)?;
let mut semantic_std = Tensor::new(1.0, device)?.to_dtype(dtype)?; // for (k, v) in dict {
for (k, v) in dict { // if k.eq("mean") {
if k.eq("mean") { // semantic_mean = v.to_device(device)?.to_dtype(dtype)?;
semantic_mean = v.to_device(device)?.to_dtype(dtype)?; // } else if k.eq("var") {
} else if k.eq("var") { // semantic_std = v.to_device(device)?.to_dtype(dtype)?.sqrt()?;
semantic_std = v.to_device(device)?.to_dtype(dtype)?.sqrt()?; // }
} // }
}
let semantic_codec_path = // let semantic_codec_path =
save_dir.to_string() + "/amphion/MaskGCT/semantic_codec/model.safetensors"; // save_dir.to_string() + "/amphion/MaskGCT/semantic_codec/model.safetensors";
let vb = // let vb =
unsafe { VarBuilder::from_mmaped_safetensors(&[semantic_codec_path], dtype, &device)? }; // unsafe { VarBuilder::from_mmaped_safetensors(&[semantic_codec_path], dtype, &device)? };
let semantic_codec = RepCodec::new(vb, &config.semantic_codec)?; // let semantic_codec = RepCodec::new(vb, &config.semantic_codec)?;
let s2mel_filters = mel_filter_bank( // let s2mel_filters = mel_filter_bank(
config.s2mel.preprocess_params.spect_params.n_fft / 2 + 1, // config.s2mel.preprocess_params.spect_params.n_fft / 2 + 1,
config.s2mel.preprocess_params.spect_params.n_mels, // config.s2mel.preprocess_params.spect_params.n_mels,
config.s2mel.preprocess_params.spect_params.fmin as f32, // config.s2mel.preprocess_params.spect_params.fmin as f32,
config // config
.s2mel // .s2mel
.preprocess_params // .preprocess_params
.spect_params // .spect_params
.fmax // .fmax
.unwrap_or(config.s2mel.preprocess_params.sr / 2) as f32, // .unwrap_or(config.s2mel.preprocess_params.sr / 2) as f32,
config.s2mel.preprocess_params.sr as f32, // config.s2mel.preprocess_params.sr as f32,
Some("slaney"), // Some("slaney"),
crate::utils::audio_utils::MelScale::Slaney, // crate::utils::audio_utils::MelScale::Slaney,
false, // false,
device, // device,
)? // )?
.t()?; // .t()?;
let s2mel_windows = create_hann_window( // let s2mel_windows = create_hann_window(
config.s2mel.preprocess_params.spect_params.win_length, // config.s2mel.preprocess_params.spect_params.win_length,
dtype, // dtype,
device, // device,
)?; // )?;
let (window_shift, window_size, padded_window_size) = // let (window_shift, window_size, padded_window_size) =
get_waveform_and_window_properties(16000, 10.0, 25.0, true)?; // get_waveform_and_window_properties(16000, 10.0, 25.0, true)?;
let (mel_energies, _) = // let (mel_energies, _) =
kaldi_get_mel_banks(80, padded_window_size, 16000 as f32, 20.0, 0.0, device)?; // kaldi_get_mel_banks(80, padded_window_size, 16000 as f32, 20.0, 0.0, device)?;
let mel_energies = mel_energies.pad_with_zeros(D::Minus1, 0, 1)?.t()?; // let mel_energies = mel_energies.pad_with_zeros(D::Minus1, 0, 1)?.t()?;
let campplus_model_path = save_dir.to_string() // let campplus_model_path = save_dir.to_string()
+ "/iic/speech_campplus_sv_zh-cn_16k-common/campplus_cn_common.bin"; // + "/iic/speech_campplus_sv_zh-cn_16k-common/campplus_cn_common.bin";
let campplus_vb = get_vb_model_path(campplus_model_path, dtype, device.clone(), None)?; // let campplus_vb = get_vb_model_path(campplus_model_path, dtype, device.clone(), None)?;
let campplus_model = CAMPPlus::new(campplus_vb, 80, 192, 32, 4, 128)?; // let campplus_model = CAMPPlus::new(campplus_vb, 80, 192, 32, 4, 128)?;
Ok(Self { Ok(Self {
device: device.clone(), device: device.clone(),
max_audio_length_seconds: 15, max_audio_length_seconds: 15,
feature_extractor, // feature_extractor,
semantic_model, // semantic_model,
semantic_mean, // semantic_mean,
semantic_std, // semantic_std,
semantic_codec, // semantic_codec,
s2mel_filters, // s2mel_filters,
s2mel_windows, // s2mel_windows,
s2mel_preprocess_params: config.s2mel.preprocess_params.clone(), // s2mel_preprocess_params: config.s2mel.preprocess_params.clone(),
window_shift, // window_shift,
window_size, // window_size,
padded_window_size, // padded_window_size,
mel_energies, // mel_energies,
campplus_model, // campplus_model,
}) })
} }
@@ -137,63 +140,64 @@ impl IndexTTS2Processor {
&self, &self,
mes: &ChatCompletionParameters, mes: &ChatCompletionParameters,
device: &Device, device: &Device,
) -> Result<(Tensor, usize)> { ) -> Result<(Tensor, usize, String)> {
let audio_url_vec = extract_audio_url(mes); let audio_url_vec = extract_audio_url(mes);
let (audio, sr) = load_audio(&audio_url_vec[0], device)?; let (audio, sr) = load_audio(&audio_url_vec[0], device)?;
self.cut_audio(&audio, sr) let (audio, sr) = self.cut_audio(&audio, sr)?;
Ok((audio, sr, audio_url_vec[0].clone()))
} }
pub fn get_emb( // pub fn get_emb(
&self, // &self,
input_features: &Tensor, // input_features: &Tensor,
attention_mask: Option<&Tensor>, // attention_mask: Option<&Tensor>,
) -> Result<Tensor> { // ) -> Result<Tensor> {
let output = // let output =
self.semantic_model // self.semantic_model
.forward(input_features, attention_mask, Some(17), false)?; // .forward(input_features, attention_mask, Some(17), false)?;
let feature = &output.specify_layer_id_hidden_state.unwrap(); // let feature = &output.specify_layer_id_hidden_state.unwrap();
let feature = feature // let feature = feature
.broadcast_sub(&self.semantic_mean)? // .broadcast_sub(&self.semantic_mean)?
.broadcast_div(&self.semantic_std)?; // .broadcast_div(&self.semantic_std)?;
Ok(feature) // Ok(feature)
} // }
pub fn s2mel_spectrogram(&self, waveform: &Tensor) -> Result<Tensor> { // pub fn s2mel_spectrogram(&self, waveform: &Tensor) -> Result<Tensor> {
let pad = (self.s2mel_preprocess_params.spect_params.n_fft // let pad = (self.s2mel_preprocess_params.spect_params.n_fft
- self.s2mel_preprocess_params.spect_params.hop_length) // - self.s2mel_preprocess_params.spect_params.hop_length)
/ 2; // / 2;
let pad_audio_22k = pad_reflect_last_dim(&waveform, (pad, pad))?; // let pad_audio_22k = pad_reflect_last_dim(&waveform, (pad, pad))?;
let spec = torch_stft( // let spec = torch_stft(
&pad_audio_22k, // &pad_audio_22k,
self.s2mel_preprocess_params.spect_params.n_fft, // self.s2mel_preprocess_params.spect_params.n_fft,
self.s2mel_preprocess_params.spect_params.hop_length, // self.s2mel_preprocess_params.spect_params.hop_length,
&self.s2mel_windows, // &self.s2mel_windows,
)? // )?
.transpose(1, 2)?; // .transpose(1, 2)?;
let spec = self.s2mel_filters.broadcast_matmul(&spec)?; // let spec = self.s2mel_filters.broadcast_matmul(&spec)?;
let spec = spec.clamp(1e-5, f64::INFINITY)?.log()?; // let spec = spec.clamp(1e-5, f64::INFINITY)?.log()?;
Ok(spec) // Ok(spec)
} // }
pub fn process_info(&self, mes: &ChatCompletionParameters) -> Result<()> { pub fn process_info(&self, mes: &ChatCompletionParameters) -> Result<(Tensor, Tensor, String)> {
let (audio, sr) = self.extract_audio_and_cut(mes, &self.device)?; let (audio, sr, audio_url) = self.extract_audio_and_cut(mes, &self.device)?;
let audio_22k = resample_simple(&audio, sr as i64, 22050)?; let audio_22k = resample_simple(&audio, sr as i64, 22050)?;
let audio_16k = resample_simple(&audio, sr as i64, 16000)?; let audio_16k = resample_simple(&audio, sr as i64, 16000)?;
let (audio_16k_features, audio_16k_mask) = // let (audio_16k_features, audio_16k_mask) =
self.feature_extractor.call(&audio_16k, 16000, true, true)?; // self.feature_extractor.call(&audio_16k, 16000, true, true)?;
let spk_cond_emb = self.get_emb(&audio_16k_features, audio_16k_mask.as_ref())?; // let spk_cond_emb = self.get_emb(&audio_16k_features, audio_16k_mask.as_ref())?;
let (_, s_ref) = self.semantic_codec.quantize(&spk_cond_emb)?; // let (_, s_ref) = self.semantic_codec.quantize(&spk_cond_emb)?;
let ref_mel = self.s2mel_spectrogram(&audio_22k)?; // let ref_mel = self.s2mel_spectrogram(&audio_22k)?;
let feat = kaldi_fbank( // let feat = kaldi_fbank(
&audio_16k, // &audio_16k,
&self.mel_energies, // &self.mel_energies,
self.window_shift, // self.window_shift,
self.window_size, // self.window_size,
self.padded_window_size, // self.padded_window_size,
0.0, // 0.0,
)?; // )?;
let feat = feat.broadcast_sub(&feat.mean_keepdim(1)?)?; // let feat = feat.broadcast_sub(&feat.mean_keepdim(1)?)?;
let style = self.campplus_model.forward(&feat)?; // let style = self.campplus_model.forward(&feat)?;
println!("style: {}", style); // println!("style: {}", style);
Ok(()) Ok((audio_22k, audio_16k, audio_url))
} }
} }
+155 -2
View File
@@ -1,13 +1,18 @@
use std::collections::HashMap;
use anyhow::{Result, anyhow};
use regex::Regex;
use crate::utils::{download_model, get_default_save_dir}; use crate::utils::{download_model, get_default_save_dir};
pub async fn download_index_tts2_need_model(save_dir: Option<&str>) -> anyhow::Result<()> { pub async fn download_index_tts2_need_model(save_dir: Option<&str>) -> Result<()> {
let save_dir = match save_dir { let save_dir = match save_dir {
Some(dir) => dir.to_string(), Some(dir) => dir.to_string(),
None => get_default_save_dir().expect("Failed to get home directory"), None => get_default_save_dir().expect("Failed to get home directory"),
}; };
let w2v_bert2_0 = "facebook/w2v-bert-2.0"; let w2v_bert2_0 = "facebook/w2v-bert-2.0";
let mask_gct= "amphion/MaskGCT"; let mask_gct = "amphion/MaskGCT";
// let campplus= "funasr/campplus"; // huggingface // let campplus= "funasr/campplus"; // huggingface
let campplus = "iic/speech_campplus_sv_zh-cn_16k-common"; // modelscope let campplus = "iic/speech_campplus_sv_zh-cn_16k-common"; // modelscope
download_model(w2v_bert2_0, &save_dir, 3).await?; download_model(w2v_bert2_0, &save_dir, 3).await?;
@@ -16,3 +21,151 @@ pub async fn download_index_tts2_need_model(save_dir: Option<&str>) -> anyhow::R
Ok(()) Ok(())
} }
#[derive(Debug, Clone)]
pub struct TextNormalizer {
// char_rep_map: HashMap<String, String>,
// zh_char_rep_map: HashMap<String, String>,
pinyin_tone_pattern: Regex,
// name_pattern: Regex,
// tech_term_pattern: Regex,
// english_contraction_pattern: Regex,
email_pattern: Regex,
cjk_range_pattern: Regex,
}
impl TextNormalizer {
pub fn new() -> Result<Self> {
let pinyin_tone_pattern: Regex = Regex::new(
// r"(?i)(?<![a-z])((?:[bpmfdtnlgkhjqxzcsryw]|[zcs]h)?(?:[aeiouüvAEIOUV]|[aeAE]i|u[aiouAIUO]|aoAO|ouOU|i[aeuAEU]|[uüvUÜV]e|[uvüUVÜ]ang?|uaiUAI|[aeiuvAEIUV]n|[aeioAEIO]ng|ia[noNAO]|i[aA][oO]ng)|ngNG|erER)([1-5])"
r"(?i)((?:[bpmfdtnlgkhjqxzcsryw]|[zcs]h)?(?:[aeiouüvAEIOUV]|[aeAE]i|u[aiouAIUO]|aoAO|ouOU|i[aeuAEU]|[uüvUÜV]e|[uvüUVÜ]ang?|uaiUAI|[aeiuvAEIUV]n|[aeioAEIO]ng|ia[noNAO]|i[aA][oO]ng)|ngNG|erER)([1-5])"
).map_err(|e| anyhow!(format!("new pinyin_tone_pattern regex error:{}", e)))?;
// let name_pattern: Regex =
// Regex::new(r"[\u{4e00}-\u{9fff}]+(?:[-·—][\u{4e00}-\u{9fff}]+){1,2}")
// .map_err(|e| anyhow!(format!("new name_pattern regex error:{}", e)))?;
// let tech_term_pattern: Regex = Regex::new(r"[A-Za-z][A-Za-z0-9]*(?:-[A-Za-z0-9]+)+")
// .map_err(|e| anyhow!(format!("new tech_term_pattern regex error:{}", e)))?;
// let english_contraction_pattern: Regex = Regex::new(
// r"(?i)(what|where|who|which|how|t?here|it|s?he|that|this)'s",
// )
// .map_err(|e| anyhow!(format!("new english_contraction_pattern regex error:{}", e)))?;
let email_pattern: Regex = Regex::new(r"^[a-zA-Z0-9]+@[a-zA-Z0-9]+\.[a-zA-Z]+$")
.map_err(|e| anyhow!(format!("new email_pattern regex error:{}", e)))?;
let cjk_range_pattern: Regex = Regex::new(r"([\u{1100}-\u{11ff}\u{2e80}-\u{a4cf}\u{a840}-\u{d7af}\u{f900}-\u{faff}\u{fe30}-\u{fe4f}\u{ff65}-\u{ffdc}\u{20000}-\u{2ffff}])")
.map_err(|e| anyhow!(format!("new cjk_range_pattern regex error:{}", e)))?;
// let mut char_rep_map = HashMap::new();
// char_rep_map.insert("".to_string(), ",".to_string());
// char_rep_map.insert("".to_string(), ",".to_string());
// char_rep_map.insert(";".to_string(), ",".to_string());
// char_rep_map.insert("".to_string(), ",".to_string());
// char_rep_map.insert("。".to_string(), ".".to_string());
// char_rep_map.insert("".to_string(), "!".to_string());
// char_rep_map.insert("".to_string(), "?".to_string());
// char_rep_map.insert("\n".to_string(), " ".to_string());
// char_rep_map.insert("·".to_string(), "-".to_string());
// char_rep_map.insert("、".to_string(), ",".to_string());
// char_rep_map.insert("...".to_string(), "…".to_string());
// char_rep_map.insert(",,,".to_string(), "…".to_string());
// char_rep_map.insert(",,,".to_string(), "…".to_string());
// char_rep_map.insert("……".to_string(), "…".to_string());
// char_rep_map.insert("“".to_string(), "'".to_string());
// char_rep_map.insert("”".to_string(), "'".to_string());
// char_rep_map.insert("\"".to_string(), "'".to_string());
// char_rep_map.insert("".to_string(), "'".to_string());
// char_rep_map.insert("".to_string(), "'".to_string());
// char_rep_map.insert("".to_string(), "'".to_string());
// char_rep_map.insert("".to_string(), "'".to_string());
// char_rep_map.insert("(".to_string(), "'".to_string());
// char_rep_map.insert(")".to_string(), "'".to_string());
// char_rep_map.insert("《".to_string(), "'".to_string());
// char_rep_map.insert("》".to_string(), "'".to_string());
// char_rep_map.insert("【".to_string(), "'".to_string());
// char_rep_map.insert("】".to_string(), "'".to_string());
// char_rep_map.insert("[".to_string(), "'".to_string());
// char_rep_map.insert("]".to_string(), "'".to_string());
// char_rep_map.insert("—".to_string(), "-".to_string());
// char_rep_map.insert("".to_string(), "-".to_string());
// char_rep_map.insert("~".to_string(), "-".to_string());
// char_rep_map.insert("「".to_string(), "'".to_string());
// char_rep_map.insert("」".to_string(), "'".to_string());
// char_rep_map.insert(":".to_string(), ",".to_string());
// let mut zh_char_rep_map = char_rep_map.clone();
// zh_char_rep_map.insert("$".to_string(), ".".to_string());
Ok(Self {
// char_rep_map,
// zh_char_rep_map,
pinyin_tone_pattern,
// name_pattern,
// tech_term_pattern,
// english_contraction_pattern,
email_pattern,
cjk_range_pattern,
})
}
pub fn match_email(&self, email: &str) -> bool {
self.email_pattern.is_match(email)
}
pub fn use_chinese(&self, s: &str) -> bool {
let has_chinese = s.chars().any(|c| ('\u{4e00}'..='\u{9fff}').contains(&c));
let has_alpha = s.chars().any(|c| c.is_alphabetic());
let is_email = self.match_email(s);
if has_chinese || !has_alpha || is_email {
return true;
}
self.pinyin_tone_pattern.is_match(s)
}
pub fn tokenize_by_cjk_char(&self, line: &str, do_upper_case: bool) -> String {
// Split the line by CJK characters
let parts: Vec<&str> = self.cjk_range_pattern.split(line.trim()).collect();
// Process each part and join with spaces
let mut result_parts = Vec::new();
for part in parts {
if !part.trim().is_empty() {
if do_upper_case {
result_parts.push(part.trim().to_uppercase());
} else {
result_parts.push(part.trim().to_string());
}
}
}
// Join the parts with spaces
result_parts.join(" ")
}
}
pub fn tokenize_by_cjk_char(line: &str, do_upper_case: bool) -> String {
let mut result_parts = Vec::new();
for ch in line.chars() {
if ('\u{1100}'..='\u{11ff}').contains(&ch)
|| ('\u{2e80}'..='\u{a4cf}').contains(&ch)
|| ('\u{a840}'..='\u{d7af}').contains(&ch)
|| ('\u{f900}'..='\u{faff}').contains(&ch)
|| ('\u{fe30}'..='\u{fe4f}').contains(&ch)
|| ('\u{ff65}'..='\u{ffdc}').contains(&ch)
|| ('\u{20000}'..='\u{2ffff}').contains(&ch)
|| ('\u{4e00}'..='\u{9fff}').contains(&ch)
{
// CJK 字符
if do_upper_case {
result_parts.push(ch.to_uppercase().collect::<String>());
} else {
result_parts.push(ch.to_string());
}
} else {
// 非 CJK 字符,保持在一起
if do_upper_case {
result_parts.push(ch.to_uppercase().to_string());
} else {
result_parts.push(ch.to_string());
}
}
}
result_parts.join(" ")
}
+3 -3
View File
@@ -28,7 +28,7 @@ impl ConvNeXtBlock {
// layer_scale_init_value: f32, // layer_scale_init_value: f32,
) -> Result<Self> { ) -> Result<Self> {
let dwconv = get_conv1d(vb.pp("dwconv"), dim, dim, 7, 3, 1, 1, dim, true)?; let dwconv = get_conv1d(vb.pp("dwconv"), dim, dim, 7, 3, 1, 1, dim, true)?;
let norm = get_layer_norm(vb.pp("norm"), 1e-6, dim)?; let norm = get_layer_norm(vb.pp("norm"), 1e-6, dim, true)?;
let pwconv1 = linear(dim, intermediate_dim, vb.pp("pwconv1"))?; let pwconv1 = linear(dim, intermediate_dim, vb.pp("pwconv1"))?;
let pwconv2 = linear(intermediate_dim, dim, vb.pp("pwconv2"))?; let pwconv2 = linear(intermediate_dim, dim, vb.pp("pwconv2"))?;
let gamma = vb.get_with_hints(dim, "gamma", Init::Const(1.0))?; let gamma = vb.get_with_hints(dim, "gamma", Init::Const(1.0))?;
@@ -73,14 +73,14 @@ impl VocosBackbone {
// layer_scale_init_value: Option<f32>, // layer_scale_init_value: Option<f32>,
) -> Result<Self> { ) -> Result<Self> {
let embed = get_conv1d(vb.pp("embed"), input_channels, dim, 7, 3, 1, 1, 1, true)?; let embed = get_conv1d(vb.pp("embed"), input_channels, dim, 7, 3, 1, 1, 1, true)?;
let norm = get_layer_norm(vb.pp("norm"), 1e-6, dim)?; let norm = get_layer_norm(vb.pp("norm"), 1e-6, dim, true)?;
let vb_convnext = vb.pp("convnext"); let vb_convnext = vb.pp("convnext");
let mut convnext = vec![]; let mut convnext = vec![];
for i in 0..num_layers { for i in 0..num_layers {
let layer = ConvNeXtBlock::new(vb_convnext.pp(i), dim, intermediate_dim)?; let layer = ConvNeXtBlock::new(vb_convnext.pp(i), dim, intermediate_dim)?;
convnext.push(layer); convnext.push(layer);
} }
let final_layer_norm = get_layer_norm(vb.pp("final_layer_norm"), 1e-6, dim)?; let final_layer_norm = get_layer_norm(vb.pp("final_layer_norm"), 1e-6, dim, true)?;
Ok(Self { Ok(Self {
embed, embed,
norm, norm,
+2
View File
@@ -37,6 +37,7 @@ impl Projector {
vb.pp("pre_norm"), vb.pp("pre_norm"),
config.rms_norm_eps, config.rms_norm_eps,
config.vision_config.hidden_size, config.vision_config.hidden_size,
true,
)?; )?;
let linear_1 = linear(hidden_size, hidden_size, vb.pp("linear_1"))?; let linear_1 = linear(hidden_size, hidden_size, vb.pp("linear_1"))?;
let linear_2 = linear(hidden_size, config.hidden_size, vb.pp("linear_2"))?; let linear_2 = linear(hidden_size, config.hidden_size, vb.pp("linear_2"))?;
@@ -278,6 +279,7 @@ impl SiglipVisionModel {
vb.pp("post_layernorm"), vb.pp("post_layernorm"),
config.layer_norm_eps, config.layer_norm_eps,
config.hidden_size, config.hidden_size,
true,
)?; )?;
Ok(Self { Ok(Self {
embeddings, embeddings,
+4 -3
View File
@@ -50,11 +50,12 @@ impl Qwen3ASRAudioEncoderLayer {
Some("out_proj"), Some("out_proj"),
)?; )?;
let self_attn_layer_norm = let self_attn_layer_norm =
get_layer_norm(vb.pp("self_attn_layer_norm"), 1e-5, config.d_model)?; get_layer_norm(vb.pp("self_attn_layer_norm"), 1e-5, config.d_model, true)?;
let activation_fn = config.activation_function; let activation_fn = config.activation_function;
let fc1 = linear(config.d_model, config.encoder_ffn_dim, vb.pp("fc1"))?; let fc1 = linear(config.d_model, config.encoder_ffn_dim, vb.pp("fc1"))?;
let fc2 = linear(config.encoder_ffn_dim, config.d_model, vb.pp("fc2"))?; let fc2 = linear(config.encoder_ffn_dim, config.d_model, vb.pp("fc2"))?;
let final_layer_norm = get_layer_norm(vb.pp("final_layer_norm"), 1e-5, config.d_model)?; let final_layer_norm =
get_layer_norm(vb.pp("final_layer_norm"), 1e-5, config.d_model, true)?;
Ok(Self { Ok(Self {
self_attn, self_attn,
self_attn_layer_norm, self_attn_layer_norm,
@@ -105,7 +106,7 @@ impl Qwen3ASRAudioEncoder {
let layer = Qwen3ASRAudioEncoderLayer::new(vb_layers.pp(i), config)?; let layer = Qwen3ASRAudioEncoderLayer::new(vb_layers.pp(i), config)?;
layers.push(layer); layers.push(layer);
} }
let ln_post = get_layer_norm(vb.pp("ln_post"), 1e-5, config.d_model)?; let ln_post = get_layer_norm(vb.pp("ln_post"), 1e-5, config.d_model, true)?;
let conv2d1 = get_conv2d( let conv2d1 = get_conv2d(
vb.pp("conv2d1"), vb.pp("conv2d1"),
1, 1,
+3 -3
View File
@@ -90,7 +90,7 @@ impl Qwen3VLVisionPatchMerger {
} else { } else {
config.hidden_size config.hidden_size
}; };
let norm = get_layer_norm(vb.pp("norm"), 1e-6, norm_size)?; let norm = get_layer_norm(vb.pp("norm"), 1e-6, norm_size, true)?;
let linear_fc1 = linear(hidden_size, hidden_size, vb.pp("linear_fc1"))?; let linear_fc1 = linear(hidden_size, hidden_size, vb.pp("linear_fc1"))?;
let act_fn = Activation::Gelu; let act_fn = Activation::Gelu;
let linear_fc2 = linear(hidden_size, config.out_hidden_size, vb.pp("linear_fc2"))?; let linear_fc2 = linear(hidden_size, config.out_hidden_size, vb.pp("linear_fc2"))?;
@@ -200,8 +200,8 @@ pub struct Qwen3VLVisionBlock {
impl Qwen3VLVisionBlock { impl Qwen3VLVisionBlock {
pub fn new(config: Qwen3VLVisionConfig, vb: VarBuilder) -> Result<Self> { pub fn new(config: Qwen3VLVisionConfig, vb: VarBuilder) -> Result<Self> {
let norm1 = get_layer_norm(vb.pp("norm1"), 1e-6, config.hidden_size)?; let norm1 = get_layer_norm(vb.pp("norm1"), 1e-6, config.hidden_size, true)?;
let norm2 = get_layer_norm(vb.pp("norm2"), 1e-6, config.hidden_size)?; let norm2 = get_layer_norm(vb.pp("norm2"), 1e-6, config.hidden_size, true)?;
let attn = Qwen3VLVisionAttention::new(config.clone(), vb.pp("attn"))?; let attn = Qwen3VLVisionAttention::new(config.clone(), vb.pp("attn"))?;
let mlp = TwoLinearMLP::new( let mlp = TwoLinearMLP::new(
vb.pp("mlp"), vb.pp("mlp"),
+5 -5
View File
@@ -42,7 +42,7 @@ impl PatchEmbed {
true, true,
)?; )?;
let norm = if patch_norm { let norm = if patch_norm {
Some(get_layer_norm(vb.pp("norm"), 1e-5, embed_dim)?) Some(get_layer_norm(vb.pp("norm"), 1e-5, embed_dim, true)?)
} else { } else {
None None
}; };
@@ -242,7 +242,7 @@ impl SwinTransformerBlock {
window_size: usize, window_size: usize,
shift_size: usize, shift_size: usize,
) -> Result<Self> { ) -> Result<Self> {
let norm1 = get_layer_norm(vb.pp("norm1"), 1e-5, dim)?; let norm1 = get_layer_norm(vb.pp("norm1"), 1e-5, dim, true)?;
let attn = WindowAttention::new( let attn = WindowAttention::new(
vb.pp("attn"), vb.pp("attn"),
@@ -251,7 +251,7 @@ impl SwinTransformerBlock {
qkv_bias, qkv_bias,
(window_size, window_size), (window_size, window_size),
)?; )?;
let norm2 = get_layer_norm(vb.pp("norm2"), 1e-5, dim)?; let norm2 = get_layer_norm(vb.pp("norm2"), 1e-5, dim, true)?;
let mlp_dim = (dim as f32 * mlp_ratio) as usize; let mlp_dim = (dim as f32 * mlp_ratio) as usize;
let mlp = TwoLinearMLP::new(vb.pp("mlp"), dim, mlp_dim, dim, act, true, "fc1", "fc2")?; let mlp = TwoLinearMLP::new(vb.pp("mlp"), dim, mlp_dim, dim, act, true, "fc1", "fc2")?;
Ok(Self { Ok(Self {
@@ -323,7 +323,7 @@ struct PatchMerging {
impl PatchMerging { impl PatchMerging {
pub fn new(vb: VarBuilder, dim: usize) -> Result<Self> { pub fn new(vb: VarBuilder, dim: usize) -> Result<Self> {
let reduction = linear_no_bias(4 * dim, 2 * dim, vb.pp("reduction"))?; let reduction = linear_no_bias(4 * dim, 2 * dim, vb.pp("reduction"))?;
let norm = get_layer_norm(vb.pp("norm"), 1e-5, 4 * dim)?; let norm = get_layer_norm(vb.pp("norm"), 1e-5, 4 * dim, true)?;
Ok(Self { reduction, norm }) Ok(Self { reduction, norm })
} }
@@ -518,7 +518,7 @@ impl SwinTransformer {
} }
let mut norms = vec![]; let mut norms = vec![];
for i in out_indices.clone() { for i in out_indices.clone() {
let layer_i = get_layer_norm(vb.pp(format!("norm{i}")), 1e-5, num_features[i])?; let layer_i = get_layer_norm(vb.pp(format!("norm{i}")), 1e-5, num_features[i], true)?;
norms.push(layer_i); norms.push(layer_i);
} }
Ok(Self { Ok(Self {
+8 -3
View File
@@ -7,9 +7,7 @@ use candle_nn::{
use crate::{ use crate::{
models::{ models::{
common::{ common::{GLU, TwoLinearMLP, eager_attention_forward, get_conv1d, get_layer_norm},
GLU, TwoLinearMLP, eager_attention_forward, get_conv1d, get_layer_norm,
},
w2v_bert_2_0::config::W2VBert2_0Config, w2v_bert_2_0::config::W2VBert2_0Config,
}, },
position_embed::rope::{RoPE, apply_rotary_pos_emb}, position_embed::rope::{RoPE, apply_rotary_pos_emb},
@@ -27,6 +25,7 @@ impl Wav2Vec2BertFeatureProjection {
vb.pp("layer_norm"), vb.pp("layer_norm"),
config.layer_norm_eps, config.layer_norm_eps,
config.feature_projection_input_dim, config.feature_projection_input_dim,
true,
)?; )?;
let projection = linear( let projection = linear(
config.feature_projection_input_dim, config.feature_projection_input_dim,
@@ -248,6 +247,7 @@ impl Wav2Vec2BertConvolutionModule {
vb.pp("layer_norm"), vb.pp("layer_norm"),
config.layer_norm_eps, config.layer_norm_eps,
config.hidden_size, config.hidden_size,
true,
)?; )?;
let pointwise_conv1 = get_conv1d( let pointwise_conv1 = get_conv1d(
vb.pp("pointwise_conv1"), vb.pp("pointwise_conv1"),
@@ -277,6 +277,7 @@ impl Wav2Vec2BertConvolutionModule {
vb.pp("depthwise_layer_norm"), vb.pp("depthwise_layer_norm"),
config.layer_norm_eps, config.layer_norm_eps,
config.hidden_size, config.hidden_size,
true,
)?; )?;
let pointwise_conv2 = get_conv1d( let pointwise_conv2 = get_conv1d(
vb.pp("pointwise_conv2"), vb.pp("pointwise_conv2"),
@@ -341,6 +342,7 @@ impl Wav2Vec2BertEncoderLayer {
vb.pp("ffn1_layer_norm"), vb.pp("ffn1_layer_norm"),
config.layer_norm_eps, config.layer_norm_eps,
config.hidden_size, config.hidden_size,
true,
)?; )?;
let ffn1 = TwoLinearMLP::new( let ffn1 = TwoLinearMLP::new(
vb.pp("ffn1"), vb.pp("ffn1"),
@@ -356,6 +358,7 @@ impl Wav2Vec2BertEncoderLayer {
vb.pp("self_attn_layer_norm"), vb.pp("self_attn_layer_norm"),
config.layer_norm_eps, config.layer_norm_eps,
config.hidden_size, config.hidden_size,
true,
)?; )?;
let self_attn = Wav2Vec2BertSelfAttention::new(vb.pp("self_attn"), config, false)?; let self_attn = Wav2Vec2BertSelfAttention::new(vb.pp("self_attn"), config, false)?;
let conv_module = Wav2Vec2BertConvolutionModule::new(vb.pp("conv_module"), config)?; let conv_module = Wav2Vec2BertConvolutionModule::new(vb.pp("conv_module"), config)?;
@@ -363,6 +366,7 @@ impl Wav2Vec2BertEncoderLayer {
vb.pp("ffn2_layer_norm"), vb.pp("ffn2_layer_norm"),
config.layer_norm_eps, config.layer_norm_eps,
config.hidden_size, config.hidden_size,
true,
)?; )?;
let ffn2 = TwoLinearMLP::new( let ffn2 = TwoLinearMLP::new(
vb.pp("ffn2"), vb.pp("ffn2"),
@@ -378,6 +382,7 @@ impl Wav2Vec2BertEncoderLayer {
vb.pp("final_layer_norm"), vb.pp("final_layer_norm"),
config.layer_norm_eps, config.layer_norm_eps,
config.hidden_size, config.hidden_size,
true,
)?; )?;
Ok(Self { Ok(Self {
ffn1_layer_norm, ffn1_layer_norm,
+15 -1
View File
@@ -1,5 +1,6 @@
use anyhow::{Ok, Result, anyhow}; use anyhow::{Result, anyhow};
use candle_core::{Device, Tensor}; use candle_core::{Device, Tensor};
use sentencepiece::SentencePieceProcessor;
use serde_json::Value; use serde_json::Value;
use tokenizers::{ use tokenizers::{
AddedToken, Tokenizer, decoders::byte_level::ByteLevel as ByteLevelDecoder, models::bpe::BPE, AddedToken, Tokenizer, decoders::byte_level::ByteLevel as ByteLevelDecoder, models::bpe::BPE,
@@ -114,3 +115,16 @@ impl TokenizerModel {
Ok(decode) Ok(decode)
} }
} }
pub fn sentencepiece_encode(
text: &str,
tokenizer: &SentencePieceProcessor,
device: &Device,
) -> Result<Tensor> {
let tokens = tokenizer
.encode(text)
.map_err(|e| anyhow!(format!("tokenizer encode error:{}", e)))?;
let token_ids = tokens.iter().map(|p| p.id).collect::<Vec<u32>>();
let tokens_t = Tensor::new(token_ids, device)?.unsqueeze(0)?;
Ok(tokens_t)
}
+6 -2
View File
@@ -219,7 +219,7 @@ pub fn crate_tensor_from_reader<R: std::io::Read>(
pub fn read_pth_tensor_info_cycle<P: AsRef<std::path::Path>>( pub fn read_pth_tensor_info_cycle<P: AsRef<std::path::Path>>(
path: P, path: P,
key: Option<&str>, key: Option<&str>,
) -> Result<Vec<(String, Tensor)>> { ) -> Result<HashMap<String, Tensor>> {
let file = std::fs::File::open(path.as_ref())?; let file = std::fs::File::open(path.as_ref())?;
let zip_reader = std::io::BufReader::new(file); let zip_reader = std::io::BufReader::new(file);
let mut zip = zip::ZipArchive::new(zip_reader)?; let mut zip = zip::ZipArchive::new(zip_reader)?;
@@ -356,7 +356,11 @@ pub fn read_pth_tensor_info_cycle<P: AsRef<std::path::Path>>(
} }
}; };
} }
Ok(tensors) let mut dict_to_hashmap = HashMap::new();
for (k, v) in tensors {
dict_to_hashmap.insert(k, v);
}
Ok(dict_to_hashmap)
} }
pub fn round_by_factor(num: u32, factor: u32) -> u32 { pub fn round_by_factor(num: u32, factor: u32) -> u32 {
+9 -1
View File
@@ -111,7 +111,7 @@ pub fn split_tensor_with_size<D: Dim>(
// "input tensor dim size % splits_size must be equal to 0" // "input tensor dim size % splits_size must be equal to 0"
// ); // );
for (i, split) in (0..dim_size).step_by(splits_size).enumerate() { for (i, split) in (0..dim_size).step_by(splits_size).enumerate() {
let size = splits_size.min(dim_size - i*splits_size); let size = splits_size.min(dim_size - i * splits_size);
split_res.push(t.narrow(dim, split, size)?); split_res.push(t.narrow(dim, split, size)?);
} }
Ok(split_res) Ok(split_res)
@@ -1060,3 +1060,11 @@ pub fn float_range_normalize(t: &Tensor) -> Result<Tensor> {
t = t.clamp(-1.0, 1.0)?; t = t.clamp(-1.0, 1.0)?;
Ok(t) Ok(t)
} }
pub fn sequence_mask(length: &Tensor, max_length: Option<u32>) -> Result<Tensor> {
let max_length = max_length.unwrap_or(length.max_all()?.to_scalar::<u32>()?);
let x = Tensor::arange(0, max_length, length.device())?.unsqueeze(0)?;
let length = length.unsqueeze(1)?;
let mask = x.broadcast_lt(&length)?;
Ok(mask)
}
+22 -11
View File
@@ -2,22 +2,33 @@
use std::time::Instant; use std::time::Instant;
use aha::utils::{tensor_utils::interpolate_nearest_1d}; use aha::utils::tensor_utils::interpolate_nearest_1d;
use anyhow::Result; use anyhow::{Result, anyhow};
use candle_core::{Tensor}; use candle_core::Tensor;
use sentencepiece::SentencePieceProcessor;
// use symphonia::core::io::MediaSourceStream; // use symphonia::core::io::MediaSourceStream;
#[test] #[test]
fn messy_test() -> Result<()> { fn messy_test() -> Result<()> {
// RUST_BACKTRACE=1 cargo test -F cuda,ffmpeg messy_test -r -- --nocapture // RUST_BACKTRACE=1 cargo test -F cuda messy_test -r -- --nocapture
let device = &candle_core::Device::Cpu; let device = &candle_core::Device::Cpu;
let t = Tensor::arange(0.0f32, 40.0, device)?.broadcast_as((1, 40, 40))?; let save_dir =
println!("t: {}", t); aha::utils::get_default_save_dir().ok_or(anyhow::anyhow!("Failed to get save dir"))?;
let i_start = Instant::now(); let model_path = format!("{}/IndexTeam/IndexTTS-2", save_dir);
let t_inter = interpolate_nearest_1d(&t, 20)?; let bpe_path = model_path.to_string() + "/bpe.model";
let i_duration = i_start.elapsed(); let tokenizer = SentencePieceProcessor::open(bpe_path)
println!("Time elapsed in interpolate_nearest_1d is: {:?}", i_duration); .map_err(|e| anyhow!(format!("load bpe.model file error:{}", e)))?;
println!("t_inter: {}", t_inter); let tokens = tokenizer
.encode("你好啊")
.map_err(|e| anyhow!(format!("tokenizer encode error:{}", e)))?;
println!("tokens: {:?}", tokens);
// let t = Tensor::arange(0.0f32, 40.0, device)?.broadcast_as((1, 40, 40))?;
// println!("t: {}", t);
// let i_start = Instant::now();
// let t_inter = interpolate_nearest_1d(&t, 20)?;
// let i_duration = i_start.elapsed();
// println!("Time elapsed in interpolate_nearest_1d is: {:?}", i_duration);
// println!("t_inter: {}", t_inter);
// let url = "https://sis-sample-audio.obs.cn-north-1.myhuaweicloud.com/16k16bit.mp3"; // let url = "https://sis-sample-audio.obs.cn-north-1.myhuaweicloud.com/16k16bit.mp3";
// let client = reqwest::blocking::Client::new(); // let client = reqwest::blocking::Client::new();
// let response = client.get(url).send()?; // let response = client.get(url).send()?;
+1 -1
View File
@@ -21,7 +21,7 @@ fn fun_asr_nano_generate() -> Result<()> {
"type": "audio", "type": "audio",
"audio_url": "audio_url":
{ {
"url": "https://package-release.coderbox.cn/aiway/test/other/%E5%93%AA%E5%90%92.wav" "url": "file://./assets/audio/zh.mp3"
} }
}, },
{ {
+1
View File
@@ -200,6 +200,7 @@ fn qwen3_weight() -> Result<()> {
#[test] #[test]
fn index_tts2_weight() -> Result<()> { fn index_tts2_weight() -> Result<()> {
// RUST_BACKTRACE=1 cargo test -F cuda index_tts2_weight -r -- --nocapture
let save_dir: String = let save_dir: String =
aha::utils::get_default_save_dir().ok_or(anyhow::anyhow!("Failed to get save dir"))?; aha::utils::get_default_save_dir().ok_or(anyhow::anyhow!("Failed to get save dir"))?;
let model_path = format!("{}/IndexTeam/IndexTTS-2/", save_dir); let model_path = format!("{}/IndexTeam/IndexTTS-2/", save_dir);