--- license: mit language: - vi base_model: - SWivid/F5-TTS pipeline_tag: text-to-speech datasets: - htdung167/vin100h-preprocessed-v2 tags: - text-to-speech - tts - vietnamese-tts - vietnamese tts - vietnamese f5-tts - vietnamese-f5-tts - viet tts - viet-tts - viet f5-tts - viet-f5-tts - vi tts - vi-tts - vi f5-tts - vi-f5-tts - f5-tts - f5 tts - speech-synthesis - voice-generation - vietnamese-speech - audio-synthesis --- ## Download Model Checkpoints ```python from huggingface_hub import snapshot_download # Download the model to the local directory 'Vi-F5-TTS' snapshot_download(repo_id="danhtran2mind/Vi-F5-TTS", local_dir="Vi-F5-TTS") ``` ```bash cd Vi-F5-TTS ``` ## Install Dependencies ```bash pip install git+https://github.com/danhtran2mind/F5-TTS.git ``` ## Inference ``` f5-tts_infer-cli \ --model_cfg "vi-fine-tuned-f5-tts.yaml" \ --ckpt_file "model_last.pt" \ --vocab_file "vocab.txt" \ --ref_audio \ --ref_text \ --gen_text "Theo đơn vị này, hiện nay do chịu ảnh hưởng của cơn bão số một, lượng rác từ đầu nguồn tấp vào bờ biển rất nhiều. Để giữ cho bãi biển luôn xanh, sạch, đẹp, ban quản lý xin kêu gọi các bạn đoàn viên, tình nguyện viên và bà con nhân dân hãy chung tay cùng ban quản lý dọn vệ sinh môi trường tại tuyến biển Hoàng Sa - Võ Nguyên Giáp - Trường Sa và tuyến Nguyễn Tất Thành." ``` ## Clear Inference code ```python from f5_tts.infer.utils_infer import ( cfg_strength, cross_fade_duration, device, fix_duration, infer_process, load_model, load_vocoder, mel_spec_type, nfe_step, preprocess_ref_audio_text, remove_silence_for_generated_wav, speed, sway_sampling_coef, target_rms, ) from omegaconf import OmegaConf from hydra.utils import get_class import torch import re import os import soundfile as sf from pathlib import Path import numpy as np import tomli from importlib.resources import files from unidecode import unidecode ``` ```python ckpt_file = "ckpts/model_last.pt" vocoder_name = "vocos" vocab_file = "vocab.txt" device = "cuda" if torch.cuda.is_available() else "cpu" # Load TTS model model_cfg = OmegaConf.load(vi-fine-tuned-f5-tts.yaml") model_cls = get_class(f"f5_tts.model.{model_cfg.model.backbone}") model_arc = model_cfg.model.arch ``` ```python ema_model = load_model( model_cls, model_arc, ckpt_file, mel_spec_type=vocoder_name, vocab_file=vocab_file, device=device ) ``` ```python ref_audio = ref_text = gen_text = "Theo đơn vị này, hiện nay do chịu ảnh hưởng của cơn bão số một, lượng rác từ đầu nguồn tấp vào bờ biển rất nhiều. Để giữ cho bãi biển luôn xanh, sạch, đẹp, ban quản lý xin kêu gọi các bạn đoàn viên, tình nguyện viên và bà con nhân dân hãy chung tay cùng ban quản lý dọn vệ sinh môi trường tại tuyến biển Hoàng Sa - Võ Nguyên Giáp - Trường Sa và tuyến Nguyễn Tất Thành." ``` ```python voices = {} save_chunk = True output_dir = "test" output_file = "basic_test.wav" wave_path = Path(output_dir) / output_file remove_silence = True if vocoder_name == "vocos": vocoder_local_path = "ckpts/vocos-mel-24khz" elif vocoder_name == "bigvgan": vocoder_local_path = "ckpts/bigvgan_v2_24khz_100band_256x" vocoder = load_vocoder( vocoder_name=vocoder_name, is_local=False, local_path=vocoder_local_path, device=device ) if save_chunk: output_chunk_dir = os.path.join(output_dir, f"{Path(output_file).stem}_chunks") if not os.path.exists(output_chunk_dir): os.makedirs(output_chunk_dir) ``` ```python def infer(): main_voice = {"ref_audio": ref_audio, "ref_text": ref_text} # if "voices" not in config: # voices = {"main": main_voice} # else: # voices = config["voices"] voices["main"] = main_voice for voice in voices: print("Voice:", voice) print("ref_audio ", voices[voice]["ref_audio"]) voices[voice]["ref_audio"], voices[voice]["ref_text"] = preprocess_ref_audio_text( voices[voice]["ref_audio"], voices[voice]["ref_text"] ) print("ref_audio_", voices[voice]["ref_audio"], "\n\n") generated_audio_segments = [] reg1 = r"(?=\[\w+\])" chunks = re.split(reg1, gen_text) print("chunks chunks ", chunks) reg2 = r"\[(\w+)\]" for text in chunks: if not text.strip(): continue match = re.match(reg2, text) if match: voice = match[1] else: print("No voice tag found, using main.") voice = "main" if voice not in voices: print(f"Voice {voice} not found, using main.") voice = "main" text = re.sub(reg2, "", text) ref_audio_ = voices[voice]["ref_audio"] ref_text_ = voices[voice]["ref_text"] gen_text_ = text.strip() print(f"Voice: {voice}") audio_segment, final_sample_rate, spectrogram = infer_process( ref_audio_, ref_text_, gen_text_, ema_model, vocoder, mel_spec_type=vocoder_name, target_rms=target_rms, cross_fade_duration=cross_fade_duration, nfe_step=nfe_step, cfg_strength=cfg_strength, sway_sampling_coef=sway_sampling_coef, speed=speed, fix_duration=fix_duration, device=device, ) generated_audio_segments.append(audio_segment) if save_chunk: if len(gen_text_) > 200: gen_text_ = gen_text_[:200] + " ... " sf.write( os.path.join(output_chunk_dir, f"{len(generated_audio_segments) - 1}_{unidecode(gen_text_)}.wav"), audio_segment, final_sample_rate, ) if generated_audio_segments: final_wave = np.concatenate(generated_audio_segments) if not os.path.exists(output_dir): os.makedirs(output_dir) with open(wave_path, "wb") as f: sf.write(f.name, final_wave, final_sample_rate) # Remove silence if remove_silence: remove_silence_for_generated_wav(f.name) print(f.name) return final_sample_rate, final_wave, wave_path final_sample_rate, final_wave, wave_path = infer() ``` ```python from IPython.display import Audio Audio(data=final_wave, rate=final_sample_rate) ``` ## Dependencies Version ### Python Version ```markdown Python v3.11.11 ``` ```markdown