Merge branch 'erew123:alltalkbeta' into alltalkbeta

This commit is contained in:
IIEleven11 authored and GitHub committed 2024-09-19 20:52:40 -07:00
commit 2e56cc91f3
21 files changed
+1574 -109

No files matched your search

+12 -3
View File
@@ -1,7 +1,11 @@
# AllTalk TTS v2 BETA # AllTalk TTS v2 BETA
This is the BETA of v2. To be clear, that means they may well be bugs, issues, missing/incomplete documentation, a variety of potential problems etc (This is what BETA refers to in the software world for those whom dont know). This means you may need a bit of technical know how to deal with things that could come up and should only continue if you feel comfortable with that. This is the BETA of v2. To be clear, that means they may well be bugs, issues, missing/incomplete documentation, a variety of potential problems etc (This is what BETA refers to in the software world for those whom dont know). This means you may need a bit of technical know how to deal with things that could come up and should only continue if you feel comfortable with that.
Github discussions on the BETA are [here in the discussion board](https://github.com/erew123/alltalk_tts/discussions/245) Github **discussions** on the BETA are [here in the discussion board](https://github.com/erew123/alltalk_tts/discussions/245)
For **Issues/Bugs/Support**, please open an issue ticket [here in the issues area](https://github.com/erew123/alltalk_tts/issues)
**Please note, my available time has become VERY limited due to unexpected family commitments. So please DYOR and refer to the TTS manufacturer (listed in the interface) for issues with their TTS engines.**
#### If you are going to run the BETA, please read all the info below.... #### If you are going to run the BETA, please read all the info below....
@@ -20,6 +24,7 @@ Please go see [here](https://github.com/erew123/alltalk_tts/discussions/237)
- FYI there is no limit on how many XTTS models AllTalk will now find/work with. - FYI there is no limit on how many XTTS models AllTalk will now find/work with.
- AllTalk starts up on 0.0.0.0, meaning it will bind to ALL available IP addresses. There is no setting its IP address any more. - AllTalk starts up on 0.0.0.0, meaning it will bind to ALL available IP addresses. There is no setting its IP address any more.
- Updated Coqui TTS engine. - Updated Coqui TTS engine.
- XTTS multiple audio sample TTS generation to improve voice reproduction https://github.com/erew123/alltalk_tts/commit/b7aa3a7c5c8df260edede52dd1b31a7b40d9b202
- Gradio web interface (see the screenshots) - Gradio web interface (see the screenshots)
- Retrieval based Voice Conversion, AKA, RVC voice Pipeline, re-written to work on Python 3.11. - Retrieval based Voice Conversion, AKA, RVC voice Pipeline, re-written to work on Python 3.11.
- TTS Generator will now use any TTS engine. - TTS Generator will now use any TTS engine.
@@ -72,8 +77,12 @@ Quick setup scripts are available for users on Windows 10/11 and Linux. Instruct
- Ensure that **Git** is installed on your system as it is required for cloning the repository. If you do not have Git installed, visit [**Git's official website**](https://git-scm.com/downloads) to download and install it. - Ensure that **Git** is installed on your system as it is required for cloning the repository. If you do not have Git installed, visit [**Git's official website**](https://git-scm.com/downloads) to download and install it.
- **Important**: Do not use dashes or spaces in your folder path (e.g. avoid `/my folder-is-this/alltalk_tts-main`) as this causes issues with Python. - **Important**: Do not use dashes or spaces in your folder path (e.g. avoid `/my folder-is-this/alltalk_tts-main`) as this causes issues with Python.
### **NOTE. IF YOU HAVE AN EXISTING ALLTALK INSTALL** this will want to create a folder called `alltalk_tts` so you will need to re-name your old `alltalk_tts` to something else OR put this in a different folder/location. #### **NOTE. IF YOU HAVE AN EXISTING ALLTALK INSTALL** this will want to create a folder called `alltalk_tts` so you will need to re-name your old `alltalk_tts` to something else OR put this in a different folder/location.
### **NOTE**. I am not saying this is a over-the-top of an old alltalk upgrade ATM. It needs the Python environment rebuilding, hence a fresh install is needed for now. #### **NOTE**. I am not saying this is a over-the-top of an old alltalk upgrade ATM. It needs the Python environment rebuilding, hence a fresh install is needed for now.
---
#### Python/PIP has recently made changes to the package installer and I have/am doing what I can to keep the requirements files working, however, this is a complicated time to say the least as some external requirements change and this can cause installation issues. Please raise a ticket if you have an error that a module is missing.
---
<details> <details>
<summary>QUICK SETUP - Text-Generation-webui</summary> <summary>QUICK SETUP - Text-Generation-webui</summary>
+207 -32
View File
@@ -139,6 +139,7 @@ goto StandaloneMenu
:InstallNvidiaTextGen :InstallNvidiaTextGen
pip install -r system\requirements\requirements_textgen.txt pip install -r system\requirements\requirements_textgen.txt
pip install -r system\requirements\requirements_textgen2.txt pip install -r system\requirements\requirements_textgen2.txt
pip install -r system\requirements\requirements_parler.txt
echo ** Faiss ** echo ** Faiss **
call "%CONDA_ROOT_PREFIX%\Scripts\conda.exe" install -y pytorch::faiss-cpu call "%CONDA_ROOT_PREFIX%\Scripts\conda.exe" install -y pytorch::faiss-cpu
echo ** FFmpeg ** echo ** FFmpeg **
@@ -398,24 +399,202 @@ if not exist "%INSTALL_ENV_DIR%\python.exe" ( echo. && echo Conda environment is
@rem activate installer env @rem activate installer env
call "%CONDA_ROOT_PREFIX%\condabin\conda.bat" activate "%INSTALL_ENV_DIR%" || ( echo. && echo Miniconda hook not found. && goto end ) call "%CONDA_ROOT_PREFIX%\condabin\conda.bat" activate "%INSTALL_ENV_DIR%" || ( echo. && echo Miniconda hook not found. && goto end )
rem Install required packages rem Install required packages
echo ** PyTorch 2.2.1 **
:install_pytorch
echo ** Installing PyTorch 2.2.1 **
call "%CONDA_ROOT_PREFIX%\Scripts\conda.exe" install -y pytorch==2.2.1 torchvision==0.17.1 torchaudio==2.2.1 pytorch-cuda=12.1 -c pytorch -c nvidia call "%CONDA_ROOT_PREFIX%\Scripts\conda.exe" install -y pytorch==2.2.1 torchvision==0.17.1 torchaudio==2.2.1 pytorch-cuda=12.1 -c pytorch -c nvidia
echo ** Faiss ** echo.
if errorlevel 1 (
echo PyTorch installation failed, errorlevel was %errorlevel%. This could be caused by:
echo.
echo 1. Internet connection issues/unable to download PyTorch from Conda's website.
echo 2. Disk space related issues - Check your disk space on this drive.
echo 3. Incorrect or missing Conda environment - Restart installation.
echo 4. Permissions issues - Check you have enough rights on this system.
echo 5. Firewall or proxy settings blocking access to Conda's servers.
echo 6. Antivirus or security software interference.
echo 7. Other issues not mentioned above.
echo.
choice /C YN /M "Do you want to retry the Pytorch installation?"
if errorlevel 1 goto install_pytorch
if errorlevel 2 goto End
) else (
echo PyTorch installation was successful.
echo.
)
:install_faiss
echo ** Installing Faiss **
call "%CONDA_ROOT_PREFIX%\Scripts\conda.exe" install -y pytorch::faiss-cpu call "%CONDA_ROOT_PREFIX%\Scripts\conda.exe" install -y pytorch::faiss-cpu
echo ** FFmpeg ** echo.
if errorlevel 1 (
echo Faiss installation failed, errorlevel was %errorlevel%. This could be caused by:
echo.
echo 1. Internet connection issues/unable to download Faiss from Conda's website.
echo 2. Disk space related issues - Check your disk space on this drive.
echo 3. Incorrect or missing Conda environment - Restart installation.
echo 4. Permissions issues - Check you have enough rights on this system.
echo 5. Firewall or proxy settings blocking access to Conda's servers.
echo 6. Antivirus or security software interference.
echo 7. Other issues not mentioned above.
echo.
choice /C YN /M "Do you want to retry the Faiss installation?"
if errorlevel 1 goto install_faiss
if errorlevel 2 goto End
) else (
echo Faiss installation was successful.
echo.
)
:install_ffmpeg
echo ** Installing FFmpeg **
call "%CONDA_ROOT_PREFIX%\Scripts\conda.exe" install -y conda-forge::ffmpeg call "%CONDA_ROOT_PREFIX%\Scripts\conda.exe" install -y conda-forge::ffmpeg
echo.
if errorlevel 1 (
echo FFmpeg installation failed, errorlevel was %errorlevel%. This could be caused by:
echo.
echo 1. Internet connection issues/unable to download FFmpeg from Conda's website.
echo 2. Disk space related issues - Check your disk space on this drive.
echo 3. Incorrect or missing Conda environment - Restart installation.
echo 4. Permissions issues - Check you have enough rights on this system.
echo 5. Firewall or proxy settings blocking access to Conda's servers.
echo 6. Antivirus or security software interference.
echo 7. Other issues not mentioned above.
echo.
choice /C YN /M "Do you want to retry the FFmpeg installation?"
if errorlevel 1 goto install_ffmpeg
if errorlevel 2 goto End
) else (
echo FFmpeg installation was successful.
echo.
)
echo ** Requirements file ** echo ** Requirements file **
pip install -r system\requirements\requirements_standalone.txt pip install -r system\requirements\requirements_standalone.txt
echo ** Gradio Update ** echo.
pip install --upgrade gradio==4.32.2
echo ** DeepSpeed **
curl -LO https://github.com/erew123/alltalk_tts/releases/download/DeepSpeed-14.0/deepspeed-0.14.0+ce78a63-cp311-cp311-win_amd64.whl
echo Installing DeepSpeed...
pip install deepspeed-0.14.0+ce78a63-cp311-cp311-win_amd64.whl
del deepspeed-0.14.0+ce78a63-cp311-cp311-win_amd64.whl
echo ** Clean Environment **
call "%CONDA_ROOT_PREFIX%\Scripts\conda.exe" clean --all --force-pkgs-dirs -y
:update_gradio
echo ** Updating Gradio **
pip install --upgrade gradio==4.32.2
echo.
if errorlevel 1 (
echo Gradio update failed, errorlevel was %errorlevel%. This could be caused by:
echo.
echo 1. Internet connection issues/unable to download Gradio from PyPI.
echo 2. Disk space related issues - Check your disk space on this drive.
echo 3. Incorrect or missing Python environment - Restart installation.
echo 4. Permissions issues - Check you have enough rights on this system.
echo 5. Firewall or proxy settings blocking access to PyPI servers.
echo 6. Antivirus or security software interference.
echo 7. Other issues not mentioned above.
echo.
choice /C YN /M "Do you want to retry the Gradio update?"
if errorlevel 1 goto update_gradio
if errorlevel 2 goto End
) else (
echo Gradio update was successful.
echo.
)
:install_deepspeed
echo ** Downloading DeepSpeed **
curl -LO https://github.com/erew123/alltalk_tts/releases/download/DeepSpeed-14.0/deepspeed-0.14.0+ce78a63-cp311-cp311-win_amd64.whl
echo.
if errorlevel 1 (
echo DeepSpeed download failed, errorlevel was %errorlevel%. This could be caused by:
echo.
echo 1. Internet connection issues/unable to reach GitHub.
echo 2. Disk space related issues - Check your disk space on this drive.
echo 3. Permissions issues - Check you have enough rights on this system.
echo 4. Firewall or proxy settings blocking access to GitHub.
echo 5. Antivirus or security software interference.
echo 6. The file may have been moved or deleted from the GitHub repository.
echo 7. Other issues not mentioned above.
echo.
choice /C YN /M "Do you want to retry the DeepSpeed download?"
if errorlevel 1 goto install_deepspeed
if errorlevel 2 goto End
) else (
echo DeepSpeed download was successful.
echo.
)
echo ** Installing DeepSpeed **
pip install deepspeed-0.14.0+ce78a63-cp311-cp311-win_amd64.whl
echo.
if errorlevel 1 (
echo DeepSpeed installation failed, errorlevel was %errorlevel%. This could be caused by:
echo.
echo 1. The DeepSpeed wheel file was not downloaded successfully in the previous step.
echo 2. Microsoft C++ development tools for Python are not installed correctly.
echo 3. Disk space related issues - Check your disk space on this drive.
echo 4. Incorrect or missing Python environment - Restart installation.
echo 5. Permissions issues - Check you have enough rights on this system.
echo 6. Antivirus or security software interference.
echo 7. Other issues not mentioned above.
echo.
echo Please ensure you have followed the instructions to install the Microsoft C++ development
echo tools for Python, which is detailed on the AllTalk GitHub page.
echo.
choice /C YN /M "Do you want to retry the DeepSpeed installation?"
if errorlevel 1 goto install_deepspeed
if errorlevel 2 goto End
) else (
echo DeepSpeed installation was successful.
del deepspeed-0.14.0+ce78a63-cp311-cp311-win_amd64.whl
echo.
)
echo ** Installing Parler **
pip install -r system\requirements\requirements_parler.txt
echo Clean Environment
call "%CONDA_ROOT_PREFIX%\Scripts\conda.exe" clean --all --force-pkgs-dirs -y
echo.
:transformers_choice
echo.
echo ======================================== IMPORTANT NOTICE ===========================================
echo Currently, Coqui-TTS and the XTTS engine requires transformers version 4.40.2 to generate streaming
echo audio. XTTS can still generate standard non-streaming audio on any version of transformers. It is
echo ONLY streaming audio that is affected and ONLY with the Coqui XTTS engine. So this would affect
echo things like Kobold, or anywhere you use XTTS with streaming audio.
echo.
echo Parler-TTS states that it wants transformers version 4.43.3 but it appears to work fine with
echo transformers 4.40.2, however using transformers 4.40.2 generates a dependcy error message as
echo Parler-TTS is untested on 4.40.2 of transformers.
echo.
echo Until the Coqui-TTS engine is updated to perform streaming with newer versions of transformers, if
echo you want to use streaming with XTTS, you will need to downgrade transformers to 4.40.2.
echo.
echo AllTalk is NOT responsible for the maintainance or upkeep of the Coqui-TTS engine.
echo.
echo If you change your mind in future you can re-run atsetup and re-apply the requirements.
echo ====================================================================================================
echo.
choice /C YN /M " Do you want to downgrade transformers to version 4.40.2 for XTTS streaming support?"
if errorlevel 2 (
echo.
echo Keeping transformers at version 4.43.3.
echo Note: XTTS streaming may not work with this version.
goto end_transformers_choice
)
if errorlevel 1 (
echo.
echo Downgrading transformers to version 4.40.2...
echo.
pip install transformers==4.40.2
if errorlevel 1 (
echo.
echo Failed to downgrade transformers. Please check your internet connection and try manually later with:
echo pip install transformers==4.40.2
) else (
echo.
echo XTTS streaming should now work correctly.
)
)
:end_transformers_choice
echo.
echo Installation process completed.
@rem Create start_environment.bat to run AllTalk environment @rem Create start_environment.bat to run AllTalk environment
echo @echo off > start_environment.bat echo @echo off > start_environment.bat
@@ -449,6 +628,9 @@ Echo Run %L_YELLOW%start_diagnostics.bat%RESET% to start the diagnostics.
Echo Run %L_YELLOW%start_finetune.bat%RESET% to start Finetuning. Echo Run %L_YELLOW%start_finetune.bat%RESET% to start Finetuning.
Echo Run %L_YELLOW%start_environment.bat%RESET% to start the AllTalk Python environment. Echo Run %L_YELLOW%start_environment.bat%RESET% to start the AllTalk Python environment.
Echo. Echo.
Echo Documentation is built into the Gradio interface. Please explore the documentation for
Echo tips, troubleshooing and explanations as most common questions are answered there.
Echo.
if "%1"=="-silent" goto End if "%1"=="-silent" goto End
pause pause
goto StandaloneMenu goto StandaloneMenu
@@ -553,28 +735,14 @@ if errorlevel 1 (
) )
@rem Run Reapply requirements @rem Run Reapply requirements
echo. echo.
echo Re-installing requirements. If you have problems after this, it may indicate
echo that the custom Python environment is damaged in some way. As such it may be
echo best to delete the custom Python environment and re-run the entire setup
echo routine again to rebuild AllTalk's Python environment. Please press a key
echo to continue re-applying the Requirements for a standalone installation.
echo. echo.
echo Installing requirements. If you have problems after this, you should
echo delete the alltalk_environment and run the setup routine again.
echo.
pip install -r system\requirements\requirements_standalone.txt
echo Installing DeepSpeed...
pip install deepspeed-0.14.0+ce78a63-cp311-cp311-win_amd64.whl
del deepspeed-0.14.0+ce78a63-cp311-cp311-win_amd64.whl
if %ERRORLEVEL% neq 0 (
echo.
echo There was an error.
echo Press any key to return to the menu.
echo.
pause
goto StandaloneMenu
)
Echo.
Echo.
Echo Requirements have been re-applied/updated.
Echo.
pause pause
goto StandaloneMenu goto install_faiss
:STPurgepipcache :STPurgepipcache
cd /D "%~dp0" cd /D "%~dp0"
@@ -666,12 +834,19 @@ goto StandaloneMenu
echo Exiting AllTalk Setup Utility... echo Exiting AllTalk Setup Utility...
echo. echo.
Echo Remember, after installation you can.... Echo Remember, after installation you can....
Echo.
Echo Run %L_YELLOW%start_alltalk.bat%RESET% to start AllTalk. Echo Run %L_YELLOW%start_alltalk.bat%RESET% to start AllTalk.
Echo Run %L_YELLOW%start_finetune.bat%RESET% to start Finetuning. Echo Run %L_YELLOW%start_finetune.bat%RESET% to start Finetuning.
Echo Run %L_YELLOW%start_environment.bat%RESET% to start the AllTalk Python environment. Echo Run %L_YELLOW%start_environment.bat%RESET% to start the AllTalk Python environment.
Echo Run %L_YELLOW%start_diagnostics.bat%RESET% to start generate a diagnostics file.
Echo. Echo.
Echo Documentation is built into the Gradio interface. Please explore the documentation for
Echo tips, troubleshooing and explanations as most common questions are answered there.
exit /b exit /b
:End :End
echo Exiting AllTalk Setup Utility... echo Exiting AllTalk Setup Utility...
Echo.
Echo Documentation is built into the Gradio interface. Please explore the documentation for
Echo tips, troubleshooing and explanations as most common questions are answered there.
exit /b exit /b
+2
View File
@@ -396,6 +396,7 @@ install_custom_standalone() {
echo Installing DeepSpeed... echo Installing DeepSpeed...
pip install deepspeed-0.14.2+cu121torch2.2-cp311-cp311-manylinux_2_24_x86_64.whl pip install deepspeed-0.14.2+cu121torch2.2-cp311-cp311-manylinux_2_24_x86_64.whl
rm deepspeed-0.14.2+cu121torch2.2-cp311-cp311-manylinux_2_24_x86_64.whl rm deepspeed-0.14.2+cu121torch2.2-cp311-cp311-manylinux_2_24_x86_64.whl
pip install -r system\requirements\requirements_parler.txt
conda clean --all --force-pkgs-dirs -y conda clean --all --force-pkgs-dirs -y
Create start_environment.sh to run AllTalk Create start_environment.sh to run AllTalk
cat << EOF > start_environment.sh cat << EOF > start_environment.sh
@@ -578,6 +579,7 @@ reapply_standalone() {
echo " Installing additional requirements." echo " Installing additional requirements."
echo echo
pip install -r system/requirements/requirements_standalone.txt pip install -r system/requirements/requirements_standalone.txt
pip install -r system\requirements\requirements_parler.txt
echo echo
echo " Requirements have been re-applied/updated." echo " Requirements have been re-applied/updated."
echo echo
+23 -3
View File
@@ -108,10 +108,30 @@ def get_cpu_info():
def get_disk_info(): def get_disk_info():
disk_info = [] disk_info = []
partitions = psutil.disk_partitions() partitions = psutil.disk_partitions(all=True)
for p in partitions: for p in partitions:
usage = psutil.disk_usage(p.mountpoint) try:
disk_info.append(f" Drive: {p.device} | Total: {usage.total / (1024 ** 3):.2f} GB | Used: {usage.used / (1024 ** 3):.2f} GB | Free: {usage.free / (1024 ** 3):.2f} GB | Type: {p.fstype}") usage = psutil.disk_usage(p.mountpoint)
disk_info.append(
f"Drive: {p.device} | Total: {usage.total / (1024 ** 3):.2f} GB | Used: {usage.used / (1024 ** 3):.2f} GB | Free: {usage.free / (1024 ** 3):.2f} GB | Type: {p.fstype}"
)
except Exception as e:
# Handle various types of errors
error_type = type(e).__name__
error_message = str(e)
if isinstance(e, PermissionError):
status = "Inaccessible or locked (Permission denied)"
elif isinstance(e, OSError):
if e.winerror == 1117: # WinError 1117: I/O device error
status = "I/O device error"
else:
status = f"OS Error: {error_message}"
else:
status = f"Error: {error_type} - {error_message}"
disk_info.append(f"Drive: {p.device} | Status: {status} | Type: {p.fstype}")
return disk_info return disk_info
def is_port_in_use(port): def is_port_in_use(port):
+5 -3
View File
@@ -1788,7 +1788,9 @@ if __name__ == "__main__":
value=False, value=False,
label="Continue Previous Project", label="Continue Previous Project",
scale=1, scale=1,
visible=False,
) )
# Continue Run has been set to invisible from the interface as its setting a 1000 epoch run when used. Have been unable to track down where this is coming from.
disable_shared_memory = gr.Checkbox( disable_shared_memory = gr.Checkbox(
value=False, value=False,
label="Disable Shared Memory Use", label="Disable Shared Memory Use",
@@ -1800,11 +1802,11 @@ if __name__ == "__main__":
scale=1, scale=1,
) )
train_csv = gr.Textbox( train_csv = gr.Textbox(
label="Train CSV:", label="Train CSV file path:",
scale=2, scale=2,
) )
eval_csv = gr.Textbox( eval_csv = gr.Textbox(
label="Eval CSV:", label="Eval CSV file path:",
scale=2, scale=2,
) )
with gr.Row(): with gr.Row():
@@ -1981,7 +1983,7 @@ if __name__ == "__main__":
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- What you are training (A human voice, A cartoon voice, A new language entirely etc)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- What you are training (A human voice, A cartoon voice, A new language entirely etc)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- How much audio you have (you may want less or more eval or epochs)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- How much audio you have (you may want less or more eval or epochs)<br>
◽ The key indicator of sufficient model training is whether it sounds right to you. Coqui suggests beginning with the base settings for training. If the resulting audio doesn't meet your expectations, additional training sessions may be necessary.<br> ◽ The key indicator of sufficient model training is whether it sounds right to you. Coqui suggests beginning with the base settings for training. If the resulting audio doesn't meet your expectations, additional training sessions may be necessary.<br>
#### 🟪 <u>Continue Previous Project</u> #### 🟪 <u>Continue Previous Project (CURRENTLY REMOVED AND NOT AVAILABLE)</u>
This option allows you to resume training from where it left off if your previous session was interrupted (e.g., due to a power outage or system crash). When enabled:<br> This option allows you to resume training from where it left off if your previous session was interrupted (e.g., due to a power outage or system crash). When enabled:<br>
◽ The system will attempt to load the most recent checkpoint from your previous training session.<br> ◽ The system will attempt to load the most recent checkpoint from your previous training session.<br>
◽ It will continue training from that point, preserving your progress and saving time.<br> ◽ It will continue training from that point, preserving your progress and saving time.<br>
+85
View File
@@ -0,0 +1,85 @@
import asyncio
import aiohttp
import time
import argparse
from concurrent.futures import ThreadPoolExecutor
async def send_tts_request(session, url, text, voice, request_id):
start_time = time.time()
try:
async with session.post(url, data={
"text_input": text,
"text_filtering": "standard",
"character_voice_gen": voice,
"narrator_enabled": "false",
"narrator_voice_gen": "en_US-ljspeech-high.onnx",
"text_not_inside": "character",
"language": "en",
"output_file_name": f"loadtest_{request_id}",
"output_file_timestamp": "true",
"autoplay": "false",
"autoplay_volume": "0.8"
}) as response:
result = await response.json()
end_time = time.time()
print(f"Request {request_id} completed in {end_time - start_time:.2f} seconds.")
print(f"Response: {result}")
return result
except Exception as e:
print(f"Request {request_id} failed: {str(e)}")
return None
async def run_load_test(num_requests, text_length, api_url, voice):
async with aiohttp.ClientSession() as session:
tasks = []
for i in range(num_requests):
text = f"This is a test of the MEM load balancing system. Request number {i+1}. " * (text_length // 10)
task = asyncio.ensure_future(send_tts_request(session, api_url, text, voice, i+1))
tasks.append(task)
results = await asyncio.gather(*tasks)
return results
def main():
parser = argparse.ArgumentParser(description="Load test for MEM TTS API")
parser.add_argument("--requests", type=int, default=5, help="Number of simultaneous requests to send")
parser.add_argument("--length", type=int, default=50, help="Approximate length of text for each request")
parser.add_argument("--url", type=str, default="http://127.0.0.1:7401/api/tts-generate", help="URL of the MEM API")
parser.add_argument("--voice", type=str, default="en_US-ljspeech-high.onnx", help="A voice the current TTS engine supports")
args = parser.parse_args()
print(f"AllTalk MEM load tester.")
print(f"\nYou can use this to load test MEM. You can specify:")
print(f"\n --requests (the amount of simultaneous request to send)")
print(f" --length (the amount of character text per request)")
print(f" --url (the URL to send the request to)")
print(f" --voice (the voice/audio sample to use)")
print(f"\nA full command line would look like this")
print(f"\npython mem_load_test.py --requests 3 --length 50 --url http://127.0.0.1:7401/api/tts-generate --voice female_01.wav")
print(f"\nAll requests are sent simultaniously at the same time. As such the 'completed in' time is")
print(f"calculated from the time the requests were sent, not the actual TTS processing time per")
print(f"individual request within the TTS engine.")
print(f"\nIf you dont specify a voice the loaded TTS engine uses, this will fail. The default voice")
print(f"being sent is en_US-ljspeech-high.onnx which is for Piper TTS.")
print(f"\nStarting load test with {args.requests} simultaneous requests...")
print(f"Each request will have approximately {args.length} characters of text.")
print(f"Sending requests to: {args.url}\n")
start_time = time.time()
# Run the async function in a separate thread to avoid blocking
with ThreadPoolExecutor() as executor:
future = executor.submit(asyncio.run, run_load_test(args.requests, args.length, args.url, args.voice))
results = future.result()
end_time = time.time()
successful_requests = sum(1 for result in results if result and result.get("status") == "generate-success")
failed_requests = sum(1 for result in results if result is None or result.get("status") != "generate-success")
print(f"\nLoad test completed in {end_time - start_time:.2f} seconds.")
print(f"Successful requests: {successful_requests}")
print(f"Failed requests: {failed_requests}")
if __name__ == "__main__":
main()
+3 -3
View File
@@ -214,7 +214,7 @@ def run_firsttime_script():
else: else:
script_path = os.path.join(this_dir, 'system', 'config', 'firstrun.py') # Default to Standalone if nothing matched. script_path = os.path.join(this_dir, 'system', 'config', 'firstrun.py') # Default to Standalone if nothing matched.
subprocess.run(['python', script_path], check=True) subprocess.run([sys.executable, script_path], check=True)
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
print(f"Error occurred while running the script: {e}") print(f"Error occurred while running the script: {e}")
except Exception as e: except Exception as e:
@@ -356,7 +356,7 @@ if os.path.isfile("/.dockerenv") and 'google.colab' not in sys.modules:
print(f"[{branding}TTS] Internal Gradio address: http://localhost:{params['gradio_port_number']}") print(f"[{branding}TTS] Internal Gradio address: http://localhost:{params['gradio_port_number']}")
# Start the subprocess (now unified for both Docker and non-Docker environments) # Start the subprocess (now unified for both Docker and non-Docker environments)
process = subprocess.Popen(["python", script_path]) process = subprocess.Popen([sys.executable, 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:
@@ -468,7 +468,7 @@ check_espeak_ng()
def start_subprocess(): def start_subprocess():
global process global process
if process is None or process.poll() is not None: if process is None or process.poll() is not None:
process = subprocess.Popen(["python", script_path]) process = subprocess.Popen([sys.executable, script_path])
return "Subprocess started." return "Subprocess started."
else: else:
return "Subprocess is already running." return "Subprocess is already running."
@@ -1 +1,20 @@
BASIC SETUP
-----------
Place the `alltalk.js` in your `\SillyTavern\public\scripts\extensions\tts\` folder, replacing the existing file. Place the `alltalk.js` in your `\SillyTavern\public\scripts\extensions\tts\` folder, replacing the existing file.
CHANGING THE DEFAULT IP ADDRESS
-------------------------------
If you change the default IP/URL in the SillyTavern interface, you need to press Enter for it to save the setting. Just typing in an address/URL will not change the setting.
SIMPLE TROUBLESHOOTING
----------------------
The settings for AllTalk are stored, saved and managed by SillyTavern and not the AllTalk extension. You can manually edit OR delete these settings if necessary by editing the `settings.json` file that SillyTavern stores. I would suggest taking a copy of the file before making any changes.
Older versions of SillyTavern store `settings.json` file in `\SillyTavern\public\`
Newer version of SillyTavern store `settings.json` file in `\SillyTavern\data\default-user`
Within the `settings.json` file you will find a section called `"AllTalk": {` and it is closed out a few lines down with `},`
You can either manually edit any of the settings in there OR you can delete the entire section from the start of `"AllTalk":` to the end of `},` and when you refresh the SillyTavern web page OR restart SillyTavern, new settings for AllTalk will be created/saved.
@@ -149,7 +149,7 @@ html += `</select>
</div> </div>
<div class="at-endpoint-option"> <div class="at-endpoint-option">
<label for="at_server">AllTalk Endpoint:</label> <label for="at_server">AllTalk Endpoint (Press Enter to save):</label>
<input id="at_server" type="text" class="text_pole" maxlength="80" value="${this.settings.provider_endpoint}"/> <input id="at_server" type="text" class="text_pole" maxlength="80" value="${this.settings.provider_endpoint}"/>
</div> </div>
</div>`; </div>`;
+6 -2
View File
@@ -119,7 +119,9 @@ if "ip_address" in config:
# Check if firstrun_model is true # Check if firstrun_model is true
if config.get('firstrun_model', False): if config.get('firstrun_model', False):
print(f"[{branding}TTS]") print(f"[{branding}TTS]")
print(f"[{branding}TTS] \033[92mThis is the first time startup. Please download a start TTS model.\033[0m") print(f"[{branding}TTS] \033[92mThis is the first time startup. Please download a start TTS model. Other TTS engines\033[0m")
print(f"[{branding}TTS] \033[92mand TTS models can be downloaded/managed in the Gradio Interface `TTS Engines Settings`\033[0m")
print(f"[{branding}TTS] \033[92mtab after inital setup.\033[0m")
print(f"[{branding}TTS]") print(f"[{branding}TTS]")
# List of available models # List of available models
@@ -170,13 +172,15 @@ if config.get('firstrun_model', False):
if selected_model['name'] == 'piper': if selected_model['name'] == 'piper':
setup_piper() setup_piper()
update_tts_engines('piper', 'piper') update_tts_engines('piper', 'piper')
set_firstrun_model_false()
elif selected_model['name'] == 'vits': elif selected_model['name'] == 'vits':
setup_vits() setup_vits()
update_tts_engines('vits', 'vits - tts_models--en--vctk--vits') update_tts_engines('vits', 'vits - tts_models--en--vctk--vits')
set_firstrun_model_false()
elif selected_model['name'] == 'xtts': elif selected_model['name'] == 'xtts':
setup_xtts() setup_xtts()
update_tts_engines('xtts', 'xtts - xttsv2_2.0.3') update_tts_engines('xtts', 'xtts - xttsv2_2.0.3')
set_firstrun_model_false()
print(f"[{branding}TTS] {selected_model['name']} model downloaded and configuration updated successfully.") print(f"[{branding}TTS] {selected_model['name']} model downloaded and configuration updated successfully.")
# Set firstrun_model to false # Set firstrun_model to false
set_firstrun_model_false() set_firstrun_model_false()
@@ -19,6 +19,9 @@ def alltalk_documentation():
""" """
silly_tavern_support = """ silly_tavern_support = """
#### SillyTavern/AllTalk extension version
If you intend to use AllTalk V2 with SillyTavern, you will need to update the SillyTavern Extension from the `\alltalk_tts\system\SillyTavern Extension\` folder. Instructions are included within the folder.
#### Important note for Text-generation-webui users #### Important note for Text-generation-webui users
You **HAVE** to disable **Enable TTS** within the Text-generation-webui AllTalk interface, otherwise Text-generation-webui will also generate TTS due to the way it sends out text. You can do this each time you start up Text-generation-webui or set it in the start-up settings at the top of this page. You **HAVE** to disable **Enable TTS** within the Text-generation-webui AllTalk interface, otherwise Text-generation-webui will also generate TTS due to the way it sends out text. You can do this each time you start up Text-generation-webui or set it in the start-up settings at the top of this page.
@@ -290,6 +293,8 @@ def alltalk_documentation():
rvc_guides = """ rvc_guides = """
RVC (Retrieval-based Voice Conversion) enhances TTS by replicating voice characteristics for characters or narrators, adding depth to synthesized speech. It functions as a TTS-to-TTS pipeline and can be used with any TTS engine/model. However, the closer the original TTS generation is to the voice you want to use with RVC, the better the result will be. Therefore, it is recommended to use a voice cloning TTS engine like Coqui XTTS with voice samples for optimal performance. RVC (Retrieval-based Voice Conversion) enhances TTS by replicating voice characteristics for characters or narrators, adding depth to synthesized speech. It functions as a TTS-to-TTS pipeline and can be used with any TTS engine/model. However, the closer the original TTS generation is to the voice you want to use with RVC, the better the result will be. Therefore, it is recommended to use a voice cloning TTS engine like Coqui XTTS with voice samples for optimal performance.
When you first enable RVC on the `Global Settings > RVC Settings` tab and click the `Update RVC Settings` button, AllTalk will create the necessary folders and download any of the missing model files required for RVC to work.
### 🟩 Voice Model Files ### 🟩 Voice Model Files
Voice models should be stored in the `/models/rvc_voices/{subfolder}` directory in their own subfolder. Typically, a voice model includes a PTH file and potentially an index file. If an index file is present, AllTalk will automatically select and use it. If multiple index files are found, none will be used, and a message will be output to the console. You can find places on the internet to download pre-generated RVC voice models e.g. https://voice-models.com/ and huggingface etc. Voice models should be stored in the `/models/rvc_voices/{subfolder}` directory in their own subfolder. Typically, a voice model includes a PTH file and potentially an index file. If an index file is present, AllTalk will automatically select and use it. If multiple index files are found, none will be used, and a message will be output to the console. You can find places on the internet to download pre-generated RVC voice models e.g. https://voice-models.com/ and huggingface etc.
+30 -13
View File
@@ -227,6 +227,15 @@ def api_documentation():
} }
``` ```
Remapping the voices through an API call:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **URL**: `http://{ipaddress}:{port}/api/openai-voicemap`<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **Method**: `POST`<br>
`curl -X PUT "http://localhost:7851/api/openai-voicemap" -H "Content-Type: application/json" -d "{\"alloy\":\"female_01.wav\",\"echo\":\"female_01.wav\",\"fable\":\"female_01.wav\",\"nova\":\"female_01.wav\",\"onyx\":\"male_01.wav\",\"shimmer\":\"male_02.wav\"}"`
You can re-map the 6x voices on the fly, to any voices supported/available for the currently loaded TTS engine by using the above style post. You can use the `curl -X GET "http://127.0.0.1:7851/api/voices"` endpoint to get a list of all currently available voices. Please note that the Gradio interface will not reflect these changes until AllTalk is reloaded as gradio caches the list.
#### Python Example #### Python Example
``` ```
import requests import requests
@@ -398,10 +407,10 @@ def api_documentation():
### 🟠 Example Command Lines (Standard Generation) ### 🟠 Example Command Lines (Standard Generation)
Standard TTS generation supports narration and generates a WAV file/blob. Standard TTS generation supports narration and generates a WAV file/blob.
> **Standard TTS Speech Example** - Generate a time-stamped file for standard text:<br><br> > **Standard TTS Speech Example** - Generate a time-stamped file for standard text and play the audio at the command prompt/terminal:<br><br>
`curl -X POST "http://127.0.0.1:7851/api/tts-generate" -d "text_input=All of this is text spoken by the character. This is text not inside quotes, though that doesnt matter in the slightest" -d "text_filtering=standard" -d "character_voice_gen=female_01.wav" -d "narrator_enabled=false" -d "narrator_voice_gen=male_01.wav" -d "text_not_inside=character" -d "language=en" -d "output_file_name=myoutputfile" -d "output_file_timestamp=true" -d "autoplay=true" -d "autoplay_volume=0.8"` `curl -X POST "http://127.0.0.1:7851/api/tts-generate" -d "text_input=All of this is text spoken by the character. This is text not inside quotes, though that doesnt matter in the slightest" -d "text_filtering=standard" -d "character_voice_gen=female_01.wav" -d "narrator_enabled=false" -d "narrator_voice_gen=male_01.wav" -d "text_not_inside=character" -d "language=en" -d "output_file_name=myoutputfile" -d "output_file_timestamp=true" -d "autoplay=true" -d "autoplay_volume=0.8"`
> **Narrator Example** - Generate a time-stamped file for text with narrator and character speech:<br><br> > **Narrator Example** - Generate a time-stamped file for text with narrator and character speech and play the audio at the command prompt/terminal:<br><br>
`curl -X POST "http://127.0.0.1:7851/api/tts-generate" -d "text_input=*This is text spoken by the narrator* \\\"This is text spoken by the character\\\;". This is text not inside quotes." -d "text_filtering=standard" -d "character_voice_gen=female_01.wav" -d "narrator_enabled=true" -d "narrator_voice_gen=male_01.wav" -d "text_not_inside=character" -d "language=en" -d "output_file_name=myoutputfile" -d "output_file_timestamp=true" -d "autoplay=true" -d "autoplay_volume=0.8"`<br> `curl -X POST "http://127.0.0.1:7851/api/tts-generate" -d "text_input=*This is text spoken by the narrator* \\\"This is text spoken by the character\\\;". This is text not inside quotes." -d "text_filtering=standard" -d "character_voice_gen=female_01.wav" -d "narrator_enabled=true" -d "narrator_voice_gen=male_01.wav" -d "text_not_inside=character" -d "language=en" -d "output_file_name=myoutputfile" -d "output_file_timestamp=true" -d "autoplay=true" -d "autoplay_volume=0.8"`<br>
> If your text contains double quotes, escape them with &#92;" (see the narrator example).<br> > If your text contains double quotes, escape them with &#92;" (see the narrator example).<br>
@@ -411,7 +420,7 @@ def api_documentation():
> `curl -X POST "http://127.0.0.1:7851/api/tts-generate" -d "text_input=All of this is text spoken by the character. This is text not inside quotes, though that doesnt matter in the slightest"` > `curl -X POST "http://127.0.0.1:7851/api/tts-generate" -d "text_input=All of this is text spoken by the character. This is text not inside quotes, though that doesnt matter in the slightest"`
Would generate the TTS for whatver engine is curretly loaded in. It will use the default API settings and default TTS engine settings to populate any missing fields, which gives you flexibility on how you want to send API requests to AllTalk. Would generate the TTS for whatver engine is curretly loaded in. It will use the default API settings and default TTS engine settings `Global Settings > AllTalk API Defaults` to populate any missing fields, which gives you flexibility on how you want to send API requests to AllTalk.
### 🟠 Request Parameters ### 🟠 Request Parameters
#### **text_input** #### **text_input**
@@ -435,6 +444,10 @@ def api_documentation():
> The name of the RVC voice file for the character. Should be in the format `folder\\file.pth` or the word `Disabled`. When Disabled is sent and RVC is globally enabled, the RVC pipeline will not be used for the character/main voice.<br><br> > The name of the RVC voice file for the character. Should be in the format `folder\\file.pth` or the word `Disabled`. When Disabled is sent and RVC is globally enabled, the RVC pipeline will not be used for the character/main voice.<br><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-d "rvccharacter_voice_gen=folder\\voice1.pth" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-d "rvccharacter_voice_gen=folder\\voice1.pth"
#### **rvccharacter_pitch**
> The pitch for the RVC voice for the character. Should be in the range `-24` up to `24` with `0` being the central point and the global setting, set in the Gradio RVC page being used if the pitch is not specified in the TTS request.<br><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-d "rvccharacter_pitch=3"
#### **narrator_enabled** #### **narrator_enabled**
> Enable or disable the narrator function. If true, minimum text filtering is set to standard.<br><br> > Enable or disable the narrator function. If true, minimum text filtering is set to standard.<br><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-d "narrator_enabled=true"<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-d "narrator_enabled=true"<br>
@@ -448,6 +461,10 @@ def api_documentation():
> The name of the RVC voice file for the narrator. Should be in the format folder\\file.pth or the word Disabled. When Disabled is sent and RVC is globally enabled, the RVC pipeline will not be used for the character/main voice.<br><br> > The name of the RVC voice file for the narrator. Should be in the format folder\\file.pth or the word Disabled. When Disabled is sent and RVC is globally enabled, the RVC pipeline will not be used for the character/main voice.<br><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-d "rvcnarrator_voice_gen=folder\\voice2.pth" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-d "rvcnarrator_voice_gen=folder\\voice2.pth"
#### **rvcnarrator_pitch**
> The pitch for the RVC voice for the narrator. Should be in the range `-24` up to `24` with `0` being the central point and the global setting, set in the Gradio RVC page being used if the pitch is not specified in the TTS request.<br><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-d "rvcnarrator_pitch=3"
#### **text_not_inside** #### **text_not_inside**
> Specify the handling of lines not inside double quotes or asterisks for the narrator feature. Options:<br><br> > Specify the handling of lines not inside double quotes or asterisks for the narrator feature. Options:<br><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;**character**: Treat as character speech.<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;**character**: Treat as character speech.<br>
@@ -480,37 +497,37 @@ def api_documentation():
#### **output_file_name*** #### **output_file_name***
> The name of the output file (excluding the .wav extension).<br><br> > The name of the output file (excluding the .wav extension).<br><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--d "output_file_name=myoutputfile" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-d "output_file_name=myoutputfile"
#### **output_file_timestamp** #### **output_file_timestamp**
> Add a timestamp to the output file name. If true, each file will have a unique timestamp; otherwise, the same file name will be overwritten each time you generate TTS.<br><br> > Add a timestamp to the output file name. If true, each file will have a unique timestamp; otherwise, the same file name will be overwritten each time you generate TTS.<br><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--d "output_file_timestamp=true"<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-d "output_file_timestamp=true"<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--d "output_file_timestamp=false" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-d "output_file_timestamp=false"
#### **autoplay** #### **autoplay**
> Enable or disable playing the generated TTS to your standard sound output device at the time of TTS generation.<br><br> > Enable or disable playing the generated TTS to your standard sound output device at the time of TTS generation.<br><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--d "autoplay=true"<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-d "autoplay=true"<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--d "autoplay=false" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-d "autoplay=false"
#### **autoplay_volume** #### **autoplay_volume**
> Set the autoplay volume. Should be between 0.1 and 1.0.<br><br> > Set the autoplay volume. Should be between 0.1 and 1.0.<br><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--d "autoplay_volume=0.8" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-d "autoplay_volume=0.8"
#### **speed** #### **speed**
> Set the speed of the generated audio. Should be between 0.25 and 2.0.<br><br> > Set the speed of the generated audio. Should be between 0.25 and 2.0.<br><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--d "speed=1.0" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-d "speed=1.0"
#### **pitch** #### **pitch**
> Set the pitch of the generated audio. Should be between -10 and 10.<br><br> > Set the pitch of the generated audio. Should be between -10 and 10.<br><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--d "pitch=0" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-d "pitch=0"
#### **temperature** #### **temperature**
> Set the temperature for the TTS engine. Should be between 0.1 and 1.0.<br><br> > Set the temperature for the TTS engine. Should be between 0.1 and 1.0.<br><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--d "temperature=0.75" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-d "temperature=0.75"
#### **repetition_penalty** #### **repetition_penalty**
> Set the repetition penalty for the TTS engine. Should be between 1.0 and 20.0.<br><br> > Set the repetition penalty for the TTS engine. Should be between 1.0 and 20.0.<br><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--d "repetition_penalty=10" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-d "repetition_penalty=10"
### 🟠 TTS Generation Response ### 🟠 TTS Generation Response
> The API returns a JSON object with the following properties:<br><br> > The API returns a JSON object with the following properties:<br><br>
+3 -3
View File
@@ -23,7 +23,7 @@ tqdm>=4.66.0
unidic-lite>=1.0.8 unidic-lite>=1.0.8
uvicorn>=0.29.0 uvicorn>=0.29.0
pillow==10.3.0 pillow==10.3.0
fastapi fastapi==0.112.2
starlette starlette
pypinyin pypinyin
pyee pyee
@@ -41,6 +41,6 @@ tomlkit
python-multipart python-multipart
hangul_romanize hangul_romanize
word2number word2number
git+https://github.com/huggingface/parler-tts.git cutlet==0.4.0
fugashi==1.3.1
piper-tts; sys_platform == "linux" piper-tts; sys_platform == "linux"
trainer
@@ -0,0 +1 @@
git+https://github.com/huggingface/parler-tts.git
+18 -17
View File
@@ -1,35 +1,36 @@
TTS coqui-tts>=0.24.1
faster-whisper>=1.0.0 faster-whisper>=1.0.3
fuzzywuzzy fuzzywuzzy>=0.18.0
gradio>=4.26.0 gradio>=4.26.0
importlib_metadata>=7.1.0 importlib_metadata>=7.2.1
inputimeout>=1.0.4 inputimeout>=1.0.4
Jinja2>=3.1.0 Jinja2>=3.1.4
librosa>=0.10.2.post1 librosa>=0.10.2.post1
local_attention>=1.9.0 local_attention>=1.9.0
nvidia-cublas-cu11>=11.11.3.6 nvidia-cublas-cu11>=11.11.3.6
nvidia-cudnn-cu11>=9.1.1.17 nvidia-cudnn-cu11>=9.1.1.17
onnxruntime-gpu>=1.18.0 onnxruntime-gpu>=1.18.1
pydantic>=2.7.0 pydantic>=2.8.2
python-ffmpeg>=2.0.0 python-ffmpeg>=2.0.12
python-Levenshtein>=0.25.1 python-Levenshtein>=0.25.1
praat-parselmouth>=0.4.0 praat-parselmouth>=0.4.4
pyworld>=0.3.0 pyworld>=0.3.4
sounddevice>=0.4.7 sounddevice>=0.4.7
soundfile>=0.12.0 soundfile>=0.12.1
spacy>=3.7.1 spacy>=3.7.1
torchcrepe>=0.0.2 torchcrepe>=0.0.2
tqdm>=4.66.0 tqdm>=4.66.5
unidic-lite>=1.0.8 unidic-lite>=1.0.8
uvicorn>=0.29.0 uvicorn>=0.29.0
pillow==10.3.0 pillow==10.3.0
pypinyin pypinyin>=0.52.0
hangul_romanize hangul_romanize>=0.1.0
word2number word2number>=1.1
git+https://github.com/huggingface/parler-tts.git cutlet==0.4.0
fugashi==1.3.1
./system/config/fairseq-0.12.4-cp311-cp311-win_amd64.whl; sys_platform == "win32" ./system/config/fairseq-0.12.4-cp311-cp311-win_amd64.whl; sys_platform == "win32"
./system/config/fairseq-0.12.3.1-cp311-cp311-linux_x86_64.whl; sys_platform == "linux" ./system/config/fairseq-0.12.3.1-cp311-cp311-linux_x86_64.whl; sys_platform == "linux"
piper-tts; sys_platform == "linux" piper-tts; sys_platform == "linux"
piper-tts; sys_platform == "darwin" piper-tts; sys_platform == "darwin"
piper-phonemize==1.1.0; sys_platform == "darwin" piper-phonemize==1.1.0; sys_platform == "darwin"
trainer fastapi==0.112.2
+6 -6
View File
@@ -1,6 +1,6 @@
coqui-tts>=0.24.1 coqui-tts>=0.24.1
faster-whisper>=1.0.0 faster-whisper>=1.0.0
fuzzywuzzy fuzzywuzzy>=0.18.0
gradio>=4.26.0 gradio>=4.26.0
importlib_metadata>=7.1.0 importlib_metadata>=7.1.0
inputimeout>=1.0.4 inputimeout>=1.0.4
@@ -22,13 +22,13 @@ torchcrepe>=0.0.2
tqdm>=4.66.0 tqdm>=4.66.0
unidic-lite>=1.0.8 unidic-lite>=1.0.8
uvicorn>=0.29.0 uvicorn>=0.29.0
pypinyin pypinyin>=0.52.0
hangul_romanize hangul_romanize>=0.1.0
word2number word2number>=1.1
git+https://github.com/huggingface/parler-tts.git cutlet==0.4.0
fugashi==1.3.1
./system/config/fairseq-0.12.4-cp311-cp311-win_amd64.whl; sys_platform == "win32" ./system/config/fairseq-0.12.4-cp311-cp311-win_amd64.whl; sys_platform == "win32"
./system/config/fairseq-0.12.3.1-cp311-cp311-linux_x86_64.whl; sys_platform == "linux" ./system/config/fairseq-0.12.3.1-cp311-cp311-linux_x86_64.whl; sys_platform == "linux"
piper-tts; sys_platform == "linux" piper-tts; sys_platform == "linux"
piper-tts; sys_platform == "darwin" piper-tts; sys_platform == "darwin"
piper-phonemize==1.1.0; sys_platform == "darwin" piper-phonemize==1.1.0; sys_platform == "darwin"
trainer
+35 -6
View File
@@ -37,6 +37,7 @@ try:
import torchaudio import torchaudio
import wave import wave
import io import io
import random
import numpy as np import numpy as np
from TTS.tts.configs.xtts_config import XttsConfig from TTS.tts.configs.xtts_config import XttsConfig
from TTS.tts.models.xtts import Xtts from TTS.tts.models.xtts import Xtts
@@ -287,7 +288,19 @@ class tts_class:
# ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ # ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
directory = self.main_dir / "voices" directory = self.main_dir / "voices"
voices = [f for f in os.listdir(directory) if os.path.isfile(os.path.join(directory, f)) and f.endswith(".wav")] # Step 1: Add .wav files in the main "voices" directory to the list
voices.extend([f for f in os.listdir(directory) if os.path.isfile(os.path.join(directory, f)) and f.endswith(".wav")])
# Step 2: Walk through subfolders and add subfolder names if they contain .wav files
for root, dirs, files in os.walk(directory):
# Skip the root directory itself and only consider subfolders
if os.path.normpath(root) != os.path.normpath(directory):
if any(f.endswith(".wav") for f in files):
folder_name = os.path.basename(root) + "/"
voices.append(folder_name)
# Remove "voices/" from the list if it somehow got added
voices = [v for v in voices if v != "voices/"]
# ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ # ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
# ↓↓↓ Keep everything below this line ↓↓↓ # ↓↓↓ Keep everything below this line ↓↓↓
@@ -470,15 +483,31 @@ class tts_class:
# XTTSv2 LOCAL & Xttsv2 FT Method # XTTSv2 LOCAL & Xttsv2 FT Method
print(f"[{self.branding}Debug] Deciding if streaming or not") if self.debug_tts else None print(f"[{self.branding}Debug] Deciding if streaming or not") if self.debug_tts else None
print(f"[{self.branding}Debug] self.current_model_loaded", self.current_model_loaded) if self.debug_tts else None print(f"[{self.branding}Debug] self.current_model_loaded is:", self.current_model_loaded) if self.debug_tts else None
self.current_model_loaded self.current_model_loaded
if os.path.isdir(voice): print(f"[{self.branding}Debug] Audio Sample Detection") if self.debug_tts else None
wavs_files = glob.glob(os.path.join(voice, "*.wav")) print(f"[{self.branding}Debug] Voice name sent in request is:", voice) if self.debug_tts else None
# Check if the voice ends with a slash, indicating it's a directory
if voice.endswith("/") or voice.endswith("\\"):
# Remove the trailing slash for proper path detection
voice = voice.rstrip("/\\")
if os.path.isdir(os.path.join(self.main_dir, "voices", voice)):
# Normalize the path for the directory and then search for .wav files
normalized_path = os.path.normpath(os.path.join(self.main_dir, "voices", voice))
wavs_files = glob.glob(os.path.join(normalized_path, "*.wav"))
print(f"[{self.branding}Debug] Directory of multiple voice samples detected. Using multiple WAV files:", wavs_files) if self.debug_tts else None
# If there are more than 5 .wav files, randomly select 5
if len(wavs_files) > 5:
wavs_files = random.sample(wavs_files, 5)
print(f"[{self.branding}Debug] More than 5 wav files detected so only using 5x random audio samples:", wavs_files) if self.debug_tts else None
else: else:
wavs_files = [f"{self.main_dir}/voices/{voice}"] # Normalize the path for the file
normalized_path = os.path.normpath(os.path.join(self.main_dir, "voices", voice))
wavs_files = [normalized_path]
print(f"[{self.branding}Debug] Single voice sample detected. Using one WAV sample:", wavs_files) if self.debug_tts else None
if self.current_model_loaded.startswith ("xtts"): if self.current_model_loaded.startswith ("xtts"):
print(f"[{self.branding}Debug] Text arriving at engine {text}") if self.debug_tts else None print(f"[{self.branding}Debug] Text arriving at TTS engine is: {text}") if self.debug_tts else None
gpt_cond_latent, speaker_embedding = self.model.get_conditioning_latents( gpt_cond_latent, speaker_embedding = self.model.get_conditioning_latents(
audio_path=wavs_files, audio_path=wavs_files,
gpt_cond_len=self.model.config.gpt_cond_len, gpt_cond_len=self.model.config.gpt_cond_len,
+16 -7
View File
@@ -280,8 +280,17 @@ def xtts_model_alltalk_settings(model_config_data):
### 🟧 Using my own Finetuned models ### 🟧 Using my own Finetuned models
Please your Finetuned models within their own folder in `/alltalk_tts/models/xtts/`. Once they are in here they will become availabe within the interface after reloading the XTTS engine.<br> Please your Finetuned models within their own folder in `/alltalk_tts/models/xtts/`. Once they are in here they will become availabe within the interface after reloading the XTTS engine.<br>
### 🟧 Using Voice Samples ### 🟧 Using Single Voice Samples
Voice samples are stored in `/alltalk_tts/voices/` and should be named using the following format `name.wav`<br> Voice samples are stored in `/alltalk_tts/voices/` and should be named using the following format `name.wav`. These files will be listed as `name.wav` in the available voices list.<br>
### 🟧 Using Multiple Voice Samples
If you have multiple voice samples for a single voice, you can organize them into subfolders within the `/alltalk_tts/voices/` directory. Each subfolder should be named according to the voice it contains, up to 5 voice samples will be randomly selected for use.<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;• Each subfolder should reflect the name or type of the voice it contains (e.g., `female_voice`, `male_voice`).<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;• The voice samples inside each subfolder should follow the standard `.wav` format.<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;• An example folder path would be `/alltalk_tts/voices/mynewvoice/` and this would be listed in the available voices list as `mynewvoice/`.<br>
This organization allows for easy selection and management of multiple voice samples while ensuring the system can correctly identify and utilize each voice. Manual CURL API requests would send the folder in the format `mynewvoice/`.
### 🟧 Where are the outputs stored & Automatic output wav file deletion ### 🟧 Where are the outputs stored & Automatic output wav file deletion
Voice outputs are stored in `/alltalk_tts/outputs/`. You can configure automatic maintenance deletion of old wav files by setting `Del WAV's older than` in the global settings.<br> Voice outputs are stored in `/alltalk_tts/outputs/`. You can configure automatic maintenance deletion of old wav files by setting `Del WAV's older than` in the global settings.<br>
@@ -292,12 +301,15 @@ def xtts_model_alltalk_settings(model_config_data):
### 🟧 Where are the models stored? ### 🟧 Where are the models stored?
This extension will download the models to `/alltalk_tts/models/xtts/` folder.<br> This extension will download the models to `/alltalk_tts/models/xtts/` folder.<br>
### 🟧 API Local, XTTSv2 Generation methods & Speed
These two methods both produce sound output in slightly different ways. XTTSv2 is the perferable method a it supports DeepSpeed, which, if you have a system capable of DeepSpeed genereation, can result in a 2-3x speed gain in generation.
""")
gr.Markdown("""
### 🟧 How do I create a new voice sample? ### 🟧 How do I create a new voice sample?
To create a new voice sample, you need to make a wav file that is `22050Hz`, `Mono`, `16 bit` 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 output from much longer clips.<br><br> To create a new voice sample, you need to make a wav file that is `22050Hz`, `Mono`, `16 bit` 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 output from much longer clips.<br><br>
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 close attention to the audio you are listening to and trying to sample. Are there noises in the background, hiss on the soundtrack, a low humm, some quiet music playing or something? The better quality the audio the better the final TTS result. Don't forget, the AI that processes the sounds can hear everything in your sample and it will use them in the voice its trying to recreate.<br><br> 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 close attention to the audio you are listening to and trying to sample. Are there noises in the background, hiss on the soundtrack, a low humm, some quiet music playing or something? The better quality the audio the better the final TTS result. Don't forget, the AI that processes the sounds can hear everything in your sample and it will use them in the voice its trying to recreate.<br><br>
Try make your clip one of nice flowing speech, like the included example files. No big pauses, gaps or other sounds. Preferably a sample that the person you are trying to copy will show a little vocal range and emotion in their voice. Also, try to avoid a clip starting or ending with breathy sounds (breathing in/out etc).<br> Try make your clip one of nice flowing speech, like the included example files. No big pauses, gaps or other sounds. Preferably a sample that the person you are trying to copy will show a little vocal range and emotion in their voice. Also, try to avoid a clip starting or ending with breathy sounds (breathing in/out etc).<br>
""")
gr.Markdown("""
### 🟧 Editing your sample! ### 🟧 Editing your sample!
So, you've downloaded your favourite celebrity interview off YouTube, from here you need to chop it down to 6 to 30 seconds in length and resample it. If you need to clean it up, do audio processing, volume level changes etc, do this before down-sampling.<br><br> So, you've downloaded your favourite celebrity interview off YouTube, from here you need to chop it down to 6 to 30 seconds in length and resample it. If you need to clean it up, do audio processing, volume level changes etc, do this before down-sampling.<br><br>
Using the latest version of Audacity `select/highlight` your 6 to 30 second clip and:<br><br> Using the latest version of Audacity `select/highlight` your 6 to 30 second clip and:<br><br>
@@ -314,9 +326,6 @@ def xtts_model_alltalk_settings(model_config_data):
> Try using the 2x different generation methods `API Local` and `XTTSv2 Local`, as they generate output in slightly different ways.<br> > Try using the 2x different generation methods `API Local` and `XTTSv2 Local`, as they generate output in slightly different ways.<br>
Additionally, use the RVC pipeline with a matching voice model, however, some samples just never seem to work correctly, so maybe try a different sample. Always remember though, this is an AI model attempting to re-create a voice, so you will never get a 100% match. Additionally, use the RVC pipeline with a matching voice model, however, some samples just never seem to work correctly, so maybe try a different sample. Always remember though, this is an AI model attempting to re-create a voice, so you will never get a 100% match.
### 🟧 API Local, XTTSv2 Generation methods & Speed
These two methods both produce sound output in slightly different ways. XTTSv2 is the perferable method a it supports DeepSpeed, which, if you have a system capable of DeepSpeed genereation, can result in a 2-3x speed gain in generation.
""") """)
return app return app
-2
View File
@@ -23,7 +23,6 @@ from torch.nn.parallel import DistributedDataParallel as DDP_th
from torch.optim.lr_scheduler import ReduceLROnPlateau from torch.optim.lr_scheduler import ReduceLROnPlateau
from torch.utils.data import DataLoader from torch.utils.data import DataLoader
from trainer.analytics import ping_training_run
from trainer.callbacks import TrainerCallback from trainer.callbacks import TrainerCallback
from trainer.generic_utils import ( from trainer.generic_utils import (
KeepAverage, KeepAverage,
@@ -597,7 +596,6 @@ class Trainer:
self.callbacks.on_init_end(self) self.callbacks.on_init_end(self)
self.dashboard_logger.add_config(config) self.dashboard_logger.add_config(config)
self.save_training_script() self.save_training_script()
ping_training_run()
@property @property
def use_apex(self): def use_apex(self):
+1082
View File
File diff suppressed because it is too large. Load diff
+15 -8
View File
@@ -2,6 +2,7 @@ import os
import sys import sys
import json import json
import time import time
import argparse
import librosa import librosa
import logging import logging
import importlib import importlib
@@ -659,7 +660,7 @@ async def generate_audio(text, voice, language, temperature, repetition_penalty,
async for _ in response: async for _ in response:
pass pass
except Exception as e: except Exception as e:
print(f"[GEN] Error during audio generation: {str(e)}") print(f"{branding}[GEN] Error during audio generation: {str(e)}")
raise raise
########################### ###########################
@@ -741,8 +742,8 @@ async def openai_tts_generate(request: Request):
model = json_data["model"] # Currently ignored model = json_data["model"] # Currently ignored
input_text = json_data["input"] input_text = json_data["input"]
voice = json_data["voice"] voice = json_data["voice"]
response_format = json_data["response_format"].lower() response_format = json_data.get("response_format", "wav").lower()
speed = json_data["speed"] speed = json_data.get("speed", 1.0)
print(f"[{branding}Debug] Input text: {input_text}") if debug_openai else None print(f"[{branding}Debug] Input text: {input_text}") if debug_openai else None
print(f"[{branding}Debug] Voice: {voice}") if debug_openai else None print(f"[{branding}Debug] Voice: {voice}") if debug_openai else None
print(f"[{branding}Debug] Speed: {speed}") if debug_openai else None print(f"[{branding}Debug] Speed: {speed}") if debug_openai else None
@@ -1594,7 +1595,7 @@ async def apifunction_trigger_analysis(threshold: int = Query(default=98)):
env["PATH"] = os.path.join(venv_path, "bin") + ":" + env["PATH"] env["PATH"] = os.path.join(venv_path, "bin") + ":" + env["PATH"]
ttslist_path = this_dir / output_directory / "ttsList.json" ttslist_path = this_dir / output_directory / "ttsList.json"
wavfile_path = this_dir / output_directory wavfile_path = this_dir / output_directory
subprocess.run(["python", "tts_diff.py", f"--threshold={threshold}", f"--ttslistpath={ttslist_path}", f"--wavfilespath={wavfile_path}"], cwd=this_dir / "system" / "tts_diff", env=env) subprocess.run([sys.executable, "tts_diff.py", f"--threshold={threshold}", f"--ttslistpath={ttslist_path}", f"--wavfilespath={wavfile_path}"], cwd=this_dir / "system" / "tts_diff", env=env)
# Read the analysis summary # Read the analysis summary
try: try:
with open(this_dir / output_directory / "analysis_summary.json", "r") as summary_file: with open(this_dir / output_directory / "analysis_summary.json", "r") as summary_file:
@@ -1613,7 +1614,7 @@ async def apifunction_srt_generation():
env["PATH"] = os.path.join(venv_path, "bin") + ":" + env["PATH"] env["PATH"] = os.path.join(venv_path, "bin") + ":" + env["PATH"]
ttslist_path = this_dir / output_directory / "ttsList.json" ttslist_path = this_dir / output_directory / "ttsList.json"
wavfile_path = this_dir / output_directory wavfile_path = this_dir / output_directory
subprocess.run(["python", "tts_srt.py", f"--ttslistpath={ttslist_path}", f"--wavfilespath={wavfile_path}"], cwd=this_dir / "system" / "tts_srt", env=env) subprocess.run([sys.executable, "tts_srt.py", f"--ttslistpath={ttslist_path}", f"--wavfilespath={wavfile_path}"], cwd=this_dir / "system" / "tts_srt", env=env)
srt_file_path = this_dir / output_directory / "subtitles.srt" srt_file_path = this_dir / output_directory / "subtitles.srt"
if not srt_file_path.exists(): if not srt_file_path.exists():
raise HTTPException(status_code=404, detail="Subtitle file not found.") raise HTTPException(status_code=404, detail="Subtitle file not found.")
@@ -1678,11 +1679,17 @@ async def read_root():
return HTMLResponse(content=rendered_html, status_code=200) return HTMLResponse(content=rendered_html, status_code=200)
# Start Uvicorn Webserver # Start Uvicorn Webserver
port_parameter = int(params["api_def"]["api_port_number"]) # port_parameter = int(params["api_def"]["api_port_number"])
if __name__ == "__main__": if __name__ == "__main__":
import uvicorn import uvicorn
# Command line argument parser
parser = argparse.ArgumentParser(description="AllTalk TTS Server")
parser.add_argument("--port", type=int, help="Port number for the server")
args = parser.parse_args()
# Determine the port to use
config_port = int(params["api_def"]["api_port_number"])
port_to_use = args.port if args.port is not None else config_port
# Start Uvicorn Webserver # Start Uvicorn Webserver
uvicorn_server = uvicorn.run(app, host="0.0.0.0", port=port_parameter, log_level="debug") uvicorn_server = uvicorn.run(app, host="0.0.0.0", port=port_to_use, log_level="debug")