Merge pull request #156 from erew123/dev

Dev to main
This commit is contained in:
erew123 authored and GitHub committed 2024-04-01 13:55:59 +01:00
commit e6e4b0b47f
6 files changed
+231 -169

No files matched your search

+99 -51
View File
@@ -1,10 +1,13 @@
import os import os
import sys
from pathlib import Path from pathlib import Path
import requests import requests
from requests.exceptions import ConnectionError
from tqdm import tqdm from tqdm import tqdm
import importlib.metadata as metadata import importlib.metadata as metadata
import json import json
from packaging import version from packaging import version
from datetime import datetime
################################################################# #################################################################
#### LOAD PARAMS FROM confignew.json - REQUIRED FOR BRANDING #### #### LOAD PARAMS FROM confignew.json - REQUIRED FOR BRANDING ####
@@ -12,14 +15,12 @@ from packaging import version
# STARTUP VARIABLE - Create "this_dir" variable as the current script directory # STARTUP VARIABLE - Create "this_dir" variable as the current script directory
this_dir = Path(__file__).parent.resolve() this_dir = Path(__file__).parent.resolve()
# load standard config file in and get settings # load standard config file in and get settings
def load_config(file_path): def load_config(file_path):
with open(file_path, "r") as config_file: with open(file_path, "r") as config_file:
config = json.load(config_file) config = json.load(config_file)
return config return config
config_file_path = this_dir / "confignew.json" config_file_path = this_dir / "confignew.json"
params = load_config(config_file_path) params = load_config(config_file_path)
@@ -37,12 +38,8 @@ if modeldownload_config_file_path.exists():
files_to_download = settings.get("files_to_download", {}) files_to_download = settings.get("files_to_download", {})
else: else:
# Default settings if the JSON file doesn't exist or is empty # Default settings if the JSON file doesn't exist or is empty
print( print(f"[{params['branding']}Startup] \033[91mWarning\033[0m modeldownload.json is missing so please re-download it and save it in the coquii_tts main folder.")
f"[{params['branding']}Startup] \033[91mWarning\033[0m modeldownload.json is missing so please re-download it and save it in the coquii_tts main folder." print(f"[{params['branding']}Startup] \033[91mWarning\033[0m API Local and XTTSv2 Local will error unless this is corrected.")
)
print(
f"[{params['branding']}Startup] \033[91mWarning\033[0m API Local and XTTSv2 Local will error unless this is corrected."
)
# Read the version specifier from requirements_nvidia.txt # Read the version specifier from requirements_nvidia.txt
with open(this_dir / "system" / "requirements" / "requirements_standalone.txt", "r") as req_file: with open(this_dir / "system" / "requirements" / "requirements_standalone.txt", "r") as req_file:
@@ -55,16 +52,12 @@ for req in requirements:
break break
if tts_version_required is None: if tts_version_required is None:
raise ValueError( raise ValueError(f"[{params['branding']}Startup] \033[91mWarning\033[0m Could not find TTS version specifier in requirements file")
f"[{params['branding']}Startup] \033[91mWarning\033[0m Could not find TTS version specifier in requirements file"
)
def create_directory_if_not_exists(directory): def create_directory_if_not_exists(directory):
if not directory.exists(): if not directory.exists():
directory.mkdir(parents=True) directory.mkdir(parents=True)
def download_file(url, destination): def download_file(url, destination):
response = requests.get(url, stream=True) response = requests.get(url, stream=True)
total_size_in_bytes = int(response.headers.get("content-length", 0)) total_size_in_bytes = int(response.headers.get("content-length", 0))
@@ -83,63 +76,118 @@ def download_file(url, destination):
def check_tts_version(): def check_tts_version():
try: try:
tts_version = metadata.version("tts") tts_version = metadata.version("tts")
print( print(f"[{params['branding']}Startup] \033[92mCurrent TTS Version : \033[93m"+tts_version+"\033[0m")
f"[{params['branding']}Startup] TTS version installed: \033[93m"
+ tts_version
+ "\033[0m"
)
if version.parse(tts_version) < version.parse(tts_version_required): if version.parse(tts_version) < version.parse(tts_version_required):
print( print(f"[{params['branding']}Startup] \033[91mWarning\033[0m TTS version is too old. Please upgrade to version \033[93m"+tts_version_required+"\033[0m or later.\033[0m")
f"[{params['branding']}Startup] \033[91mWarning\033[0m TTS version is too old. Please upgrade to version \033[93m" print(f"[{params['branding']}Startup] \033[91mWarning\033[0m At your terminal/command prompt \033[94mpip install --upgrade tts\033[0m")
+ tts_version_required
+ "\033[0m or later.\033[0m"
)
print(
f"[{params['branding']}Startup] \033[91mWarning\033[0m At your terminal/command prompt \033[94mpip install --upgrade tts\033[0m"
)
else: else:
print(f"[{params['branding']}Startup] TTS version is up to date.") print(f"[{params['branding']}Startup] \033[92mCurrent TTS Version is :\033[93m Up to date\033[0m")
except metadata.PackageNotFoundError: except metadata.PackageNotFoundError:
print( print(f"[{params['branding']}Startup] \033[91mWarning\033[0m TTS is not installed")
f"[{params['branding']}Startup] \033[91mWarning\033[0m TTS is not installed."
)
def check_torch_version():
import torch
pytorch_version = torch.__version__
cuda_version = torch.version.cuda
major, minor, micro = sys.version_info[:3]
python_version = f"{major}.{minor}.{micro}"
print(f"[{params['branding']}Startup] \033[92mCurrent Python Version :\033[93m {python_version}\033[0m")
print(f"[{params['branding']}Startup] \033[92mCurrent PyTorch Version:\033[93m {pytorch_version}\033[0m")
if cuda_version is None:
print(f"[{params['branding']}Startup] \033[92mCurrent CUDA Version :\033[91m CUDA is not available\033[0m")
else:
print(f"[{params['branding']}Startup] \033[92mCurrent CUDA Version :\033[93m {cuda_version}\033[0m")
def ordinal(n):
return "%d%s" % (n, "th" if 4 <= n % 100 <= 20 else {1: "st", 2: "nd", 3: "rd"}.get(n % 10, "th"))
def format_datetime(iso_str):
# Parse the ISO 8601 string to datetime
dt = datetime.strptime(iso_str, "%Y-%m-%dT%H:%M:%SZ")
# Format the datetime into a more readable string
return dt.strftime(f"{ordinal(dt.day)} %B %Y at %H:%M")
def fetch_latest_commit_sha_and_date(owner, repo):
url = f"https://api.github.com/repos/{owner}/{repo}/commits"
try:
response = requests.get(url)
if response.status_code == 200:
latest_commit = response.json()[0]
latest_commit_sha = latest_commit['sha']
latest_commit_date = latest_commit['commit']['committer']['date']
return latest_commit_sha, latest_commit_date
else:
print(f"[{params['branding']}Startup] \033[92m{params['branding']}Github updated :\033[91m Failed to fetch the latest commits due to an unexpected response from GitHub")
return None, None
except ConnectionError:
# This block is executed when a connection error occurs
print(f"[{params['branding']}Startup] \033[92m{params['branding']}Github updated :\033[91m Could not reach GitHub to check for updates\033[0m")
return None, None
def read_or_initialize_sha(file_path):
if os.path.exists(file_path):
with open(file_path, 'r') as file:
data = json.load(file)
return data.get("last_known_commit_sha")
else:
# File doesn't exist, fetch the latest SHA and create the file
latest_commit_sha = fetch_latest_commit_sha_and_date(github_site, github_repository)
if latest_commit_sha:
with open(file_path, 'w') as file:
json.dump({"last_known_commit_sha": latest_commit_sha}, file)
return latest_commit_sha
else:
# Handle the case where GitHub couldn't be reached
return None
def update_sha_file(file_path, new_sha):
with open(file_path, 'w') as file:
json.dump({"last_known_commit_sha": new_sha}, file)
# Check and create directories # Check and create directories
if str(base_path) == "models": if str(base_path) == "models":
create_directory_if_not_exists(this_dir / base_path / model_path) create_directory_if_not_exists(this_dir / base_path / model_path)
else: else:
create_directory_if_not_exists(base_path / model_path) create_directory_if_not_exists(base_path / model_path)
print( print(f"[{params['branding']}Startup] \033[94mInfo\033[0m Custom path set in \033[93mmodeldownload.json\033[0m. Using the following settings:")
f"[{params['branding']}Startup] \033[94mInfo\033[0m Custom path set in \033[93mmodeldownload.json\033[0m. Using the following settings:" print(f"[{params['branding']}Startup] \033[94mInfo\033[0m Base folder Path:\033[93m",base_path,"\033[0m",)
) print(f"[{params['branding']}Startup] \033[94mInfo\033[0m Model folder Path:\033[93m",model_path,"\033[0m",)
print( print(f"[{params['branding']}Startup] \033[94mInfo\033[0m Full Path:\033[93m",base_path / model_path,"\033[0m",)
f"[{params['branding']}Startup] \033[94mInfo\033[0m Base folder Path:\033[93m",
base_path,
"\033[0m",
)
print(
f"[{params['branding']}Startup] \033[94mInfo\033[0m Model folder Path:\033[93m",
model_path,
"\033[0m",
)
print(
f"[{params['branding']}Startup] \033[94mInfo\033[0m Full Path:\033[93m",
base_path / model_path,
"\033[0m",
)
# Download files if they don't exist # Download files if they don't exist
print("[" + params["branding"] + "Startup] Checking Model is Downloaded.") print(f"[{params['branding']}Startup] \033[92mModel is available :\033[93m Checking\033[0m")
for filename, url in files_to_download.items(): for filename, url in files_to_download.items():
if str(base_path) == "models": if str(base_path) == "models":
destination = this_dir / base_path / model_path / filename destination = this_dir / base_path / model_path / filename
else: else:
destination = Path(base_path) / model_path / filename destination = Path(base_path) / model_path / filename
if not destination.exists(): if not destination.exists():
print(f"[{params['branding']}Startup] Downloading " + filename + "...") print(f"[{params['branding']}Startup] \033[92mModel Downloading file : \033[93m" + filename + "\033[0m")
download_file(url, destination) download_file(url, destination)
print(f"[{params['branding']}Startup] \033[92mModel is available :\033[93m Checked\033[0m")
github_site = "erew123"
github_repository = "alltalk_tts"
check_torch_version()
check_tts_version() check_tts_version()
# Define the file path based on your directory structure
sha_file_path = this_dir / "system" / "config" / "at_github_sha.json"
# Read or initialize the SHA (adjusted for handling both SHA and date)
last_known_commit_sha = read_or_initialize_sha(sha_file_path) # Assuming adjustment for date
# Assuming you have fetched the latest commit SHA and date
latest_commit_sha, latest_commit_date = fetch_latest_commit_sha_and_date(github_site, github_repository)
formatted_date = format_datetime(latest_commit_date) if latest_commit_date else "an unknown date"
if latest_commit_sha and latest_commit_sha != last_known_commit_sha:
#print(f"There's an update available for alltalk_tts.")
print(f"[{params['branding']}Startup] \033[92m{params['branding']}Github updated :\033[93m {formatted_date}\033[0m")
# Update the file with the new SHA
update_sha_file(sha_file_path, latest_commit_sha)
elif latest_commit_sha == last_known_commit_sha:
#print(f"Your alltalk_tts software is up to date.")
print(f"[{params['branding']}Startup] \033[92m{params['branding']}Github updated :\033[93m {formatted_date}\033[0m")
+116 -107
View File
@@ -9,12 +9,16 @@ import threading
import signal import signal
import sys import sys
import atexit import atexit
import shutil
from pathlib import Path from pathlib import Path
from datetime import datetime, timedelta from datetime import datetime, timedelta
import re import re
import numpy as np import numpy as np
import soundfile as sf import soundfile as sf
import uuid import uuid
import logging
# Store the current disable level
current_disable_level = logging.getLogger().manager.disable
###################################### ######################################
#### ALLTALK ALLOWED STARTUP TIME #### #### ALLTALK ALLOWED STARTUP TIME ####
@@ -30,43 +34,109 @@ startup_wait_time = 120
# STARTUP VARIABLE - Create "this_dir" variable as the current script directory # STARTUP VARIABLE - Create "this_dir" variable as the current script directory
this_dir = Path(__file__).parent.resolve() this_dir = Path(__file__).parent.resolve()
# load config file in and get settings # load config file in and get settings
def load_config(file_path): def load_config(file_path):
with open(file_path, "r") as config_file: with open(file_path, "r") as config_file:
config = json.load(config_file) config = json.load(config_file)
return config return config
config_file_path = this_dir / "confignew.json" config_file_path = this_dir / "confignew.json"
# Load the params dictionary from the confignew.json file # Load the params dictionary from the confignew.json file
params = load_config(config_file_path) params = load_config(config_file_path)
print(f"[{params['branding']}Startup]\033[94m _ _ _ \033[1;35m_____ _ _ \033[0m _____ _____ ____ ")
print(f"[{params['branding']}Startup]\033[94m / \ | | |\033[1;35m_ _|_ _| | | __ \033[0m |_ _|_ _/ ___| ")
print(f"[{params['branding']}Startup]\033[94m / _ \ | | |\033[1;35m | |/ _` | | |/ / \033[0m | | | | \___ \ ")
print(f"[{params['branding']}Startup]\033[94m / ___ \| | |\033[1;35m | | (_| | | < \033[0m | | | | ___) |")
print(f"[{params['branding']}Startup]\033[94m /_/ \_\_|_|\033[1;35m |_|\__,_|_|_|\_\ \033[0m |_| |_| |____/ ")
print(f"[{params['branding']}Startup]")
##############################################
#### Update any changes to confignew.json ####
##############################################
update_config_path = this_dir / "system" / "config" / "at_configupdate.json"
downgrade_config_path = this_dir / "system" / "config" / "at_configdowngrade.json"
def changes_needed(main_config, update_config, downgrade_config):
"""Check if there are any changes to be made to the main configuration."""
for key in downgrade_config.keys():
if key in main_config:
return True
for key, value in update_config.items():
if key not in main_config:
return True
return False
def update_config(config_file_path, update_config_path, downgrade_config_path):
try:
with open(config_file_path, 'r') as file:
main_config = json.load(file)
with open(update_config_path, 'r') as file:
update_config = json.load(file)
with open(downgrade_config_path, 'r') as file:
downgrade_config = json.load(file)
# Determine if changes are needed
if changes_needed(main_config, update_config, downgrade_config):
# Backup with timestamp to avoid overwriting
timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
backup_path = config_file_path.with_suffix(f".{timestamp}.bak")
logging.info(f"Creating backup of the main config to {backup_path}")
shutil.copy(config_file_path, backup_path)
# Proceed with updates and downgrades
for key, value in update_config.items():
if key not in main_config:
main_config[key] = value
for key in downgrade_config.keys():
if key in main_config:
del main_config[key]
# Save the updated configuration
with open(config_file_path, 'w') as file:
json.dump(main_config, file, indent=4)
print(f"[{params['branding']}Startup] \033[92mConfig file check : \033[91mUpdates applied\033[0m")
else:
print(f"[{params['branding']}Startup] \033[92mConfig file check : \033[93mNo Updates required\033[0m")
except Exception as e:
print(f"[{params['branding']}Startup] \033[92mConfig file check : \033[91mError updating\033[0m")
# Update the configuration
update_config(config_file_path, update_config_path, downgrade_config_path)
# Re-Load the params dictionary from the confignew.json file
params = load_config(config_file_path)
#########################################
#### Continue on with Startup Checks ####
#########################################
# Required for sentence splitting # Required for sentence splitting
try: try:
from TTS.api import TTS from TTS.api import TTS
from TTS.utils.synthesizer import Synthesizer from TTS.utils.synthesizer import Synthesizer
except ModuleNotFoundError: except ModuleNotFoundError:
logger.error( # Inform the user about the missing module and suggest next steps
f"[{params['branding']}]\033[91mWarning\033[0m Could not find the TTS module. Make sure to install the requirements for the {params['branding']} extension." print(f"[{params['branding']}]\033[91mWarning\033[0m Could not find the TTS module. Make sure to install the requirements for the {params['branding']} extension.")
f"[{params['branding']}]\033[91mWarning\033[0m Linux / Mac:\npip install -r /alltalk_tts/requirements.txt\n" print(f"[{params['branding']}]\033[91mWarning\033[0m Please use the ATSetup utility or check the Github installation instructions.")
f"[{params['branding']}]\033[91mWarning\033[0m Windows:\npip install -r \\alltalk_tts\\requirements.txt\n" # Re-raise the ModuleNotFoundError to stop the program and print the traceback
f"[{params['branding']}]\033[91mWarning\033[0m If you used the one-click installer, paste the command above in the terminal window launched after running the cmd_ script. On Windows, that's cmd_windows.bat." raise
)
raise
# IMPORT - Attempt Importing DeepSpeed (required for displaying Deepspeed checkbox in gradio) # Suppress logging
logging.disable(logging.ERROR)
try: try:
import deepspeed import deepspeed
deepspeed_installed = True deepspeed_installed = True
except ImportError: except ImportError:
deepspeed_installed = False deepspeed_installed = False
# Restore previous logging level
logging.disable(current_disable_level)
# Import gradio if being used within text generation webUI # Import gradio if being used within text generation webUI
try: try:
import gradio as gr import gradio as gr
from modules import chat, shared, ui_chat from modules import chat, shared, ui_chat
from modules.logging_colors import logger from modules.logging_colors import logger
from modules.ui import create_refresh_button from modules.ui import create_refresh_button
@@ -75,9 +145,10 @@ try:
# This is set to check if the script is being run within text generation webui or as a standalone script. False is running as part of text gen web ui or a gradio interface # This is set to check if the script is being run within text generation webui or as a standalone script. False is running as part of text gen web ui or a gradio interface
running_in_standalone = False running_in_standalone = False
output_folder_wav = params["output_folder_wav"] output_folder_wav = params["output_folder_wav"]
print(f"[{params['branding']}Startup] \033[92m{params['branding']}startup Mode : \033[93mText-Gen-webui mode\033[0m")
except ModuleNotFoundError: except ModuleNotFoundError:
output_folder_wav = params["output_folder_wav_standalone"] output_folder_wav = params["output_folder_wav_standalone"]
print(f"[{params['branding']}Startup] Running script.py in standalone mode") print(f"[{params['branding']}Startup] \033[92m{params['branding']}startup Mode : \033[93mStandalone mode\033[0m")
# This is set to check if the script is being run within text generation webui or as a standalone script. true means standalone # This is set to check if the script is being run within text generation webui or as a standalone script. true means standalone
running_in_standalone = True running_in_standalone = True
@@ -98,23 +169,12 @@ def get_available_voices():
return sorted([voice.name for voice in Path(f"{this_dir}/voices").glob("*.wav")]) return sorted([voice.name for voice in Path(f"{this_dir}/voices").glob("*.wav")])
#########################
#### LICENSE DISPLAY ####
#########################
# STARTUP Display Licence Information
print(f"[{params['branding']}Startup] \033[94mCoqui Public Model License\033[0m")
print(f"[{params['branding']}Startup] \033[94mhttps://coqui.ai/cpml.txt\033[0m")
############################################ ############################################
#### DELETE OLD OUTPUT WAV FILES IF SET #### #### DELETE OLD OUTPUT WAV FILES IF SET ####
############################################ ############################################
def delete_old_files(folder_path, days_to_keep): def delete_old_files(folder_path, days_to_keep):
current_time = datetime.now() current_time = datetime.now()
print( print(f"[{params['branding']}Startup] \033[92mWAV file deletion :\033[93m {formatted_date}\033[0m",delete_output_wavs_setting,)
f"[{params['branding']}Startup] Deletion of old output folder WAV files is currently enabled and set at",
delete_output_wavs_setting,
)
for file_name in os.listdir(folder_path): for file_name in os.listdir(folder_path):
file_path = os.path.join(folder_path, file_name) file_path = os.path.join(folder_path, file_name)
if os.path.isfile(file_path): if os.path.isfile(file_path):
@@ -130,20 +190,18 @@ output_folder_wav = os.path.normpath(output_folder_wav)
# Check and perform file deletion # Check and perform file deletion
if delete_output_wavs_setting.lower() == "disabled": if delete_output_wavs_setting.lower() == "disabled":
print( print("["+ params["branding"]+"Startup] \033[92mWAV file deletion :\033[93m Disabled\033[0m")
"["
+ params["branding"]
+ "Startup] Old output wav file deletion is set to disabled."
)
else: else:
try: try:
days_to_keep = int(delete_output_wavs_setting.split()[0]) days_to_keep = int(delete_output_wavs_setting.split()[0])
delete_old_files(output_folder_wav, days_to_keep) delete_old_files(output_folder_wav, days_to_keep)
except ValueError: except ValueError:
print( print(f"[{params['branding']}Startup] \033[92mWAV file deletion :\033[93m Invalid setting for deleting old wav files. Please use 'Disabled' or 'X Days' format\033[0m")
f"[{params['branding']}Startup] Invalid setting for deleting old wav files. Please use 'Disabled' or 'X Days' format."
)
if deepspeed_installed:
print(f"[{params['branding']}Startup] \033[92mDeepSpeed version :\033[93m",deepspeed.__version__,"\033[0m")
else:
print(f"[{params['branding']}Startup] \033[92mDeepSpeed version :\033[91m Not Detected\033[0m")
######################## ########################
#### STARTUP CHECKS #### #### STARTUP CHECKS ####
@@ -153,8 +211,6 @@ def check_required_files():
this_dir = Path(__file__).parent.resolve() this_dir = Path(__file__).parent.resolve()
download_script_path = this_dir / "modeldownload.py" download_script_path = this_dir / "modeldownload.py"
subprocess.run(["python", str(download_script_path)]) subprocess.run(["python", str(download_script_path)])
print(f"[{params['branding']}Startup] All required files are present.")
# STARTUP Call Check routine # STARTUP Call Check routine
check_required_files() check_required_files()
@@ -190,7 +246,6 @@ elif params["tts_method_xtts_local"] == True:
# Set the default for Narrated text without asterisk or quotes to be Narrator # Set the default for Narrated text without asterisk or quotes to be Narrator
non_quoted_text_is = True non_quoted_text_is = True
###################### ######################
#### GRADIO STUFF #### #### GRADIO STUFF ####
###################### ######################
@@ -237,9 +292,7 @@ script_path = this_dir / "tts_server.py"
def signal_handler(sig, frame): def signal_handler(sig, frame):
print( print(f"[{params['branding']}Shutdown] \033[94mReceived Ctrl+C, terminating subprocess\033[92m")
f"[{params['branding']}Shutdown] \033[94mReceived Ctrl+C, terminating subprocess\033[92m"
)
if process.poll() is None: if process.poll() is None:
process.terminate() process.terminate()
process.wait() # Wait for the subprocess to finish process.wait() # Wait for the subprocess to finish
@@ -258,33 +311,20 @@ else:
process = subprocess.Popen(["python", script_path]) process = subprocess.Popen(["python", script_path])
# Check if the subprocess has started successfully # Check if the subprocess has started successfully
if process.poll() is None: if process.poll() is None:
print(f"[{params['branding']}Startup] TTS Subprocess starting") print(f"[{params['branding']}Startup] \033[92mTTS Subprocess :\033[93m Starting up\033[0m")
print(f"[{params['branding']}Startup]") print(f"[{params['branding']}Startup]")
print( print(
f"[{params['branding']}Startup] \033[94m {params['branding']}Settings & Documentation:\033[00m", f"[{params['branding']}Startup] \033[94m{params['branding']}Settings & Documentation:\033[00m",
f"\033[92mhttp://{params['ip_address']}:{params['port_number']}\033[00m", f"\033[92mhttp://{params['ip_address']}:{params['port_number']}\033[00m",
) )
print(f"[{params['branding']}Startup]") print(f"[{params['branding']}Startup]")
else: else:
print( print(f"[{params['branding']}Startup] \033[91mWarning\033[0m TTS Subprocess Webserver failing to start process")
f"[{params['branding']}Startup] \033[91mWarning\033[0m TTS Subprocess Webserver failing to start process" print(f"[{params['branding']}Startup] \033[91mWarning\033[0m It could be that you have something on port:",params["port_number"],)
) print(f"[{params['branding']}Startup] \033[91mWarning\033[0m Or you have not started in a Python environement with all the necesssary bits installed")
print( print(f"[{params['branding']}Startup] \033[91mWarning\033[0m Check you are starting Text-generation-webui with either the start_xxxxx file or the Python environment with cmd_xxxxx file.")
f"[{params['branding']}Startup] \033[91mWarning\033[0m It could be that you have something on port:", print(f"[{params['branding']}Startup] \033[91mWarning\033[0m xxxxx is the type of OS you are on e.g. windows, linux or mac.")
params["port_number"], print(f"[{params['branding']}Startup] \033[91mWarning\033[0m Alternatively, you could check no other Python processes are running that shouldnt be e.g. Restart your computer is the simple way.")
)
print(
f"[{params['branding']}Startup] \033[91mWarning\033[0m Or you have not started in a Python environement with all the necesssary bits installed"
)
print(
f"[{params['branding']}Startup] \033[91mWarning\033[0m Check you are starting Text-generation-webui with either the start_xxxxx file or the Python environment with cmd_xxxxx file."
)
print(
f"[{params['branding']}Startup] \033[91mWarning\033[0m xxxxx is the type of OS you are on e.g. windows, linux or mac."
)
print(
f"[{params['branding']}Startup] \033[91mWarning\033[0m Alternatively, you could check no other Python processes are running that shouldnt be e.g. Restart your computer is the simple way."
)
# Cleanly kill off this script, but allow text-generation-webui to keep running, albeit without this alltalk_tts # Cleanly kill off this script, but allow text-generation-webui to keep running, albeit without this alltalk_tts
sys.exit(1) sys.exit(1)
@@ -300,26 +340,14 @@ else:
break break
except requests.RequestException as e: except requests.RequestException as e:
# Print the exception for debugging purposes # Print the exception for debugging purposes
print( print(f"[{params['branding']}Startup] \033[91mWarning\033[0m TTS Subprocess has NOT started up yet, Will keep trying for {timeout} seconds maximum. Please wait.")
f"[{params['branding']}Startup] \033[91mWarning\033[0m TTS Subprocess has NOT started up yet, Will keep trying for {timeout} seconds maximum. Please wait."
)
time.sleep(5) time.sleep(5)
else: else:
print( print(f"\n[{params['branding']}Startup] Startup timed out. Full help available here \033[92mhttps://github.com/erew123/alltalk_tts#-help-with-problems\033[0m")
f"\n[{params['branding']}Startup] Startup timed out. Full help available here \033[92mhttps://github.com/erew123/alltalk_tts#-help-with-problems\033[0m" print(f"[{params['branding']}Startup] On older system you may wish to open and edit \033[94mscript.py\033[0m with a text editor and changing the")
) print(f"[{params['branding']}Startup] \033[94mstartup_wait_time = 120\033[0m setting to something like \033[94mstartup_wait_time = 240\033[0m as this will allow")
print( print(f"[{params['branding']}Startup] AllTalk more time to try load the model into your VRAM. Otherise please visit the Github for")
f"[{params['branding']}Startup] On older system you may wish to open and edit \033[94mscript.py\033[0m with a text editor and changing the" print(f"[{params['branding']}Startup] a list of other possible troubleshooting options.")
)
print(
f"[{params['branding']}Startup] \033[94mstartup_wait_time = 120\033[0m setting to something like \033[94mstartup_wait_time = 240\033[0m as this will allow"
)
print(
f"[{params['branding']}Startup] AllTalk more time to try load the model into your VRAM. Otherise please visit the Github for"
)
print(
f"[{params['branding']}Startup] a list of other possible troubleshooting options."
)
# Cleanly kill off this script, but allow text-generation-webui to keep running, albeit without this alltalk_tts # Cleanly kill off this script, but allow text-generation-webui to keep running, albeit without this alltalk_tts
sys.exit(1) sys.exit(1)
@@ -371,9 +399,7 @@ def send_reload_request(tts_method):
return f'<audio src="file/{audio_path}" controls autoplay></audio>' return f'<audio src="file/{audio_path}" controls autoplay></audio>'
except requests.exceptions.RequestException as e: except requests.exceptions.RequestException as e:
# Handle the HTTP request error # Handle the HTTP request error
print( print(f"[{params['branding']}Server] \033[91mWarning\033[0m Error during request to webserver process: {e}")
f"[{params['branding']}Server] \033[91mWarning\033[0m Error during request to webserver process: {e}"
)
return {"status": "error", "message": str(e)} return {"status": "error", "message": str(e)}
@@ -400,9 +426,7 @@ def send_lowvram_request(low_vram):
return f'<audio src="file/{audio_path}" controls autoplay></audio>' return f'<audio src="file/{audio_path}" controls autoplay></audio>'
except requests.exceptions.RequestException as e: except requests.exceptions.RequestException as e:
# Handle the HTTP request error # Handle the HTTP request error
print( print(f"[{params['branding']}Server] \033[91mWarning\033[0m Error during request to webserver process: {e}")
f"[{params['branding']}Server] \033[91mWarning\033[0m Error during request to webserver process: {e}"
)
return {"status": "error", "message": str(e)} return {"status": "error", "message": str(e)}
@@ -417,7 +441,6 @@ def send_deepspeed_request(deepspeed_param):
audio_path = this_dir / "system" / "at_sounds" / "deepspeedenabled.wav" audio_path = this_dir / "system" / "at_sounds" / "deepspeedenabled.wav"
else: else:
audio_path = this_dir / "system" / "at_sounds" / "deepspeeddisabled.wav" audio_path = this_dir / "system" / "at_sounds" / "deepspeeddisabled.wav"
url = f"{base_url}/api/deepspeed?new_deepspeed_value={deepspeed_param}" url = f"{base_url}/api/deepspeed?new_deepspeed_value={deepspeed_param}"
headers = {"Content-Type": "application/json"} headers = {"Content-Type": "application/json"}
response = requests.post(url, headers=headers) response = requests.post(url, headers=headers)
@@ -430,9 +453,7 @@ def send_deepspeed_request(deepspeed_param):
return f'<audio src="file/{audio_path}" controls autoplay></audio>' return f'<audio src="file/{audio_path}" controls autoplay></audio>'
except requests.exceptions.RequestException as e: except requests.exceptions.RequestException as e:
# Handle the HTTP request error # Handle the HTTP request error
print( print(f"[{params['branding']}Server] \033[91mWarning\033[0m Error during request to webserver process: {e}")
f"[{params['branding']}Server] \033[91mWarning\033[0m Error during request to webserver process: {e}"
)
return {"status": "error", "message": str(e)} return {"status": "error", "message": str(e)}
@@ -465,9 +486,7 @@ Synthesizer.split_into_sentences = new_split_into_sentences
def before_audio_generation(string, params): def before_audio_generation(string, params):
# Check Model is loaded into cuda or cpu and error if not # Check Model is loaded into cuda or cpu and error if not
if not params["tts_model_loaded"]: if not params["tts_model_loaded"]:
print( print(f"[{params['branding']}Model] \033[91mWarning\033[0m Model is still loading, please wait before trying to generate TTS")
f"[{params['branding']}Model] \033[91mWarning\033[0m Model is still loading, please wait before trying to generate TTS"
)
return return
string = html.unescape(string) or random_sentence() string = html.unescape(string) or random_sentence()
if string == "": if string == "":
@@ -491,13 +510,9 @@ def combine(audio_files, output_folder, state):
# Save the combined audio to a file with a specified sample rate # Save the combined audio to a file with a specified sample rate
if "character_menu" in state: if "character_menu" in state:
output_file_path = os.path.join( output_file_path = os.path.join(output_folder, f'{state["character_menu"]}_{int(time.time())}_combined.wav')
output_folder, f'{state["character_menu"]}_{int(time.time())}_combined.wav'
)
else: else:
output_file_path = os.path.join( output_file_path = os.path.join(output_folder, f"TTSOUT_{int(time.time())}_combined.wav")
output_folder, f"TTSOUT_{int(time.time())}_combined.wav"
)
sf.write(output_file_path, audio, samplerate=sample_rate) sf.write(output_file_path, audio, samplerate=sample_rate)
# Clean up unnecessary files # Clean up unnecessary files
for audio_file in audio_files: for audio_file in audio_files:
@@ -544,9 +559,7 @@ def voice_preview(string):
) )
# Check if lock is already acquired # Check if lock is already acquired
if process_lock.locked(): if process_lock.locked():
print( print(f"[{params['branding']}Model] \033[91mWarning\033[0m Audio generation is already in progress. Please wait.")
f"[{params['branding']}Model] \033[91mWarning\033[0m Audio generation is already in progress. Please wait."
)
return return
if generate_response.get("status") == "generate-success": if generate_response.get("status") == "generate-success":
# Handle Gradio and playback # Handle Gradio and playback
@@ -666,14 +679,10 @@ def output_modifier(string, state):
# Determine the voice to use based on the part type # Determine the voice to use based on the part type
if part_type == "narrator": if part_type == "narrator":
voice_to_use = params["narrator_voice"] voice_to_use = params["narrator_voice"]
print( print(f"[{params['branding']}TTSGen] \033[92mNarrator\033[0m") # Green
f"[{params['branding']}TTSGen] \033[92mNarrator\033[0m"
) # Green
elif part_type == "character": elif part_type == "character":
voice_to_use = params["voice"] voice_to_use = params["voice"]
print( print(f"[{params['branding']}TTSGen] \033[36mCharacter\033[0m") # Yellow
f"[{params['branding']}TTSGen] \033[36mCharacter\033[0m"
) # Yellow
else: else:
# Handle ambiguous parts based on user preference # Handle ambiguous parts based on user preference
voice_to_use = ( voice_to_use = (
+2 -1
View File
@@ -474,7 +474,7 @@
<span style="color: #3366ff;">22050Hz</span>, <span style="color: #3366ff;">Mono</span>, <span <span style="color: #3366ff;">22050Hz</span>, <span style="color: #3366ff;">Mono</span>, <span
style="color: #3366ff;">16 bit</span> and between 6 to 30 seconds long, though 8 to 10 seconds is usually style="color: #3366ff;">16 bit</span> and between 6 to 30 seconds long, though 8 to 10 seconds is usually
good enough. The model can handle up to 30 second samples, however I've not noticed any improvement in voice good enough. The model can handle up to 30 second samples, however I've not noticed any improvement in voice
output from a much longer clips. output from much longer clips.
</p> </p>
<p>You want to find a nice clear selection of audio, so lets say <p>You want to find a nice clear selection of audio, so lets say
you wanted to clone your favourite celebrity. You may go looking for an interview where they are talking. Pay you wanted to clone your favourite celebrity. You may go looking for an interview where they are talking. Pay
@@ -1357,6 +1357,7 @@
<h3 id="🟨-help-with-problems">🟨 Help with problems</h3> <h3 id="🟨-help-with-problems">🟨 Help with problems</h3>
<h4 id="🔄-minor-updatesbug-fixes-list-can-be-found-here">&nbsp;&nbsp;&nbsp;&nbsp; 🔄 <strong>Minor updates/bug <h4 id="🔄-minor-updatesbug-fixes-list-can-be-found-here">&nbsp;&nbsp;&nbsp;&nbsp; 🔄 <strong>Minor updates/bug
fixes list</strong> can be found <a href="https://github.com/erew123/alltalk_tts/issues/25">here</a></h4> fixes list</strong> can be found <a href="https://github.com/erew123/alltalk_tts/issues/25">here</a></h4>
<h4>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Please check Github for the most up to date help list <a href="https://github.com/erew123/alltalk_tts#-help-with-problems">here</a></h4>
<details> <details>
<summary>🟨 How to make a diagnostics report file</summary> <summary>🟨 How to make a diagnostics report file</summary>
+2
View File
@@ -0,0 +1,2 @@
{
}
+2
View File
@@ -0,0 +1,2 @@
{
}
+10 -10
View File
@@ -8,7 +8,8 @@ from TTS.tts.configs.xtts_config import XttsConfig
from TTS.tts.models.xtts import Xtts from TTS.tts.models.xtts import Xtts
import io import io
import wave import wave
import logging
logging.disable(logging.WARNING)
########################## ##########################
#### Webserver Imports#### #### Webserver Imports####
########################## ##########################
@@ -120,12 +121,6 @@ try:
deepspeed_available = True deepspeed_available = True
except ImportError: except ImportError:
pass pass
if deepspeed_available:
print(f"[{params['branding']}Startup] DeepSpeed \033[93mDetected\033[0m")
print(f"[{params['branding']}Startup] Activate DeepSpeed in {params['branding']}settings")
else:
print(f"[{params['branding']}Startup] DeepSpeed \033[93mNot Detected\033[0m. See https://github.com/microsoft/DeepSpeed")
@asynccontextmanager @asynccontextmanager
async def startup_shutdown(no_actual_value_it_demanded_something_be_here): async def startup_shutdown(no_actual_value_it_demanded_something_be_here):
@@ -187,9 +182,8 @@ async def setup():
# Calculate start time minus end time # Calculate start time minus end time
generate_elapsed_time = generate_end_time - generate_start_time generate_elapsed_time = generate_end_time - generate_start_time
# Print out the result of the load time # Print out the result of the load time
print( print(f"[{params['branding']}Model] \033[94mModel Loaded in \033[93m{generate_elapsed_time:.2f} seconds.\033[0m")
f"[{params['branding']}Model] \033[94mModel Loaded in \033[93m{generate_elapsed_time:.2f} seconds.\033[0m" print(f"[{params['branding']}Model] Ready")
)
# Set "tts_model_loaded" to true # Set "tts_model_loaded" to true
params["tts_model_loaded"] = True params["tts_model_loaded"] = True
# Set the output path for wav files # Set the output path for wav files
@@ -223,6 +217,8 @@ async def api_manual_load_model():
model_path=modeldownload_base_path / modeldownload_model_path, model_path=modeldownload_base_path / modeldownload_model_path,
config_path=modeldownload_base_path / modeldownload_model_path / "config.json", config_path=modeldownload_base_path / modeldownload_model_path / "config.json",
).to(device) ).to(device)
print(f"[{params['branding']}Model] \033[94mCoqui Public Model License\033[0m")
print(f"[{params['branding']}Model] \033[94mhttps://coqui.ai/cpml.txt\033[0m")
return model return model
@@ -252,6 +248,8 @@ async def xtts_manual_load_model():
use_deepspeed=params["deepspeed_activate"], use_deepspeed=params["deepspeed_activate"],
) )
model.to(device) model.to(device)
print(f"[{params['branding']}Model] \033[94mCoqui Public Model License\033[0m")
print(f"[{params['branding']}Model] \033[94mhttps://coqui.ai/cpml.txt\033[0m")
return model return model
# MODEL LOADER For "XTTSv2 FT" # MODEL LOADER For "XTTSv2 FT"
@@ -270,6 +268,8 @@ async def xtts_ft_manual_load_model():
use_deepspeed=params["deepspeed_activate"], use_deepspeed=params["deepspeed_activate"],
) )
model.to(device) model.to(device)
print(f"[{params['branding']}Model] \033[94mCoqui Public Model License\033[0m")
print(f"[{params['branding']}Model] \033[94mhttps://coqui.ai/cpml.txt\033[0m")
return model return model
# MODEL UNLOADER # MODEL UNLOADER