tools/Universal_TTS_Finetune/notebook/universal_tts_finetune_webui.ipynb
<a href="https://colab.research.google.com/github/DrewThomasson/Universal_TTS_Finetune/blob/main/notebook/universal_tts_finetune_webui.ipynb" target="_parent"></a>
This Jupyter Notebook allows you to easily run the fine-tuning interface on Google Colab with GPU acceleration enabled. It supports fine-tuning both Coqui XTTS v2 and Piper models, speech dataset preprocessing, and inference testing.
For documentation and local installation guide, visit the repository at: https://github.com/DrewThomasson/Universal_TTS_Finetune
# @title 🛠️ Install Requirements
try:
import google.colab
in_colab = True
except ImportError:
in_colab = False
if in_colab:
print("Running on Google Colab. Installing system dependencies...")
!sudo apt-get update
!sudo apt-get -y install libegl1 libopengl0 libxcb-cursor0 espeak-ng libsndfile1
!pip install -r https://raw.githubusercontent.com/DrewThomasson/Universal_TTS_Finetune/main/requirements.txt
else:
print("Running locally. Make sure you install requirements.txt in your environment:")
print("pip install -r requirements.txt")
# @title 🚀 Run Web Interface
try:
import google.colab
in_colab = True
except ImportError:
in_colab = False
import os
if in_colab:
# @markdown Specify whether you want to save datasets and models directly to Google Drive to prevent losing them when the session terminates.
use_google_drive = True # @param {type:"boolean"}
google_drive_path = "/content/drive/MyDrive/Universal_TTS_Finetune" # @param {type:"string"}
if use_google_drive:
from google.colab import drive
print(" mounting Google Drive...")
drive.mount('/content/drive')
out_path = google_drive_path
os.makedirs(out_path, exist_ok=True)
else:
out_path = "/content/Universal_TTS_Finetune/finetune_models"
print(f"Outputs will be saved to: {out_path}")
%cd /content/
if not os.path.exists('/content/Universal_TTS_Finetune'):
print("Cloning repository...")
!git clone https://github.com/DrewThomasson/Universal_TTS_Finetune.git
else:
print("Repository already exists, pulling latest changes...")
%cd /content/Universal_TTS_Finetune
!git pull
%cd /content/Universal_TTS_Finetune
else:
out_path = "./finetune_models"
print(f"Running locally. Outputs will be saved to: {out_path}")
!python web_gui.py --share --out_path "{out_path}"
# @title 📦 Zip and Upload Fine-tuned Models
# @markdown Note: If you used Google Drive, your files are already safe. Use this cell to create a quick shareable download link via file.io.
try:
import google.colab
in_colab = True
except ImportError:
in_colab = False
import shutil
import requests
import os
from tqdm import tqdm
# Define the paths
try:
base_out = out_path
except NameError:
if in_colab:
base_out = '/content/Universal_TTS_Finetune/finetune_models'
else:
base_out = './finetune_models'
finetune_dir = os.path.join(base_out, 'ready') # @param {type:"string"}
dataset_dir = os.path.join(base_out, 'dataset') # @param {type:"string"}
# Create a temporary directory to collect both folders before zipping
if in_colab:
temp_dir = "/content/temp_finetune_dataset"
zip_filename = "/content/finetune_and_dataset.zip"
else:
temp_dir = "./temp_finetune_dataset"
zip_filename = "./finetune_and_dataset.zip"
if os.path.exists(temp_dir):
shutil.rmtree(temp_dir)
os.makedirs(temp_dir, exist_ok=True)
# Copy both directories into the temporary directory with a progress bar
def copy_with_progress(src, dst):
if not os.path.exists(src):
print(f"Warning: Path {src} does not exist. Skipping.")
return
total_files = sum(len(files) for _, _, files in os.walk(src))
with tqdm(total=total_files, desc=f"Copying {os.path.basename(src)}") as pbar:
for root, _, files in os.walk(src):
rel_path = os.path.relpath(root, src)
target_path = os.path.join(dst, rel_path)
os.makedirs(target_path, exist_ok=True)
for file in files:
shutil.copy(os.path.join(root, file), target_path)
pbar.update(1)
copy_with_progress(finetune_dir, os.path.join(temp_dir, "ready"))
copy_with_progress(dataset_dir, os.path.join(temp_dir, "dataset"))
# Create a zip file of the combined directories with progress
if os.path.exists(zip_filename):
os.remove(zip_filename)
zip_base = os.path.splitext(zip_filename)[0]
with tqdm(total=100, desc="Zipping files") as pbar:
shutil.make_archive(zip_base, 'zip', root_dir=temp_dir)
pbar.update(100)
# Define a function to stream the upload with a progress bar
def upload_with_progress(file_path, url):
file_size = os.path.getsize(file_path)
with open(file_path, 'rb') as f, tqdm(
total=file_size, unit='B', unit_scale=True, desc="Uploading"
) as progress:
response = requests.post(
url,
files={"file": (file_path, f)},
stream=True,
headers={"Connection": "keep-alive"},
)
for chunk in response.iter_content(chunk_size=4096):
if chunk:
progress.update(len(chunk))
return response
# Upload the zip file to file.io with a progress bar
print("Uploading archive to file.io...")
response = upload_with_progress(zip_filename, "https://file.io/?expires=1d")
# Parse the response and display the download link
if response.status_code == 200:
download_link = response.json().get('link', 'Error: No link found.')
print(f"Your file is ready: {download_link}")
else:
print(f"Failed to upload: {response.status_code} - {response.text}")