Compare commits

..
Author SHA1 Message Date
Paladinium 4959ae36c1 Merge pull request #517 from Paladinium/alltalkbeta_docker_improvements
Refactoring docker images, updating CUDA to 12.6 and pytorch 2.6
2025-02-12 22:11:40 +01:00
ekoc 284c100860 Refactoring docker images, updating CUDA to 12.6 and pytorch 2.6 2025-02-12 22:01:34 +01:00
Paladinium 73d9d9450b Merge pull request #514 from Demannu/dockerbeta-bugfix
AllTalkBeta: Docker Build: Fix conda build error logic
2025-02-11 22:41:41 +01:00
Demannu 62fd9ce2e5 Fix conda docker build error logic 2025-02-11 16:41:20 -05:00
erew123 591d86978b Update rvc_files.json 2025-01-30 06:26:44 +00:00
erew123 5576826513 Ensure no tuples 2025-01-28 19:54:37 +00:00
erew123 e0d753c8a1 check for spaces in file name 2025-01-26 00:38:58 +00:00
erew123 f8fe5ce167 Ensure no blank character name/output file 2025-01-26 00:36:27 +00:00
erew123 8f5bb216a6 Capture null input/outputs
Captures empty text inputs or outputs that would interfere with TTS generation (input) or returning a none/null text value back to TGWUI (output)
2025-01-25 23:14:05 +00:00
erew123 c8d2a6fa51 Update requirements_colab.txt
lock local_attention version
2025-01-17 11:13:13 +00:00
erew123 7287fede1b Update requirements_standalone.txt
Lock local_attention version
2025-01-17 10:53:23 +00:00
erew123 8e6e18f449 Merge pull request #476 from SilyNoMeta/feat/auto-lang-detection
Add language auto-detection
2025-01-06 14:55:42 +00:00
erew123 fe4110581e Merge pull request #475 from SilyNoMeta/feat/f5-pickletensor
Add initial support for pickletensor models to F5-TTS
2025-01-06 14:37:47 +00:00
Ilyas Hilali 53e632b70b Print language detection related message to debug_tts 2025-01-05 18:03:20 +01:00
Ilyas Hilali f21f828ab5 Add zh:zh in fallbacks as it is present in the preset of language on the main page (first commit was useless:) 2025-01-05 14:50:43 +01:00
Ilyas Hilali 201f03e4f8 Add zh:zh in fallbacks as it is present in the preset of language on the main page 2025-01-05 14:23:20 +01:00
erew123 d1babe1f6b Merge pull request #447 from ekirts-h/alltalkbeta
Fix to enable/disable BPE and VAD
2025-01-05 11:29:36 +00:00
erew123 9c5dc99e89 Merge pull request #438 from Paladinium/alltalkbeta_config_refactoring
Use pydantic for config serialization/deserialization
2025-01-05 11:26:40 +00:00
Ilyas Hilali 0182e8fd01 Add a warning when a pickle file is loaded 2025-01-05 12:13:07 +01:00
Ilyas Hilali a495c0a239 Add fallbacks languages 2025-01-04 19:03:48 +01:00
Ilyas ecb15200dc Add language auto-detection
* adds langdetect as requirement for colab, standalone and textgen
* adds "auto" to the language dropdown in the Advanced Engine/Model Settings panel
* replace the hardcoded "en" by "auto" when called by the OpenAI compatible Speech API
2025-01-04 00:38:52 +01:00
Ilyas Hilali e72a7bf5c9 Add initial support for pickletensor models to F5-TTS
* Tested with @RASPAUDIO french model available here : https://huggingface.co/RASPIAUDIO/F5-French-MixedSpeakers-reduced
2025-01-03 18:32:52 +01:00
erew123 5ce8a6681e Merge pull request #469 from manifestinteractive/patch-1
Resolves "Create: command not found" error
2024-12-23 06:50:31 +00:00
erew123 0b2bfceeb8 Merge pull request #464 from chadgauth/fix/openai-voicemap-doc
Fix help content documentation
2024-12-23 06:47:18 +00:00
Peter Schmalfeldt 83bf72a905 Create: command not found
Resolve error in `atsetup.sh`

> ./atsetup.sh: line 367: Create: command not found

This was just a comment that did not have a `#` in front of it.
2024-12-22 23:00:57 -05:00
erew123 79c26243d6 Update docker-build.sh
make build directories
2024-12-22 16:26:01 +00:00
Chad Gauthier f5e09de2b3 fix documentation 2024-12-21 18:26:46 -06:00
erew123 5a18d68d20 Merge pull request #457 from Paladinium/alltalkbeta_docker
Adding Dockerfile and scripts for building and starting
2024-12-20 21:42:28 +00:00
ekoc 78b0a51c4e Fixing a typo in the readme 2024-12-20 21:41:06 +01:00
ekoc c7f9b04826 Fixing docker build for DeepSpeed, introducing build for conda environment 2024-12-20 21:18:20 +01:00
ekoc 7522fa87d6 Adding docker build for DeepSpeed 2024-12-19 11:09:03 +01:00
ekoc 9a99126f68 Adding Dockerfile and scripts for building and starting 2024-12-16 20:34:46 +01:00
erew123 6052453d26 Character count and whitespace sanitization 2024-12-12 06:28:32 +00:00
erew123 27df5b8038 Update requirements_colab.txt 2024-12-08 03:02:41 +00:00
erew123 183a37460e Update requirements_textgen.txt 2024-12-08 03:02:25 +00:00
erew123 f15dcd23a7 Fix Coqui TTS to 0.24.3
resolved bug in current 0.25.0 version
2024-12-08 03:02:02 +00:00
ekirts-h e155d8eb22 Fix to disable BPE and VAD
Swap the string "True" / "False" to boolean before passing as they always return True in if statement and does not properly disable the functions even when set to disable in webui.
2024-12-07 20:19:09 +13:00
ekoc 46a023829d Use pydantic for config serialization/deserialization 2024-12-04 21:57:12 +01:00
erew123 239b656633 Merge pull request #427 from hykilpikonna/alltalkbeta
[F] Fix #251: Expected a value of type 'str'
2024-11-29 04:41:38 +00:00
Azalea Gui 0c6e113aff [F] Fix #251: Expected a value of type 'str' 2024-11-28 22:19:44 -05:00
erew123 94f90e149e Update python-ci.yml 2024-11-27 19:43:26 +00:00
erew123 cc160820c4 Update README.md 2024-11-27 19:37:23 +00:00
erew123 af29b1ed75 Added "hi" hindi language
I believe the tokenizers now support Hindi, but don't know for sure. Will require the XTTS 2.0.3 model. Anything earlier doesn't support Hindi.
2024-11-27 05:11:01 +00:00
erew123 1297a28cb4 Export to MP3 option 2024-11-27 05:00:56 +00:00
erew123 415b9357b0 Update python-ci.yml 2024-11-27 03:55:19 +00:00
erew123 f46796d121 Update python-ci.yml 2024-11-27 03:38:16 +00:00
erew123 fae005f59d Delete .github/workflows/publish-docker.yml 2024-11-27 03:36:08 +00:00
erew123 66d5090b2e Update README.md 2024-11-27 03:19:41 +00:00
erew123 65ba0d73ac python-ci.yml alltalkbeta only
on:
  push:
    branches:
      - alltalkbeta
  pull_request:
    branches:
      - alltalkbeta
2024-11-27 03:04:53 +00:00
erew123 0b232bdb7c Added SSL Proxy 2024-11-27 02:08:21 +00:00
erew123 b51e9cde2f SSL Proxy 2024-11-27 02:07:15 +00:00
erew123 1bed9f586e UPD Help content 2024-11-27 02:06:24 +00:00
erew123 e220d70e7e PyOpenSSL 2024-11-27 02:05:06 +00:00
erew123 1be14414cf Add files via upload 2024-11-26 22:03:57 +00:00
erew123 2819e09063 Add files via upload 2024-11-26 22:00:30 +00:00
erew123 f92ea060b0 Update basediagnostics.log 2024-11-26 03:00:45 +00:00
erew123 72a495c108 basediagnostics.log updated 2024-11-26 03:00:03 +00:00
erew123 abd4eb8450 lint cleanup 2024-11-26 02:27:27 +00:00
erew123 9309303ccb Updated TGWUI Remote Extension 2024-11-26 00:48:45 +00:00
erew123 393bff6ab9 Update atsetup.sh 2024-11-26 00:23:42 +00:00
erew123 7c23b043d9 Update atsetup.bat 2024-11-26 00:20:18 +00:00
erew123 c44f17cd38 Update atsetup.sh ffmpeg 2024-11-25 23:37:21 +00:00
erew123 3ed501badc Update atsetup.bat FFmpeg 2024-11-25 23:35:53 +00:00
erew123 231bc21fa7 Updated to use new ffmpeg 2024-11-25 23:33:12 +00:00
erew123 aa794e458b Updated Transcode functions
new FFmpeg install required:
ffmpeg-python>=0.2.0
conda install -c conda-forge ffmpeg=*=*gpl*
2024-11-25 23:32:07 +00:00
erew123 72af6c2455 changed to ffmpeg-python>=0.2.0 2024-11-25 23:30:57 +00:00
erew123 a941cffcc0 Command-Line Arguments
7. **Command-Line Arguments**:
    - Accepts a `--tts_model` argument to bypass the interactive menu and directly set up a specific TTS engine
      on the first time start-up:
        - `piper`: Sets up the Piper TTS engine.
        - `vits`: Sets up the VITS TTS engine.
        - `xtts`: Sets up the XTTS TTS engine.
        - `none`: Skips model setup entirely.
2024-11-25 22:01:51 +00:00
erew123 19359f542b cmdline arguments for first run
**Command-Line Arguments**:
    - Accepts a `--tts_model` argument to bypass the interactive menu and directly set up a specific TTS engine
      on the first time start-up:
        - `piper`: Sets up the Piper TTS engine.
        - `vits`: Sets up the VITS TTS engine.
        - `xtts`: Sets up the XTTS TTS engine.
        - `none`: Skips model setup entirely.
2024-11-25 22:01:17 +00:00
erew123 9d319ecb3a added extra transcoding logging for debug 2024-11-25 16:30:52 +00:00
erew123 f16f6b9498 Correct passing latent:voice on narrator 2024-11-25 05:25:21 +00:00
erew123 856d67fe5b Updated firstrun better docker/colab support
In Docker or Google colab environments where people may not have access to a keyboard, just download piper (as its small) and dont wait the 60 seconds for a keypress.
2024-11-25 01:35:04 +00:00
erew123 50cafba12f Google colab detection fix 2024-11-25 00:33:37 +00:00
erew123 3d3047fb93 Update tts_server.py 2024-11-24 23:53:13 +00:00
erew123 883d8a82d0 Update script.py 2024-11-24 23:51:11 +00:00
erew123 a23dcf6de7 current_commit_sha correction 2024-11-24 23:36:56 +00:00
erew123 bb55313b9e Update README.md 2024-11-24 20:24:50 +00:00
erew123 c7cfed60fe Update README.md 2024-11-24 12:02:46 +00:00
erew123 eef198eae1 Merge pull request #417 from erew123/configrework
AllTalk Version 2 Complete
2024-11-24 11:59:55 +00:00
erew123 06b28c1ce7 Merge pull request #414 from Paladinium/configrework
Adding github action for CI
2024-11-24 11:49:45 +00:00
erew123 1c09bb985a lint 2024-11-24 11:49:21 +00:00
erew123 3cb30504e5 Try statement to capture missing imports
hopefully will catch those whom don't reinstall requirements
2024-11-24 11:30:03 +00:00
erew123 c0498ed8c9 Add files via upload 2024-11-24 11:14:00 +00:00
erew123 a5550bb254 script.py & tts_server.py updates 2024-11-24 11:12:15 +00:00
erew123 7909327f51 fix missing model logic 2024-11-24 06:18:24 +00:00
erew123 03c9d810ff fix missing model logic 2024-11-24 06:17:53 +00:00
erew123 e0621a97d6 Added JSON latents creation
- System automatically creates `.json` latent files alongside voice samples
    - Latents are voice characteristics extracted from audio
    - Generated on first use of a voice file
    - Stored next to original audio (e.g., `broadcaster_male.wav` → `broadcaster_male.json`)
    - Improves generation speed for subsequent uses
    - No manual management needed
2024-11-24 05:56:54 +00:00
erew123 11a116f54c small note 2024-11-24 05:01:19 +00:00
erew123 82894fe1ff tts-gen adds whisper version support 2024-11-24 02:20:00 +00:00
erew123 44d450a4b7 TTS-Diff Adds whisper version support 2024-11-24 02:19:11 +00:00
erew123 1ed7b860c5 XTTS Latents & Multi-voice folders 2024-11-22 19:44:50 +00:00
erew123 87cb4e2754 Correct Finetune CSS 2024-11-22 19:41:35 +00:00
erew123 bc3d9a6d4a Confirm upload vits 2024-11-22 19:31:39 +00:00
erew123 6d50941146 Update basediagnostics.log to current build 2024-11-22 19:30:19 +00:00
erew123 2edfd4f517 updated help content 2024-11-22 19:25:32 +00:00
erew123 ddbe382e67 scipy & plotly added 2024-11-22 19:24:56 +00:00
erew123 b8560779d1 scipy & plotly 2024-11-22 19:23:41 +00:00
erew123 acde395350 Update atsetup.bat Gradio 4.44.1 2024-11-22 19:20:42 +00:00
erew123 8ea93d35cf Update atsetup.sh Gradio 4.44.1 2024-11-22 19:20:08 +00:00
ekoc 94b4bad972 Adding github action for CI 2024-11-22 10:29:00 +01:00
erew123 925c73af63 Update help_content.py 2024-11-22 08:14:58 +00:00
erew123 73d3bc7495 Upload of NEW script.py & tts_server.py
Fully re-worked script.py and tts_server.py

### THIS IS THE BIG CHANGE COMMIT FOR V2 ###
2024-11-22 07:36:02 +00:00
erew123 85f204c3f1 Updates to Piper 2024-11-22 07:33:28 +00:00
erew123 1a5c10710d Updates to TTS Engines 2024-11-22 07:32:38 +00:00
erew123 7e73053fd7 Updated TTS Diff
Uses Whisper now
2024-11-22 06:59:55 +00:00
erew123 190ccd7551 Update requirements_standalone.txt 2024-11-22 06:59:16 +00:00
erew123 bcfcd1e469 Update requirements_colab.txt 2024-11-22 06:58:57 +00:00
erew123 4556b2b1c7 Delete system/gradio_pages/api_documentation.py
No Longer used
2024-11-22 06:57:31 +00:00
erew123 0cec908ada Delete system/gradio_pages/alltalk_welcome.py
No Longer used
2024-11-22 06:57:20 +00:00
erew123 10368fc5c0 Delete system/gradio_pages/alltalk_generation_help.py
No Longer used
2024-11-22 06:57:06 +00:00
erew123 d145da5ca2 Delete system/gradio_pages/alltalk_documentation.py
No Longer used
2024-11-22 06:56:46 +00:00
erew123 b6f4731df7 Delete system/gradio_pages/alltalk_about.py
No Longer used
2024-11-22 06:56:30 +00:00
erew123 cf3381c512 Updated Help/Welcome screen 2024-11-22 06:54:12 +00:00
erew123 24dc04b167 Delete system/config/at_configupdate.json 2024-11-22 06:53:02 +00:00
erew123 cbe02ff8d1 Delete system/config/at_configdowngrade.json 2024-11-22 06:52:52 +00:00
erew123 37c46a91f3 Delete system/config/AllTalk API Process.png
No Longer used
2024-11-22 06:52:31 +00:00
erew123 4190269d29 Delete system/at_sounds directory
No longer used
2024-11-22 06:51:58 +00:00
erew123 9e7a785303 Add default_config_path
Added default_config_path & set debug_narrator = False
2024-11-20 01:15:10 +00:00
erew123 fff2fac88d Updated config.py 2024-11-20 00:50:19 +00:00
erew123 18b580db04 Delete system/TGWUI Extension directory
Had to change dir to TGWUI_Extension to support import via script.py
2024-11-20 00:49:31 +00:00
erew123 c13dd9ddd7 Updated TGWUI Remote Extension
Updates:
- Fully re-worked
- Behaves as both a remote extension & the TGWUI code for script.py to import
- Added RVC pitch support
- Config will be central OR JSON file depending how the script is run/imported
2024-11-20 00:48:43 +00:00
erew123 cea89ddb45 Re-work of core system files
Updated:
- script.py
- tts_server.py
- test_server.py (used to test the AllTalk server endpoints)
2024-11-20 00:46:02 +00:00
erew123 eea4bbf4da Merge pull request #395 from Paladinium/alltalkbeta_config_refactoring
Adding config classes and tests
2024-11-18 22:25:28 +00:00
ekoc 13aff24e0b Use config classes for firstrun and welcome 2024-11-17 16:00:54 +01:00
erew123 8f871a0601 Final Commit to ST
https://github.com/SillyTavern/SillyTavern/pull/3060
2024-11-17 12:34:18 +00:00
erew123 ac24e5fc9a Added debugging to Training section 2024-11-17 04:38:46 +00:00
erew123 f8c9c58d67 clarify some language in the help content 2024-11-17 00:00:41 +00:00
erew123 9a2b4309a5 Custom dataset - ensure lang set
When using custom datasets that are not built within finetune, ensure lang.txt is read correctly.
2024-11-16 23:51:56 +00:00
erew123 80dd102da8 Fix Dataset Validation when no errors found
Fixes an issue where the dataframe errors if no transcription errors found.
Added debugging option for dataset validation
2024-11-16 15:49:41 +00:00
erew123 f938f83131 Update README.md 2024-11-16 05:28:27 +00:00
erew123 6df2b6eeb4 Delete training_metrics.png 2024-11-16 05:10:56 +00:00
erew123 af1cab8676 Moved metrics_logger.py
moved into trainer_alltalk folder
2024-11-16 05:10:37 +00:00
erew123 adc9bb8cc6 Lint clean & documentation
Cleaned finetune lint
Moved documentation out
Moved metrics logger
2024-11-16 05:09:48 +00:00
ekoc 4d12520801 Fixing some bugs 2024-11-15 21:08:08 +01:00
ekoc 8bc14d7692 Using config classes just for tts_server.py as 1st step 2024-11-15 20:17:04 +01:00
ekoc 80ad19fbe2 Merge tts_engines.json and new_engines.json in config classes 2024-11-15 10:02:16 +01:00
ekoc f07ad31212 Extend AlltalkTTSEnginesConfig 2024-11-15 10:02:16 +01:00
ekoc 1e4e18f977 Adding gradio_pages to config.py 2024-11-15 10:02:16 +01:00
ekoc 37e665c5d8 Adding file lock and backup 2024-11-15 10:02:11 +01:00
ekoc 521e60739b Adding file change check and moving code to abstract class 2024-11-15 10:00:26 +01:00
ekoc 61f24cf6b0 Adding config classes and tests 2024-11-15 10:00:26 +01:00
erew123 b538564da6 Update to use openai-whisper 2024-11-15 00:40:02 +00:00
erew123 5c4726de96 New Finetune
added subprocess
2024-11-15 00:38:43 +00:00
erew123 2e2714548f Update requirements_textgen.txt 2024-11-15 00:34:12 +00:00
erew123 17b9481fff Update requirements_textgen.txt 2024-11-15 00:26:09 +00:00
erew123 6383b1a134 rem faster-whisper add openai-whisper
Removed:
nvidia-cublas-cu11>=11.11.3.6
nvidia-cudnn-cu11>=9.1.1.17
faster-whisper>=1.0.3

Added:
openai-whisper
2024-11-15 00:25:34 +00:00
erew123 a9433f23f3 Update README.md 2024-11-15 00:23:12 +00:00
erew123 22f3eb01e5 Update README.md 2024-11-15 00:22:49 +00:00
erew123 1bd8f6aed9 New Finetune for XTTS
Interface cleaned
Documentation improved & expanded
Dataset generation improved:
- Better VAD detection
- Better debugging/information
- Better editing/managing transcriptions
- Basic audio editing
- Re-transcription on detections of duplicate audio when splitting large files.
- Control over model precision fp16/fp32/mixed
- Migrate to openai-whisper (also saving 1.5GB on installation requirements for cublas)
Testing stage allows you to choose what minimum length audio
Model export exports all audio with text file descriptions of too long/too short
Misc other improvements too numerous to mention
2024-11-15 00:21:40 +00:00
erew123 9df1065be0 Update README.md 2024-11-11 14:19:16 +00:00
erew123 029e5dd1b9 Update README.md 2024-11-11 14:12:13 +00:00
erew123 4aa4493cc5 Clearer messages commit correction 2024-11-11 11:35:59 +00:00
erew123 5a3a20dcba Clearer message on missing model files 2024-11-11 11:33:40 +00:00
erew123 73c8c71be9 Clearer messages 2024-11-11 11:23:09 +00:00
erew123 80821081fb Update README.md 2024-11-11 05:14:09 +00:00
erew123 20361d4a0c Update README.md 2024-11-11 05:04:25 +00:00
erew123 4d512f4677 Built in Server version selection 2024-11-10 19:42:38 +00:00
erew123 51e0b21682 Improvements Dataset Management & Wav files.
Logging and console/terminal output may need some work correcting in future,
2024-11-10 17:25:02 +00:00
erew123 07053f8076 Update README.md 2024-11-09 00:27:29 +00:00
erew123 79e8e49d06 Update README.md 2024-11-09 00:25:05 +00:00
erew123 e7a8fff709 Update README.md 2024-11-09 00:24:34 +00:00
erew123 398de26248 Update script.py 2024-11-08 20:33:59 +00:00
erew123 e0527ca8a3 Update legacy API Saving 2024-11-08 20:33:23 +00:00
erew123 c2e1095bb8 add gradio page section 2024-11-08 20:14:56 +00:00
erew123 03148509e4 Update for Coqui 0.24.3 2024-11-06 01:43:14 +00:00
erew123 bfe14f3524 Update for Coqui 0.24.3 2024-11-06 01:42:08 +00:00
erew123 8536eae276 Update for Coqui 0.24.3 2024-11-06 01:41:39 +00:00
erew123 67693f66e0 Update for Coqui 0.24.3 2024-11-06 01:41:22 +00:00
erew123 590eb23e78 add UNetT import 2024-11-05 10:25:32 +00:00
erew123 1b4e982955 add back setup routine 2024-11-05 10:22:50 +00:00
erew123 5a81e4818b Add support for the E2 model to F5-TTS 2024-11-05 10:19:45 +00:00
erew123 1a5945235d F5-TTS Unload model correct tab 2024-11-05 09:51:50 +00:00
erew123 88c97ea700 Update README.md 2024-11-05 08:04:01 +00:00
erew123 d593bfe52e Gituhub check on alltalkbeta branch on start 2024-11-05 07:57:05 +00:00
erew123 0e61d0aa24 Added F5-TTS engine 2024-11-05 00:15:04 +00:00
erew123 834f7a4454 Added F5-TTS engine 2024-11-05 00:12:44 +00:00
erew123 a8ed41a53b text correction 2024-11-05 00:04:43 +00:00
erew123 2c2c31ef09 F5-TTS final updates 2024-11-05 00:03:47 +00:00
erew123 75a3b68551 Update tts_server.py close warning on line 42 2024-11-04 22:47:02 +00:00
erew123 5d43b23eb7 F5-TTS Engine/Settings changes 2024-11-04 22:27:19 +00:00
erew123 bcd84a4c20 Setting for float16
# Set Parler Precision. Options are:
        #     "float32" (full precision)
        #     "float16" (half precision)
        #     "bfloat16" (brain floating point)
2024-11-03 20:24:24 +00:00
erew123 a56a2bae5c f5tts - still a work in progress
Just uploading this so I have a reference point in time that I wont lose.
2024-11-03 15:11:50 +00:00
erew123 82f4c29c7d f5tts requirements file 2024-11-03 13:12:16 +00:00
erew123 8e466ee119 Update tts_server.py 2024-11-03 12:57:43 +00:00
erew123 6ba6549f0f Audio Sample Text reference for F5-TTS engine 2024-11-03 11:39:50 +00:00
erew123 630cc61057 Update README.md 2024-10-31 17:09:43 +00:00
erew123 99f36bd4fa Merge pull request #383 from Paladinium/alltalk_beta_rvc_cache
Introduce LRU cache for RVC
2024-10-31 16:57:26 +00:00
erew123 d7ac6c401a Merge pull request #393 from UXVirtual/rvc-tts-server-fix
Fix for missing pitch when calling run_rvc OpenAI endpoint
2024-10-31 15:52:44 +00:00
Michael Andrew 7dd2fd836c Fix for missing pitch when calling run_rvc
- Adds the missing pitch argument when calling `run_rvc()`. Previously this was failing when RVC was enabled and TTS was generated using the OpenAI compatible API interface.
2024-11-01 01:30:56 +13:00
erew123 ac884fa10c Update requirements_textgen.txt 2024-10-31 09:14:18 +00:00
erew123 afc9543f6d Update requirements_colab.txt 2024-10-31 09:14:00 +00:00
erew123 f4ac29699a Update requirements_standalone.txt 2024-10-31 09:13:41 +00:00
erew123 0c9034c1f3 Docker bits
Update to gradio interface to be able to set the API address when used within docker.
2024-10-27 01:35:46 +01:00
erew123 75db4f6340 Dropped back Faiss. Should be fixed 2024-10-22 23:01:03 +01:00
erew123 dc2b5dc2fb Locked pytorch::faiss-cpu=1.9.0=py3.11_h491596c_0_cpu
Because Facebook messed up the installer on the next release, so locked to version pytorch::faiss-cpu=1.9.0=py3.11_h491596c_0_cpu for now
2024-10-22 22:10:12 +01:00
erew123 d6fa4103f9 Update atsetup.bat 2024-10-21 15:23:18 +01:00
erew123 bb314fa60d minor additions
Close GPTTrainerConfig( on line 965
analytics_enabled=False for Gradio (stop it complaining about new versions of Gradio)
demo.queue().launch( line 2387 to launch Gradio.
2024-10-20 07:26:30 +01:00
erew123 fbffe0ac47 Merge pull request #288 from IIEleven11/alltalkbeta
Finetuning update re PR 288
2024-10-20 07:18:01 +01:00
ekoc 362683a645 Introduce LRU cache for RVC 2024-10-18 09:21:15 +02:00
erew123 ad239e9815 Update requirements_colab.txt 2024-10-17 06:53:49 +01:00
erew123 a33e05ea01 Update alltalk_welcome.py 2024-10-16 08:04:24 +01:00
erew123 55a9353a55 Add files via upload 2024-10-16 07:58:11 +01:00
erew123 23d813021b Update xtts_settings_page.py 2024-10-16 07:57:30 +01:00
erew123 5ced67d5ee Update vits_settings_page.py 2024-10-16 07:57:10 +01:00
erew123 b19b6f9f48 Update piper_settings_page.py 2024-10-16 07:56:52 +01:00
erew123 97ddb39218 Update parler_settings_page.py 2024-10-16 07:56:32 +01:00
erew123 f4590d5245 quieten gradio 2024-10-16 07:55:49 +01:00
erew123 37941ab114 Links to WIKI on splashscreen 2024-10-15 07:52:08 +01:00
erew123 ecb4e6b35e Update basediagnostics.log 2024-10-14 20:26:26 +01:00
erew123 2f77da7110 Update atsetup.sh 2024-10-14 19:39:42 +01:00
erew123 33de756042 Update atsetup.bat 2024-10-14 19:38:16 +01:00
erew123 e65187e474 Update atsetup.bat 2024-10-14 19:28:43 +01:00
erew123 7a6061491d Update README.md 2024-10-14 00:42:11 +01:00
erew123 4ffc975b13 Update README.md 2024-10-14 00:23:28 +01:00
erew123 d118ef1efb Merge pull request #366 from Calajese/alltalkbeta
Use correct slash on atsetup.sh
2024-10-10 22:07:02 +01:00
Calajese d084abc113 Use correct slash on atsetup.sh 2024-10-10 07:25:08 +00:00
erew123 0c5e1c44c8 Fix Linux GUI issue 2024-10-04 11:32:52 +01:00
erew123 0c95094892 Update README.md 2024-10-02 20:34:38 +01:00
erew123 a8311005aa Better handling of tts_engines.json in corrupt/missing scenario 2024-10-02 00:19:37 +01:00
erew123 471c67dd3a Update README.md 2024-10-01 15:07:10 +01:00
erew123 76a50cf47f Note re Hindi support on XTTS
Hindi support only works on XTTS model 2.0.3 and must use the API method (load it as APITTS) in the Generate window of the Gradio interface.
2024-10-01 14:50:52 +01:00
erew123 75e753d235 Update README.md 2024-10-01 12:17:25 +01:00
erew123 0bec11ebd2 Update README.md 2024-10-01 12:03:03 +01:00
erew123 40911c6453 Update README.md 2024-09-29 00:21:33 +01:00
erew123 31b7456744 Update README.md 2024-09-29 00:18:55 +01:00
erew123 45af56393e Update diagnostics.py 2024-09-28 21:32:21 +01:00
erew123 1d61d1552d Added diagnostics instructions 2024-09-28 14:14:57 +01:00
erew123 f2abd0d5a8 Add files via upload 2024-09-28 13:14:06 +01:00
erew123 9d59eb15c8 added other checks 2024-09-28 13:13:49 +01:00
erew123 5e12e4ae24 resolve flask[async] import on first run 2024-09-27 22:05:30 +01:00
erew123 be392cee00 Added compare
You can now compare a base standalone installation with your diagnostic file and match versions.
2024-09-27 21:56:08 +01:00
erew123 18b1d49b72 Base diagnostics log file for the diagnostics.
Updating the diagnostics to compare peoples diagnostics with a base diagnostic log file, in the hope it simplifies issues.
2024-09-27 21:43:57 +01:00
erew123 fb6c9f65af Update README.md 2024-09-25 14:36:34 +01:00
erew123 a280c38a81 Added manual Windows env creation inst 2024-09-25 14:33:51 +01:00
erew123 c2a175f005 More verbose error messages 2024-09-24 09:48:08 +01:00
erew123 dbba59ef0b Update atsetup.bat 2024-09-24 09:05:24 +01:00
erew123 f1464ec29d Fixed Regenerate with RVC 2024-09-22 13:30:17 +01:00
erew123 9ba7f2e454 Add files via upload 2024-09-22 13:17:11 +01:00
erew123 d66e461f8a Added Pitch settings to RVC 2024-09-22 12:50:13 +01:00
erew123 16a78a90ef Preview Voice supports RVC now 2024-09-22 10:07:27 +01:00
erew123 e534cedc62 Add RVC Voice & Pitch selection
Preview also supports RVC
2024-09-22 10:05:46 +01:00
erew123 efb59a071f Update README.md 2024-09-21 22:45:37 +01:00
erew123 db0171da55 Delete mem_load_test.py 2024-09-21 22:15:02 +01:00
erew123 372aa493d6 MEM Updated
Adds:

- Queue viewer
- Additional Endpoints
- Load Tester
- Updated documentation
2024-09-21 22:14:29 +01:00
IIEleven11 aafae8da82 Fixed slurred speech by freezing all layers but the two embedding layers 2024-09-19 21:11:31 -07:00
IIEleven11 2e56cc91f3 Merge branch 'erew123:alltalkbeta' into alltalkbeta 2024-09-19 20:52:40 -07:00
erew123 c6cf8afce3 Document rvccharacter_pitch 2024-09-19 08:53:25 +01:00
erew123 375b2ba31e path correction 2024-09-18 07:31:55 +01:00
erew123 e36c67efe4 Add files via upload 2024-09-18 01:35:36 +01:00
erew123 bb26cb8f28 MEM updated w/Queue system & Load Tester
Is there an in-built queue system to handle different requests to different loaded engines?
A: MEM incorporates a built-in queue system to manage multiple TTS requests across loaded engine instances:

All TTS requests are received through the API port (default: 7401).
The queue system distributes incoming requests among available TTS engine instances.
If all engines are busy, new requests are held in a queue until an engine becomes available.
The system continuously checks for available engines to process waiting requests.
If a request cannot be processed within the allocated time, it will be marked as failed.
This queue system aims to balance the load across all running engines efficiently. Advanced features for queue management and dynamic timeout calculations are available and can be configured in the MEM settings.

Note: As this is a research and testing implementation, its performance in high-load or production environments is not guaranteed. For load testing, you can use the provided mem_load_test.py script to simulate multiple simultaneous requests.

To use the load testing tool: `python mem_load_test.py --requests [number_of_requests] --length [text_length] --url "http://127.0.0.1:7501/api/tts-generate"`
2024-09-18 01:09:20 +01:00
erew123 e68ec7d733 add settings mgmt 2024-09-17 11:40:01 +01:00
erew123 37be9472ca Update tts_server.py 2024-09-16 21:54:25 +01:00
erew123 8dbb64c683 Added TTS_mem - Multi Engine Manager
AllTalk MEM (Multi Engine Manager) is a research tool designed to manage and test multiple instances of different Text-to-Speech (TTS) engines being loaded simultaneously, with a view to a centralised engine being able to handle multiple requests simultaneously. AllTalk MEM is currently in a demonstration, testing, and experimental phase.

⚠️ MEM is not intended for production use at this time and there is NO support being offered on MEM. ⚠️
2024-09-16 18:43:56 +01:00
erew123 6f75fe1c28 Updated messages within the install routines. 2024-09-15 13:29:21 +01:00
erew123 a1b22c4ca1 Merge pull request #344 from GenericMale/fix-openai-fields
Fix optional fields in OpenAI API
2024-09-14 18:45:37 +01:00
GenericMale 24e6076b40 fix: use sys.executable for subprocess calls 2024-09-13 19:10:52 +02:00
GenericMale cf3635ea48 fix(openai-api): KeyError when response_format or speed omitted 2024-09-13 19:09:07 +02:00
erew123 7f98ef3905 Update requirements_colab.txt 2024-09-13 16:21:47 +01:00
erew123 3d9d10a456 Set FastAPI to 0.112.2
Gradio is still having issues with later version of FastAPI
2024-09-13 16:21:11 +01:00
erew123 8ae881e3b0 Pushed back in Cutlett and Fugashi 2024-09-10 12:40:43 +01:00
erew123 57a6b3ba39 Add note & double setting firstrun false
Added an additional note to the first run splash screen to explain additional models/engines are managed in the gradio interface.
Doubled the effort to mark first time run has been completed.
2024-09-10 11:35:33 +01:00
erew123 da7ecfbb6b SillyTavern Note Added
Added notes on changing the IP/URL and basic details on how to debug/clear out older settings.
2024-09-10 10:42:56 +01:00
erew123 341984315d Update README.md 2024-08-30 13:11:31 +01:00
erew123 d105ca02a5 Update README.md 2024-08-30 13:09:53 +01:00
erew123 b7aa3a7c5c Multi audio sample TTS generation w/XTTS
🟧 Using Single Voice Samples
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.

🟧 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.

     • Each subfolder should reflect the name or type of the voice it contains (e.g., female_voice, male_voice).
     • The voice samples inside each subfolder should follow the standard .wav format.
     • An example folder path would be `/alltalk_tts/voices/mynewvoice/` and this would be listed in the available voices list as `mynewvoice/`.

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/`.
2024-08-30 12:55:06 +01:00
erew123 5cb09eb813 Add files via upload 2024-08-28 12:59:28 +01:00
erew123 c267bb198e Update requirements_colab.txt 2024-08-28 12:49:12 +01:00
erew123 28cb6ca3f0 Update requirements_textgen.txt 2024-08-28 12:48:58 +01:00
erew123 9a0896f692 Update requirements_standalone.txt 2024-08-28 12:48:50 +01:00
erew123 d76b6c2903 Remove continue training 2024-08-28 12:48:27 +01:00
erew123 c66fcee5e1 remove ping_trainingrun 2024-08-28 12:36:51 +01:00
erew123 84db50fc18 Update requirements_textgen.txt 2024-08-24 13:36:56 +01:00
erew123 e5afa958cb Update requirements_standalone.txt 2024-08-24 13:35:34 +01:00
erew123 4775d0db34 work around locked drive letters 2024-08-24 13:30:02 +01:00
erew123 0a1a81a962 Add files via upload 2024-08-21 09:14:53 +01:00
erew123 7e6a972198 Update README.md 2024-08-15 20:06:08 +01:00
erew123 2bc0660770 Update atsetup.bat 2024-08-15 19:55:04 +01:00
erew123 4c016a49a3 Update atsetup.sh 2024-08-15 19:54:15 +01:00
erew123 cf625469f5 Update atsetup.bat 2024-08-15 19:37:12 +01:00
erew123 a1452bf0b7 Upload Parler requirements as a seperate
Parler have updated parts of their script and the requirements cause issues if used with other requirements files as they are too restrictive.
2024-08-15 19:34:23 +01:00
erew123 458b0c38f2 Update requirements_standalone.txt 2024-08-15 19:28:29 +01:00
erew123 2a40143eca Update requirements_colab.txt 2024-08-15 19:28:17 +01:00
erew123 61f36d5b0d Update requirements_textgen.txt 2024-08-15 19:28:02 +01:00
erew123 cc5a665ad6 Update requirements_standalone.txt 2024-08-15 18:27:40 +01:00
erew123 633e14d153 Add files via upload 2024-08-13 13:34:20 +01:00
IIEleven11 9a177c5a9c Merge branch 'erew123:alltalkbeta' into alltalkbeta 2024-08-11 05:05:26 -07:00
erew123 a8ec5e19ce Attempt locale-independent float value.
Attempt to resolve suspicion that some OS/Language character sets may be using a comma for decimal separation, rather than a period e.g. `10,0` vs `10.0`

This could be affecting the repetition penalty setting with XTTS when called from a command line/terminal request where the period `.` isnt being specifed.
2024-08-10 09:59:48 +01:00
erew123 a40c7a7729 Allow zh and zh-cn 2024-08-09 13:08:02 +01:00
erew123 c1c7b8cf65 Updated Parler to the v1 model (mini and large available) 2024-08-09 10:32:47 +01:00
erew123 df764f71ef update Parler model to v1 mini 2024-08-09 08:46:05 +01:00
erew123 1f0cf09822 Update requirements_colab.txt 2024-08-09 08:36:29 +01:00
erew123 526e71a46e Update requirements_textgen.txt 2024-08-09 08:35:59 +01:00
erew123 569b4a7403 PIP requirements. Merge pull request #301 from IIEleven11/cloud_instance
Update requirements_standalone.txt
2024-08-09 08:33:48 +01:00
IIEleven11 4494ef24c0 Update requirements_standalone.txt
Not sure what happened but all of a sudden this stopped working. I chased the dep issues down and fixed the wildcard * with >< operators issue
2024-08-09 00:21:13 -07:00
IIEleven11 8b373d50dc Merge branch 'erew123:alltalkbeta' into alltalkbeta 2024-08-09 00:18:24 -07:00
erew123 cf93ef1de0 Merge pull request #299 from bmalaski/fixexport
BUGFIX: Exporting Model after Restart
2024-08-08 08:38:12 +01:00
Bryant21 98d4d4fd25 BUGFIX: Exporting Model after Restart 2024-08-07 23:38:41 -04:00
IIEleven11 c6b7b39218 Merge branch 'erew123:alltalkbeta' into alltalkbeta 2024-08-06 23:01:58 -07:00
erew123 2560c29771 Updated dropdown size after Distil added 2024-08-04 18:54:06 +01:00
erew123 0be7eae436 Merge pull request #295 from bmalaski/distiled
Add distil-large-v3 for dataset creation
2024-08-04 18:52:49 +01:00
Bryant21 6b43c40a8c Update finetune.py 2024-08-04 13:33:53 -04:00
Bryant21 94c9257dee change default to distil 2024-08-04 13:27:42 -04:00
Bryant21 eaf38309a2 Update finetune.py 2024-08-04 13:22:51 -04:00
IIEleven11 44bd45a624 Fixed merge of vocab.json and new tokenizer for custom dataset
Fixed vocab.json merge, new tokenizer for custom dataset, dataset cleaner.
2024-08-02 21:40:23 -07:00
IIEleven11 9047dcb139 removed unecessary scripts and finetune.py edit 2024-08-01 00:07:46 -07:00
IIEleven11 7e2d3455d2 removed unecessary scripts and finetune.py edit 2024-08-01 00:05:42 -07:00
IIEleven11 d44d721d69 Tokenizer changes 2024-07-31 18:30:47 -07:00
erew123 bf68a89c11 /api/openai-voicemap API endpoint
Can call /api/openai-voicemap with 

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\"}"

Caveats:

- You have to update all the voices in one go, not just one voice.
- Its up to you to ensure you have the correct voices for the TTS engine that's loaded in which you can find currently available on /api/voices
- The in-memory mappings will update, but Gradio will have cached what was originally in the settings, so it wont display the changes in the Gradio interface without a restart of AllTalk/Gradio
2024-07-28 08:52:00 +01:00
erew123 5257497b57 Notes/warning on docker like environments 2024-07-27 09:17:20 +01:00
erew123 6fac1aa5f9 Additional Instructions. 2024-07-27 09:05:03 +01:00
erew123 4c97c83d25 Added additional instructions 2024-07-27 08:46:29 +01:00
erew123 61e6c2c105 downgrade pip version
python -m pip install --upgrade "pip<24.1"

Due to how the new pip handles requirements
2024-07-27 07:40:19 +01:00
erew123 0755aa033b googlecolab downgrade pip
python -m pip install --upgrade "pip<24.1"
2024-07-27 07:38:38 +01:00
erew123 fe44f3608a atsetup.bat silent install option
-silent command line switch.
2024-07-26 07:44:55 +01:00
erew123 f1c53866ba Czech & Turkish character set 2024-07-22 09:42:22 +01:00
erew123 a9fc8699d8 Extend base API config for Czech & Turkish 2024-07-22 09:01:45 +01:00
erew123 e63b882e52 Extend admin.html character set for TTS 2024-07-21 18:35:35 +01:00
erew123 21064be53a Update finetune.py 2024-07-21 18:10:56 +01:00
erew123 c03ab37dd2 Finetune - Allow number of workers selection 2024-07-21 17:31:52 +01:00
erew123 b03e08405e Update clipboard-to-tts.py 2024-07-17 13:41:38 +01:00
erew123 c31e1f68b5 Update instructions.txt 2024-07-16 16:25:47 +01:00
erew123 d542e6ba14 Clipboard to TTS
A very rough bit of code for Windows to generate TTS from any text sent to the WINDOWS clipboard with Ctrl+C
2024-07-16 16:21:40 +01:00
erew123 0f26ca4bbf API address changes apply correctly 2024-07-13 21:49:37 +01:00
erew123 16152fe135 Added trainer to requirements 2024-07-13 07:19:19 +01:00
erew123 f03f359f41 Merge pull request #255 from bmalaski/alltalkbeta_enhancements
Alltalkbeta enhancements - Finetuning
2024-07-13 07:11:22 +01:00
erew123 e40470fbea Improve diags on systems with no CUDA 2024-07-05 08:31:40 +01:00
bmalaski d5c20262a8 Update WarmUpScheduler.py 2024-07-04 22:18:28 -04:00
bmalaski 6a992cb8f4 Update WarmUpScheduler.py 2024-07-03 09:59:25 -04:00
bmalaski e347f15046 add warmup 2024-07-02 00:14:54 -04:00
erew123 41a059e517 Add files via upload 2024-07-01 09:56:09 +01:00
erew123 797a4b996a Update finetune.py 2024-07-01 08:32:56 +01:00
bmalaski e081442bf3 Update finetune.py 2024-06-25 15:49:20 -04:00
erew123 bccd7ee971 Update README.md 2024-06-24 09:27:58 +01:00
erew123 4cba3af3b5 Add files via upload 2024-06-22 16:02:12 +01:00
erew123 f016c6cd90 add condition on message 2024-06-22 15:17:12 +01:00
erew123 da767a5472 Update requirements_colab.txt 2024-06-22 14:51:40 +01:00
erew123 633113f909 Update requirements_textgen2.txt 2024-06-22 14:51:25 +01:00
erew123 45e3ed9237 Update requirements_standalone.txt
added Pillow
2024-06-22 14:51:06 +01:00
bmalaski a97ad658c1 ported changes form original branch 2024-06-20 22:54:57 -04:00
bmalaski 062483df1a start merge 2024-06-20 13:56:31 -04:00
erew123 92ce5e24bc Update some error messages for Streaming. 2024-06-19 11:08:48 +01:00
erew123 b32c68df29 update default pitch 2024-06-17 20:59:16 +01:00
erew123 84312bb6b4 RVC Pitch on API
adds RVC pitch to the API and generate screen.
Still need to update TGWUI, SillyTavern Extensions along with documentation.
2024-06-17 11:42:54 +01:00
erew123 6f4bec7ab2 Extended TTS generation timeout in Gradio
extended the timeout to await a TTS generation response, just to help with Google colab
2024-06-13 12:21:08 +01:00
erew123 6f75ab9f60 WIP Google Colab workbook
This is a work in progress. There are issues to address:
- RVC does not work yet.
- There is a stutter on the 1st TTS generation.
- Transcoding damages the file in some way (seems to be a colab specific issue)
- First model selection and other configuration settings may need to be pre-set.
- Long TTS generations can timeout in Gradio interface, hence should be run on at least a T4 runtime.
2024-06-13 12:18:41 +01:00
erew123 50f335255e Data validation/missing files printout @ console 2024-06-13 10:38:23 +01:00
erew123 037d774f2c Update re Google Colab/DeepSpeed compile
DeepSpeed needs to compile the first time it loads in and a longer wait time is required for the 1st model load with DeepSpeed
2024-06-12 17:13:18 +01:00
erew123 465afd57c8 Accordion on the main Generate screen 2024-06-12 15:35:25 +01:00
erew123 af97384003 Changed a bit of documentation. 2024-06-12 15:21:23 +01:00
erew123 6aa7a182d1 Update atsetup.bat
removed conda log level
2024-06-12 14:32:18 +01:00
erew123 279dd54694 Update the TGWUI Extension
Github is doing something very strange here and shows my file being uploaded 2x, even though I double checked I had selected only the 1x file. Hopefully this doesnt break things
2024-06-12 14:19:57 +01:00
erew123 7fc89885eb Update to deal with TGWUI loading. 2024-06-12 14:04:17 +01:00
erew123 646c615ccf Update confignew.json 2024-06-12 13:01:33 +01:00
erew123 2a87d2d662 Updated numbering, added validation
Updated the numbering of generated wav's so they match within the CSV files.
Added a dataset validation option to compare the Whisper generated wav files vs the transcribed text in the CSV files. This is purely to point you in the direction of data that may need changing/editing within your training dataset.
2024-06-12 11:01:06 +01:00
erew123 cf9b736da3 added word2number 2024-06-12 10:58:41 +01:00
erew123 411b93f55c Prep for Google Colab 2024-06-11 10:19:00 +01:00
erew123 bc0ebc03a6 Removed ryan high and medium
Both those models have issues with generation https://github.com/rhasspy/piper/issues/128
2024-06-11 10:18:17 +01:00
erew123 8b016533c4 initial google colab requirements test 2024-06-10 22:35:51 +01:00
erew123 07ec2325cc Update README.md 2024-06-10 22:23:23 +01:00
erew123 3029319c68 Create .gitignore 2024-06-10 22:16:38 +01:00
erew123 475546133b Delete .gitignore 2024-06-10 22:14:57 +01:00
erew123 af0bb11c4e Path normalisation when splitting files 2024-06-10 21:47:01 +01:00
erew123 6a840a591c Updated diagnostics
Added some extra info and automatic selection/timeout of requirements files.
2024-06-10 16:23:11 +01:00
erew123 e86109aa14 Gradio over LAN access 2024-06-10 10:31:38 +01:00
erew123 1d81376097 Update confignew.json 2024-06-07 09:25:45 +01:00
erew123 eb4dabbbf4 Update README.md 2024-06-06 23:36:54 +01:00
erew123 b1bc5b1825 Update README.md 2024-06-06 23:36:06 +01:00
erew123 c2077f03ca Update README.md 2024-06-06 23:30:31 +01:00
erew123 073aa403f2 Update README.md 2024-06-06 23:29:24 +01:00
erew123 4a10a6659b Update README.md 2024-06-06 23:26:46 +01:00
erew123 ff6d0ae695 Update README.md 2024-06-06 23:25:22 +01:00
erew123 f3ea73dec9 Add files via upload 2024-06-06 22:55:57 +01:00
erew123 493a603542 Update tts_engines.json 2024-06-06 22:51:03 +01:00
erew123 8538b96cd2 Add files via upload 2024-06-06 22:41:01 +01:00
erew123 ba76cb24ce Update README.md 2024-06-06 22:32:14 +01:00
erew123 d74c1ecd60 Update README.md 2024-06-06 22:31:45 +01:00
erew123 1631caf1e8 Update README.md 2024-06-06 22:24:59 +01:00
erew123 e2788cac1e Update README.md 2024-06-06 22:23:39 +01:00
erew123 762ca1e427 upload ffmpeg 2024-06-06 22:16:54 +01:00
erew123 f12e6e80a7 Add files via upload 2024-06-06 21:53:45 +01:00
erew123 9fd928f6e7 initial upload attempt
initial upload attempt
2024-06-06 21:40:12 +01:00
erew123 84c19ed5a9 Delete voices/arnold.wav 2024-06-06 21:22:18 +01:00
erew123 862fe96003 Update README.md 2024-06-06 21:17:21 +01:00
erew123 98a74e9625 Add files via upload 2024-06-06 21:12:17 +01:00
erew123 0dbff4786f Update README.md 2024-06-06 17:05:46 +01:00
erew123 e10f713283 Delete diagnostics.py 2024-06-06 15:28:05 +01:00
erew123 e65b262116 Delete atsetup.bat 2024-06-06 15:27:52 +01:00
erew123 5cc57254b7 Delete atsetup.sh 2024-06-06 15:27:45 +01:00
erew123 8b9a0b8b45 Delete confignew.json 2024-06-06 15:27:38 +01:00
erew123 51b5a95563 Delete tts_server.py 2024-06-06 15:27:29 +01:00
erew123 9e45aded81 Delete script.py 2024-06-06 15:27:22 +01:00
erew123 8c71ce67fe Delete nvidia.Dockerfile 2024-06-06 15:27:14 +01:00
erew123 38b06e6f63 Delete modeldownload.py 2024-06-06 15:27:07 +01:00
erew123 f3fa28f84b Delete modeldownload.json 2024-06-06 15:27:00 +01:00
erew123 cbe8d813a9 Delete launch.sh 2024-06-06 15:26:52 +01:00
erew123 3c123d3678 Delete finetune.py 2024-06-06 15:26:43 +01:00
erew123 fc22fb8add Delete dockerconfig.json 2024-06-06 15:26:36 +01:00
erew123 6ee7362b46 Delete docker-compose.yml 2024-06-06 15:26:28 +01:00
erew123 a518f86eab Delete docker-compose-cuda.yml 2024-06-06 15:26:18 +01:00
erew123 43ec92eb07 Delete Dockerfile 2024-06-06 15:25:52 +01:00
erew123 ddf965aee3 Delete .gitignore 2024-06-06 15:25:44 +01:00
erew123 f32feedc1f Delete system directory 2024-06-06 15:25:24 +01:00
586 changed files with 64310 additions and 11920 deletions

No files matched your search

@@ -1,6 +1,6 @@
--- ---
name: Support Request/Issue name: Support request OR Bug report
about: Use this to create a support request or report a bug/issue about: Create a report to help us improve
title: '' title: ''
labels: '' labels: ''
assignees: '' assignees: ''
-1
View File
@@ -1 +0,0 @@
blank_issues_enabled: false
+1 -4
View File
@@ -1,15 +1,12 @@
--- ---
name: Feature request name: Feature request
about: Use this to create a Feature request about: Suggest an idea for this project
title: '' title: ''
labels: '' labels: ''
assignees: '' assignees: ''
--- ---
**Please confirm you have read the current Features request list**
https://github.com/erew123/alltalk_tts/discussions/74
**Is your feature request related to a problem? Please describe.** **Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
+33
View File
@@ -0,0 +1,33 @@
---
name: Support request OR Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
🔴 If you have installed AllTalk in a custom Python environment, I will only be able to provide limited assistance/support. AllTalk draws on a variety of scripts and libraries that are not written or managed by myself, and they may fail, error or give strange results in custom built python environments.
🔴 Please generate a diagnostics report and upload the "diagnostics.log" as this helps me understand your configuration.
https://github.com/erew123/alltalk_tts/tree/main?#-how-to-make-a-diagnostics-report-file
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behaviour:
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Text/logs**
If applicable, copy/paste in your logs here from the console.
**Desktop (please complete the following information):**
AllTalk was updated: [approx. date]
Custom Python environment: [yes/no give details if yes]
Text-generation-webUI was updated: [approx. date]
**Additional context**
Add any other context about the problem here.
-73
View File
@@ -1,73 +0,0 @@
name: 'Setting up docker'
inputs:
DOCKERHUB_USERNAME:
description: "Docker hub username"
required: true
DOCKERHUB_REPO_NAME:
description: "Docker hub repo name"
required: true
DOCKERHUB_TOKEN:
description: "Docker hub token"
required: true
runs:
using: "composite"
steps:
- name: Free Disk Space (Ubuntu)
uses: jlumbroso/free-disk-space@v1.3.1
with:
tool-cache: true
swap-storage: false
large-packages: false
- name: Read variables
shell: bash
run: |
source ./docker/variables.sh
for key in "${!ALLTALK_VARS[@]}"
do
echo "${key}=${ALLTALK_VARS[${key}]}"
echo "${key}=${ALLTALK_VARS[${key}]}" >> $GITHUB_ENV
done
- name: Extract version from Git Tag
shell: bash {0}
run: |
# Use the git tag if existing, otherwise 'latest':
DOCKER_TAG=$( echo "${{ github.ref }}" | grep -q tags | cut -d'/' -f 3 )
if [ -z "${DOCKER_TAG}" ]; then
DOCKER_TAG="latest"
fi
echo "Using DOCKER_TAG=${DOCKER_TAG}"
echo "DOCKER_TAG=${DOCKER_TAG}" >> $GITHUB_ENV
- name: Extract Docker Hub User and Repo Name
shell: bash
env:
DOCKERHUB_USERNAME: ${{ inputs.DOCKERHUB_USERNAME }}
DOCKERHUB_REPO_NAME: ${{ inputs.DOCKERHUB_REPO_NAME }}
run: |
if [ -n "${DOCKERHUB_USERNAME}" ]; then
echo "Using Github repository variable 'DOCKERHUB_USERNAME' as Docker hub username with value: '${DOCKERHUB_USERNAME}'"
echo "DOCKERHUB_USERNAME=${DOCKERHUB_USERNAME}" >> $GITHUB_ENV
else
echo "Using Github repository name as Docker hub username"
echo "DOCKERHUB_USERNAME=$(echo ${{ github.repository }} | cut -d'/' -f 1)" >> $GITHUB_ENV
fi
if [ -n "${DOCKERHUB_REPO_NAME}" ]; then
echo "Using Github repository variable 'DOCKERHUB_REPO_NAME' as Docker hub repo name with value: '${DOCKERHUB_REPO_NAME}'"
echo "DOCKERHUB_REPO_NAME=${DOCKERHUB_REPO_NAME}" >> $GITHUB_ENV
else
echo "Using Github repository name as Docker hub repo name"
echo "DOCKERHUB_REPO_NAME=$(echo ${{ github.repository }} | cut -d'/' -f 2)" >> $GITHUB_ENV
fi
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ inputs.DOCKERHUB_USERNAME }}
password: ${{ inputs.DOCKERHUB_TOKEN }}
-124
View File
@@ -1,124 +0,0 @@
name: Publish Docker v2
on:
workflow_dispatch:
release:
types: [ published ]
push:
branches:
- 'alltalkbeta'
tags:
- 'v*'
# Limit the concurrency of entire workflow runs for a specific branch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build_base_environment_docker_image:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup docker
uses: ./.github/actions/docker-setup
with:
DOCKERHUB_USERNAME: ${{ vars.DOCKERHUB_USERNAME }}
DOCKERHUB_REPO_NAME: ${{ vars.DOCKERHUB_REPO_NAME }}
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: |
${{ env.DOCKERHUB_USERNAME }}/${{ env.DOCKERHUB_REPO_NAME }}_environment
tags: |
# Use sematic versioning on push tag event:
type=semver,pattern={{version}}
# set latest tag for main and alltalkbeta branch:
type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'main') || github.ref == format('refs/heads/{0}', 'alltalkbeta') }}
- uses: dorny/paths-filter@v3
id: changes
with:
base: 'alltalkbeta'
filters: |
docker-base:
- 'docker/variables.sh'
- 'docker/base/Dockerfile'
docker-workflow:
- '.github/workflows/publish-docker*.yml'
- name: Build and push base Docker image
if: |
steps.changes.outputs.docker-base == 'true' ||
steps.changes.outputs.docker-workflow == 'true' ||
github.event_name == 'release' ||
(github.event_name == 'push' && contains(github.ref, 'refs/tags/'))
uses: docker/build-push-action@v6
with:
context: ./docker/base
file: ./docker/base/Dockerfile
platforms: "linux/amd64"
push: true
build-args: |
CUDA_VERSION=${{ env.CUDA_VERSION }}
PYTHON_VERSION=${{ env.PYTHON_VERSION }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=registry,ref=${{ env.DOCKERHUB_USERNAME }}/${{ env.DOCKERHUB_REPO_NAME }}_environment:buildcache
cache-to: type=registry,ref=${{ env.DOCKERHUB_USERNAME }}/${{ env.DOCKERHUB_REPO_NAME }}_environment:buildcache,mode=max
build_main_docker_image:
needs: build_base_environment_docker_image
runs-on: ubuntu-latest
strategy:
matrix:
tts: [ xtts, vits, piper ]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup docker
uses: ./.github/actions/docker-setup
with:
DOCKERHUB_USERNAME: ${{ vars.DOCKERHUB_USERNAME }}
DOCKERHUB_REPO_NAME: ${{ vars.DOCKERHUB_REPO_NAME }}
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: |
${{ env.DOCKERHUB_USERNAME }}/${{ env.DOCKERHUB_REPO_NAME }}
flavor: |
suffix=-${{ matrix.tts }},onlatest=true
tags: |
# Use sematic versioning on push tag event:
type=semver,pattern={{version}}
# set latest tag for main and alltalkbeta branch:
type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'main') || github.ref == format('refs/heads/{0}', 'alltalkbeta') }}
- name: Build and push base Docker image
uses: docker/build-push-action@v6
with:
context: .
file: ./Dockerfile
platforms: "linux/amd64"
push: true
build-args: |
TTS_MODEL=${{ matrix.tts }}
ALLTALK_DIR=${{ env.ALLTALK_DIR }}
DEEPSPEED_VERSION=${{ env.DEEPSPEED_VERSION }}
DOCKER_TAG=${{ env.DOCKER_TAG }}
DOCKER_REPOSITORY=${{ env.DOCKERHUB_USERNAME }}/
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=registry,ref=${{ env.DOCKERHUB_USERNAME }}/${{ env.DOCKERHUB_REPO_NAME }}:buildcache-${{ matrix.tts }}
cache-to: type=registry,ref=${{ env.DOCKERHUB_USERNAME }}/${{ env.DOCKERHUB_REPO_NAME }}:buildcache-${{ matrix.tts }},mode=max
-67
View File
@@ -1,67 +0,0 @@
name: Publish Docker image (main branch)
on:
# push:
# branches: [main]
release:
types: [published]
workflow_dispatch:
jobs:
build_and_push:
runs-on: ubuntu-latest
strategy:
matrix:
include:
- dockerfile: "Dockerfile"
platforms: "linux/amd64"
tag_name: "cpu"
- dockerfile: "nvidia.Dockerfile"
platforms: "linux/amd64"
tag_name: "cuda"
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Lowercase Actor and Extract Repo Name
run: |
echo "ACTOR_LOWER=$(echo ${{ github.actor }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV
echo "REPO_NAME=$(echo ${{ github.repository }} | cut -d'/' -f 2)" >> $GITHUB_ENV
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ env.ACTOR_LOWER }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
file: ./${{ matrix.dockerfile }}
platforms: ${{ matrix.platforms }}
push: true
tags: |
ghcr.io/${{ env.ACTOR_LOWER }}/${{ env.REPO_NAME }}:${{ matrix.tag_name }}-${{ github.sha }}
ghcr.io/${{ env.ACTOR_LOWER }}/${{ env.REPO_NAME }}:${{ matrix.tag_name }}
ghcr.io/${{ env.ACTOR_LOWER }}/${{ env.REPO_NAME }}:latest
${{ vars.DOCKERHUB_USERNAME }}/${{ env.REPO_NAME }}:${{ matrix.tag_name }}-${{ github.sha }}
${{ vars.DOCKERHUB_USERNAME }}/${{ env.REPO_NAME }}:${{ matrix.tag_name }}
${{ vars.DOCKERHUB_USERNAME }}/${{ env.REPO_NAME }}:latest
- name: Docker Hub Description
uses: peter-evans/dockerhub-description@v3.4.2
with:
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
repository: ${{ vars.DOCKERHUB_USERNAME }}/${{ env.REPO_NAME }}
+174 -6
View File
@@ -1,8 +1,176 @@
voices/*.* voices/*
models/*.* models/*
outputs/*.* outputs/*
finetune/*.* finetune/*
config.json alltalk_environment/*
system/config/at_github_sha.json
system/tts_engines/tts_engines.json
confignew.json confignew.json
models.json
diagnostics.log diagnostics.log
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
.pdm.toml
.pdm-python
.pdm-build/
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
.idea/*
# Docker build
docker/deepspeed/build
+78
View File
@@ -0,0 +1,78 @@
# Docker
The Docker image currently works on Windows and Linux, optionally supporting NVIDIA GPUs.
## General Remarks
- The resulting Docker image is 21 GB in size. Building might require even more disk space temporarily.
- Another 15 GB is required for building DeepSpeed
- Build time depends on your hardware and internet connection. Expect at least 20-30min to be normal for a full build.
- This includes building the conda environment as well as DeepSpeed, which is the basis for the alltalk Docker image.
- The Docker build for alltalk:
- Downloads XTTS as default TTS engine
- Enables RVC by default
- Downloads all supported RVC models
- Enables deepspeed by default
- Starting the Docker image should only a few seconds due to all the steps that were already executed during build.
## Docker for Linux
### Ubuntu Specific Setup for GPUs
1. Make sure the latest nvidia drivers are installed: `sudo ubuntu-drivers install`
1. Install Docker your preferred way. One way to do it is to follow the official documentation [here](https://docs.docker.com/engine/install/ubuntu/#uninstall-old-versions).
- Start by uninstalling the old versions
- Follow the "apt" repository installation method
- Check that everything is working with the "hello-world" container
1. If, when launching the docker contain, you have an error message saying that the GPU cannot be used, you might have to install [Nvidia Docker Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html).
- Install with the "apt" method
- Run the docker configuration command
```sudo nvidia-ctk runtime configure --runtime=docker```
- Restart docker
## Docker for Windows (WSL2)
### Windows Specific Setup for GPUs
> Make sure your Nvidia drivers are up to date: https://www.nvidia.com/download/index.aspx
1. Install WSL2 in PowerShell with `wsl --install` and restart
2. Open PowerShell, type and enter ```ubuntu```. It should now load you into wsl2
3. Remove the original nvidia cache key: `sudo apt-key del 7fa2af80`
4. Download CUDA toolkit keyring: `wget https://developer.download.nvidia.com/compute/cuda/repos/wsl-ubuntu/x86_64/cuda-keyring_1.1-1_all.deb`
5. Install keyring: `sudo dpkg -i cuda-keyring_1.1-1_all.deb`
6. Update package list: `sudo apt-get update`
7. Install CUDA toolkit: `sudo apt-get -y install cuda-toolkit-12-6`
8. Install Docker Desktop using WSL2 as the backend
9. Restart
10. If you wish to monitor the terminal remotely via SSH, follow [this guide](https://www.hanselman.com/blog/how-to-ssh-into-wsl2-on-windows-10-from-an-external-machine).
11. Open PowerShell, type ```ubuntu```, [then follow below](#building-and-running-in-docker)
## Building and Running in Docker
1. Open a terminal (or Ubuntu WSL) and go where you cloned the repo
3. Build the image with `./docker-build.sh`
4. Start the container with `./docker-start.sh`
5. Visit `http://localhost:7851/` or remotely with `http://<ip>:7851`
## Arguments for building and starting docker
There are various arguments to customize the build and start of the docker image.
### Arguments for `docker-build.sh`
- `--tts_model` allows to choose the TTS model that is used by default. Valid values are `piper`, `vits`, `xtts`. Defaults to `xtts`.
- Example: `docker-build.sh --tts_model piper`
- `--tag` allows to choose the docker tag. Defaults to `latest`.
- Example: `docker-build.sh --tag mytag`
- `--clean` allows remove existing dependency build like conda environment or DeepSpeed.
- Example: `docker-build.sh --clean`
### Arguments for `docker-start.sh`
- `--config` lets you choose a config JSON file which can subset of `confignew.json`. This allows you to change only
few values and leave the rest as defined in the default `confignew.json` file.
- Example: `docker-start.sh --config /my/config/file.json` with content `{"branding": "My Brand "}` will just change
the branding in `confignew.json`.
- `--voices` lets you add voices for the TTS engine in WAV format. You have to specify the folder containing all
voice files.
- Example: `docker-start.sh --voices /my/voices/dir`
- `--rvc_voices` similar to voices, this option lets you pick the folder containing the RVC models.
- Example: `docker-start.sh --rvc_voices /my/rvc/voices/dir`
- `--no_ui` allows you to not expose port 7852 for the gradio interface. Note that you still have to set `launch_gradio`
to `false` via JSON file passed to `--config`.
- `--tag` allows to choose the docker tag of the image to run. Defaults to `latest`.
- Example: `docker-start.sh --tag mytag`
- Since the above commands only address the most important options, you might pass additional arbitrary docker commands
to the `docker-start.sh`.
+121 -17
View File
@@ -1,20 +1,124 @@
FROM nvidia/cuda:12.1.1-devel-ubuntu22.04 ARG GITHUB_REPOSITORY
ENV HOST 0.0.0.0 FROM ${GITHUB_REPOSITORY}alltalk_environment:latest
RUN apt-get update && apt-get upgrade -y \
&& apt-get install -y git build-essential portaudio19-dev \ # Argument to choose the model: piper, vits, xtts
python3 python3-pip gcc wget \ ARG TTS_MODEL="xtts"
ocl-icd-opencl-dev opencl-headers clinfo \ ENV TTS_MODEL=$TTS_MODEL
libclblast-dev libopenblas-dev libaio-dev \
&& mkdir -p /etc/OpenCL/vendors && echo "libnvidia-opencl.so.1" > /etc/OpenCL/vendors/nvidia.icd \ ARG DEEPSPEED_VERSION=0.16.2
&& ln -s /usr/bin/python3 /usr/bin/python ENV DEEPSPEED_VERSION=$DEEPSPEED_VERSION
ARG ALLTALK_DIR=/opt/alltalk
ENV GRADIO_SERVER_NAME="0.0.0.0"
WORKDIR ${ALLTALK_DIR}
##############################################################################
# Install python dependencies (cannot use --no-deps because requirements are not complete)
##############################################################################
COPY system/config system/config
COPY system/requirements/requirements_standalone.txt system/requirements/requirements_standalone.txt
COPY system/requirements/requirements_parler.txt system/requirements/requirements_parler.txt
ENV PIP_CACHE_DIR=${ALLTALK_DIR}/pip_cache
RUN <<EOR
conda activate alltalk
mkdir ${ALLTALK_DIR}/pip_cache
pip install --no-cache-dir --cache-dir=${ALLTALK_DIR}/pip_cache -r system/requirements/requirements_standalone.txt
pip install --no-cache-dir --cache-dir=${ALLTALK_DIR}/pip_cache --upgrade gradio==4.32.2
# Parler:
pip install --no-cache-dir --cache-dir=${ALLTALK_DIR}/pip_cache -r system/requirements/requirements_parler.txt
conda clean --all --force-pkgs-dirs -y && pip cache purge
EOR
##############################################################################
# Install DeepSpeed
##############################################################################
RUN mkdir -p /tmp/deepseped
COPY docker/deepspeed/build/*.whl /tmp/deepspeed/
RUN <<EOR
DEEPSPEED_WHEEL=$(realpath /tmp/deepspeed/*.whl)
conda activate alltalk
echo "Using precompiled DeepSpeed wheel at ${DEEPSPEED_WHEEL}"
CFLAGS="-I$CONDA_PREFIX/include/" LDFLAGS="-L$CONDA_PREFIX/lib/" \
pip install --no-cache-dir ${DEEPSPEED_WHEEL}
if [ $? -ne 0 ] ; then
echo "Failed to install pip dependencies: $RESULT"
exit 1
fi
rm ${DEEPSPEED_WHEEL}
conda clean --all --force-pkgs-dirs -y && pip cache purge
EOR
##############################################################################
# Writing scripts to start alltalk:
##############################################################################
RUN <<EOR
cat << EOF > start_alltalk.sh
#!/usr/bin/env bash
source ~/.bashrc
# Merging config from docker_confignew.json into confignew.json:
jq -s '.[0] * .[1] * .[2]' confignew.json docker_default_config.json docker_confignew.json > confignew.json.tmp
mv confignew.json.tmp confignew.json
conda activate alltalk
python script.py
EOF
cat << EOF > start_finetune.sh
#!/usr/bin/env bash
source ~/.bashrc
export TRAINER_TELEMETRY=0
conda activate alltalk
python finetune.py
EOF
cat << EOF > start_diagnostics.sh
#!/usr/bin/env bash
source ~/.bashrc
conda activate alltalk
python diagnostics.py
EOF
chmod +x start_alltalk.sh
chmod +x start_finetune.sh
chmod +x start_diagnostics.sh
EOR
WORKDIR /app
ENV CUDA_DOCKER_ARCH=all
COPY system/requirements/requirements_docker.txt system/requirements/requirements_docker.txt
RUN pip install --no-cache-dir --no-deps -r system/requirements/requirements_docker.txt && \
pip install --no-cache-dir deepspeed
COPY . . COPY . .
EXPOSE 7851 7852 ##############################################################################
RUN chmod +x launch.sh # Create script to execute firstrun.py and run it:
ENTRYPOINT ["sh", "-c", "./launch.sh"] ##############################################################################
RUN echo $'#!/usr/bin/env bash \n\
source ~/.bashrc \n\
conda activate alltalk \n\
python ./system/config/firstrun.py $@' > ./start_firstrun.sh
RUN chmod +x start_firstrun.sh
RUN ./start_firstrun.sh --tts_model $TTS_MODEL
RUN mkdir -p ${ALLTALK_DIR}/outputs
RUN mkdir -p /root/.triton/autotune
##############################################################################
# Enable deepspeed for all models:
##############################################################################
RUN find . -name model_settings.json -exec sed -i -e 's/"deepspeed_enabled": false/"deepspeed_enabled": true/g' {} \;
##############################################################################
# Download all RVC models:
##############################################################################
RUN <<EOR
jq -r '.[]' system/tts_engines/rvc_files.json > /tmp/rvc_files.txt
xargs -n 1 curl --create-dirs --output-dir models/rvc_base -LO < /tmp/rvc_files.txt
rm -f /tmp/rvc_files.txt
EOR
##############################################################################
# Start alltalk:
##############################################################################
ENTRYPOINT ["sh", "-c", "./start_alltalk.sh"]
+117 -1431
View File
File diff suppressed because it is too large. Load diff
+229 -37
View File
@@ -42,6 +42,9 @@ if "%ERRORLEVEL%" NEQ "0" (
goto end goto end
) )
:: Check for "-silent" install command-line argument
if "%1"=="-silent" goto InstallCustomStandalone
:MainMenu :MainMenu
cls cls
echo. echo.
@@ -49,10 +52,11 @@ echo %L_BLUE%ALLTALK WINDOWS SETUP UTILITY%RESET%
echo. echo.
echo INSTALLATION TYPE echo INSTALLATION TYPE
echo 1) I am using AllTalk as part of %L_GREEN%Text-generation-webui%RESET% echo 1) I am using AllTalk as part of %L_GREEN%Text-generation-webui%RESET%
echo 2) I am using AllTalk as a %L_GREEN%Standalone Application%RESET% echo 2) I am using AllTalk as a %L_BLUE%Standalone Application%RESET%
echo. echo.
echo 9) %L_RED%Exit/Quit%RESET% echo 9) %L_RED%Exit/Quit%RESET%
echo. echo.
echo.
set /p UserOption=" Enter your choice: " set /p UserOption=" Enter your choice: "
if "%UserOption%"=="1" goto WebUIMenu if "%UserOption%"=="1" goto WebUIMenu
@@ -134,6 +138,13 @@ 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_parler.txt
echo ** Faiss **
call "%CONDA_ROOT_PREFIX%\Scripts\conda.exe" install -y pytorch::faiss-cpu
echo ** FFmpeg **
call "%CONDA_ROOT_PREFIX%\Scripts\conda.exe" install -y -c conda-forge "ffmpeg=*=*gpl*"
call "%CONDA_ROOT_PREFIX%\Scripts\conda.exe" install -y -c conda-forge "ffmpeg=*=h*_*" --no-deps
if %ERRORLEVEL% neq 0 ( if %ERRORLEVEL% neq 0 (
echo. echo.
echo There was an error installing the requirements. echo There was an error installing the requirements.
@@ -359,7 +370,7 @@ set TEMP=%cd%\alltalk_environment
set INSTALL_DIR=%cd%\alltalk_environment set INSTALL_DIR=%cd%\alltalk_environment
set CONDA_ROOT_PREFIX=%cd%\alltalk_environment\conda set CONDA_ROOT_PREFIX=%cd%\alltalk_environment\conda
set INSTALL_ENV_DIR=%cd%\alltalk_environment\env set INSTALL_ENV_DIR=%cd%\alltalk_environment\env
set MINICONDA_DOWNLOAD_URL=https://repo.anaconda.com/miniconda/Miniconda3-py310_23.3.1-0-Windows-x86_64.exe set MINICONDA_DOWNLOAD_URL=https://repo.anaconda.com/miniconda/Miniconda3-py311_24.4.0-0-Windows-x86_64.exe
set conda_exists=F set conda_exists=F
@rem figure out whether git and conda need to be installed @rem figure out whether git and conda need to be installed
@@ -381,28 +392,207 @@ call "%CONDA_ROOT_PREFIX%\_conda.exe" --version || ( echo. && echo Miniconda not
@rem create the installer env @rem create the installer env
echo Packages to install: %PACKAGES_TO_INSTALL% echo Packages to install: %PACKAGES_TO_INSTALL%
call "%CONDA_ROOT_PREFIX%\_conda.exe" create --no-shortcuts -y -k --prefix "%INSTALL_ENV_DIR%" python=3.11 || ( echo. && echo Conda environment creation failed. && goto end ) call "%CONDA_ROOT_PREFIX%\_conda.exe" create --no-shortcuts -y -k --prefix "%INSTALL_ENV_DIR%" python=3.11.9 || ( echo. && echo Conda environment creation failed. && goto end )
@rem check if conda environment was actually created @rem check if conda environment was actually created
if not exist "%INSTALL_ENV_DIR%\python.exe" ( echo. && echo Conda environment is empty. && goto end ) if not exist "%INSTALL_ENV_DIR%\python.exe" ( echo. && echo Conda environment is empty. && goto end )
@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
: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
echo. echo.
echo Downloading and installing PyTorch. This step can take a long time if errorlevel 1 (
echo depending on your internet connection and hard drive speed. Please echo PyTorch installation failed, errorlevel was %errorlevel%. There should be a Conda
echo be patient. echo error message above with a code and/or text explanation of the issue. Please note
echo the error code to help with diagnotics.
echo. echo.
pip install torch==2.2.2+cu121 torchaudio>=2.2.2+cu121 --upgrade --force-reinstall --extra-index-url https://download.pytorch.org/whl/cu121 echo Generally speaking though, errors could be caused by:
echo Installing other requirements.
echo. 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.
echo Known errors are in the AllTalk Github Wiki > Error Messages Help/Support
echo.
choice /C YN /M "Do you want to retry the Pytorch installation?"
if errorlevel 2 goto End
if errorlevel 1 goto install_pytorch
) else (
echo PyTorch installation was successful.
echo.
)
:install_faiss
echo ** Installing Faiss **
call "%CONDA_ROOT_PREFIX%\Scripts\conda.exe" install -y pytorch::faiss-cpu
echo.
if errorlevel 1 (
echo Faiss installation failed, errorlevel was %errorlevel%. There should be a Conda
echo error message above with a code and/or text explanation of the issue. Please note
echo the error code to help with diagnotics.
echo.
echo Generally speaking though, errors 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. Your Conda policy is set to Strict see the Github Wiki for help with this.
echo 8. Other issues not mentioned above.
echo.
echo Known errors are in the AllTalk Github Wiki > Error Messages Help/Support
echo.
choice /C YN /M "Do you want to retry the Faiss installation?"
if errorlevel 2 goto End
if errorlevel 1 goto install_faiss
) else (
echo Faiss installation was successful.
echo.
)
:install_ffmpeg
echo ** Installing FFmpeg **
call "%CONDA_ROOT_PREFIX%\Scripts\conda.exe" install -y -c conda-forge "ffmpeg=*=*gpl*"
call "%CONDA_ROOT_PREFIX%\Scripts\conda.exe" install -y -c conda-forge "ffmpeg=*=h*_*" --no-deps
echo.
if errorlevel 1 (
echo FFmpeg installation failed, errorlevel was %errorlevel%. There should be a Conda
echo error message above with a code and/or text explanation of the issue. Please note
echo the error code to help with diagnotics.
echo.
echo Generally speaking though, errors 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. Your Conda policy is set to Strict see the Github Wiki for help with this.
echo 8. Other issues not mentioned above.
echo.
echo Known errors are in the AllTalk Github Wiki > Error Messages Help/Support
echo.
choice /C YN /M "Do you want to retry the FFmpeg installation?"
if errorlevel 2 goto End
if errorlevel 1 goto install_ffmpeg
) else (
echo FFmpeg installation was successful.
echo.
)
echo ** Requirements file **
pip install -r system\requirements\requirements_standalone.txt pip install -r system\requirements\requirements_standalone.txt
curl -LO https://github.com/erew123/alltalk_tts/releases/download/DeepSpeed-14.0/deepspeed-0.14.0+ce78a63-cp311-cp311-win_amd64.whl echo.
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
:update_gradio
echo ** Updating Gradio **
pip install --upgrade gradio==4.44.1
echo.
if errorlevel 1 (
echo Gradio update failed, errorlevel was %errorlevel%. There should be an error
echo message above with a code and/or text explanation of the issue. Please note
echo the error code to help with diagnotics.
echo.
echo Generally speaking though, errors 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.
echo Known errors are in the AllTalk Github Wiki > Error Messages Help/Support
echo.
choice /C YN /M "Do you want to retry the Gradio update?"
if errorlevel 2 goto End
if errorlevel 1 goto update_gradio
) 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%. There should be an error
echo message above with a code and/or text explanation of the issue. Please note
echo the error code to help with diagnotics.
echo.
echo Generally speaking though, errors 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.
echo Known errors are in the AllTalk Github Wiki > Error Messages Help/Support
echo.
choice /C YN /M "Do you want to retry the DeepSpeed download?"
if errorlevel 2 goto End
if errorlevel 1 goto install_deepspeed
) 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%. There should be an error
echo message above with a code and/or text explanation of the issue. Please note
echo the error code to help with diagnotics. General issues may be:
echo.
echo Generally speaking though, errors 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 Known errors are in the AllTalk Github Wiki > Error Messages Help/Support
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 2 goto End
if errorlevel 1 goto install_deepspeed
) 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.
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
@@ -424,11 +614,22 @@ echo set CONDA_ROOT_PREFIX=%cd%\alltalk_environment\conda >> start_finetune.bat
echo set INSTALL_ENV_DIR=%cd%\alltalk_environment\env >> start_finetune.bat echo set INSTALL_ENV_DIR=%cd%\alltalk_environment\env >> start_finetune.bat
echo call "%CONDA_ROOT_PREFIX%\condabin\conda.bat" activate "%INSTALL_ENV_DIR%" >> start_finetune.bat echo call "%CONDA_ROOT_PREFIX%\condabin\conda.bat" activate "%INSTALL_ENV_DIR%" >> start_finetune.bat
echo call python finetune.py >> start_finetune.bat echo call python finetune.py >> start_finetune.bat
echo @echo off > start_diagnostics.bat
echo cd /D "%~dp0" >> start_diagnostics.bat
echo set CONDA_ROOT_PREFIX=%cd%\alltalk_environment\conda >> start_diagnostics.bat
echo set INSTALL_ENV_DIR=%cd%\alltalk_environment\env >> start_diagnostics.bat
echo call "%CONDA_ROOT_PREFIX%\condabin\conda.bat" activate "%INSTALL_ENV_DIR%" >> start_diagnostics.bat
echo call python diagnostics.py >> start_diagnostics.bat
Echo. 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_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
pause pause
goto StandaloneMenu goto StandaloneMenu
@@ -445,7 +646,7 @@ if not exist "%cd%\alltalk_environment\" (
if not defined CONDA_PREFIX goto NoCondaEnvDeleteCustomStandalone if not defined CONDA_PREFIX goto NoCondaEnvDeleteCustomStandalone
@rem Deactivate Conda environment if it's active @rem Deactivate Conda environment if it's active
Echo Exiting the Conda Environment. Please run %L_GREEN%atsetup.bat%RESET% again and delete the environment. Echo Exiting the Conda Environment. Please run %L_GREEN%atsetup.bat%RESET% again and delete the environment.
conda deactivate call conda deactivate
:NoCondaEnvDeleteCustomStandalone :NoCondaEnvDeleteCustomStandalone
echo Deleting "alltalk_environment". Please wait. echo Deleting "alltalk_environment". Please wait.
rd /s /q "alltalk_environment" rd /s /q "alltalk_environment"
@@ -455,6 +656,7 @@ if %ERRORLEVEL% neq 0 (
echo. echo.
echo Failed to delete alltalk_environment folder. echo Failed to delete alltalk_environment folder.
echo Please make sure it is not in use and try again. echo Please make sure it is not in use and try again.
echo Worst case, manually delete the folder called 'alltalk_environment'
echo. echo.
pause pause
goto StandaloneMenu goto StandaloneMenu
@@ -531,32 +733,14 @@ if errorlevel 1 (
) )
@rem Run Reapply requirements @rem Run Reapply requirements
echo. echo.
echo Downloading and installing PyTorch. This step can take a long time echo Re-installing requirements. If you have problems after this, it may indicate
echo depending on your internet connection and hard drive speed. Please echo that the custom Python environment is damaged in some way. As such it may be
echo be patient. echo best to delete the custom Python environment and re-run the entire setup
echo. echo routine again to rebuild AllTalk's Python environment. Please press a key
pip install torch==2.2.2+cu121 torchaudio>=2.2.2+cu121 --upgrade --force-reinstall --extra-index-url https://download.pytorch.org/whl/cu121 echo to continue re-applying the Requirements for a standalone installation.
echo Installing other requirements.
echo.
pip install -r system\requirements\requirements_standalone.txt
C:/Windows/system32/curl.exe -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
if %ERRORLEVEL% neq 0 (
echo.
echo There was an error.
echo Press any key to return to the menu.
echo. echo.
pause pause
goto StandaloneMenu goto install_faiss
)
Echo.
Echo.
Echo Requirements have been re-applied/updated.
Echo.
pause
goto StandaloneMenu
:STPurgepipcache :STPurgepipcache
cd /D "%~dp0" cd /D "%~dp0"
@@ -648,12 +832,20 @@ 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 and the AllTalk Wiki page on Github.
Echo Please explore the documentation for tips, troubleshooing and explanations on the most
Echo common questions.
exit /b exit /b
+66 -28
View File
@@ -139,6 +139,37 @@ install_nvidia_textgen() {
fi fi
echo echo
echo " Requirements installed successfully." echo " Requirements installed successfully."
echo " Installing additional requirements..."
if ! pip install -r system/requirements/requirements_textgen2.txt; then
echo
echo " There was an error installing additional requirements."
echo " Please check the output for details."
read -p " Press any key to return to the menu. " -n 1
echo
return
fi
if ! conda install -y pytorch::faiss-cpu; then
echo
echo " There was an error installing faiss-cpu."
echo " Please check the output for details."
read -p " Press any key to return to the menu. " -n 1
echo
return
fi
if ! conda install -y conda-forge::ffmpeg; then
echo
echo " There was an error installing ffmpeg."
echo " Please check the output for details."
read -p " Press any key to return to the menu. " -n 1
echo
return
fi
echo
echo " Additional requirements installed successfully."
echo echo
echo -e " To install ${L_YELLOW}DeepSpeed${NC} on Linux, there are additional" echo -e " To install ${L_YELLOW}DeepSpeed${NC} on Linux, there are additional"
echo -e " steps required. Please see the Github or documentation on DeepSeed." echo -e " steps required. Please see the Github or documentation on DeepSeed."
@@ -147,6 +178,7 @@ install_nvidia_textgen() {
echo echo
} }
tg_gitpull() { tg_gitpull() {
echo echo
if ! git pull; then if ! git pull; then
@@ -172,17 +204,9 @@ install_deepspeed() {
echo echo
echo -e " ${L_BLUE}DEEPSPEED INSTALLATION REQUIREMENTS${NC}" echo -e " ${L_BLUE}DEEPSPEED INSTALLATION REQUIREMENTS${NC}"
echo echo
echo -e " - NVIDIA CUDA Toolkit must be installed from your ${L_GREEN}Linux package manager${NC}" echo -e " - Please go see this link as the instructions are there.${NC}"
echo -e " or ${L_GREEN}https://developer.nvidia.com/cuda-toolkit-archive${NC}" echo -e " The instructions there are making it as simple as posisble.${NC}"
echo -e " - The environment variable ${L_GREEN}CUDA_HOME${NC} must be set in your Python env" echo -e " ${L_GREEN}https://github.com/erew123/alltalk_tts/releases/tag/DeepSpeed-14.2-Linux${NC}"
echo -e " e.g. export CUDA_HOME=/usr/local/cuda."
echo -e " - ${L_GREEN}libaio-dev${NC} must be installed."
echo
echo -e " See the following link for full instructions:"
echo -e " ${L_GREEN}https://github.com/erew123/alltalk_tts?#-deepspeed-installation-options${NC}"
echo
echo -e " ${L_BLUE}Please ${L_RED}confirm${L_BLUE} that you have completed these steps before continuing"
echo -e " with the DeepSpeed installation, or the install ${L_RED}will fail.${NC}"
echo echo
read -p " Have you completed all the above steps? (y/n): " confirm read -p " Have you completed all the above steps? (y/n): " confirm
@@ -192,7 +216,7 @@ install_deepspeed() {
fi fi
echo -e "\n ${GREEN}Proceeding with DeepSpeed installation...${NC}" echo -e "\n ${GREEN}Proceeding with DeepSpeed installation...${NC}"
pip install deepspeed
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo -e " ${RED}There was an error installing DeepSpeed.${NC}" echo -e " ${RED}There was an error installing DeepSpeed.${NC}"
return return
@@ -255,9 +279,6 @@ standalone_menu() {
echo " 4) Delete AllTalk's custom Python environment" echo " 4) Delete AllTalk's custom Python environment"
echo " 5) Purge the PIP cache" echo " 5) Purge the PIP cache"
echo echo
echo " DEEPSPEED"
echo " 6) DeepSpeed Instructions/Install"
echo
echo " OTHER" echo " OTHER"
echo " 8) Generate a diagnostics file" echo " 8) Generate a diagnostics file"
echo echo
@@ -271,7 +292,6 @@ standalone_menu() {
3) reapply_standalone ;; 3) reapply_standalone ;;
4) delete_custom_standalone ;; 4) delete_custom_standalone ;;
5) pippurge_standalone ;; 5) pippurge_standalone ;;
6) install_deepspeed ;;
8) generate_diagnostics_standalone ;; 8) generate_diagnostics_standalone ;;
9) exit 0 ;; 9) exit 0 ;;
*) echo "Invalid option"; sleep 2 ;; *) echo "Invalid option"; sleep 2 ;;
@@ -302,8 +322,7 @@ install_custom_standalone() {
INSTALL_DIR="$(pwd)/alltalk_environment" INSTALL_DIR="$(pwd)/alltalk_environment"
CONDA_ROOT_PREFIX="${INSTALL_DIR}/conda" CONDA_ROOT_PREFIX="${INSTALL_DIR}/conda"
INSTALL_ENV_DIR="${INSTALL_DIR}/env" INSTALL_ENV_DIR="${INSTALL_DIR}/env"
MINICONDA_DOWNLOAD_URL="https://repo.anaconda.com/miniconda/Miniconda3-py310_23.3.1-0-Linux-${OS_ARCH}.sh" MINICONDA_DOWNLOAD_URL="https://repo.anaconda.com/miniconda/Miniconda3-py311_24.4.0-0-Linux-${OS_ARCH}.sh"
if [ ! -x "${CONDA_ROOT_PREFIX}/bin/conda" ]; then if [ ! -x "${CONDA_ROOT_PREFIX}/bin/conda" ]; then
echo "Downloading Miniconda from $MINICONDA_DOWNLOAD_URL to ${INSTALL_DIR}/miniconda_installer.sh" echo "Downloading Miniconda from $MINICONDA_DOWNLOAD_URL to ${INSTALL_DIR}/miniconda_installer.sh"
mkdir -p "${INSTALL_DIR}" mkdir -p "${INSTALL_DIR}"
@@ -314,22 +333,37 @@ install_custom_standalone() {
fi fi
if [ ! -d "${INSTALL_ENV_DIR}" ]; then if [ ! -d "${INSTALL_ENV_DIR}" ]; then
"${CONDA_ROOT_PREFIX}/bin/conda" create -y --prefix "${INSTALL_ENV_DIR}" python=3.11 "${CONDA_ROOT_PREFIX}/bin/conda" create -y --prefix "${INSTALL_ENV_DIR}" -c conda-forge python=3.11.9
echo "Conda environment created at ${INSTALL_ENV_DIR}." echo "Conda environment created at ${INSTALL_ENV_DIR}."
fi fi
# Activate the environment and install requirements # Activate the environment and install requirements
source "${CONDA_ROOT_PREFIX}/etc/profile.d/conda.sh" source "${CONDA_ROOT_PREFIX}/etc/profile.d/conda.sh"
conda activate "${INSTALL_ENV_DIR}" conda activate "${INSTALL_ENV_DIR}"
# pip install torch==2.2.1+cu121 torchaudio==2.2.1+cu121 --upgrade --force-reinstall --extra-index-url https://download.pytorch.org/whl/cu121 --no-cache-dir
conda install -y pytorch=2.2.1 torchvision torchaudio pytorch-cuda=12.1 -c pytorch -c nvidia
conda install -y nvidia/label/cuda-12.1.0::cuda-toolkit=12.1
conda install -y pytorch::faiss-cpu
conda install -y -c conda-forge "ffmpeg=*=*gpl*"
conda install -y -c conda-forge "ffmpeg=*=h*_*" --no-deps
echo echo
echo " Downloading and installing PyTorch. This step can take a long time"
echo " depending on your internet connection and hard drive speed. Please"
echo " be patient."
pip install torch==2.2.1+cu121 torchaudio==2.2.1+cu121 --upgrade --force-reinstall --extra-index-url https://download.pytorch.org/whl/cu121
echo echo
echo
echo " Fix Nvidia's broken symlinks in the /env/lib folder"
echo
# Define the environment path
env_path="${INSTALL_ENV_DIR}/lib"
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
curl -LO https://github.com/erew123/alltalk_tts/releases/download/DeepSpeed-14.0/deepspeed-0.14.2+cu121torch2.2-cp311-cp311-manylinux_2_24_x86_64.whl
pip install --upgrade gradio==4.44.1
echo Installing DeepSpeed...
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
pip install -r system/requirements/requirements_parler.txt
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
#!/bin/bash #!/bin/bash
@@ -346,33 +380,36 @@ unset PYTHONPATH
unset PYTHONHOME unset PYTHONHOME
export CUDA_PATH="$INSTALL_ENV_DIR" export CUDA_PATH="$INSTALL_ENV_DIR"
export CUDA_HOME="$CUDA_PATH" export CUDA_HOME="$CUDA_PATH"
export LD_LIBRARY_PATH=`python3 -c 'import os; import nvidia.cublas.lib; import nvidia.cudnn.lib; print(os.path.dirname(nvidia.cublas.lib.__file__) + ":" + os.path.dirname(nvidia.cudnn.lib.__file__))'`
# activate env # activate env
bash --init-file <(echo "source \"$CONDA_ROOT_PREFIX/etc/profile.d/conda.sh\" && conda activate \"$INSTALL_ENV_DIR\"") bash --init-file <(echo "source \"$CONDA_ROOT_PREFIX/etc/profile.d/conda.sh\" && conda activate \"$INSTALL_ENV_DIR\"")
EOF EOF
# Create start_alltalk.sh to run AllTalk
cat << EOF > start_alltalk.sh cat << EOF > start_alltalk.sh
#!/bin/bash #!/bin/bash
export LD_LIBRARY_PATH=`python3 -c 'import os; import nvidia.cublas.lib; import nvidia.cudnn.lib; print(os.path.dirname(nvidia.cublas.lib.__file__) + ":" + os.path.dirname(nvidia.cudnn.lib.__file__))'`
source "${CONDA_ROOT_PREFIX}/etc/profile.d/conda.sh" source "${CONDA_ROOT_PREFIX}/etc/profile.d/conda.sh"
conda activate "${INSTALL_ENV_DIR}" conda activate "${INSTALL_ENV_DIR}"
python script.py python script.py
EOF EOF
# Create start_finetune.sh to run AllTalk
cat << EOF > start_finetune.sh cat << EOF > start_finetune.sh
#!/bin/bash #!/bin/bash
export TRAINER_TELEMETRY=0 export TRAINER_TELEMETRY=0
export LD_LIBRARY_PATH=`python3 -c 'import os; import nvidia.cublas.lib; import nvidia.cudnn.lib; print(os.path.dirname(nvidia.cublas.lib.__file__) + ":" + os.path.dirname(nvidia.cudnn.lib.__file__))'`
source "${CONDA_ROOT_PREFIX}/etc/profile.d/conda.sh" source "${CONDA_ROOT_PREFIX}/etc/profile.d/conda.sh"
conda activate "${INSTALL_ENV_DIR}" conda activate "${INSTALL_ENV_DIR}"
python finetune.py python finetune.py
EOF
cat << EOF > start_diagnostics.sh
#!/bin/bash
source "${CONDA_ROOT_PREFIX}/etc/profile.d/conda.sh"
conda activate "${INSTALL_ENV_DIR}"
python diagnostics.py
EOF EOF
chmod +x start_alltalk.sh chmod +x start_alltalk.sh
chmod +x start_environment.sh chmod +x start_environment.sh
chmod +x start_finetune.sh chmod +x start_finetune.sh
chmod +x start_diagnostics.sh
echo echo
echo echo
echo -e " Run ${L_YELLOW}./start_alltalk.sh${NC} to start AllTalk." echo -e " Run ${L_YELLOW}./start_alltalk.sh${NC} to start AllTalk."
echo -e " Run ${L_YELLOW}./start_diagnostics.sh${NC} to start Diagnostics."
echo -e " Run ${L_YELLOW}./start_finetune.sh${NC} to start Finetuning." echo -e " Run ${L_YELLOW}./start_finetune.sh${NC} to start Finetuning."
echo -e " Run ${L_YELLOW}./start_environment.sh${NC} to start the AllTalk Python environment." echo -e " Run ${L_YELLOW}./start_environment.sh${NC} to start the AllTalk Python environment."
echo echo
@@ -508,6 +545,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
+371
View File
@@ -0,0 +1,371 @@
import os
import time
import shutil
from pathlib import Path
from filelock import FileLock
from abc import ABC, abstractmethod
from typing import Callable, MutableSequence
from pydantic import BaseModel, ConfigDict, AliasGenerator, AliasChoices, Field
class AlltalkConfigTheme(BaseModel):
# Map 'class' to 'clazz' and vice versa
model_config = ConfigDict(
alias_generator=AliasGenerator(
validation_alias=lambda field_name:
{
"clazz": AliasChoices("clazz", "class"),
}.get(field_name, None),
serialization_alias=lambda field_name: "class" if field_name == "clazz" else field_name,
)
)
file: str | None = None
clazz: str = "gradio/base"
class AlltalkConfigRvcSettings(BaseModel):
rvc_enabled: bool = False
rvc_char_model_file: str = "Disabled"
rvc_narr_model_file: str = "Disabled"
split_audio: bool = True
autotune: bool = False
pitch: int = 0
filter_radius: int = 3
index_rate: float = 0.75
rms_mix_rate: int = 1
protect: float = 0.5
hop_length: int = 130
f0method: str = "fcpe"
embedder_model: str = "hubert"
training_data_size: int = 45000
class AlltalkConfigTgwUi(BaseModel):
tgwui_activate_tts: bool = True
tgwui_autoplay_tts: bool = True
tgwui_narrator_enabled: str = "false"
tgwui_non_quoted_text_is: str = "character"
tgwui_deepspeed_enabled: bool = False
tgwui_language: str = "English"
tgwui_lowvram_enabled: bool = False
tgwui_pitch_set: int = 0
tgwui_temperature_set: float = 0.75
tgwui_repetitionpenalty_set: int = 10
tgwui_generationspeed_set: int = 1
tgwui_narrator_voice: str = "female_01.wav"
tgwui_show_text: bool = True
tgwui_character_voice: str = "female_01.wav"
tgwui_rvc_char_voice: str = "Disabled"
tgwui_rvc_char_pitch: int = 0
tgwui_rvc_narr_voice: str = "Disabled"
tgwui_rvc_narr_pitch: int = 0
class AlltalkConfigApiDef(BaseModel):
api_port_number: int = 7851
api_allowed_filter: str = "[^a-zA-Z0-9\\s.,;:!?\\-\\'\"$\\u0400-\\u04FF\\u00C0-\\u017F\\u0150\\u0151\\u0170\\u0171\\u011E\\u011F\\u0130\\u0131\\u0900-\\u097F\\u2018\\u2019\\u201C\\u201D\\u3001\\u3002\\u3040-\\u309F\\u30A0-\\u30FF\\u4E00-\\u9FFF\\u3400-\\u4DBF\\uF900-\\uFAFF\\u0600-\\u06FF\\u0750-\\u077F\\uFB50-\\uFDFF\\uFE70-\\uFEFF\\uAC00-\\uD7A3\\u1100-\\u11FF\\u3130-\\u318F\\uFF01\\uFF0c\\uFF1A\\uFF1B\\uFF1F]"
api_length_stripping: int = 3
api_max_characters: int = 2000
api_use_legacy_api: bool = False
api_legacy_ip_address: str = "127.0.0.1"
api_text_filtering: str = "standard"
api_narrator_enabled: str = "false"
api_text_not_inside: str = "character"
api_language: str = "en"
api_output_file_name: str = "myoutputfile"
api_output_file_timestamp: bool = True
api_autoplay: bool = False
api_autoplay_volume: float = 0.5
class AlltalkConfigDebug(BaseModel):
debug_transcode: bool = False
debug_tts: bool = False
debug_openai: bool = False
debug_concat: bool = False
debug_tts_variables: bool = False
debug_rvc: bool = False
debug_func: bool = False
debug_api: bool = False
debug_fullttstext: bool = False
debug_narrator: bool = False
debug_gradio_IP: bool = False
debug_transcribe: bool = False
debug_proxy: bool = False
class AlltalkConfigGradioPages(BaseModel):
Generate_Help_page: bool = True
Voice2RVC_page: bool = True
TTS_Generator_page: bool = True
TTS_Engines_Settings_page: bool = True
alltalk_documentation_page: bool = True
api_documentation_page: bool = True
class AlltalkAvailableEngine(BaseModel):
name: str = ""
selected_model: str = ""
class AlltalkConfigProxyEndpoint(BaseModel):
enabled: bool = False
external_port: int = 0
external_ip: str = "0.0.0.0"
cert_name: str = ""
class AlltalkConfigProxySettings(BaseModel):
proxy_enabled: bool = False
start_on_startup: bool = False
gradio_endpoint: AlltalkConfigProxyEndpoint = AlltalkConfigProxyEndpoint(external_port=444)
api_endpoint: AlltalkConfigProxyEndpoint = AlltalkConfigProxyEndpoint(external_port=443)
cert_validation: bool = True
logging_enabled: bool = True
log_level: str = "INFO"
class AbstractJsonConfig(ABC):
def __init__(self, config_path: Path | str, file_check_interval: int):
super().__init__()
self.__delegate = None
self.__config_path = Path(config_path) if type(config_path) is str else config_path
self.__last_read_time = 0 # Track when we last read the file
self.__file_check_interval = file_check_interval
def get_config_path(self):
return self.__config_path
def reload(self):
self._load_config()
return self
def _reload_on_change(self):
# Check if config file has been modified and reload if needed
if time.time() - self.__last_read_time >= self.__file_check_interval:
try:
most_recent_modification = self.get_config_path().stat().st_mtime
if most_recent_modification > self.__last_read_time:
self.reload()
except Exception as e:
print(f"Error checking config file: {e}")
def _load_config(self):
self.__last_read_time = self.get_config_path().stat().st_mtime
def __load():
with open(self.get_config_path(), "r") as configfile:
json_string = configfile.read()
# The delegate is the actual config loaded:
self.__delegate = self._handle_loaded_config(json_string)
self.__with_lock_and_backup(self.get_config_path(), False, __load)
def _save_file(self, path: Path | None | str, default=None, indent=4):
file_path = (Path(path) if type(path) is str else path) if path is not None else self.get_config_path()
def __save():
with open(file_path, 'w') as file:
file.write(self.__delegate.model_dump_json(indent=indent, by_alias=True))
self.__with_lock_and_backup(file_path, True, __save)
def __with_lock_and_backup(self, path: Path, backup: bool, callable: Callable[[], None]):
lock_path = path.with_suffix('.lock')
backup_path = None
try:
with FileLock(lock_path):
# Create backup:
if path.exists() and backup:
backup_path = path.with_suffix('.backup')
shutil.copy(path, backup_path)
try:
callable()
except Exception as e:
if backup_path and backup_path.exists():
shutil.copy(backup_path, path)
raise Exception(f"Failed to save config: {e}")
finally:
# Cleanup lock and backup files:
if lock_path.exists():
lock_path.unlink()
if backup and backup_path and backup_path.exists():
backup_path.unlink()
@abstractmethod
def _handle_loaded_config(self, json_string: str):
pass
def to_dict(self):
return self.__delegate.model_dump(by_alias=True)
# Delegation to the loaded config data
@property
def _xtra(self): return [o for o in dir(self.__delegate) if not o.startswith('_')]
def __getattr__(self, key):
if key in self._xtra: return getattr(self.__delegate, key)
raise AttributeError(key)
def __getattribute__(self, key):
if key.startswith("_"):
# Private and protected attributes always are on self:
return super().__getattribute__(key)
if key in self._xtra:
# Delegate attribute
return getattr(self.__delegate, key)
# Get own attribute:
return super().__getattribute__(key)
def __setattr__(self, key, value):
if key.startswith("_"):
# Private and protected attributes always are on self:
super().__setattr__(key, value)
elif key in dir(self.__delegate):
# Delegate attribute
setattr(self.__delegate, key, value)
else:
# Set own attribute:
super().__setattr__(key, value)
def __dir__(self):
def custom_dir(c, add): return dir(type(c)) + list(c.__dict__.keys()) + add
return custom_dir(self, self._xtra)
class AlltalkNewEnginesConfigFields:
engines_available: MutableSequence[AlltalkAvailableEngine] = Field(default_factory=list)
class AlltalkNewEnginesConfigModel(BaseModel, AlltalkNewEnginesConfigFields):
def get_engine_names_available(self):
return [engine.name for engine in self.engines_available]
def get_engines_matching(self, condition: Callable[[AlltalkAvailableEngine], bool]):
return [x for x in self.engines_available if condition(x)]
class AlltalkNewEnginesConfig(AbstractJsonConfig, AlltalkNewEnginesConfigFields):
__instance = None
__this_dir = Path(__file__).parent.resolve()
def __init__(self, config_path: Path | str = os.path.join(__this_dir, "system", "tts_engines", "new_engines.json")):
super().__init__(config_path, 5)
self._load_config()
@staticmethod
def get_instance():
if AlltalkNewEnginesConfig.__instance is None:
AlltalkNewEnginesConfig.__instance = AlltalkNewEnginesConfig()
AlltalkNewEnginesConfig.__instance._reload_on_change()
return AlltalkNewEnginesConfig.__instance
def _handle_loaded_config(self, json_string: str):
return AlltalkNewEnginesConfigModel.model_validate_json(json_string)
class AlltalkTTSEnginesConfigFields:
engines_available: MutableSequence[AlltalkAvailableEngine] = Field(default_factory=list)
engine_loaded: str = ""
selected_model: str = ""
class AlltalkTTSEnginesConfigModel(BaseModel, AlltalkTTSEnginesConfigFields):
def get_engine_names_available(self):
return [engine.name for engine in self.engines_available]
def is_valid_engine(self, engine_name):
return engine_name in self.get_engine_names_available()
def change_engine(self, requested_engine):
if requested_engine == self.engine_loaded:
return self
for engine in self.engines_available:
if engine.name == requested_engine:
self.engine_loaded = requested_engine
self.selected_model = engine.selected_model
return self
return self
class AlltalkTTSEnginesConfig(AbstractJsonConfig, AlltalkTTSEnginesConfigFields):
__instance = None
__this_dir = Path(__file__).parent.resolve()
def __init__(self, config_path: Path | str = os.path.join(__this_dir, "system", "tts_engines", "tts_engines.json")):
super().__init__(config_path, 5)
self._load_config()
@staticmethod
def get_instance(force_reload = False):
if AlltalkTTSEnginesConfig.__instance is None:
force_reload = False
AlltalkTTSEnginesConfig.__instance = AlltalkTTSEnginesConfig()
if force_reload:
AlltalkTTSEnginesConfig.__instance.reload()
else:
AlltalkTTSEnginesConfig.__instance._reload_on_change()
return AlltalkTTSEnginesConfig.__instance
def _handle_loaded_config(self, json_string: str):
cfg = AlltalkTTSEnginesConfigModel.model_validate_json(json_string)
cfg.engines_available = self.__handle_loaded_config_engines(cfg.engines_available)
return cfg
def __handle_loaded_config_engines(self, available_engines):
available_engine_names = [engine.name for engine in available_engines]
# Getting the engines that are not already part of the available engines:
new_engines_config = AlltalkNewEnginesConfig.get_instance()
new_engines = new_engines_config.get_engines_matching(lambda eng: eng.name not in available_engine_names)
# Merge engines:
return available_engines + new_engines
def save(self, path: Path | str | None = None):
self._save_file(path)
class AlltalkConfigFields:
branding: str = "AllTalk "
delete_output_wavs: str = "Disabled"
gradio_interface: bool = True
output_folder: str = "outputs"
gradio_port_number: int = 7852
firstrun_model: bool = True
firstrun_splash: bool = True
launch_gradio: bool = True
transcode_audio_format: str = "Disabled"
theme: AlltalkConfigTheme = AlltalkConfigTheme()
rvc_settings: AlltalkConfigRvcSettings = AlltalkConfigRvcSettings()
tgwui: AlltalkConfigTgwUi = AlltalkConfigTgwUi()
api_def: AlltalkConfigApiDef = AlltalkConfigApiDef()
debugging: AlltalkConfigDebug = AlltalkConfigDebug()
gradio_pages: AlltalkConfigGradioPages = AlltalkConfigGradioPages()
proxy_settings: AlltalkConfigProxySettings = AlltalkConfigProxySettings()
class AlltalkConfigModel(BaseModel, AlltalkConfigFields):
__this_dir = Path(__file__).parent.resolve()
def get_output_directory(self):
return self.__this_dir / self.output_folder
class AlltalkConfig(AbstractJsonConfig, AlltalkConfigFields):
__instance = None
__this_dir = Path(__file__).parent.resolve()
def __init__(self, config_path: Path | str = __this_dir / "confignew.json"):
super().__init__(config_path, 5)
self._load_config()
@staticmethod
def default_config_path():
return AlltalkConfig.__this_dir / "confignew.json"
@staticmethod
def get_instance(force_reload = False):
if AlltalkConfig.__instance is None:
force_reload = False
AlltalkConfig.__instance = AlltalkConfig()
if force_reload:
AlltalkConfig.__instance.reload()
else:
AlltalkConfig.__instance._reload_on_change()
return AlltalkConfig.__instance
def save(self, path: Path | str | None = None):
self._save_file(path)
def _handle_loaded_config(self, json_string: str):
model = AlltalkConfigModel.model_validate_json(json_string)
model.get_output_directory().mkdir(parents=True, exist_ok=True)
return model
+105 -21
View File
@@ -1,25 +1,109 @@
{ {
"activate": true,
"autoplay": true,
"branding": "AllTalk ", "branding": "AllTalk ",
"narrator_enabled": false,
"deepspeed_activate": false,
"delete_output_wavs": "Disabled", "delete_output_wavs": "Disabled",
"ip_address": "127.0.0.1", "gradio_interface": true,
"language": "English", "output_folder": "outputs",
"low_vram": false, "gradio_port_number": 7852,
"local_temperature": "0.7", "firstrun_model": true,
"local_repetition_penalty": "10.0", "firstrun_splash": true,
"tts_model_loaded": true, "launch_gradio": true,
"tts_model_name": "tts_models/multilingual/multi-dataset/xtts_v2", "transcode_audio_format": "Disabled",
"narrator_voice": "female_01.wav", "theme": {
"output_folder_wav": "extensions/alltalk_tts/outputs/", "file": null,
"output_folder_wav_standalone": "outputs/", "class": "gradio/base"
"port_number": "7851", },
"remove_trailing_dots": false, "rvc_settings": {
"show_text": true, "rvc_enabled": false,
"tts_method_api_local": false, "rvc_char_model_file": "Disabled",
"tts_method_api_tts": false, "rvc_narr_model_file": "Disabled",
"tts_method_xtts_local": true, "split_audio": true,
"voice": "female_01.wav" "autotune": false,
"pitch": 0,
"filter_radius": 3,
"index_rate": 0.75,
"rms_mix_rate": 1,
"protect": 0.5,
"hop_length": 130,
"f0method": "fcpe",
"embedder_model": "hubert",
"training_data_size": 45000
},
"tgwui": {
"tgwui_activate_tts": true,
"tgwui_autoplay_tts": true,
"tgwui_narrator_enabled": "false",
"tgwui_non_quoted_text_is": "character",
"tgwui_deepspeed_enabled": false,
"tgwui_language": "English",
"tgwui_lowvram_enabled": false,
"tgwui_pitch_set": 0,
"tgwui_temperature_set": 0.75,
"tgwui_repetitionpenalty_set": 10,
"tgwui_generationspeed_set": 1,
"tgwui_narrator_voice": "female_01.wav",
"tgwui_show_text": true,
"tgwui_character_voice": "female_01.wav",
"tgwui_rvc_char_voice": "Disabled",
"tgwui_rvc_char_pitch": 0,
"tgwui_rvc_narr_voice": "Disabled",
"tgwui_rvc_narr_pitch": 0
},
"api_def": {
"api_port_number": 7851,
"api_allowed_filter": "[^a-zA-Z0-9\\s.,;:!?\\-\\'\"$\\u0400-\\u04FF\\u00C0-\\u017F\\u0150\\u0151\\u0170\\u0171\\u011E\\u011F\\u0130\\u0131\\u0900-\\u097F\\u2018\\u2019\\u201C\\u201D\\u3001\\u3002\\u3040-\\u309F\\u30A0-\\u30FF\\u4E00-\\u9FFF\\u3400-\\u4DBF\\uF900-\\uFAFF\\u0600-\\u06FF\\u0750-\\u077F\\uFB50-\\uFDFF\\uFE70-\\uFEFF\\uAC00-\\uD7A3\\u1100-\\u11FF\\u3130-\\u318F\\uFF01\\uFF0c\\uFF1A\\uFF1B\\uFF1F]",
"api_length_stripping": 3,
"api_max_characters": 2000,
"api_use_legacy_api": false,
"api_legacy_ip_address": "127.0.0.1",
"api_text_filtering": "standard",
"api_narrator_enabled": "false",
"api_text_not_inside": "character",
"api_language": "en",
"api_output_file_name": "myoutputfile",
"api_output_file_timestamp": true,
"api_autoplay": false,
"api_autoplay_volume": 0.5
},
"debugging": {
"debug_transcode": false,
"debug_tts": false,
"debug_openai": false,
"debug_concat": false,
"debug_tts_variables": false,
"debug_rvc": false,
"debug_func": false,
"debug_api": false,
"debug_fullttstext": false,
"debug_narrator": false,
"debug_gradio_IP": false,
"debug_transcribe": false,
"debug_proxy": false
},
"gradio_pages": {
"Generate_Help_page": true,
"Voice2RVC_page": true,
"TTS_Generator_page": true,
"TTS_Engines_Settings_page": true,
"alltalk_documentation_page": true,
"api_documentation_page": true
},
"proxy_settings": {
"proxy_enabled": false,
"start_on_startup": false,
"gradio_endpoint": {
"enabled": false,
"external_port": 444,
"external_ip": "0.0.0.0",
"cert_name": ""
},
"api_endpoint": {
"enabled": false,
"external_port": 443,
"external_ip": "0.0.0.0",
"cert_name": ""
},
"cert_validation": true,
"logging_enabled": true,
"log_level": "INFO"
}
} }
+909 -95
View File
File diff suppressed because it is too large. Load diff
+98
View File
@@ -0,0 +1,98 @@
#!/usr/bin/env bash
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
cd $SCRIPT_DIR
. ${SCRIPT_DIR=}/docker/variables.sh
TTS_MODEL=xtts
DOCKER_TAG=latest
CLEAN=false
# Create required build directories if they don't exist
mkdir -p ${SCRIPT_DIR=}/docker/deepspeed/build
echo "Created build directories"
# Parse arguments
while [ "$#" -gt 0 ]; do
case "$1" in
--cuda-version)
CUDA_VERSION="$2"
shift
;;
--python-version)
PYTHON_VERSION="$2"
shift
;;
--tts_model)
TTS_MODEL="$2"
shift
;;
--deepspeed-version)
DEEPSPEED_VERSION="$2"
shift
;;
--tag)
DOCKER_TAG="$2"
shift
;;
--github-repository)
if [ -n "${GITHUB_REPOSITORY}" ] && ! [[ $GITHUB_REPOSITORY =~ ^--.* ]]; then
GITHUB_REPOSITORY="$2"
shift
fi
;;
--clean)
CLEAN=true
;;
*)
printf '%s\n' "Invalid argument ($1)"
exit 1
;;
esac
shift
done
if [ "$CLEAN" = true ]; then
rm -rf ${SCRIPT_DIR=}/docker/deepspeed/build
# Recreate directories after clean
mkdir -p ${SCRIPT_DIR=}/docker/deepspeed/build
echo "Cleaned and recreated build directories"
fi
echo "Building base environment image"
$SCRIPT_DIR/docker/base/build-base-env.sh \
--cuda-version ${CUDA_VERSION} \
--python-version ${PYTHON_VERSION} \
--github-repository ${GITHUB_REPOSITORY} \
--tag ${DOCKER_TAG}
if [ $? -ne 0 ]; then
echo "Failed to build base environment image"
exit 1
fi
echo "Building DeepSpeed"
$SCRIPT_DIR/docker/deepspeed/build-deepspeed.sh \
--python-version ${PYTHON_VERSION} \
--github-repository ${GITHUB_REPOSITORY} \
--tag ${DOCKER_TAG}
if [ $? -ne 0 ]; then
echo "Failed to build DeepSpeed"
exit 1
fi
echo "Starting docker build process using TTS model '${TTS_MODEL}' and docker tag '${DOCKER_TAG}'"
echo "Building for CUDA $CUDA_VERSION using python ${PYTHON_VERSION}"
docker buildx \
build \
--progress=plain \
--build-arg TTS_MODEL=$TTS_MODEL \
--build-arg ALLTALK_DIR=$ALLTALK_DIR \
--build-arg DEEPSPEED_VERSION=$DEEPSPEED_VERSION \
-t ${GITHUB_REPOSITORY}alltalk_beta:${DOCKER_TAG} \
.
echo "Docker build process finished. Use docker-start.sh to start the container."
-20
View File
@@ -1,20 +0,0 @@
version: '3.8'
services:
alltalk-tts:
image: erew123/alltalk_tts:cuda
restart: unless-stopped
ports:
- "7851:7851"
volumes:
- ./outputs:/app/outputs/
- ./models:/app/models/
- ./voices:/app/voices/
- ./finetune/put-voice-samples-in-here:/app/finetune/put-voice-samples-in-here
- ./dockerconfig.json:/app/confignew.json
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [ gpu ]
-27
View File
@@ -1,27 +0,0 @@
version: '3.8'
services:
alltalk-tts:
image: ${IMAGE:-alltalk:v1-9c}
restart: unless-stopped
ports:
- "7851:7851"
- "7852:7852"
volumes:
- ./outputs:/app/outputs/
- ./models:/app/models/
- ./voices:/app/voices/
- ./finetune/put-voice-samples-in-here:/app/finetune/put-voice-samples-in-here
- ./dockerconfig.json:/app/confignew.json
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:7851/api/ready"]
interval: 1m30s
timeout: 30s
retries: 5
start_period: 30s
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [ gpu ]
+74
View File
@@ -0,0 +1,74 @@
#!/usr/bin/env bash
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
. ${SCRIPT_DIR=}/docker/variables.sh
WITH_UI=true
DOCKER_TAG=latest
declare -a ADDITIONAL_ARGS=()
# Parse arguments
while [ "$#" -gt 0 ]; do
case "$1" in
--config)
CONFIG="$2"
shift
;;
--voices)
VOICES="$2"
shift
;;
--rvc_voices)
RVC_VOICES="$2"
shift
;;
--no_ui)
WITH_UI=false
;;
--tag)
DOCKER_TAG="$2"
shift
;;
--github-repository)
if [ -n "${GITHUB_REPOSITORY}" ] && ! [[ $GITHUB_REPOSITORY =~ ^--.* ]]; then
GITHUB_REPOSITORY="$2"
shift
fi
;;
*)
# Allow to pass arbitrary arguments to docker as well to be flexible:
ADDITIONAL_ARGS+=( $1 )
;;
esac
shift
done
# Compose docker arguments based on user input to the script:
declare -a DOCKER_ARGS=()
if [[ -n $CONFIG ]]; then
# Mount the config file to docker_confignew.json:
DOCKER_ARGS+=( -v ${CONFIG}:${ALLTALK_DIR}/docker_confignew.json )
fi
if [[ -n $VOICES ]]; then
DOCKER_ARGS+=( -v ${VOICES}:${ALLTALK_DIR}/voices )
fi
if [[ -n $RVC_VOICES ]]; then
DOCKER_ARGS+=( -v ${RVC_VOICES}:${ALLTALK_DIR}/models/rvc_voices )
fi
if [ "$WITH_UI" = true ] ; then
DOCKER_ARGS+=( -p 7852:7852 )
fi
docker run \
--rm \
-it \
-p 7851:7851 \
--gpus=all \
--name alltalk \
"${DOCKER_ARGS[@]}" \
"${ADDITIONAL_ARGS[@]}" \
${GITHUB_REPOSITORY}alltalk_beta:${DOCKER_TAG} &> /dev/stdout
+80
View File
@@ -0,0 +1,80 @@
FROM continuumio/miniconda3:24.7.1-0 AS build
ARG CUDA_VERSION=12.6.0
ENV CUDA_VERSION=$CUDA_VERSION
ARG PYTHON_VERSION=3.11.11
ENV PYTHON_VERSION=$PYTHON_VERSION
SHELL ["/bin/bash", "-l", "-c"]
ENV SHELL=/bin/bash
ENV HOST=0.0.0.0
ENV DEBIAN_FRONTEND=noninteractive
ENV CUDA_DOCKER_ARCH=all
ENV NVIDIA_VISIBLE_DEVICES=all
ENV CONDA_AUTO_UPDATE_CONDA="false"
ENV ALLTALK_DIR=/opt/alltalk
##############################################################################
# Installation/Basic Utilities
##############################################################################
RUN <<EOR
apt-get update
apt-get upgrade -y
apt-get install --no-install-recommends -y \
espeak-ng \
curl \
wget \
jq \
vim
apt-get clean && rm -rf /var/lib/apt/lists/*
EOR
##############################################################################
# Create a conda environment and install dependencies:
##############################################################################
RUN <<EOR
CUDA_SHORT_VERSION=${CUDA_VERSION%.*}
conda create -y -n "alltalk" -c conda-forge python=${PYTHON_VERSION}
conda activate alltalk
conda install -y \
gcc_linux-64 \
gxx_linux-64 \
libaio \
faiss-gpu=1.9.0 \
cuda=${CUDA_VERSION} cuda-tools=${CUDA_VERSION} cuda-toolkit=${CUDA_VERSION} cuda-version=${CUDA_SHORT_VERSION} \
cuda-command-line-tools=${CUDA_VERSION} cuda-compiler=${CUDA_VERSION} cuda-runtime=${CUDA_VERSION} \
cuda-libraries=${CUDA_VERSION} cuda-libraries-dev=${CUDA_VERSION} cuda-libraries-static=${CUDA_VERSION} \
cuda-cudart=${CUDA_SHORT_VERSION} cuda-cudart_linux-64=${CUDA_SHORT_VERSION} \
cudnn=9.3 \
py-cpuinfo=9 \
conda-forge::ffmpeg=7.1.0 \
conda-forge::portaudio=19.7.0 \
-c pytorch \
-c nvidia \
-c anaconda
if [ $? -ne 0 ] ; then
echo "Failed to install conda dependencies: $RESULT"
exit 1
fi
conda clean -a && pip cache purge
EOR
RUN <<EOR
CUDA_SHORT_VERSION=${CUDA_VERSION%.*}
CUDA_SHORT_VERSION_NO_DOT=${CUDA_SHORT_VERSION//./}
conda activate alltalk
mkdir -p ${ALLTALK_DIR}/pip_cache
pip install --no-cache-dir --cache-dir=${ALLTALK_DIR}/pip_cache \
torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu${CUDA_SHORT_VERSION_NO_DOT}
if [ $? -ne 0 ] ; then
echo "Failed to install pip dependencies: $RESULT"
exit 1
fi
EOR
+47
View File
@@ -0,0 +1,47 @@
#!/usr/bin/env bash
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
cd $SCRIPT_DIR
. ${SCRIPT_DIR=}/../variables.sh
DOCKER_TAG=latest
# Parse arguments
while [ "$#" -gt 0 ]; do
case "$1" in
--cuda-version)
CUDA_VERSION="$2"
shift
;;
--python-version)
PYTHON_VERSION="$2"
shift
;;
--tag)
DOCKER_TAG="$2"
shift
;;
--github-repository)
if [ -n "${GITHUB_REPOSITORY}" ] && ! [[ $GITHUB_REPOSITORY =~ ^--.* ]]; then
GITHUB_REPOSITORY="$2"
shift
fi
;;
*)
echo "Unknown argument '$1'"
exit 1
;;
esac
shift
done
echo "Building conda environment using python ${PYTHON_VERSION} with CUDA ${CUDA_VERSION}"
docker buildx \
build \
--progress=plain \
--build-arg CUDA_VERSION=$CUDA_VERSION \
--build-arg PYTHON_VERSION=$PYTHON_VERSION \
-t ${GITHUB_REPOSITORY}alltalk_environment:${DOCKER_TAG} \
.
+65
View File
@@ -0,0 +1,65 @@
ARG GITHUB_REPOSITORY
FROM ${GITHUB_REPOSITORY}alltalk_environment:latest
ARG DEEPSPEED_VERSION=0.16.3
ENV DEEPSPEED_VERSION=$DEEPSPEED_VERSION
##############################################################################
# Directories:
##############################################################################
ENV STAGE_DIR=/tmp
RUN mkdir -p ${STAGE_DIR}
##############################################################################
# Install python dependencies
##############################################################################
ENV PIP_CACHE_DIR=/tmp/pip_cache
RUN <<EOR
conda activate alltalk
pip install \
deepspeed-kernels
EOR
##############################################################################
# Clone DeepSpeed sources
##############################################################################
RUN <<EOR
git clone https://github.com/microsoft/DeepSpeed.git ${STAGE_DIR}/DeepSpeed
cd ${STAGE_DIR}/DeepSpeed
git checkout .
git checkout "tags/v${DEEPSPEED_VERSION}" -b "v${DEEPSPEED_VERSION}"
# Patching some files due to bug https://github.com/microsoft/DeepSpeed/issues/6709
START_LINE=`awk '/#ifndef BF16_AVAILABLE/{ print NR; exit }' csrc/transformer/inference/csrc/gelu.cu`
TO_LINE=$((START_LINE + 2))
sed -i "${START_LINE},${TO_LINE}d" ./csrc/transformer/inference/csrc/gelu.cu
START_LINE=`awk '/#ifndef BF16_AVAILABLE/{ print NR; exit }' csrc/transformer/inference/csrc/transform.cu`
TO_LINE=$((START_LINE + 2))
sed -i "${START_LINE},${TO_LINE}d" ./csrc/transformer/inference/csrc/transform.cu
EOR
##############################################################################
# Create DeepSpeed build file
##############################################################################
RUN <<EOR
cat << EOF > build_deepspeed.sh
#!/usr/bin/env bash
source ~/.bashrc
mkdir -p /deepspeed
conda activate alltalk
cd ${STAGE_DIR}/DeepSpeed
DS_BUILD_OPS=1 python setup.py build_ext -j8 bdist_wheel
mv ${STAGE_DIR}/DeepSpeed/dist/*.whl /deepspeed/
EOF
EOR
RUN chmod +x /build_deepspeed.sh
##############################################################################
# Build DeepSpeed:
##############################################################################
ENTRYPOINT ["/build_deepspeed.sh"]
+65
View File
@@ -0,0 +1,65 @@
#!/usr/bin/env bash
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
cd $SCRIPT_DIR
. ${SCRIPT_DIR=}/../variables.sh
DOCKER_TAG=latest
# Parse arguments
while [ "$#" -gt 0 ]; do
case "$1" in
--python-version)
PYTHON_VERSION="$2"
shift
;;
--deepspeed-version)
DEEPSPEED_VERSION="$2"
shift
;;
--tag)
DOCKER_TAG="$2"
shift
;;
--github-repository)
if [ -n "${GITHUB_REPOSITORY}" ] && ! [[ $GITHUB_REPOSITORY =~ ^--.* ]]; then
GITHUB_REPOSITORY="$2"
shift
fi
;;
*)
echo "Unknown argument '$1'"
exit 1
;;
esac
shift
done
PYTHON_SHORT_VERSION=${PYTHON_VERSION%.*}
PYTHON_VERSION_NO_DOT=${PYTHON_SHORT_VERSION//./}
if [[ -n $(find build -name "deepspeed-${DEEPSPEED_VERSION}*-cp${PYTHON_VERSION_NO_DOT}-cp${PYTHON_VERSION_NO_DOT}-*.whl") ]]
then
echo "DeepSpeed was already built - skipping..."
exit 0
fi
echo "Building DeepSpeed $DEEPSPEED_VERSION using python ${PYTHON_VERSION}"
rm -rf build # make sure to properly clean up
mkdir -p build
docker buildx \
build \
--build-arg GITHUB_REPOSITORY=$GITHUB_REPOSITORY \
--build-arg DEEPSPEED_VERSION=$DEEPSPEED_VERSION \
-t ${GITHUB_REPOSITORY}alltalk_deepspeed:${DOCKER_TAG} \
.
docker run \
--rm \
-it \
--gpus=all \
--name deepspeed \
-v $SCRIPT_DIR/build:/deepspeed \
${GITHUB_REPOSITORY}alltalk_deepspeed:${DOCKER_TAG}
+7
View File
@@ -0,0 +1,7 @@
#!/usr/bin/env bash
export CUDA_VERSION=12.6.0
export PYTHON_VERSION=3.11.11
export DEEPSPEED_VERSION=0.16.2
export ALLTALK_DIR=/opt/alltalk
export GITHUB_REPOSITORY=
+1
View File
@@ -0,0 +1 @@
{}
+7
View File
@@ -0,0 +1,7 @@
{
"delete_output_wavs": "1",
"rvc_settings": {
"rvc_enabled": true,
"f0method": "rmvpe"
}
}
-25
View File
@@ -1,25 +0,0 @@
{
"activate": true,
"autoplay": true,
"branding": "AllTalk ",
"narrator_enabled": false,
"deepspeed_activate": true,
"delete_output_wavs": "Disabled",
"ip_address": "127.0.0.1",
"language": "English",
"low_vram": false,
"local_temperature": "0.7",
"local_repetition_penalty": "10.0",
"tts_model_loaded": true,
"tts_model_name": "tts_models/multilingual/multi-dataset/xtts_v2",
"narrator_voice": "female_01.wav",
"output_folder_wav": "extensions/alltalk_tts/outputs/",
"output_folder_wav_standalone": "outputs/",
"port_number": "7851",
"remove_trailing_dots": false,
"show_text": true,
"tts_method_api_local": false,
"tts_method_api_tts": false,
"tts_method_xtts_local": true,
"voice": "female_01.wav"
}
+4149 -1228
View File
File diff suppressed because it is too large. Load diff
+329
View File
@@ -0,0 +1,329 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "H-WKVp4Uukcl"
},
"source": [
"#Install Server Requirements\n",
"This should be run on a minimum of a T4 runtime, though it will run on a CPU only session, however long TTS generations may time out/error.\n",
"\n",
"This is a **work in progress**. Known issues:\n",
"\n",
"- The 1st TTS generation has a brief stutter.\n",
"- RVC is not yet working.\n",
"- Transcoding/ffmpeg isnt working.\n",
"- Things yet to do on selecting your first model and other configuration setups.\n",
"\n",
"If you enable DeepSpeed for XTTS models, DeepSpeed has to compile on the 1st TTS generation which can take about 90 seconds. After that it should be fine."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"cellView": "form",
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "W6ls-RHTQeZv",
"outputId": "25c62fb3-26ef-4493-8647-1d8e49bf5f01"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"************************************\n",
"** Server requirements installed ***\n",
"*** Please proceed to next step ****\n",
"************************************\n",
"\n"
]
}
],
"source": [
"#@markdown Click the `Play button` to the left of this message to install the requirements.<br><br>\n",
"#@markdown **OPTIONAL** Mounting your Google Drive allows you to drag and drop samples/models via the `drive/Mydrive` path. This allows you<br>\n",
"#@markdown to store or use specific audio samples or finetuned models.<br>\n",
"#@markdown **Audio samples** need to be placed in `alltalk_tts/voices`<br>\n",
"#@markdown **XTTS models** need to be placed in `alltalk_tts/models/xtts/{yourmodelfolderhere}`<br>\n",
"mount_gdrive = False #@param{type:\"boolean\"}\n",
"\n",
"if mount_gdrive:\n",
" from google.colab import drive\n",
" drive.mount('/content/drive')\n",
"from IPython.display import clear_output\n",
"print(\"*******************************************************************\")\n",
"print(\"** Installing server requirements. This will take 5-10 minutes ****\")\n",
"print(\"*******************************************************************\")\n",
"!apt install libasound2-dev portaudio19-dev libportaudio2 libportaudiocpp0 libaio-dev espeak-ng > '/dev/null' 2>&1\n",
"clear_output()\n",
"print(\"************************\")\n",
"print(\"*** Cloning AllTalk ****\")\n",
"print(\"************************\\n\")\n",
"!git clone -b alltalkbeta https://github.com/erew123/alltalk_tts\n",
"clear_output()\n",
"print(\"\\n********************************\")\n",
"print(\"*** Installing Requirements ****\")\n",
"print(\"********************************\\n\")\n",
"!python -m pip install --upgrade \"pip<24.1\"\n",
"!pip install --quiet -r /content/alltalk_tts/system/requirements/requirements_colab.txt\n",
"clear_output()\n",
"print(\"\\n*****************************\")\n",
"print(\"*** Installing DeepSpeed ****\")\n",
"print(\"*****************************\\n\")\n",
"!pip install deepspeed\n",
"!pip install orjson\n",
"!pip install faiss-cpu\n",
"!pip install fairseq\n",
"clear_output()\n",
"print(\"\\n******************************\")\n",
"print(\"*** Installing Cloudflare ****\")\n",
"print(\"******************************\\n\")\n",
"# Install cloudflare\n",
"!wget -q https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb > '/dev/null' 2>&1\n",
"!apt install ./cloudflared-linux-amd64.deb aria2 > '/dev/null' 2>&1\n",
"!rm cloudflared-linux-amd64.deb > '/dev/null' 2>&1\n",
"!python -m spacy download en_core_web_md\n",
"clear_output()\n",
"print(\"\\n***************************\")\n",
"print(\"*** Installing Cutlass ****\")\n",
"print(\"***************************\\n\")\n",
"# Clone the CUTLASS repository\n",
"!git clone https://github.com/NVIDIA/cutlass.git\n",
"!export CUTLASSPATH=/content/cutlass\n",
"!sudo curl -L https://github.com/BtbN/FFmpeg-Builds/releases/download/latest/ffmpeg-master-latest-linux64-gpl.tar.xz -o /usr/local/bin/ffmpeg.tar.xz\n",
"clear_output()\n",
"%cd /usr/local/bin/\n",
"clear_output()\n",
"!7z e /usr/local/bin/ffmpeg.tar.xz -y\n",
"clear_output()\n",
"!7z e /usr/local/bin/ffmpeg.tar -y\n",
"clear_output()\n",
"!sudo chmod a+rx /usr/local/bin/ffmpeg\n",
"clear_output()\n",
"!pip uninstall jax -y\n",
"clear_output()\n",
"print(\"************************************\")\n",
"print(\"** Server requirements installed ***\")\n",
"print(\"*** Please proceed to next step ****\")\n",
"print(\"************************************\\n\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "2nk26r66RQ23"
},
"source": [
"\n",
"# Start AllTalk TTS Server\n",
"\n",
"This will start the AllTalk API and Gradio Web interface. From here you can download models, generate TTS and use external applications via the API address.\n",
"\n",
"The AllTalk API address is what you would use in Kobold, SillyTavern, TGWUI's Remote extension etc if you want to generate TTS with those applications."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"cellView": "form",
"id": "9PCQhSoiWvhL"
},
"outputs": [],
"source": [
"#@markdown Click the `Play button` to the left of this message to start AllTalk API and Gradio Interface<br>\n",
"import re\n",
"import time\n",
"import json\n",
"import threading\n",
"import time\n",
"\n",
"def keep_alive():\n",
" while True:\n",
" time.sleep(60) # Run every 60 seconds (adjust as needed)\n",
"\n",
"keep_alive_thread = threading.Thread(target=keep_alive)\n",
"keep_alive_thread.start()\n",
"\n",
"Tunnel = \"cloudflare\"\n",
"host = \"127.0.0.1\"\n",
"ports = [7851, 7852]\n",
"tunnel_urls = []\n",
"\n",
"# Starting tunnels for each port.\n",
"for port in ports:\n",
" if Tunnel == \"cloudflare\":\n",
" !nohup cloudflared tunnel --url http://{host}:{port} > lt_{port}.log 2>&1 &\n",
" else:\n",
" !nohup npx lt -p {port} > lt_{port}.log 2>&1 &\n",
"\n",
"# Wait a couple of seconds for the tunnels to initialize.\n",
"time.sleep(10)\n",
"\n",
"# Extract URLs for each tunnel.\n",
"for port in ports:\n",
" log_file = f'lt_{port}.log'\n",
" with open(log_file, 'r') as testwritefile:\n",
" log_content = testwritefile.read()\n",
"\n",
" # Use regular expressions to find the URL.\n",
" if Tunnel == \"cloudflare\":\n",
" url_match = re.search(r'(https://[-a-z0-9]+\\.trycloudflare\\.com)', log_content)\n",
" else:\n",
" url_match = re.search(r'your url is: (https?://\\S+)', log_content)\n",
"\n",
" if url_match:\n",
" tunnel_url = url_match.group(1)\n",
" tunnel_urls.append(tunnel_url)\n",
" else:\n",
" print(f\"URL for port {port} not found.\")\n",
"\n",
"# Save the tunnel URLs to a JSON file.\n",
"try:\n",
" # Try to open the JSON file for reading.\n",
" with open('/content/alltalk_tts/googlecolab.json', 'r') as f:\n",
" data = json.load(f)\n",
"except FileNotFoundError:\n",
" # If the file doesn't exist, create an empty dictionary.\n",
" data = {}\n",
"\n",
"data['google_ip_address'] = tunnel_urls\n",
"\n",
"# Write the modified data (or newly created data) back to the file.\n",
"with open('/content/alltalk_tts/googlecolab.json', 'w') as f:\n",
" json.dump(data, f)\n",
"\n",
"host = \"0.0.0.0\"\n",
"\n",
"if Tunnel == \"localtunnel\":\n",
" print(\"Before you copy the link above click on it and copy that ip:\")\n",
" !curl ipv4.icanhazip.com\n",
"\n",
"# Start API server.\n",
"!python /content/alltalk_tts/script.py\n"
]
},
{
"cell_type": "markdown",
"source": [
"# Start XTTS model Finetuning\n",
"\n",
"Starts the Finetuning application for XTTS models.\n",
"\n",
"You can either run the `Start AllTalk` to download the base XTTS model(s) for finetuning. Or you can use the folder icon on the left hand side of the screen and upload an XTTS model that you want to finetune. If you are manually uploading a model, you would place your model files in `models/xtts/{yourmodelfolderhere}` and you will need all the models files in that folder `config.json, dvae.pth, mel_stats.pth, model.pth, speakers_xtts.pth, vocab.json`. Without 1x model available, Finetuning will not start.\n",
"\n",
"Likewise you can download your finetuned model from there, OR copy it to your Google Drive after finetuning, for later use in AllTalk. To access the Finetuning Gradio interface, connect to the `Google Colab Finetuning url` when Finetuning has started."
],
"metadata": {
"id": "gDzNPMwM7qvs"
}
},
{
"cell_type": "code",
"source": [
"#@markdown Click the `Play button` to the left of this message to start Finetuning<br>\n",
"import re\n",
"import time\n",
"import json\n",
"import threading\n",
"import time\n",
"\n",
"def keep_alive():\n",
" while True:\n",
" time.sleep(60) # Run every 60 seconds (adjust as needed)\n",
"\n",
"keep_alive_thread = threading.Thread(target=keep_alive)\n",
"keep_alive_thread.start()\n",
"\n",
"Tunnel = \"cloudflare\"\n",
"host = \"127.0.0.1\"\n",
"ports = [7052]\n",
"tunnel_urls = []\n",
"\n",
"# Starting tunnels for each port.\n",
"for port in ports:\n",
" if Tunnel == \"cloudflare\":\n",
" !nohup cloudflared tunnel --url http://{host}:{port} > lt_{port}.log 2>&1 &\n",
" else:\n",
" !nohup npx lt -p {port} > lt_{port}.log 2>&1 &\n",
"\n",
"# Wait a couple of seconds for the tunnels to initialize.\n",
"time.sleep(10)\n",
"\n",
"# Extract URLs for each tunnel.\n",
"for port in ports:\n",
" log_file = f'lt_{port}.log'\n",
" with open(log_file, 'r') as testwritefile:\n",
" log_content = testwritefile.read()\n",
"\n",
" # Use regular expressions to find the URL.\n",
" if Tunnel == \"cloudflare\":\n",
" url_match = re.search(r'(https://[-a-z0-9]+\\.trycloudflare\\.com)', log_content)\n",
" else:\n",
" url_match = re.search(r'your url is: (https?://\\S+)', log_content)\n",
"\n",
" if url_match:\n",
" tunnel_url = url_match.group(1)\n",
" tunnel_urls.append(tunnel_url)\n",
" print(f\"Google Colab Finetuning url: {tunnel_url}\\n\")\n",
" print(f\"********************************************************************\")\n",
" print(f\"**** Use the above URL to connect to Finetuning on Google Colab ****\")\n",
" print(f\"********************************************************************\")\n",
" print(f\"************* Now starting the Finetuning Application **************\")\n",
" print(f\"********************************************************************\\n\")\n",
" else:\n",
" print(f\"URL for port {port} not found.\")\n",
"\n",
"# Save the tunnel URLs to a JSON file.\n",
"try:\n",
" # Try to open the JSON file for reading.\n",
" with open('/content/alltalk_tts/googlecolab.json', 'r') as f:\n",
" data = json.load(f)\n",
"except FileNotFoundError:\n",
" # If the file doesn't exist, create an empty dictionary.\n",
" data = {}\n",
"\n",
"data['google_ip_address'] = tunnel_urls\n",
"\n",
"# Write the modified data (or newly created data) back to the file.\n",
"with open('/content/alltalk_tts/googlecolab.json', 'w') as f:\n",
" json.dump(data, f)\n",
"\n",
"host = \"0.0.0.0\"\n",
"\n",
"if Tunnel == \"localtunnel\":\n",
" print(\"Before you copy the link above click on it and copy that ip:\")\n",
" !curl ipv4.icanhazip.com\n",
"\n",
"# Start API server.\n",
"!python /content/alltalk_tts/finetune.py\n"
],
"metadata": {
"cellView": "form",
"id": "Dewvq5s38Sfd"
},
"execution_count": null,
"outputs": []
}
],
"metadata": {
"accelerator": "GPU",
"colab": {
"gpuType": "T4",
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
},
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
-5
View File
@@ -1,5 +0,0 @@
#!/bin/sh
python modeldownload.py
uvicorn tts_server:app --host 0.0.0.0 --port 7851 --workers 1 --proxy-headers &
sleep 5
python script.py
-14
View File
@@ -1,14 +0,0 @@
{
"base_path": "models",
"model_path": "xttsv2_2.0.2",
"files_to_download": {
"LICENSE.txt": "https://huggingface.co/coqui/XTTS-v2/resolve/v2.0.2/LICENSE.txt?download=true",
"README.md": "https://huggingface.co/coqui/XTTS-v2/resolve/v2.0.2/README.md?download=true",
"config.json": "https://huggingface.co/coqui/XTTS-v2/resolve/v2.0.2/config.json?download=true",
"model.pth": "https://huggingface.co/coqui/XTTS-v2/resolve/v2.0.2/model.pth?download=true",
"dvae.pth": "https://huggingface.co/coqui/XTTS-v2/resolve/v2.0.2/dvae.pth?download=true",
"mel_stats.pth": "https://huggingface.co/coqui/XTTS-v2/resolve/v2.0.2/mel_stats.pth?download=true",
"speakers_xtts.pth": "https://huggingface.co/coqui/XTTS-v2/resolve/v2.0.2/speakers_xtts.pth?download=true",
"vocab.json": "https://huggingface.co/coqui/XTTS-v2/resolve/v2.0.2/vocab.json?download=true"
}
}
-193
View File
@@ -1,193 +0,0 @@
import os
import sys
from pathlib import Path
import requests
from requests.exceptions import ConnectionError
from tqdm import tqdm
import importlib.metadata as metadata
import json
from packaging import version
from datetime import datetime
#################################################################
#### LOAD PARAMS FROM confignew.json - REQUIRED FOR BRANDING ####
#################################################################
# STARTUP VARIABLE - Create "this_dir" variable as the current script directory
this_dir = Path(__file__).parent.resolve()
# load standard config file in and get settings
def load_config(file_path):
with open(file_path, "r") as config_file:
config = json.load(config_file)
return config
config_file_path = this_dir / "confignew.json"
params = load_config(config_file_path)
# Define the path to the modeldownload config file file
modeldownload_config_file_path = this_dir / "modeldownload.json"
# Check if the JSON file exists
if modeldownload_config_file_path.exists():
with open(modeldownload_config_file_path, "r") as config_file:
settings = json.load(config_file)
# Extract settings from the loaded JSON
base_path = Path(settings.get("base_path", ""))
model_path = Path(settings.get("model_path", ""))
files_to_download = settings.get("files_to_download", {})
else:
# Default settings if the JSON file doesn't exist or is empty
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.")
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
with open(this_dir / "system" / "requirements" / "requirements_standalone.txt", "r") as req_file:
requirements = req_file.readlines()
tts_version_required = None
for req in requirements:
if req.startswith("TTS=="):
tts_version_required = req.strip().split("==")[1]
break
if tts_version_required is None:
raise ValueError(f"[{params['branding']}Startup] \033[91mWarning\033[0m Could not find TTS version specifier in requirements file")
def create_directory_if_not_exists(directory):
if not directory.exists():
directory.mkdir(parents=True)
def download_file(url, destination):
response = requests.get(url, stream=True)
total_size_in_bytes = int(response.headers.get("content-length", 0))
block_size = 1024 # 1 Kibibyte
progress_bar = tqdm(total=total_size_in_bytes, unit="iB", unit_scale=True)
with open(destination, "wb") as file:
for data in response.iter_content(block_size):
progress_bar.update(len(data))
file.write(data)
progress_bar.close()
def check_tts_version():
try:
tts_version = metadata.version("tts")
print(f"[{params['branding']}Startup] \033[92mCurrent TTS Version : \033[93m"+tts_version+"\033[0m")
if version.parse(tts_version) < version.parse(tts_version_required):
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")
print(f"[{params['branding']}Startup] \033[91mWarning\033[0m At your terminal/command prompt \033[94mpip install --upgrade tts\033[0m")
else:
print(f"[{params['branding']}Startup] \033[92mCurrent TTS Version is :\033[93m Up to date\033[0m")
except metadata.PackageNotFoundError:
print(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
if str(base_path) == "models":
create_directory_if_not_exists(this_dir / base_path / model_path)
else:
create_directory_if_not_exists(base_path / model_path)
print(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(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
print(f"[{params['branding']}Startup] \033[92mModel is available :\033[93m Checking\033[0m")
for filename, url in files_to_download.items():
if str(base_path) == "models":
destination = this_dir / base_path / model_path / filename
else:
destination = Path(base_path) / model_path / filename
if not destination.exists():
print(f"[{params['branding']}Startup] \033[92mModel Downloading file : \033[93m" + filename + "\033[0m")
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()
# 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")
-22
View File
@@ -1,22 +0,0 @@
FROM nvidia/cuda:12.1.1-devel-ubuntu22.04
ENV HOST 0.0.0.0
RUN apt-get update && apt-get upgrade -y \
&& apt-get install -y git build-essential portaudio19-dev \
python3 python3-pip gcc wget \
ocl-icd-opencl-dev opencl-headers clinfo \
libclblast-dev libopenblas-dev \
&& mkdir -p /etc/OpenCL/vendors && echo "libnvidia-opencl.so.1" > /etc/OpenCL/vendors/nvidia.icd \
&& ln -s /usr/bin/python3 /usr/bin/python
RUN mkdir /app/pip_cache
ENV PIP_CACHE_DIR=/app/pip_cache
WORKDIR /app
COPY . .
ENV CUDA_DOCKER_ARCH=all
RUN pip install --no-cache-dir --no-deps -r system/requirements/requirements_standalone.txt --cache-dir=/app/pip_cache && \
pip install --no-cache-dir deepspeed --cache-dir=/app/pip_cache
EXPOSE 7851
RUN chmod +x launch.sh
ENTRYPOINT ["sh", "-c", "./launch.sh"]
+2
View File
@@ -0,0 +1,2 @@
[pytest]
pythonpath = .
+4793 -916
View File
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,20 @@
BASIC SETUP
-----------
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.
File diff suppressed because it is too large. Load diff
@@ -0,0 +1 @@
Place the `alltalk.js` in your `\SillyTavern\public\scripts\extensions\tts\` folder, replacing the existing file.
@@ -281,7 +281,7 @@ class AllTalkTtsProvider {
if (narratorVoiceSelect) narratorVoiceSelect.disabled = !this.settings.narrator_enabled; if (narratorVoiceSelect) narratorVoiceSelect.disabled = !this.settings.narrator_enabled;
} }
const modelSelect = document.getElementById('switch_model'); const modelSelect = document.getElementById('switch_model');
if (this.settings.finetuned_model === true) { if (this.settings.finetuned_model === 'true') {
const ftOption = document.createElement('option'); const ftOption = document.createElement('option');
ftOption.value = 'XTTSv2 FT'; ftOption.value = 'XTTSv2 FT';
ftOption.textContent = 'XTTSv2 FT'; ftOption.textContent = 'XTTSv2 FT';
@@ -695,7 +695,7 @@ class AllTalkTtsProvider {
const data = await response.json(); const data = await response.json();
if (data.output_file_url) { if (data.output_file_url) {
// Use an audio element to play the .wav file // Use an audio element to play the .wav file
const audioElement = new Audio(data.output_file_url); const audioElement = new Audio(`${this.settings.provider_endpoint}${data.output_file_url}`);
audioElement.play().catch(e => console.error("Error playing audio:", e)); audioElement.play().catch(e => console.error("Error playing audio:", e));
} else { } else {
console.warn("[previewTtsVoice] No output file URL received in the response"); console.warn("[previewTtsVoice] No output file URL received in the response");
@@ -798,7 +798,8 @@ class AllTalkTtsProvider {
throw new Error(`HTTP ${response.status}: ${errorText}`); throw new Error(`HTTP ${response.status}: ${errorText}`);
} }
const data = await response.json(); const data = await response.json();
const outputUrl = data.output_file_url; //const outputUrl = data.output_file_url;
const outputUrl = `${this.settings.provider_endpoint}${data.output_file_url}`;
return outputUrl; // Return only the output_file_url return outputUrl; // Return only the output_file_url
} catch (error) { } catch (error) {
console.error("[fetchTtsGeneration] Exception caught:", error); console.error("[fetchTtsGeneration] Exception caught:", error);
@@ -0,0 +1,17 @@
Text-generation-webui remote extension for AllTalk!
This folder contains everything you need to set up a Text-generation-webui extension that can communicate with an AllTalk server remotely.
To get started, follow these simple steps:
1) In your Text-generation-webui's extensions folder, create a new folder and name it "alltalk_tts".
2) Take all the files from this current folder and copy them into the newly created "alltalk_tts" folder.
3) Start & Open Text-generation-webui and look for "alltalk_tts" in the list of extensions. Select alltalk_tts, save your settings and restart Text-generation-webui.
4) Text-generation-webui will restart and load the AllTalk extension. You may see an error/warning as the extension will not yet have the IP address details of your remote AllTalk server.
5) In the extension settings, enter the correct IP address and port of your AllTalk server. If your AllTalk server is running on a remote machine accessed through a secure tunnel, make sure to use "https" instead of "http".
6) After entering the server details, click on the "Refresh settings & voices" button. If the settings are correct, the extension will download all the available settings from the AllTalk server.
7) The first time you successfully generate speech using the extension, the settings will be automatically saved to a local configuration file.
Please note that if the AllTalk server you're connected to doesn't support certain settings/features, those options will be greyed out and unavailable in the extension.
Please use the "Refresh settings & voices" button to make sure the extension is in sync with your AllTalk server.
@@ -0,0 +1,720 @@
The birch canoe slid on the smooth planks.
Glue the sheet to the dark blue background.
It's easy to tell the depth of a well.
These days a chicken leg is a rare dish.
Rice is often served in round bowls.
The juice of lemons makes fine punch.
The box was thrown beside the parked truck.
The hogs were fed chopped corn and garbage.
Four hours of steady work faced us.
A large size in stockings is hard to sell.
The boy was there when the sun rose.
A rod is used to catch pink salmon.
The source of the huge river is the clear spring.
Kick the ball straight and follow through.
Help the woman get back to her feet.
A pot of tea helps to pass the evening.
Smoky fires lack flame and heat.
The soft cushion broke the man's fall.
The salt breeze came across from the sea.
The girl at the booth sold fifty bonds.
The small pup gnawed a hole in the sock.
The fish twisted and turned on the bent hook.
Press the pants and sew a button on the vest.
The swan dive was far short of perfect.
The beauty of the view stunned the young boy.
Two blue fish swam in the tank.
Her purse was full of useless trash.
The colt reared and threw the tall rider.
It snowed, rained, and hailed the same morning.
Read verse out loud for pleasure.
Hoist the load to your left shoulder.
Take the winding path to reach the lake.
Note closely the size of the gas tank.
Wipe the grease off his dirty face.
Mend the coat before you go out.
The wrist was badly strained and hung limp.
The stray cat gave birth to kittens.
The young girl gave no clear response.
The meal was cooked before the bell rang.
What joy there is in living.
A king ruled the state in the early days.
The ship was torn apart on the sharp reef.
Sickness kept him home the third week.
The wide road shimmered in the hot sun.
The lazy cow lay in the cool grass.
Lift the square stone over the fence.
The rope will bind the seven books at once.
Hop over the fence and plunge in.
The friendly gang left the drug store.
Mesh wire keeps chicks inside.
The frosty air passed through the coat.
The crooked maze failed to fool the mouse.
Adding fast leads to wrong sums.
The show was a flop from the very start.
A saw is a tool used for making boards.
The wagon moved on well oiled wheels.
March the soldiers past the next hill.
A cup of sugar makes sweet fudge.
Place a rosebush near the porch steps.
Both lost their lives in the raging storm.
We talked of the side show in the circus.
Use a pencil to write the first draft.
He ran half way to the hardware store.
The clock struck to mark the third period.
A small creek cut across the field.
Cars and busses stalled in snow drifts.
The set of china hit the floor with a crash.
This is a grand season for hikes on the road.
The dune rose from the edge of the water.
Those words were the cue for the actor to leave.
A yacht slid around the point into the bay.
The two met while playing on the sand.
The ink stain dried on the finished page.
The walled town was seized without a fight.
The lease ran out in sixteen weeks.
A tame squirrel makes a nice pet.
The horn of the car woke the sleeping cop.
The heart beat strongly and with firm strokes.
The pearl was worn in a thin silver ring.
The fruit peel was cut in thick slices.
The Navy attacked the big task force.
See the cat glaring at the scared mouse.
There are more than two factors here.
The hat brim was wide and too droopy.
The lawyer tried to lose his case.
The grass curled around the fence post.
Cut the pie into large parts.
Men strive but seldom get rich.
Always close the barn door tight.
He lay prone and hardly moved a limb.
The slush lay deep along the street.
A wisp of cloud hung in the blue air.
A pound of sugar costs more than eggs.
The fin was sharp and cut the clear water.
The play seems dull and quite stupid.
Bail the boat to stop it from sinking.
The term ended in late June that year.
A tusk is used to make costly gifts.
Ten pins were set in order.
The bill was paid every third week.
Oak is strong and also gives shade.
Cats and dogs each hate the other.
The pipe began to rust while new.
Open the crate but don't break the glass.
Add the sum to the product of these three.
Thieves who rob friends deserve jail.
The ripe taste of cheese improves with age.
Act on these orders with great speed.
The hog crawled under the high fence.
Move the vat over the hot fire.
The bark of the pine tree was shiny and dark.
Leaves turn brown and yellow in the fall.
The pennant waved when the wind blew.
Split the log with a quick, sharp blow.
Burn peat after the logs give out.
He ordered peach pie with ice cream.
Weave the carpet on the right hand side.
Hemp is a weed found in parts of the tropics.
A lame back kept his score low.
We find joy in the simplest things.
Type out three lists of orders.
The harder he tried the less he got done.
The boss ran the show with a watchful eye.
The cup cracked and spilled its contents.
Paste can cleanse the most dirty brass.
The slang word for raw whiskey is booze.
It caught its hind paw in a rusty trap.
The wharf could be seen at the farther shore.
Feel the heat of the weak dying flame.
The tiny girl took off her hat.
A cramp is no small danger on a swim.
He said the same phrase thirty times.
Pluck the bright rose without leaves.
Two plus seven is less than ten.
The glow deepened in the eyes of the sweet girl.
Bring your problems to the wise chief.
Write a fond note to the friend you cherish.
Clothes and lodging are free to new men.
We frown when events take a bad turn.
Port is a strong wine with a smoky taste.
The young kid jumped the rusty gate.
Guess the results from the first scores.
A salt pickle tastes fine with ham.
The just claim got the right verdict.
These thistles bend in a high wind.
Pure bred poodles have curls.
The tree top waved in a graceful way.
The spot on the blotter was made by green ink.
Mud was spattered on the front of his white shirt.
The cigar burned a hole in the desk top.
The empty flask stood on the tin tray.
A speedy man can beat this track mark.
He broke a new shoelace that day.
The coffee stand is too high for the couch.
The urge to write short stories is rare.
The pencils have all been used.
The pirates seized the crew of the lost ship.
We tried to replace the coin but failed.
She sewed the torn coat quite neatly.
The sofa cushion is red and of light weight.
The jacket hung on the back of the wide chair.
At that high level the air is pure.
Drop the two when you add the figures.
A filing case is now hard to buy.
An abrupt start does not win the prize.
Wood is best for making toys and blocks.
The office paint was a dull, sad tan.
He knew the skill of the great young actress.
A rag will soak up spilled water.
A shower of dirt fell from the hot pipes.
Steam hissed from the broken valve.
The child almost hurt the small dog.
There was a sound of dry leaves outside.
The sky that morning was clear and bright blue.
Torn scraps littered the stone floor.
Sunday is the best part of the week.
The doctor cured him with these pills.
The new girl was fired today at noon.
They felt gay when the ship arrived in port.
Add the store's account to the last cent.
Acid burns holes in wool cloth.
Fairy tales should be fun to write.
Eight miles of woodland burned to waste.
The third act was dull and tired the players.
A young child should not suffer fright.
Add the column and put the sum here.
We admire and love a good cook.
There the flood mark is ten inches.
He carved a head from the round block of marble.
She has a smart way of wearing clothes.
The fruit of a fig tree is apple-shaped.
Corn cobs can be used to kindle a fire.
Where were they when the noise started.
The paper box is full of thumb tacks.
Sell your gift to a buyer at a good gain.
The tongs lay beside the ice pail.
The petals fall with the next puff of wind.
Bring your best compass to the third class.
They could laugh although they were sad.
Farmers came in to thresh the oat crop.
The brown house was on fire to the attic.
The lure is used to catch trout and flounder.
Float the soap on top of the bath water.
A blue crane is a tall wading bird.
A fresh start will work such wonders.
The club rented the rink for the fifth night.
After the dance, they went straight home.
The hostess taught the new maid to serve.
He wrote his last novel there at the inn.
Even the worst will beat his low score.
The cement had dried when he moved it.
The loss of the second ship was hard to take.
The fly made its way along the wall.
Do that with a wooden stick.
Live wires should be kept covered.
The large house had hot water taps.
It is hard to erase blue or red ink.
Write at once or you may forget it.
The doorknob was made of bright clean brass.
The wreck occurred by the bank on Main Street.
A pencil with black lead writes best.
Coax a young calf to drink from a bucket.
Schools for ladies teach charm and grace.
The lamp shone with a steady green flame.
They took the axe and the saw to the forest.
The ancient coin was quite dull and worn.
The shaky barn fell with a loud crash.
Jazz and swing fans like fast music.
Rake the rubbish up and then burn it.
Slash the gold cloth into fine ribbons.
Try to have the court decide the case.
They are pushed back each time they attack.
He broke his ties with groups of former friends.
They floated on the raft to sun their white backs.
The map had an X that meant nothing.
Whitings are small fish caught in nets.
Some ads serve to cheat buyers.
Jerk the rope and the bell rings weakly.
A waxed floor makes us lose balance.
Madam, this is the best brand of corn.
On the islands the sea breeze is soft and mild.
The play began as soon as we sat down.
This will lead the world to more sound and fury.
Add salt before you fry the egg.
The rush for funds reached its peak Tuesday.
The birch looked stark white and lonesome.
The box is held by a bright red snapper.
To make pure ice, you freeze water.
The first worm gets snapped early.
Jump the fence and hurry up the bank.
Yell and clap as the curtain slides back.
They are men who walk the middle of the road.
Both brothers wear the same size.
In some form or other we need fun.
The prince ordered his head chopped off.
The houses are built of red clay bricks.
Ducks fly north but lack a compass.
Fruit flavors are used in fizz drinks.
These pills do less good than others.
Canned pears lack full flavor.
The dark pot hung in the front closet.
Carry the pail to the wall and spill it there.
The train brought our hero to the big town.
We are sure that one war is enough.
Gray paint stretched for miles around.
The rude laugh filled the empty room.
High seats are best for football fans.
Tea served from the brown jug is tasty.
A dash of pepper spoils beef stew.
A zestful food is the hot-cross bun.
The horse trotted around the field at a brisk pace.
Find the twin who stole the pearl necklace.
Cut the cord that binds the box tightly.
The red tape bound the smuggled food.
Look in the corner to find the tan shirt.
The cold drizzle will halt the bond drive.
Nine men were hired to dig the ruins.
The junk yard had a mouldy smell.
The flint sputtered and lit a pine torch.
Soak the cloth and drown the sharp odor.
The shelves were bare of both jam or crackers.
A joy to every child is the swan boat.
All sat frozen and watched the screen.
A cloud of dust stung his tender eyes.
To reach the end he needs much courage.
Shape the clay gently into block form.
A ridge on a smooth surface is a bump or flaw.
Hedge apples may stain your hands green.
Quench your thirst, then eat the crackers.
Tight curls get limp on rainy days.
The mute muffled the high tones of the horn.
The gold ring fits only a pierced ear.
The old pan was covered with hard fudge.
Watch the log float in the wide river.
The node on the stalk of wheat grew daily.
The heap of fallen leaves was set on fire.
Write fast if you want to finish early.
His shirt was clean but one button was gone.
The barrel of beer was a brew of malt and hops.
Tin cans are absent from store shelves.
Slide the box into that empty space.
The plant grew large and green in the window.
The beam dropped down on the workmen's head.
Pink clouds floated with the breeze.
She danced like a swan, tall and graceful.
The tube was blown and the tire flat and useless.
It is late morning on the old wall clock.
Let's all join as we sing the last chorus.
The last switch cannot be turned off.
The fight will end in just six minutes.
The store walls were lined with colored frocks.
The peace league met to discuss their plans.
The rise to fame of a person takes luck.
Paper is scarce, so write with much care.
The quick fox jumped on the sleeping cat.
The nozzle of the fire hose was bright brass.
Screw the round cap on as tight as needed.
Time brings us many changes.
The purple tie was ten years old.
Men think and plan and sometimes act.
Fill the ink jar with sticky glue.
He smoke a big pipe with strong contents.
We need grain to keep our mules healthy.
Pack the records in a neat thin case.
The crunch of feet in the snow was the only sound.
The copper bowl shone in the sun's rays.
Boards will warp unless kept dry.
The plush chair leaned against the wall.
Glass will clink when struck by metal.
Bathe and relax in the cool green grass.
Nine rows of soldiers stood in line.
The beach is dry and shallow at low tide.
The idea is to sew both edges straight.
The kitten chased the dog down the street.
Pages bound in cloth make a book.
Try to trace the fine lines of the painting.
Women form less than half of the group.
The zones merge in the central part of town.
A gem in the rough needs work to polish.
Code is used when secrets are sent.
Most of the news is easy for us to hear.
He used the lathe to make brass objects.
The vane on top of the pole revolved in the wind.
Mince pie is a dish served to children.
The clan gathered on each dull night.
Let it burn, it gives us warmth and comfort.
A castle built from sand fails to endure.
A child's wit saved the day for us.
Tack the strip of carpet to the worn floor.
Next Tuesday we must vote.
Pour the stew from the pot into the plate.
Each penny shone like new.
The man went to the woods to gather sticks.
The dirt piles were lines along the road.
The logs fell and tumbled into the clear stream.
Just hoist it up and take it away.
A ripe plum is fit for a king's palate.
Our plans right now are hazy.
Brass rings are sold by these natives.
It takes a good trap to capture a bear.
Feed the white mouse some flower seeds.
The thaw came early and freed the stream.
He took the lead and kept it the whole distance.
The key you designed will fit the lock.
Plead to the council to free the poor thief.
Better hash is made of rare beef.
This plank was made for walking on.
The lake sparkled in the red hot sun.
He crawled with care along the ledge.
Tend the sheep while the dog wanders.
It takes a lot of help to finish these.
Mark the spot with a sign painted red.
Take two shares as a fair profit.
The fur of cats goes by many names.
North winds bring colds and fevers.
He asks no person to vouch for him.
Go now and come here later.
A sash of gold silk will trim her dress.
Soap can wash most dirt away.
That move means the game is over.
He wrote down a long list of items.
A siege will crack the strong defense.
Grape juice and water mix well.
Roads are paved with sticky tar.
Fake stones shine but cost little.
The drip of the rain made a pleasant sound.
Smoke poured out of every crack.
Serve the hot rum to the tired heroes.
Much of the story makes good sense.
The sun came up to light the eastern sky.
Heave the line over the port side.
A lathe cuts and trims any wood.
It's a dense crowd in two distinct ways.
His hip struck the knee of the next player.
The stale smell of old beer lingers.
The desk was firm on the shaky floor.
It takes heat to bring out the odor.
Beef is scarcer than some lamb.
Raise the sail and steer the ship northward.
A cone costs five cents on Mondays.
A pod is what peas always grow in.
Jerk the dart from the cork target.
No cement will hold hard wood.
We now have a new base for shipping.
A list of names is carved around the base.
The sheep were led home by a dog.
Three for a dime, the young peddler cried.
The sense of smell is better than that of touch.
No hardship seemed to keep him sad.
Grace makes up for lack of beauty.
Nudge gently but wake her now.
The news struck doubt into restless minds.
Once we stood beside the shore.
A chink in the wall allowed a draft to blow.
Fasten two pins on each side.
A cold dip restores health and zest.
He takes the oath of office each March.
The sand drifts over the sill of the old house.
The point of the steel pen was bent and twisted.
There is a lag between thought and act.
Seed is needed to plant the spring corn.
Draw the chart with heavy black lines.
The boy owed his pal thirty cents.
The chap slipped into the crowd and was lost.
Hats are worn to tea and not to dinner.
The ramp led up to the wide highway.
Beat the dust from the rug onto the lawn.
Say it slowly but make it ring clear.
The straw nest housed five robins.
Screen the porch with woven straw mats.
This horse will nose his way to the finish.
The dry wax protects the deep scratch.
He picked up the dice for a second roll.
These coins will be needed to pay his debt.
The nag pulled the frail cart along.
Twist the valve and release hot steam.
The vamp of the shoe had a gold buckle.
The smell of burned rags itches my nose.
New pants lack cuffs and pockets.
The marsh will freeze when cold enough.
They slice the sausage thin with a knife.
The bloom of the rose lasts a few days.
A gray mare walked before the colt.
Breakfast buns are fine with a hot drink.
Bottles hold four kinds of rum.
The man wore a feather in his felt hat.
He wheeled the bike past the winding road.
Drop the ashes on the worn old rug.
The desk and both chairs were painted tan.
Throw out the used paper cup and plate.
A clean neck means a neat collar.
The couch cover and hall drapes were blue.
The stems of the tall glasses cracked and broke.
The wall phone rang loud and often.
The clothes dried on a thin wooden rack.
Turn on the lantern which gives us light.
The cleat sank deeply into the soft turf.
The bills were mailed promptly on the tenth of the month.
To have is better than to wait and hope.
The price is fair for a good antique clock.
The music played on while they talked.
Dispense with a vest on a day like this.
The bunch of grapes was pressed into wine.
He sent the figs, but kept the ripe cherries.
The hinge on the door creaked with old age.
The screen before the fire kept in the sparks.
Fly by night, and you waste little time.
Thick glasses helped him read the print.
Birth and death mark the limits of life.
The chair looked strong but had no bottom.
The kite flew wildly in the high wind.
A fur muff is stylish once more.
The tin box held priceless stones.
We need an end of all such matter.
The case was puzzling to the old and wise.
The bright lanterns were gay on the dark lawn.
We don't get much money but we have fun.
The youth drove with zest, but little skill.
Five years he lived with a shaggy dog.
A fence cuts through the corner lot.
The way to save money is not to spend much.
Shut the hatch before the waves push it in.
The odor of spring makes young hearts jump.
Crack the walnut with your sharp side teeth.
He offered proof in the form of a large chart.
Send the stuff in a thick paper bag.
A quart of milk is water for the most part.
They told wild tales to frighten him.
The three story house was built of stone.
In the rear of the ground floor was a large passage.
A man in a blue sweater sat at the desk.
Oats are a food eaten by horse and man.
Their eyelids droop for want of sleep.
A sip of tea revives his tired friend.
There are many ways to do these things.
Tuck the sheet under the edge of the mat.
A force equal to that would move the earth.
We like to see clear weather.
The work of the tailor is seen on each side.
Take a chance and win a china doll.
Shake the dust from your shoes, stranger.
She was kind to sick old people.
The square wooden crate was packed to be shipped.
The dusty bench stood by the stone wall.
We dress to suit the weather of most days.
Smile when you say nasty words.
A bowl of rice is free with chicken stew.
The water in this well is a source of good health.
Take shelter in this tent, but keep still.
That guy is the writer of a few banned books.
The little tales they tell are false.
The door was barred, locked, and bolted as well.
Ripe pears are fit for a queen's table.
A big wet stain was on the round carpet.
The kite dipped and swayed, but stayed aloft.
The pleasant hours fly by much too soon.
The room was crowded with a wild mob.
This strong arm shall shield your honor.
She blushed when he gave her a white orchid.
The beetle droned in the hot June sun.
Press the pedal with your left foot.
Neat plans fail without luck.
The black trunk fell from the landing.
The bank pressed for payment of the debt.
The theft of the pearl pin was kept secret.
Shake hands with this friendly child.
The vast space stretched into the far distance.
A rich farm is rare in this sandy waste.
His wide grin earned many friends.
Flax makes a fine brand of paper.
Hurdle the pit with the aid of a long pole.
A strong bid may scare your partner stiff.
Even a just cause needs power to win.
Peep under the tent and see the clowns.
The leaf drifts along with a slow spin.
Cheap clothes are flashy but don't last.
A thing of small note can cause despair.
Flood the mails with requests for this book.
A thick coat of black paint covered all.
The pencil was cut to be sharp at both ends.
Those last words were a strong statement.
He wrote his name boldly at the top of the sheet.
Dill pickles are sour but taste fine.
Down that road is the way to the grain farmer.
Either mud or dust are found at all times.
The best method is to fix it in place with clips.
If you mumble your speech will be lost.
At night the alarm roused him from a deep sleep.
Read just what the meter says.
Fill your pack with bright trinkets for the poor.
The small red neon lamp went out.
Clams are small, round, soft, and tasty.
The fan whirled its round blades softly.
The line where the edges join was clean.
Breathe deep and smell the piny air.
It matters not if he reads these words or those.
A brown leather bag hung from its strap.
A toad and a frog are hard to tell apart.
A white silk jacket goes with any shoes.
A break in the dam almost caused a flood.
Paint the sockets in the wall dull green.
The child crawled into the dense grass.
Bribes fail where honest men work.
Trample the spark, else the flames will spread.
The hilt of the sword was carved with fine designs.
A round hole was drilled through the thin board.
Footprints showed the path he took up the beach.
She was waiting at my front lawn.
A vent near the edge brought in fresh air.
Prod the old mule with a crooked stick.
It is a band of steel three inches wide.
The pipe ran almost the length of the ditch.
It was hidden from sight by a mass of leaves and shrubs.
The weight of the package was seen on the high scale.
Wake and rise, and step into the green outdoors.
The green light in the brown box flickered.
The brass tube circled the high wall.
The lobes of her ears were pierced to hold rings.
Hold the hammer near the end to drive the nail.
Next Sunday is the twelfth of the month.
Every word and phrase he speaks is true.
He put his last cartridge into the gun and fired.
They took their kids from the public school.
Drive the screw straight into the wood.
Keep the hatch tight and the watch constant.
Sever the twine with a quick snip of the knife.
Paper will dry out when wet.
Slide the catch back and open the desk.
Help the weak to preserve their strength.
A sullen smile gets few friends.
Stop whistling and watch the boys march.
Jerk the cord, and out tumbles the gold.
Slide the tray across the glass top.
The cloud moved in a stately way and was gone.
Light maple makes for a swell room.
Set the piece here and say nothing.
Dull stories make her laugh.
A stiff cord will do to fasten your shoe.
Get the trust fund to the bank early.
Choose between the high road and the low.
A plea for funds seems to come again.
He lent his coat to the tall gaunt stranger.
There is a strong chance it will happen once more.
The duke left the park in a silver coach.
Greet the new guests and leave quickly.
When the frost has come it is time for turkey.
Sweet words work better than fierce.
A thin stripe runs down the middle.
A six comes up more often than a ten.
Lush fern grow on the lofty rocks.
The ram scared the school children off.
The team with the best timing looks good.
The farmer swapped his horse for a brown ox.
Sit on the perch and tell the others what to do.
A steep trail is painful for our feet.
The early phase of life moves fast.
Green moss grows on the northern side.
Tea in thin china has a sweet taste.
Pitch the straw through the door of the stable.
The latch on the back gate needed a nail.
The goose was brought straight from the old market.
The sink is the thing in which we pile dishes.
A whiff of it will cure the most stubborn cold.
The facts don't always show who is right.
She flaps her cape as she parades the street.
The loss of the cruiser was a blow to the fleet.
Loop the braid to the left and then over.
Plead with the lawyer to drop the lost cause.
Calves thrive on tender spring grass.
Post no bills on this office wall.
Tear a thin sheet from the yellow pad.
A cruise in warm waters in a sleek yacht is fun.
A streak of color ran down the left edge.
It was done before the boy could see it.
Crouch before you jump or miss the mark.
Pack the kits and don't forget the salt.
The square peg will settle in the round hole.
Fine soap saves tender skin.
Poached eggs and tea must suffice.
Bad nerves are jangled by a door slam.
Ship maps are different from those for planes.
Dimes showered down from all sides.
They sang the same tunes at each party.
The sky in the west is tinged with orange red.
The pods of peas ferment in bare fields.
The horse balked and threw the tall rider.
The hitch between the horse and cart broke.
Pile the coal high in the shed corner.
A gold vase is both rare and costly.
The knife was hung inside its bright sheath.
The rarest spice comes from the far East.
The roof should be tilted at a sharp slant.
A smatter of French is worse than none.
The mule trod the treadmill day and night.
The aim of the contest is to raise a great fund.
To send it now in large amounts is bad.
There is a fine hard tang in salty air.
Cod is the main business of the north shore.
The slab was hewn from heavy blocks of slate.
Dunk the stale biscuits into strong drink.
Hang tinsel from both branches.
Cap the jar with a tight brass cover.
The poor boy missed the boat again.
Be sure to set the lamp firmly in the hole.
Pick a card and slip it under the pack.
A round mat will cover the dull spot.
The first part of the plan needs changing.
A good book informs of what we ought to know.
The mail comes in three batches per day.
You cannot brew tea in a cold pot.
Dots of light betrayed the black cat.
Put the chart on the mantel and tack it down.
The night shift men rate extra pay.
The red paper brightened the dim stage.
See the player scoot to third base.
Slide the bill between the two leaves.
Many hands help get the job done.
We don't like to admit our small faults.
No doubt about the way the wind blows.
Dig deep in the earth for pirate's gold.
The steady drip is worse than a drenching rain.
A flat pack takes less luggage space.
Green ice frosted the punch bowl.
A stuffed chair slipped from the moving van.
The stitch will serve but needs to be shortened.
A thin book fits in the side pocket.
The gloss on top made it unfit to read.
The hail pattered on the burnt brown grass.
Seven seals were stamped on great sheets.
Our troops are set to strike heavy blows.
The store was jammed before the sale could start.
It was a bad error on the part of the new judge.
One step more and the board will collapse.
Take the match and strike it against your shoe.
The pot boiled, but the contents failed to jell.
The baby puts his right foot in his mouth.
The bombs left most of the town in ruins.
Stop and stare at the hard working man.
The streets are narrow and full of sharp turns.
The pup jerked the leash as he saw a feline shape.
Open your book to the first page.
Fish evade the net and swim off.
Dip the pail once and let it settle.
Will you please answer that phone.
The big red apple fell to the ground.
The curtain rose and the show was on.
The young prince became heir to the throne.
He sent the boy on a short errand.
Leave now and you will arrive on time.
The corner store was robbed last night.
A gold ring will please most any girl.
The long journey home took a year.
She saw a cat in the neighbor's house.
A pink shell was found on the sandy beach.
Small children came to see him.
The grass and bushes were wet with dew.
The blind man counted his old coins.
A severe storm tore down the barn.
She called his name many times.
When you hear the bell, come quickly.
+18
View File
@@ -0,0 +1,18 @@
{
"Arabic": "ar",
"Chinese": "zh-cn",
"Czech": "cs",
"Dutch": "nl",
"English": "en",
"French": "fr",
"German": "de",
"Hungarian": "hu",
"Italian": "it",
"Japanese": "ja",
"Korean": "ko",
"Polish": "pl",
"Portuguese": "pt",
"Russian": "ru",
"Spanish": "es",
"Turkish": "tr"
}
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,29 @@
{
"branding": "AllTalk ",
"tgwui": {
"tgwui_activate_tts": true,
"tgwui_autoplay_tts": true,
"tgwui_narrator_enabled": "false",
"tgwui_non_quoted_text_is": "silent",
"tgwui_deepspeed_enabled": false,
"tgwui_language": "English",
"tgwui_lowvram_enabled": false,
"tgwui_pitch_set": 0,
"tgwui_temperature_set": 0.75,
"tgwui_repetitionpenalty_set": 10,
"tgwui_generationspeed_set": 1,
"tgwui_narrator_voice": "en_US-ljspeech-high.onnx",
"tgwui_show_text": true,
"tgwui_character_voice": "en_US-ljspeech-high.onnx",
"tgwui_rvc_char_voice": "Disabled",
"tgwui_rvc_char_pitch": 0,
"tgwui_rvc_narr_voice": "Disabled",
"tgwui_rvc_narr_pitch": 0
},
"remote_connection": {
"server_protocol": "http://",
"server_address": "127.0.0.1:7851",
"connection_timeout": 5,
"use_legacy_api": false
}
}
+586 -2338
View File
File diff suppressed because it is too large. Load diff
+2 -15
View File
@@ -124,7 +124,6 @@
<option value="English" {% if data.language=='English' %}selected{% endif %}>English</option> <option value="English" {% if data.language=='English' %}selected{% endif %}>English</option>
<option value="French" {% if data.language=='French' %}selected{% endif %}>French</option> <option value="French" {% if data.language=='French' %}selected{% endif %}>French</option>
<option value="German" {% if data.language=='German' %}selected{% endif %}>German</option> <option value="German" {% if data.language=='German' %}selected{% endif %}>German</option>
<option value="Hindi" {% if data.language=='Hindi' %}selected{% endif %}>Hindi</option>
<option value="Hungarian" {% if data.language=='Hungarian' %}selected{% endif %}>Hungarian</option> <option value="Hungarian" {% if data.language=='Hungarian' %}selected{% endif %}>Hungarian</option>
<option value="Italian" {% if data.language=='Italian' %}selected{% endif %}>Italian</option> <option value="Italian" {% if data.language=='Italian' %}selected{% endif %}>Italian</option>
<option value="Japanese" {% if data.language=='Japanese' %}selected{% endif %}>Japanese</option> <option value="Japanese" {% if data.language=='Japanese' %}selected{% endif %}>Japanese</option>
@@ -216,20 +215,8 @@
modeldownload_model_path }}</span> modeldownload_model_path }}</span>
<label for="port_number" style="color: red;"> Port Number:</label>
<input id="port_number" name="port_number" required="" type="text" value="{{ data.port_number }}" /><br>
<label for="ip_address" style="color: red;"> IP Address:</label>
<input id="ip_address" name="ip_address" required="" type="text" value="{{ data.ip_address }}" />
<label for="port_number" style="color: red;"> &nbsp; &nbsp; Port Number:</label>
<input id="port_number" name="port_number" required="" type="text" value="{{ data.port_number }}" />
<div class="radio-group"> <div class="radio-group">
<label for="tts_method_api_local" style="color: #33cc33;">Model: <span <label for="tts_method_api_local" style="color: #33cc33;">Model: <span
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+296
View File
@@ -0,0 +1,296 @@
import sys
import time
import signal
import json
import warnings
import pyperclip
import requests
from PyQt5.QtWidgets import (QApplication, QSystemTrayIcon, QMenu, QWidget, QVBoxLayout, QLabel,
QLineEdit, QPushButton, QMessageBox, QComboBox, QSlider)
from PyQt5.QtCore import Qt, QThread, pyqtSignal, QTimer
from PyQt5.QtGui import QIcon
# Suppress the specific warning
warnings.filterwarnings("ignore", category=UserWarning, module="charset_normalizer")
SETTINGS_FILE = "tts_settings.json"
TTS_SERVER_URL = "http://127.0.0.1:7851"
LANGUAGES = {
"ar": "Arabic", "zh-cn": "Chinese (Simplified)", "cs": "Czech", "nl": "Dutch",
"en": "English", "fr": "French", "de": "German", "hi": "Hindi (limited support)",
"hu": "Hungarian", "it": "Italian", "ja": "Japanese", "ko": "Korean",
"pl": "Polish", "pt": "Portuguese", "ru": "Russian", "es": "Spanish", "tr": "Turkish"
}
class ClipboardMonitor(QThread):
text_changed = pyqtSignal(str)
def __init__(self):
super().__init__()
self.last_text = pyperclip.paste()
self.running = True
def run(self):
while self.running:
current_text = pyperclip.paste()
if current_text != self.last_text:
self.text_changed.emit(current_text)
self.last_text = current_text
time.sleep(0.5)
def stop(self):
self.running = False
class TTSWorker(QThread):
error_occurred = pyqtSignal(str)
def __init__(self, api_url, params):
super().__init__()
self.api_url = api_url
self.params = params
self.text_queue = []
def add_text(self, text):
self.text_queue.append(text)
def run(self):
while True:
if self.text_queue:
text = self.text_queue.pop(0)
self.send_to_tts(text)
else:
time.sleep(0.1)
def send_to_tts(self, text):
params = self.params.copy()
params["text_input"] = text
params["language"] = params["language"][:2] # Ensure we only send the 2-letter code
try:
response = requests.post(f"{self.api_url}/api/tts-generate", data=params)
if response.status_code != 200:
error_message = f"TTS generation failed with status code: {response.status_code}. Response: {response.text}"
print(error_message)
self.error_occurred.emit(error_message)
except requests.RequestException as e:
error_message = f"Error sending request to TTS API: {e}"
print(error_message)
self.error_occurred.emit(error_message)
class SettingsWindow(QWidget):
settings_updated = pyqtSignal(dict)
def __init__(self, tts_worker):
super().__init__()
self.tts_worker = tts_worker
self.voices = []
self.init_ui()
def init_ui(self):
layout = QVBoxLayout()
self.setLayout(layout)
layout.addWidget(QLabel("AllTalk API URL:"))
self.api_url_input = QLineEdit(self.tts_worker.api_url)
layout.addWidget(self.api_url_input)
layout.addWidget(QLabel("Voice:"))
self.voice_combo = QComboBox()
layout.addWidget(self.voice_combo)
layout.addWidget(QLabel("Language:"))
self.language_combo = QComboBox()
for code, name in LANGUAGES.items():
self.language_combo.addItem(f"{name} ({code})", code)
current_lang = self.tts_worker.params.get("language", "en")
index = self.language_combo.findData(current_lang)
if index >= 0:
self.language_combo.setCurrentIndex(index)
layout.addWidget(self.language_combo)
layout.addWidget(QLabel("Text Filtering:"))
self.text_filtering_input = QLineEdit(self.tts_worker.params["text_filtering"])
layout.addWidget(self.text_filtering_input)
layout.addWidget(QLabel("Playback Volume:"))
self.volume_slider = QSlider(Qt.Horizontal)
self.volume_slider.setRange(1, 10)
self.volume_slider.setValue(int(float(self.tts_worker.params["autoplay_volume"]) * 10))
layout.addWidget(self.volume_slider)
save_button = QPushButton("Save")
save_button.clicked.connect(self.save_settings)
layout.addWidget(save_button)
refresh_button = QPushButton("Refresh Voices")
refresh_button.clicked.connect(self.refresh_voices)
layout.addWidget(refresh_button)
self.setWindowTitle("AllTalk Clipboard TTS")
self.setGeometry(300, 300, 300, 400)
self.refresh_voices()
def refresh_voices(self):
try:
response = requests.get(f"{self.tts_worker.api_url}/api/voices")
if response.status_code == 200:
data = response.json()
if data["status"] == "success" and "voices" in data:
self.voices = data["voices"]
self.voice_combo.clear()
for voice in self.voices:
self.voice_combo.addItem(voice)
if self.voices:
current_voice = self.tts_worker.params["character_voice_gen"]
if current_voice in self.voices:
self.voice_combo.setCurrentText(current_voice)
else:
self.voice_combo.setCurrentIndex(0)
else:
QMessageBox.warning(self, "Error", "Failed to fetch voices: Unexpected response format")
else:
QMessageBox.warning(self, "Error", f"Failed to fetch voices. Status code: {response.status_code}")
except requests.RequestException as e:
QMessageBox.warning(self, "Error", f"Failed to fetch voices: {str(e)}")
def save_settings(self):
new_settings = {
"api_url": self.api_url_input.text(),
"params": {
"character_voice_gen": self.voice_combo.currentText(),
"language": self.language_combo.currentData(),
"text_filtering": self.text_filtering_input.text(),
"output_file_name": "clipboard_tts",
"output_file_timestamp": "true",
"autoplay": "true",
"autoplay_volume": str(self.volume_slider.value() / 10.0)
}
}
self.settings_updated.emit(new_settings)
self.hide()
class TTSApp(QSystemTrayIcon):
def __init__(self, app):
super().__init__(parent=app)
self.app = app
self.load_settings()
self.init_ui()
def load_settings(self):
try:
with open(SETTINGS_FILE, 'r') as f:
self.settings = json.load(f)
except FileNotFoundError:
self.settings = {
"api_url": TTS_SERVER_URL,
"params": {
"text_filtering": "standard",
"character_voice_gen": "",
"language": "en",
"output_file_name": "clipboard_tts",
"output_file_timestamp": "true",
"autoplay": "true",
"autoplay_volume": "0.8"
}
}
def save_settings(self):
with open(SETTINGS_FILE, 'w') as f:
json.dump(self.settings, f)
def init_ui(self):
self.tts_worker = TTSWorker(self.settings["api_url"], self.settings["params"])
self.tts_worker.error_occurred.connect(self.show_error_message)
self.tts_worker.start()
self.clipboard_monitor = ClipboardMonitor()
self.clipboard_monitor.text_changed.connect(self.on_text_changed)
self.setIcon(QIcon("icon.png"))
self.setVisible(True)
menu = QMenu()
start_action = menu.addAction("Start Monitoring")
start_action.triggered.connect(self.start_monitoring)
stop_action = menu.addAction("Stop Monitoring")
stop_action.triggered.connect(self.stop_monitoring)
settings_action = menu.addAction("Settings")
settings_action.triggered.connect(self.show_settings)
exit_action = menu.addAction("Exit")
exit_action.triggered.connect(self.exit_app)
self.setContextMenu(menu)
self.settings_window = SettingsWindow(self.tts_worker)
self.settings_window.settings_updated.connect(self.update_settings)
def on_text_changed(self, text):
self.tts_worker.add_text(text)
def start_monitoring(self):
self.clipboard_monitor.start()
self.showMessage("TTS App", "Clipboard monitoring started")
def stop_monitoring(self):
self.clipboard_monitor.stop()
self.showMessage("TTS App", "Clipboard monitoring stopped")
def show_settings(self):
self.settings_window.show()
def update_settings(self, new_settings):
self.settings = new_settings
self.tts_worker.api_url = new_settings["api_url"]
self.tts_worker.params = new_settings["params"]
self.save_settings()
self.showMessage("TTS App", "Settings updated successfully")
def show_error_message(self, message):
QMessageBox.critical(None, "Error", message)
def exit_app(self):
self.clipboard_monitor.stop()
self.tts_worker.quit()
QApplication.instance().quit()
def check_server_ready(url, timeout=10):
start_time = time.time()
while time.time() - start_time < timeout:
try:
response = requests.get(f"{url}/api/ready")
if response.status_code == 200 and response.text == "Ready":
return True
except requests.RequestException:
pass
time.sleep(1)
return False
def signal_handler(signal, frame):
print("[Clipboard to TTS] Exiting...")
QApplication.instance().quit()
if __name__ == "__main__":
print("[Clipboard to TTS] AllTalk Clipboard to TTS is starting...")
if not check_server_ready(TTS_SERVER_URL):
print("[Clipboard to TTS] Error: AllTalk TTS server is not ready. Please start the AllTalk server and try again.")
sys.exit(1)
signal.signal(signal.SIGINT, signal_handler)
app = QApplication(sys.argv)
if not QSystemTrayIcon.isSystemTrayAvailable():
print("[Clipboard to TTS] System tray is not available on this system.")
sys.exit(1)
tts_app = TTSApp(app)
# This allows for Ctrl+C to work
timer = QTimer()
timer.start(500)
timer.timeout.connect(lambda: None)
print("[Clipboard to TTS] AllTalk Clipboard to TTS is running... Check your system tray for the icon.")
print("[Clipboard to TTS] Press Ctrl+C to exit")
sys.exit(app.exec_())
Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

+13
View File
@@ -0,0 +1,13 @@
This is a Windows only clipboard to TTS extension. Its a very rough bit of code with no logic or error handling built in.
When run it will create a system tray icon that you can Start/Stop clipboard monitoring for the text stored in the clipboard changing. When the text changes, it will be sent to AllTalk for TTS generation. You can specify the voice to use in the System Tray icon Settings area.
In the main folder, run "start_environment.bat" to start the AllTalk Python environment.
You will need to "pip install pyqt5 pyperclip requests" for to install the requirements into the AllTalk Python environment (you will only need to do this the once, but always start the Python environment).
Go to the "cliptotts" folder and "python clipboard-to-tts.py" which should start the application.
Start monitoring of the clipboard on the icon in the system tray.
When you Ctrl+C text to the clipboard, it will be sent over for TTS generation and it will play back at the AllTalk console.
-2
View File
@@ -1,2 +0,0 @@
{
}
-2
View File
@@ -1,2 +0,0 @@
{
}
+564
View File
@@ -0,0 +1,564 @@
======================================
AllTalk Base Diagnostic log file for Standalone Installations
======================================
Diagnostic log created at 2024-11-06 01:25:33.123679
======================================
OPERATING SYSTEM:
OS Version: Windows 10.0.22631
Note: Windows 11 will list as build is 10.x.22xxx
HARDWARE ENVIRONMENT:
CPU: Physical Cores: 8, Total Cores: 16, Max Frequency: 3800.0 MHz
System RAM: 19.46 GB available out of 31.34 GB total
GPU INFORMATION:
Fri Sep 27 20:50:15 2024
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 560.94 Driver Version: 560.94 CUDA Version: 12.6 |
|-----------------------------------------+------------------------+----------------------+
| GPU Name Driver-Model | Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|=========================================+========================+======================|
| 0 NVIDIA GeForce RTX 4070 WDDM | 00000000:01:00.0 On | N/A |
| 0% 39C P8 13W / 200W | 1071MiB / 12282MiB | 1% Default |
| | | N/A |
+-----------------------------------------+------------------------+----------------------+
+-----------------------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=========================================================================================|
| 0 N/A N/A 1508 C+G ...nt.CBS_cw5n1h2txyewy\SearchHost.exe N/A |
| 0 N/A N/A 2756 C+G ...\cef\cef.win7x64\steamwebhelper.exe N/A |
| 0 N/A N/A 5488 C+G ...2txyewy\StartMenuExperienceHost.exe N/A |
| 0 N/A N/A 6504 C+G ...ekyb3d8bbwe\PhoneExperienceHost.exe N/A |
| 0 N/A N/A 7212 C+G ...t.LockApp_cw5n1h2txyewy\LockApp.exe N/A |
| 0 N/A N/A 8604 C+G C:\Windows\explorer.exe N/A |
| 0 N/A N/A 8852 C+G ...ft Office\root\Office16\OUTLOOK.EXE N/A |
| 0 N/A N/A 11964 C+G ...5.0_x64__cv1g1gvanyjgm\WhatsApp.exe N/A |
| 0 N/A N/A 12516 C+G ...CBS_cw5n1h2txyewy\TextInputHost.exe N/A |
| 0 N/A N/A 13376 C+G ...\cef\cef.win7x64\steamwebhelper.exe N/A |
| 0 N/A N/A 17632 C+G ...nr4m\radeonsoftware\AMDRSSrcExt.exe N/A |
| 0 N/A N/A 18316 C+G ...m\radeonsoftware\RadeonSoftware.exe N/A |
| 0 N/A N/A 18908 C+G ...siveControlPanel\SystemSettings.exe N/A |
| 0 N/A N/A 19032 C+G ...am Files\Microsoft VS Code\Code.exe N/A |
| 0 N/A N/A 21216 C+G ...bytes\Anti-Malware\Malwarebytes.exe N/A |
| 0 N/A N/A 21476 C+G ...crosoft\Edge\Application\msedge.exe N/A |
| 0 N/A N/A 21604 C+G ...ta\Local\WeMod\app-9.10.3\WeMod.exe N/A |
| 0 N/A N/A 22344 C+G ...__8wekyb3d8bbwe\WindowsTerminal.exe N/A |
| 0 N/A N/A 25292 C+G ...5n1h2txyewy\ShellExperienceHost.exe N/A |
| 0 N/A N/A 26220 C ...\alltalk_environment\env\python.exe N/A |
| 0 N/A N/A 27960 C+G ...Brave-Browser\Application\brave.exe N/A |
+-----------------------------------------------------------------------------------------+
CUDA:
CUDA Working: Success - CUDA is available and working.
CUDA_HOME : N/A
CUDA Device : NVIDIA GeForce RTX 4070
CUDA Memory : 11.99 GB
CUDA Version: 12.1
DISK INFORMATION:
Drive: C:\ | Total: 1000.95 GB | Used: 852.08 GB | Free: 148.87 GB | Type: NTFS
NETWORK PORT:
Port Status : Port 7851 is available.
Cublas64_11 Path: C:\myfiles\alltalk_tts\alltalk_environment\env\Lib\site-packages\nvidia/cublas\bin\cublas64_11.dll
Windows C++ Build tools & Windows SDK:
Windows Version: Windows 11
Visual C++ Build Tools and/or Visual Studio found:
Visual Studio 2019 Build Tools (Path: C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools)
Windows SDK(s) found:
SDK Version: 10.0.22000.0
Path: C:\Program Files (x86)\Windows Kits\10
Python setuptools version: 75.1.0
Windows Espeak-ng:
Espeak-ng version: eSpeak NG text-to-speech: 1.52-dev Data at: C:\Program Files\eSpeak NG\/espeak-ng-data
PYTHON & PYTORCH:
Torch Version: 2.2.1
Python Version: 3.11.10
Python Version Info: sys.version_info(major=3, minor=11, micro=10, releaselevel='final', serial=0)
Python Executable: C:\myfiles\alltalk_tts\alltalk_environment\env\python.exe
Python Virtual Environment: N/A (Should be N/A when in Text-generation-webui Conda Python environment)
Conda Environment: C:\myfiles\alltalk_tts\alltalk_environment\env
Python Search Path:
C:\myfiles\alltalk_tts
C:\myfiles\alltalk_tts\alltalk_environment\env\python311.zip
C:\myfiles\alltalk_tts\alltalk_environment\env\DLLs
C:\myfiles\alltalk_tts\alltalk_environment\env\Lib
C:\myfiles\alltalk_tts\alltalk_environment\env
C:\myfiles\alltalk_tts\alltalk_environment\env\Lib\site-packages
C:\myfiles\alltalk_tts\alltalk_environment\env\Lib\site-packages\win32
C:\myfiles\alltalk_tts\alltalk_environment\env\Lib\site-packages\win32\lib
C:\myfiles\alltalk_tts\alltalk_environment\env\Lib\site-packages\Pythonwin
OS SEARCHPATH ENVIRONMENT:
C:\myfiles\alltalk_tts\alltalk_environment\env\Lib\site-packages\PyQt6\Qt6\bin
C:\myfiles\alltalk_tts\alltalk_environment\env
C:\myfiles\alltalk_tts\alltalk_environment\env\Library\mingw-w64\bin
C:\myfiles\alltalk_tts\alltalk_environment\env\Library\usr\bin
C:\myfiles\alltalk_tts\alltalk_environment\env\Library\bin
C:\myfiles\alltalk_tts\alltalk_environment\env\Scripts
C:\myfiles\alltalk_tts\alltalk_environment\env\bin
C:\Program Files (x86)\Common Files\Oracle\Java\javapath
C:\Windows\system32
C:\Windows
C:\Windows\System32\Wbem
C:\Windows\System32\WindowsPowerShell\v1.0
C:\Program Files\dotnet
C:\Program Files\NVIDIA Corporation\NVIDIA NvDLISR
C:\Program Files\Git\cmd
C:\ProgramData\chocolatey\bin
C:
C:\Program Files\nodejs
C:\Program Files (x86)\Windows Kits\10\App Certification Kit
C:\Program Files\Microsoft VS Code\bin
C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common
C:\Program Files\NVIDIA Corporation\Nsight Compute 2023.1.0
C:\Program Files\eSpeak NG
C:\Program Files (x86)\eSpeak NG
CONDA INFORMATION:
Conda Executable: C:\myfiles\alltalk_tts\alltalk_environment\conda\condabin\..\Scripts\conda.exe
Conda Version: 24.4.0
Current Environment: C:\myfiles\alltalk_tts\alltalk_environment\env
Conda Environments:
- C:\myfiles\alltalk_tts\alltalk_environment\conda
- C:\myfiles\alltalk_tts\alltalk_environment\env
CONDA PACKAGES IN CURRENT ENVIRONMENT:
CONDA-FORGE PACKAGES:
aom Version: 3.9.1 Channel: conda-forge
cairo Version: 1.18.0 Channel: conda-forge
ffmpeg Version: 4.3.1 Channel: conda-forge
fontconfig Version: 2.15.0 Channel: conda-forge
freetype Version: 2.12.1 Channel: conda-forge
harfbuzz Version: 9.0.0 Channel: conda-forge
icu Version: 75.1 Channel: conda-forge
lcms2 Version: 2.15 Channel: conda-forge
libexpat Version: 2.6.4 Channel: conda-forge
libglib Version: 2.82.2 Channel: conda-forge
libiconv Version: 1.17 Channel: conda-forge
libintl Version: 0.22.5 Channel: conda-forge
libopus Version: 1.3.1 Channel: conda-forge
libpng Version: 1.6.44 Channel: conda-forge
libsqlite Version: 3.47.0 Channel: conda-forge
libxcb Version: 1.13 Channel: conda-forge
libxml2 Version: 2.13.5 Channel: conda-forge
libzlib Version: 1.3.1 Channel: conda-forge
openh264 Version: 2.4.1 Channel: conda-forge
openssl Version: 3.4.0 Channel: conda-forge
pcre2 Version: 10.44 Channel: conda-forge
pixman Version: 0.43.4 Channel: conda-forge
python Version: 3.11.10 Channel: conda-forge
python_abi Version: 3.11 Channel: conda-forge
svt-av1 Version: 2.2.1 Channel: conda-forge
tk Version: 8.6.13 Channel: conda-forge
vc14_runtime Version: 14.42.34433 Channel: conda-forge
vs2015_runtime Version: 14.42.34433 Channel: conda-forge
x264 Version: 1!164.3095 Channel: conda-forge
x265 Version: 3.5 Channel: conda-forge
xorg-libxau Version: 1.0.11 Channel: conda-forge
xorg-libxdmcp Version: 1.1.3 Channel: conda-forge
zlib Version: 1.3.1 Channel: conda-forge
zstd Version: 1.5.6 Channel: conda-forge
PKGS/MAIN PACKAGES:
blas Version: 1.0 Channel: pkgs/main
brotli-python Version: 1.0.9 Channel: pkgs/main
bzip2 Version: 1.0.8 Channel: pkgs/main
ca-certificates Version: 2024.9.24 Channel: pkgs/main
certifi Version: 2024.8.30 Channel: pkgs/main
charset-normalizer Version: 3.3.2 Channel: pkgs/main
dav1d Version: 1.2.1 Channel: pkgs/main
font-ttf-dejavu-sans-mono Version: 2.37 Channel: pkgs/main
font-ttf-inconsolata Version: 2.001 Channel: pkgs/main
font-ttf-source-code-pro Version: 2.030 Channel: pkgs/main
font-ttf-ubuntu Version: 0.83 Channel: pkgs/main
fonts-anaconda Version: 1 Channel: pkgs/main
fonts-conda-ecosystem Version: 1 Channel: pkgs/main
gmpy2 Version: 2.1.2 Channel: pkgs/main
graphite2 Version: 1.3.14 Channel: pkgs/main
idna Version: 3.7 Channel: pkgs/main
intel-openmp Version: 2023.1.0 Channel: pkgs/main
jinja2 Version: 3.1.4 Channel: pkgs/main
jpeg Version: 9e Channel: pkgs/main
lerc Version: 3.0 Channel: pkgs/main
libdeflate Version: 1.17 Channel: pkgs/main
libffi Version: 3.4.4 Channel: pkgs/main
libjpeg-turbo Version: 2.0.0 Channel: pkgs/main
libtiff Version: 4.5.0 Channel: pkgs/main
libuv Version: 1.48.0 Channel: pkgs/main
libwebp-base Version: 1.3.2 Channel: pkgs/main
lz4-c Version: 1.9.4 Channel: pkgs/main
markupsafe Version: 2.1.3 Channel: pkgs/main
mkl Version: 2023.1.0 Channel: pkgs/main
mkl-service Version: 2.4.0 Channel: pkgs/main
mkl_fft Version: 1.3.11 Channel: pkgs/main
mkl_random Version: 1.2.8 Channel: pkgs/main
mpc Version: 1.1.0 Channel: pkgs/main
mpfr Version: 4.0.2 Channel: pkgs/main
mpir Version: 3.0.0 Channel: pkgs/main
mpmath Version: 1.3.0 Channel: pkgs/main
networkx Version: 3.2.1 Channel: pkgs/main
numpy Version: 1.26.4 Channel: pkgs/main
numpy-base Version: 1.26.4 Channel: pkgs/main
openjpeg Version: 2.5.2 Channel: pkgs/main
packaging Version: 24.1 Channel: pkgs/main
pip Version: 24.2 Channel: pkgs/main
pthread-stubs Version: 0.3 Channel: pkgs/main
pysocks Version: 1.7.1 Channel: pkgs/main
pyyaml Version: 6.0.2 Channel: pkgs/main
requests Version: 2.32.3 Channel: pkgs/main
setuptools Version: 75.1.0 Channel: pkgs/main
sqlite Version: 3.45.3 Channel: pkgs/main
sympy Version: 1.13.2 Channel: pkgs/main
tbb Version: 2021.8.0 Channel: pkgs/main
ucrt Version: 10.0.20348.0 Channel: pkgs/main
urllib3 Version: 2.2.3 Channel: pkgs/main
vc Version: 14.40 Channel: pkgs/main
wheel Version: 0.44.0 Channel: pkgs/main
win_inet_pton Version: 1.1.0 Channel: pkgs/main
xz Version: 5.4.6 Channel: pkgs/main
yaml Version: 0.2.5 Channel: pkgs/main
PKGS/MSYS2 PACKAGES:
m2w64-gcc-libgfortran Version: 5.3.0 Channel: pkgs/msys2
m2w64-gcc-libs Version: 5.3.0 Channel: pkgs/msys2
m2w64-gcc-libs-core Version: 5.3.0 Channel: pkgs/msys2
m2w64-gmp Version: 6.1.0 Channel: pkgs/msys2
m2w64-libwinpthread-git Version: 5.0.0.4634.697f757 Channel: pkgs/msys2
msys2-conda-epoch Version: 20160418 Channel: pkgs/msys2
OTHER PACKAGES:
faiss-cpu Version: 1.9.0 Channel: pytorch
libfaiss Version: 1.9.0 Channel: pytorch
pytorch Version: 2.2.1 Channel: pytorch
pytorch-cuda Version: 12.1 Channel: pytorch
pytorch-mutex Version: 1.0 Channel: pytorch
PACKAGE VERSIONS vs REQUIREMENTS FILE:
coqui-tts Required: >= 0.24.3 Installed: 0.24.3
filelock Required: >= 3.16.1 Installed: 3.13.4
fuzzywuzzy Required: >= 0.18.0 Installed: 0.18.0
ffmpeg-python Required: >= 0.2.0 Installed: 0.2.0
gradio Required: == 4.44.1 Installed: 4.44.1
importlib_metadata Required: >= 7.2.1 Installed: 8.5.0
inputimeout Required: >= 1.0.4 Installed: 1.0.4
Jinja2 Required: >= 3.1.4 Installed: 3.1.4
librosa Required: >= 0.10.2.post1 Installed: 0.10.2.post1
onnxruntime-gpu Required: >= 1.18.1 Installed: 1.20.1
pydantic Required: >= 2.8.2 Installed: 2.10.1
python-Levenshtein Required: >= 0.25.1 Installed: 0.26.1
praat-parselmouth Required: >= 0.4.4 Installed: 0.4.5
pyworld Required: >= 0.3.4 Installed: 0.3.4
sounddevice Required: >= 0.4.7 Installed: 0.5.1
soundfile Required: >= 0.12.1 Installed: 0.12.1
spacy Required: >= 3.7.1 Installed: 3.7.5
torchcrepe Required: >= 0.0.2 Installed: 0.0.23
tqdm Required: >= 4.66.5 Installed: 4.67.1
unidic-lite Required: >= 1.0.8 Installed: 1.0.8
uvicorn Required: >= 0.29.0 Installed: 0.32.1
pillow Required: == 10.3.0 Installed: 10.3.0
pypinyin Required: >= 0.52.0 Installed: 0.53.0
word2number Required: >= 1.1 Installed: 1.1
cutlet Required: == 0.4.0 Installed: 0.4.0
fugashi Required: == 1.3.1 Installed: 1.3.1
fastapi Required: == 0.112.2 Installed: 0.112.2
plotly Required: == 5.24.1 Installed: 5.24.1
scipy Required: == 1.14.1 Installed: 1.14.1
PYTHON PACKAGES:
absl-py = 2.1.0
accelerate = 1.1.1
aiofiles = 23.2.1
aiohappyeyeballs = 2.4.3
aiohttp = 3.11.7
aiosignal = 1.3.1
annotated-types = 0.7.0
antlr4-python3-runtime = 4.9.3
anyascii = 0.3.2
anyio = 4.6.2.post1
argbind = 0.3.9
asttokens = 2.4.1
attrs = 24.2.0
audioread = 3.0.1
babel = 2.16.0
bitarray = 3.0.0
bitsandbytes = 0.44.1
blis = 0.7.11
boto3 = 1.35.69
botocore = 1.35.69
Brotli = 1.0.9
cached_path = 1.6.4
cachetools = 5.5.0
catalogue = 2.0.10
certifi = 2024.8.30
cffi = 1.17.1
charset-normalizer = 3.3.2
click = 8.1.7
cloudpathlib = 0.20.0
colorama = 0.4.6
coloredlogs = 15.0.1
confection = 0.1.5
contourpy = 1.3.1
coqpit = 0.0.17
coqui-tts = 0.24.3
coqui-tts-trainer = 0.1.7
cutlet = 0.4.0
cycler = 0.12.1
cymem = 2.0.10
Cython = 3.0.11
datasets = 3.1.0
dateparser = 1.1.8
decorator = 5.1.1
deepspeed = 0.14.0+ce78a63
descript-audiotools = 0.7.4
descript-audio-codec = 1.0.0
dill = 0.3.8
docker-pycreds = 0.4.0
docopt = 0.6.2
docstring_parser = 0.16
einops = 0.8.0
einx = 0.3.0
ema-pytorch = 0.7.6
encodec = 0.1.1
executing = 2.1.0
fairseq = 0.12.4
faiss = 1.9.0
fastapi = 0.112.2
ffmpeg-python = 0.2.0
ffmpy = 0.4.0
filelock = 3.13.4
fire = 0.7.0
flatbuffers = 24.3.25
flatten-dict = 0.4.2
fonttools = 4.55.0
frozendict = 2.4.6
frozenlist = 1.5.0
fsspec = 2024.9.0
fugashi = 1.3.1
future = 1.0.0
fuzzywuzzy = 0.18.0
gitdb = 4.0.11
GitPython = 3.1.43
gmpy2 = 2.1.2
googleapis-common-protos = 1.66.0
google-api-core = 2.23.0
google-auth = 2.36.0
google-cloud-core = 2.4.1
google-cloud-storage = 2.18.2
google-crc32c = 1.6.0
google-resumable-media = 2.7.2
gradio = 4.44.1
gradio_client = 1.3.0
grpcio = 1.68.0
gruut = 2.4.0
gruut-ipa = 0.13.0
gruut_lang_de = 2.0.1
gruut_lang_en = 2.0.1
gruut_lang_es = 2.0.1
gruut_lang_fr = 2.0.2
h11 = 0.14.0
hangul-romanize = 0.1.0
hjson = 3.1.0
httpcore = 1.0.7
httpx = 0.27.2
huggingface-hub = 0.26.2
humanfriendly = 10.0
hydra-core = 1.3.2
idna = 3.7
importlib_metadata = 8.5.0
importlib_resources = 6.4.5
inflect = 7.4.0
inputimeout = 1.0.4
ipython = 8.29.0
jaconv = 0.4.0
jedi = 0.19.2
jieba = 0.42.1
Jinja2 = 3.1.4
jmespath = 1.0.1
joblib = 1.4.2
jsonlines = 1.2.0
julius = 0.2.7
kiwisolver = 1.4.7
langcodes = 3.5.0
language_data = 1.3.0
lazy_loader = 0.4
Levenshtein = 0.26.1
librosa = 0.10.2.post1
llvmlite = 0.43.0
local-attention = 1.9.15
lxml = 5.3.0
marisa-trie = 1.2.1
Markdown = 3.7
markdown2 = 2.5.1
markdown-it-py = 3.0.0
MarkupSafe = 2.1.3
matplotlib = 3.9.2
matplotlib-inline = 0.1.7
mdurl = 0.1.2
mkl_fft = 1.3.11
mkl_random = 1.2.8
mkl-service = 2.4.0
mojimoji = 0.0.13
more-itertools = 10.5.0
mpmath = 1.3.0
msgpack = 1.1.0
multidict = 6.1.0
multiprocess = 0.70.16
murmurhash = 1.0.11
networkx = 3.2.1
ninja = 1.11.1.2
num2words = 0.5.13
numba = 0.60.0
numpy = 1.26.4
omegaconf = 2.3.0
onnxruntime-gpu = 1.20.1
openai-whisper = 20240930
orjson = 3.10.12
packaging = 24.1
pandas = 2.2.3
parler_tts = 0.2.1
parso = 0.8.4
pillow = 10.3.0
pip = 24.2
platformdirs = 4.3.6
plotly = 5.24.1
pooch = 1.8.2
portalocker = 3.0.0
praat-parselmouth = 0.4.5
preshed = 3.0.9
prompt_toolkit = 3.0.48
propcache = 0.2.0
protobuf = 4.25.5
proto-plus = 1.25.0
psutil = 6.1.0
pure_eval = 0.2.3
pyarrow = 18.1.0
pyasn1 = 0.6.1
pyasn1_modules = 0.4.1
pycparser = 2.22
pydantic = 2.10.1
pydantic_core = 2.27.1
pydub = 0.25.1
Pygments = 2.18.0
pyloudnorm = 0.1.1
pynvml = 11.5.3
pyparsing = 3.2.0
pypinyin = 0.53.0
PyQt6 = 6.7.1
PyQt6-Qt6 = 6.7.3
PyQt6_sip = 13.8.0
pyreadline3 = 3.5.4
pysbd = 0.3.4
PySocks = 1.7.1
pystoi = 0.4.1
python-crfsuite = 0.9.11
python-dateutil = 2.9.0.post0
python-Levenshtein = 0.26.1
python-multipart = 0.0.17
pytz = 2024.2
pywin32 = 308
pyworld = 0.3.4
PyYAML = 6.0.2
py-cpuinfo = 9.0.0
randomname = 0.2.1
RapidFuzz = 3.10.1
regex = 2024.11.6
requests = 2.32.3
resampy = 0.4.3
rich = 13.9.4
rotary-embedding-torch = 0.8.5
rsa = 4.9
ruff = 0.8.0
s3transfer = 0.10.4
sacrebleu = 2.4.3
safetensors = 0.4.5
scikit-learn = 1.5.2
scipy = 1.14.1
semantic-version = 2.10.0
sentencepiece = 0.2.0
sentry-sdk = 2.19.0
setproctitle = 1.3.4
setuptools = 75.1.0
shellingham = 1.5.4
six = 1.16.0
smart-open = 7.0.5
smmap = 5.0.1
sniffio = 1.3.1
sounddevice = 0.5.1
soundfile = 0.12.1
soxr = 0.5.0.post1
spacy = 3.7.5
spacy-legacy = 3.0.12
spacy-loggers = 1.0.5
srsly = 2.4.8
stack-data = 0.6.3
starlette = 0.38.6
SudachiDict-core = 20241021
SudachiPy = 0.6.9
sympy = 1.13.2
tabulate = 0.9.0
tenacity = 9.0.0
tensorboard = 2.18.0
tensorboard-data-server = 0.7.2
termcolor = 2.5.0
thinc = 8.2.5
threadpoolctl = 3.5.0
tiktoken = 0.8.0
tokenizers = 0.20.3
tomli = 2.1.0
tomlkit = 0.12.0
torch = 2.2.1
torchaudio = 2.2.1
torchcrepe = 0.0.23
torchdiffeq = 0.2.5
torchvision = 0.17.1
torch-stoi = 0.2.3
tqdm = 4.67.1
traitlets = 5.14.3
transformers = 4.46.1
transformers-stream-generator = 0.0.5
typeguard = 4.4.1
typer = 0.13.1
typing_extensions = 4.12.2
tzdata = 2024.2
tzlocal = 5.2
unidic-lite = 1.0.8
urllib3 = 2.2.3
uvicorn = 0.32.1
vocos = 0.1.0
wandb = 0.18.7
wasabi = 1.1.3
wcwidth = 0.2.13
weasel = 0.4.1
websockets = 12.0
Werkzeug = 3.1.3
wheel = 0.44.0
win-inet-pton = 1.1.0
word2number = 1.1
wrapt = 1.17.0
xxhash = 3.5.0
x-transformers = 1.42.17
yarl = 1.18.0
zipp = 3.21.0
DeepSpeed Installation Requirements:
OS : Windows
Python : 3.11.10
PyTorch: 2.2.1
CUDA : 12.1
To install DeepSpeed, run the following command based on your environment:
pip install deepspeed==<version> --no-cache-dir
Ensure to choose the correct DeepSpeed version matching your environment.
+382
View File
@@ -0,0 +1,382 @@
"""
firstrun.py
This script handles the first-time setup for the Alltalk TTS system. It allows the user to download and configure
the initial Text-to-Speech (TTS) engine and associated models. It provides automatic detection for Docker or Google
Colab environments to simplify the setup process, as well as an interactive menu or command-line arguments for manual configuration.
Features:
---------
1. **Automatic Environment Detection**:
- Detects if the script is running in a Docker container or Google Colab environment.
- Automatically sets up the Piper TTS engine in these cases.
2. **Command-Line Arguments**:
- Accepts a `--tts_model` argument to bypass the interactive menu and directly set up a specific TTS engine:
- `piper`: Sets up the Piper TTS engine.
- `vits`: Sets up the VITS TTS engine.
- `xtts`: Sets up the XTTS TTS engine.
- `none`: Skips model setup entirely.
3. **Interactive Menu**:
- If no command-line argument is provided and the environment is not Docker/Colab, it presents an interactive
menu for the user to select a TTS model.
4. **Configuration Management**:
- Updates the Alltalk TTS configuration files to reflect the selected TTS engine and marks the initial setup as complete.
Usage:
------
Command-Line:
python firstrun.py --tts_model [piper|vits|xtts|none]
Interactive Mode:
python firstrun.py
In Docker/Colab:
The script automatically selects and sets up the Piper TTS engine without user interaction.
Functions:
----------
- **is_running_in_colab**: Detects if the script is running in Google Colab.
- **is_running_in_docker**: Detects if the script is running in a Docker container.
- **download_file**: Downloads a file with a progress bar and retry logic.
- **setup_piper**: Sets up the Piper TTS engine and downloads associated files.
- **setup_vits**: Sets up the VITS TTS engine and downloads associated files.
- **setup_xtts**: Sets up the XTTS TTS engine and downloads associated files.
- **update_tts_engines**: Updates the configuration to reflect the selected TTS engine.
- **set_firstrun_model_false**: Marks the initial setup as complete in the configuration.
- **warning_message**: Displays post-setup warnings or tips for the user.
Notes:
------
- Ensure network access is available for downloading models during setup.
- Configuration files are automatically updated and backed up if needed.
"""
import argparse
import json
from pathlib import Path
import os
import shutil
import time
import sys
import zipfile
import requests
from tqdm import tqdm
from inputimeout import inputimeout, TimeoutOccurred
# Setting the module search path:
sys.path.insert(0, str(Path(__file__).parent.parent.parent.resolve()))
from config import AlltalkTTSEnginesConfig, AlltalkConfig #pylint: disable=wrong-import-position
this_dir = Path(__file__).parent.resolve().parent.resolve().parent.resolve()
def is_running_in_colab():
"""Test for google colab"""
try:
import google.colab
return True
except ImportError:
return False
def is_running_in_docker():
"""Test for google colab"""
path = '/proc/self/cgroup'
return os.path.exists('/.dockerenv') or (
os.path.exists(path) and any('docker' in line for line in open(path, encoding='utf-8'))
)
def download_file(url: str, dest_path: str, timeout: int = 30, retries: int = 3) -> bool:
"""
Download a file from a URL to a specified destination path with progress bar.
Args:
url (str): URL of the file to download.
dest_path (str): Destination path where the file will be saved.
timeout (int, optional): Connection and read timeout in seconds. Defaults to 30.
retries (int, optional): Number of retry attempts for failed downloads. Defaults to 3.
Returns:
bool: True if the file was successfully downloaded, False otherwise.
Raises:
ValueError: If the downloaded file size does not match the expected size.
"""
progress_bar = None
for attempt in range(1, retries + 1):
try:
print(f"Attempting to download: {url} (Attempt {attempt}/{retries})")
response = requests.get(url, stream=True, timeout=(timeout, timeout))
response.raise_for_status()
total_size = int(response.headers.get('content-length', 0))
block_size = 1024 # 1 Kibibyte
# Initialize progress bar
progress_bar = tqdm(total=total_size, unit='iB', unit_scale=True,
desc=f"Downloading {Path(dest_path).name} (Attempt {attempt}/{retries})")
Path(dest_path).parent.mkdir(parents=True, exist_ok=True)
with open(dest_path, 'wb') as dwn_file:
for data in response.iter_content(block_size):
if data:
dwn_file.write(data)
progress_bar.update(len(data))
if progress_bar:
progress_bar.close()
# Verify file size
if progress_bar.n != total_size and total_size > 0:
raise ValueError(
f"Downloaded size ({progress_bar.n} bytes) does not match expected size ({total_size} bytes)."
)
print(f"Download completed: {dest_path}")
return True
except requests.Timeout:
print(f"Timeout error during download: {url}")
except requests.ConnectionError:
print(f"Connection error during download: {url}")
except requests.exceptions.RequestException as e:
print(f"HTTP error during download: {url}. Details: {str(e)}")
except ValueError as e:
print(f"File validation error: {str(e)}")
if Path(dest_path).exists():
Path(dest_path).unlink() # Remove incomplete file
break # Stop retrying on file validation errors
except Exception as e:
print(f"Unexpected error during download: {str(e)}")
break # Stop retrying on unexpected errors
finally:
if progress_bar:
progress_bar.close()
if Path(dest_path).exists():
Path(dest_path).unlink() # Remove incomplete file
if attempt < retries:
print(f"Retrying in 5 seconds... (Attempt {attempt + 1}/{retries})")
time.sleep(5)
else:
print(f"Exhausted all retries for {url}.")
# Return False if all attempts fail
return False
def setup_piper():
"""Download base piper files"""
os.makedirs(this_dir / 'models/piper', exist_ok=True)
os.makedirs(this_dir / 'models/xtts', exist_ok=True)
download_file("https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_US/ljspeech/high/en_US-ljspeech-high.onnx?download=true",
this_dir / "models/piper/en_US-ljspeech-high.onnx")
download_file("https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_US/ljspeech/high/en_US-ljspeech-high.onnx.json?download=true.json",
this_dir / "models/piper/en_US-ljspeech-high.onnx.json")
def setup_vits():
"""Download base vits files"""
os.makedirs(this_dir / 'models/vits', exist_ok=True)
os.makedirs(this_dir / 'models/xtts', exist_ok=True)
zip_path = this_dir / 'models/vits/vits.zip'
download_file("https://coqui.gateway.scarf.sh/v0.6.1_models/tts_models--en--vctk--vits.zip", zip_path)
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
zip_ref.extractall(this_dir / 'models/vits')
os.remove(zip_path)
def setup_xtts():
"""Download base xtts files"""
os.makedirs(this_dir / 'models/xtts/xttsv2_2.0.3', exist_ok=True)
base_url = "https://huggingface.co/coqui/XTTS-v2/resolve/v2.0.3/"
files = [
"LICENSE.txt",
"README.md",
"config.json",
"model.pth",
"dvae.pth",
"mel_stats.pth",
"speakers_xtts.pth",
"vocab.json"
]
for each_file in files:
download_file(base_url + each_file + "?download=true", this_dir / f"models/xtts/xttsv2_2.0.3/{each_file}")
def update_tts_engines(engine):
"""Set engine to users choice that matches the download"""
try:
config_instance = AlltalkTTSEnginesConfig.get_instance()
config_instance.change_engine(engine)
config_instance.save()
except Exception as e:
print(f"[{branding}TTS] Error updating TTS engine configuration: {str(e)}")
def set_firstrun_model_false():
"""
Marks the first-run setup as complete in the Alltalk configuration.
This function updates the `firstrun_model` flag in the configuration file to `False`,
indicating that the initial setup has been completed. It attempts to save the updated
configuration and verifies the changes, retrying with a direct file write if necessary.
"""
try:
# Get a fresh instance of the config
config_fr = AlltalkConfig.get_instance()
config_fr.firstrun_model = False
# Force a flush to disk immediately
config_fr.save()
# Verify the save worked
config_path = AlltalkConfig.default_config_path()
with open(config_path, 'r', encoding="utf-8") as f:
saved_config = json.load(f)
if saved_config.get('firstrun_model', True):
print(f"[{branding}TTS] Warning: Failed to save firstrun_model=False")
# Try one more time with direct file write
saved_config['firstrun_model'] = False
with open(config_path, 'w', encoding="utf-8") as f:
json.dump(saved_config, f, indent=2)
except Exception as e:
print(f"[{branding}TTS] Error saving firstrun configuration: {str(e)}")
def warning_message():
"""AllTalk V1 Warning message re updating"""
print(f"[{branding}TTS]")
print(f"[{branding}TTS] \033[93mIf you have you have UPGRADED from v1 ensure you have re-installed\033[0m")
print(f"[{branding}TTS] \033[93mthe requirements. Otherwise you will get failures and errors!\033[0m")
print(f"[{branding}TTS] \033[93mOn Linux ignore the \033[0m'sparse_attn requires a torch version' \033[93mand\033[0m")
print(f"[{branding}TTS] \033[0m'using untested triton version' \033[93mmessages.\033[0m")
print(f"[{branding}TTS]")
# Load confignew.json (might be version 1 or 2):
with open(AlltalkConfig.default_config_path(), 'r', encoding="utf-8") as file:
config_json = json.load(file)
branding = config_json['branding']
# Check if the config file is version 1
if "ip_address" in config_json:
print(f"[{branding}TTS] Detected version 1 configuration file.")
print(f"[{branding}TTS] Upgrading to version 2 configuration file...")
# Backup the old configuration file
backup_path = AlltalkConfig.default_config_path() + ".backup"
shutil.copyfile(AlltalkConfig.default_config_path(), backup_path)
# Copy the new configuration template to replace the old config file
new_config_template_path = this_dir / 'system/config/confignew.json'
shutil.copyfile(new_config_template_path, AlltalkConfig.default_config_path())
print(f"[{branding}TTS] Configuration file upgraded successfully.")
config = AlltalkConfig.get_instance()
branding = config.branding
# Argument parser setup
parser = argparse.ArgumentParser(description="TTS Setup Script")
parser.add_argument('--tts_model', type=str, choices=['piper', 'vits', 'xtts', 'none'],
help="Specify TTS model to set up (piper, vits, xtts, or none)")
args = parser.parse_args()
# Check if firstrun_model is true
if config.firstrun_model:
# Handle command-line argument for tts_model
if args.tts_model:
if args.tts_model == 'piper':
setup_piper()
update_tts_engines('piper')
set_firstrun_model_false()
elif args.tts_model == 'vits':
setup_vits()
update_tts_engines('vits')
set_firstrun_model_false()
elif args.tts_model == 'xtts':
setup_xtts()
update_tts_engines('xtts')
set_firstrun_model_false()
elif args.tts_model == 'none':
print(f"[{branding}TTS] No TTS model setup requested.")
print(f"[{branding}TTS] Setup completed for {args.tts_model}. Exiting.")
sys.exit()
# Check for Colab or Docker environment first
if is_running_in_colab() or is_running_in_docker():
print(f"[{branding}TTS] Detected Colab/Docker environment - automatically selecting Piper")
setup_piper()
update_tts_engines('piper')
set_firstrun_model_false()
warning_message()
sys.exit()
# Present the menu if no argument is passed and not in Colab/Docker
print(f"[{branding}TTS]")
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 initial setup.\033[0m")
print(f"[{branding}TTS]")
# List of available models
models = [
{"name": "piper", "model": "piper"},
{"name": "vits", "model": "tts_models--en--vctk--vits"},
{"name": "xtts", "model": "xttsv2_2.0.3"},
]
# Display models to the user
print(f"[{branding}TTS] \033[94mAvailable First Time Start-up models:\033[0m")
print(f"[{branding}TTS]")
for idx, model in enumerate(models):
print(f"[{branding}TTS] \033[93m{idx + 1}. \033[94m{model['name']} - {model['model']}\033[0m")
print(f"[{branding}TTS] \033[93m{len(models) + 1}.\033[94m I have my own models already\033[0m")
print(f"[{branding}TTS]")
print(f"[{branding}TTS] \033[94mIn \033[91m60 seconds\033[0m \033[94ma Piper model will be \033[91mdownloaded automatically.\033[0m")
print(f"[{branding}TTS]")
# Auto-select model after 60 seconds
selected_model = models[0] # Default to the first model (piper)
try:
user_choice = inputimeout(prompt=f"[{branding}TTS] \033[92mEnter your choice 1-4: \033[0m ", timeout=60)
except TimeoutOccurred:
user_choice = None
if user_choice is None:
print(f"[{branding}TTS]")
print(f"[{branding}TTS] No input received. Proceeding with the default model (piper).")
elif user_choice.lower() == 'own' or (user_choice.isdigit() and int(user_choice) == len(models) + 1):
print(f"[{branding}TTS]")
print(f"[{branding}TTS] Please use the Gradio interface TTS Engine Settings > [Engine Name] > Model Download")
print(f"[{branding}TTS] To download models for your selected TTS Engine. Or use the [Engine Name] help sections")
print(f"[{branding}TTS] for instructions on using your own TTS models.")
print(f"[{branding}TTS]")
os.makedirs('models/piper', exist_ok=True)
os.makedirs('models/vits', exist_ok=True)
os.makedirs('models/xtts/', exist_ok=True)
os.makedirs('models/f5-tts/', exist_ok=True)
os.makedirs('models/rvc_voices/', exist_ok=True)
update_tts_engines('piper')
set_firstrun_model_false()
warning_message()
exit()
if user_choice is not None and user_choice.isdigit() and 1 <= int(user_choice) <= len(models):
selected_model = models[int(user_choice) - 1]
warning_message()
if user_choice is None or user_choice.lower() != 'own':
if selected_model['name'] == 'piper':
setup_piper()
update_tts_engines('piper')
elif selected_model['name'] == 'vits':
setup_vits()
update_tts_engines('vits')
elif selected_model['name'] == 'xtts':
setup_xtts()
update_tts_engines('xtts')
print(f"[{branding}TTS] {selected_model['name']} model downloaded and configuration updated successfully.")
# Set firstrun_model to false
set_firstrun_model_false()
warning_message()
sys.exit()
else:
sys.exit()
+287
View File
@@ -0,0 +1,287 @@
import json
import os
import shutil
import sys
import time
import zipfile
import requests
from tqdm import tqdm
from inputimeout import inputimeout, TimeoutOccurred
from pathlib import Path
from typing import Optional, Dict, List, Any
# Setting the module search path:
sys.path.insert(0, str(Path(__file__).parent.parent.parent.resolve()))
from config import AlltalkTTSEnginesConfig, AlltalkConfig
this_dir = Path(__file__).parent.resolve().parent.resolve().parent.resolve()
def is_running_in_colab() -> bool:
"""Check if the script is running in Google Colab."""
try:
import google.colab
return True
except ImportError:
return False
def is_running_in_docker() -> bool:
"""Check if the script is running in a Docker container."""
return os.path.exists('/.dockerenv') or (
os.path.exists('/proc/self/cgroup') and
any('docker' in line for line in open('/proc/self/cgroup'))
)
def download_file(url: str, dest_path: str, timeout: int = 30) -> bool:
"""
Download a file from a URL with progress bar and error handling.
Args:
url: URL to download from
dest_path: Where to save the file
timeout: Connection timeout in seconds
Returns:
bool: True if download was successful
"""
progress_bar = None
try:
response = requests.get(url, stream=True, timeout=timeout)
response.raise_for_status()
total_size = int(response.headers.get('content-length', 0))
block_size = 1024
progress_bar = tqdm(total=total_size, unit='iB', unit_scale=True,
desc=f"Downloading {Path(dest_path).name}")
Path(dest_path).parent.mkdir(parents=True, exist_ok=True)
with open(dest_path, 'wb') as file:
for data in response.iter_content(block_size):
if data:
file.write(data)
progress_bar.update(len(data))
if progress_bar.n != total_size and total_size > 0:
raise requests.exceptions.RequestException(
f"Incomplete download: {progress_bar.n}/{total_size} bytes"
)
return True
except Exception as e:
print(f"Error downloading {url}: {str(e)}")
if Path(dest_path).exists():
Path(dest_path).unlink()
return False
finally:
if progress_bar:
progress_bar.close()
def setup_model(model_name: str) -> bool:
"""
Set up a specific TTS model.
Args:
model_name: Name of the model to setup ('piper', 'vits', or 'xtts')
Returns:
bool: True if setup was successful
"""
try:
if model_name == "piper":
os.makedirs(this_dir / 'models/piper', exist_ok=True)
os.makedirs(this_dir / 'models/xtts', exist_ok=True)
return all([
download_file(
"https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_US/ljspeech/high/en_US-ljspeech-high.onnx?download=true",
this_dir / "models/piper/en_US-ljspeech-high.onnx"
),
download_file(
"https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_US/ljspeech/high/en_US-ljspeech-high.onnx.json?download=true.json",
this_dir / "models/piper/en_US-ljspeech-high.onnx.json"
)
])
elif model_name == "vits":
os.makedirs(this_dir / 'models/vits', exist_ok=True)
os.makedirs(this_dir / 'models/xtts', exist_ok=True)
zip_path = this_dir / 'models/vits/vits.zip'
if not download_file(
"https://coqui.gateway.scarf.sh/v0.6.1_models/tts_models--en--vctk--vits.zip",
zip_path
):
return False
try:
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
zip_ref.extractall(this_dir / 'models/vits')
os.remove(zip_path)
return True
except Exception as e:
print(f"Error extracting VITS model: {str(e)}")
return False
elif model_name == "xtts":
os.makedirs(this_dir / 'models/xtts/xttsv2_2.0.3', exist_ok=True)
base_url = "https://huggingface.co/coqui/XTTS-v2/resolve/v2.0.3/"
files = [
"LICENSE.txt", "README.md", "config.json", "model.pth",
"dvae.pth", "mel_stats.pth", "speakers_xtts.pth", "vocab.json"
]
return all(
download_file(
base_url + file + "?download=true",
this_dir / f"models/xtts/xttsv2_2.0.3/{file}"
) for file in files
)
return False
except Exception as e:
print(f"Error setting up {model_name}: {str(e)}")
return False
def update_tts_engines(engine: str) -> bool:
"""Update TTS engine configuration with error handling."""
try:
AlltalkTTSEnginesConfig.get_instance().change_engine(engine).save()
return True
except Exception as e:
print(f"Error updating TTS engine configuration: {str(e)}")
return False
def set_firstrun_model_false() -> bool:
"""Set firstrun_model to false with verification."""
try:
# Get fresh config instance and update
config = AlltalkConfig.get_instance()
config.firstrun_model = False
config.save()
# Verify the save worked
config_path = AlltalkConfig.default_config_path()
with open(config_path, 'r') as f:
saved_config = json.load(f)
if saved_config.get('firstrun_model', True):
print(f"Warning: Failed to save firstrun_model=False")
# Try direct file write as fallback
saved_config['firstrun_model'] = False
with open(config_path, 'w') as f:
json.dump(saved_config, f, indent=2)
return True
except Exception as e:
print(f"Error saving firstrun configuration: {str(e)}")
return False
def warning_message(branding: str):
"""Display warning messages about installation and compatibility."""
print(f"[{branding}TTS]")
print(f"[{branding}TTS] \033[93mIf you have UPGRADED from v1 ensure you have re-installed\033[0m")
print(f"[{branding}TTS] \033[93mthe requirements. Otherwise you will get failures and errors!\033[0m")
print(f"[{branding}TTS] \033[93mOn Linux ignore the \033[0m'sparse_attn requires a torch version' \033[93mand\033[0m")
print(f"[{branding}TTS] \033[0m'using untested triton version' \033[93mmessages.\033[0m")
print(f"[{branding}TTS]")
def main():
"""Main execution function."""
try:
# Load configuration
with open(AlltalkConfig.default_config_path(), 'r') as file:
config_json = json.load(file)
branding = config_json['branding']
# Handle version 1 config upgrade
if "ip_address" in config_json:
print(f"[{branding}TTS] Detected version 1 configuration file.")
print(f"[{branding}TTS] Upgrading to version 2 configuration file...")
backup_path = AlltalkConfig.default_config_path() + ".backup"
shutil.copyfile(AlltalkConfig.default_config_path(), backup_path)
new_config_template_path = this_dir / 'system/config/confignew.json'
shutil.copyfile(new_config_template_path, AlltalkConfig.default_config_path())
print(f"[{branding}TTS] Configuration file upgraded successfully.")
config = AlltalkConfig.get_instance()
branding = config.branding
if not config.firstrun_model:
return
# Auto-select Piper for Colab/Docker
if is_running_in_colab() or is_running_in_docker():
print(f"[{branding}TTS] Detected Colab/Docker environment - automatically selecting Piper")
if setup_model('piper'):
update_tts_engines('piper')
set_firstrun_model_false()
warning_message(branding)
return
# Normal interactive setup
models = [
{"name": "piper", "model": "piper"},
{"name": "vits", "model": "tts_models--en--vctk--vits"},
{"name": "xtts", "model": "xttsv2_2.0.3"},
]
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]")
print(f"[{branding}TTS] \033[94mAvailable First Time Start-up models:\033[0m")
print(f"[{branding}TTS]")
for idx, model in enumerate(models):
print(f"[{branding}TTS] \033[93m{idx + 1}. \033[94m{model['name']} - {model['model']}\033[0m")
print(f"[{branding}TTS] \033[93m{len(models) + 1}.\033[94m I have my own models already\033[0m")
print(f"[{branding}TTS]")
print(f"[{branding}TTS] \033[94mIn \033[91m60 seconds\033[0m \033[94ma Piper model will be \033[91mdownloaded automatically.\033[0m")
print(f"[{branding}TTS]")
try:
user_choice = inputimeout(
prompt=f"[{branding}TTS] \033[92mEnter your choice 1-4: \033[0m ",
timeout=60
)
except TimeoutOccurred:
user_choice = None
if user_choice is None:
print(f"[{branding}TTS] No input received. Proceeding with the default model (piper).")
selected_model = models[0]
elif user_choice.lower() == 'own' or (user_choice.isdigit() and int(user_choice) == len(models) + 1):
print(f"[{branding}TTS] If you have your own XTTS models, please move them into the")
print(f"[{branding}TTS] \033[93m/models/xtts/\033[0m folder")
os.makedirs('models/piper', exist_ok=True)
os.makedirs('models/vits', exist_ok=True)
os.makedirs('models/xtts/', exist_ok=True)
update_tts_engines('piper')
set_firstrun_model_false()
warning_message(branding)
return
elif user_choice.isdigit() and 1 <= int(user_choice) <= len(models):
selected_model = models[int(user_choice) - 1]
warning_message(branding)
else:
print(f"[{branding}TTS] Invalid choice. Proceeding with the default model (piper).")
selected_model = models[0]
if setup_model(selected_model['name']):
update_tts_engines(selected_model['name'])
set_firstrun_model_false()
print(f"[{branding}TTS] {selected_model['name']} model downloaded and configuration updated successfully.")
warning_message(branding)
except Exception as e:
print(f"Unexpected error: {str(e)}")
sys.exit(1)
if __name__ == "__main__":
main()
+92
View File
@@ -0,0 +1,92 @@
#!/bin/bash
# Get the conda environment path
env_path="${CONDA_DEFAULT_ENV}/lib"
# List of broken symlinks
declare -A symlinks=(
["libcufile.so"]="libcufile.so"
["libcufile_rdma.so"]="libcufile_rdma.so"
["libcudart.so"]="libcudart.so"
["libnvjpeg.so"]="libnvjpeg.so"
["libcurand.so"]="libcurand.so"
["libnvJitLink.so"]="libnvJitLink.so"
["libnvrtc-builtins.so"]="libnvrtc-builtins.so"
["libnvrtc.so"]="libnvrtc.so"
)
# Function to test for broken symlinks
test_broken_symlinks() {
echo "Testing for broken symlinks..."
broken_found=false
for link in "${!symlinks[@]}"; do
if [ -L "$env_path/$link" ] && [ ! -e "$env_path/$link" ]; then
echo "Broken symlink found: $env_path/$link"
broken_found=true
fi
done
if [ "$broken_found" = false ]; then
echo "No broken symlinks found."
fi
}
# Function to fix broken symlinks
fix_broken_symlinks() {
echo "Fixing broken symlinks..."
for link in "${!symlinks[@]}"; do
if [ -L "$env_path/$link" ] && [ ! -e "$env_path/$link" ]; then
echo "Removing broken link: $env_path/$link"
rm "$env_path/$link"
# Find all possible target files
target_files=($(find "$env_path" -name "${symlinks[$link]}*"))
if [ ${#target_files[@]} -gt 0 ]; then
echo "Select a target file for $link:"
for i in "${!target_files[@]}"; do
echo "$((i+1)). ${target_files[$i]}"
done
read -p "Enter the number of the target file to use: " choice
choice=$((choice-1))
if [[ $choice -ge 0 && $choice -lt ${#target_files[@]} ]]; then
target="${target_files[$choice]}"
echo "Creating new symlink: $env_path/$link -> $target"
ln -s "$target" "$env_path/$link"
else
echo "Invalid choice, skipping $link."
fi
else
echo "No target files found for $link."
fi
fi
done
echo "Verification of symbolic links:"
ls -l $env_path | grep -E "libcufile.so|libcudart.so|libcufile_rdma.so|libnvjpeg.so|libcurand.so|libnvJitLink.so|libnvrtc-builtins.so|libnvrtc.so"
}
# Menu
while true; do
echo "Select an option:"
echo "1. Test for broken symlinks"
echo "2. Fix broken symlinks"
echo "3. Exit"
read -p "Enter your choice [1-3]: " choice
case $choice in
1)
test_broken_symlinks
;;
2)
fix_broken_symlinks
;;
3)
echo "Exiting."
break
;;
*)
echo "Invalid choice. Please select 1, 2, or 3."
;;
esac
done
-1
View File
@@ -6,7 +6,6 @@
"English": "en", "English": "en",
"French": "fr", "French": "fr",
"German": "de", "German": "de",
"Hindi": "hi",
"Hungarian": "hu", "Hungarian": "hu",
"Italian": "it", "Italian": "it",
"Japanese": "ja", "Japanese": "ja",
@@ -0,0 +1,13 @@
find {addpathheretoscan}/alltalk_environment/env/lib -xtype l
here are the list on Cuda-Toolkit 12.1, others vary
.../alltalk_environment/env/lib/libcufile.so
.../alltalk_environment/env/lib/libcudart.so
.../alltalk_environment/env/lib/libcufile_rdma.so
.../alltalk_environment/env/lib/libnvjpeg.so
.../alltalk_environment/env/lib/libcurand.so
.../alltalk_environment/env/lib/libnvJitLink.so
.../alltalk_environment/env/lib/libnvrtc-builtins.so
.../alltalk_environment/env/lib/libnvrtc.so
Binary file not shown.
Binary file not shown.
+54
View File
@@ -0,0 +1,54 @@
import json
import os
def merge_vocabularies(base_vocab_path, new_vocab_path, output_path):
# Load the base model's vocab.json
with open(base_vocab_path, 'r') as f:
base_data = json.load(f)
# Load the new bpe_tokenizer.json
with open(new_vocab_path, 'r') as f:
new_data = json.load(f)
# Extract the vocabularies
base_vocab = base_data['model']['vocab']
new_vocab = new_data['model']['vocab']
# Find the maximum value in the base vocabulary
max_value = max(base_vocab.values())
# Merge the vocabularies
for key, value in new_vocab.items():
if key not in base_vocab:
max_value += 1
base_vocab[key] = max_value
# Update the base data with the merged vocabulary
base_data['model']['vocab'] = base_vocab
# Extract the merges
base_merges = base_data['model']['merges']
new_merges = new_data['model']['merges']
# Merge the merges
merged_merges = base_merges.copy()
for merge in new_merges:
if merge not in merged_merges:
merged_merges.append(merge)
# Update the base data with the merged merges
base_data['model']['merges'] = merged_merges
# Write the merged vocabulary and merges to the output file
with open(output_path, 'w') as f:
json.dump(base_data, f, ensure_ascii=False, indent=2)
print(f"Merged vocabulary and merges saved to {output_path}")
# Define file paths
base_vocab_path = "/alltalk_tts/models/xtts/xttsv2_2.0.2/originalvocab.json" # base model vocab.json path (2.0.2)
new_vocab_path = "/alltalk_tts/expanded_models/tortoise_tokenizer2xttsv2.json" # path to the custom dataset vocab.json
output_path = "/alltalk_tts/expanded_models/combined_vocab.json" # location for combined vocab.json
# Merge the vocabularies
merge_vocabularies(base_vocab_path, new_vocab_path, output_path)
+60
View File
@@ -0,0 +1,60 @@
# Credit Jarod Mica https://github.com/JarodMica/tortoise_dataset_tools/blob/master/bpe_tokenizer_tools/train_bpe_tokenizer.py
# provide a cleaned txt file with only the transcription. Youll get back out the datasets vocab.json
from tokenizers import Tokenizer
from tokenizers.models import BPE
from tokenizers.trainers import BpeTrainer
from tokenizers.pre_tokenizers import Whitespace
from tkinter import Tk, filedialog
import json
import re
def clean_text(input_file_path, output_file_path):
# Define the pattern to match numbers, specific symbols, and new lines
# add \d to match any digit, and | is used to specify alternatives
pattern = r'|�|«|\$|\n'
with open(input_file_path, 'r', encoding='utf-8') as input_file:
text = input_file.read()
cleaned_text = re.sub(pattern, '', text)
with open(output_file_path, 'w', encoding='utf-8') as output_file:
output_file.write(cleaned_text)
def train_tokenizer(input_path, tokenizer_path, language, special_tokens=["[STOP]", "[UNK]", "[SPACE]" ], vocab_size=256):
# Initialize a tokenizer with the BPE model
tokenizer = Tokenizer(BPE(unk_token="[UNK]"))
# Use a basic whitespace pre-tokenizer
tokenizer.pre_tokenizer = Whitespace()
# trainer = BpeTrainer(special_tokens=["[STOP]", "[UNK]", "[SPACE]", "0","1","2","3","4","5","6","7","8","9",], vocab_size=256)
trainer = BpeTrainer(special_tokens=special_tokens, vocab_size=vocab_size)
clean_text(input_path, input_path)
tokenizer.train([input_path], trainer)
tokenizer.save(tokenizer_path)
with open(tokenizer_path, 'r', encoding='utf-8') as f:
tokenizer_json = json.load(f)
# Add language to tokenizer
tokenizer_json['model']['language'] = language
with open(tokenizer_path, 'w', encoding='utf-8') as f:
json.dump(tokenizer_json, f, ensure_ascii=False, indent=4)
def choose_file():
root = Tk()
root.withdraw()
file = filedialog.askopenfilename()
root.destroy()
return file
if __name__ == "__main__":
input_path = choose_file()
tokenizer_path = "/alltalk_tts/expanded_models/tortoise_tokenizer2xttsv2.json" # define path to put the newly create vocab.json
special_tokens = ["[STOP]", "[UNK]", "[SPACE]"]
vocab_size = 256 # model is stuck at this size
train_tokenizer(input_path, tokenizer_path, language='multi', special_tokens=special_tokens, vocab_size=vocab_size)
+121
View File
@@ -0,0 +1,121 @@
"""
This script does not have any specific alltalk integration yet. So we are manually entering paths and it works as a standalone.
The script does the following:
- Expands the embedding layer of the base XTTSv2 model according to the user created/trained bpe_tokenizer-vocab.json and the base model vocab.json.
Set variable paths with the base config and base model.pth.
Set the new tokenizer/vocab bpe_tokenizer-vocab.json location.
The new model will be saved at \expanded_models\expanded_model.pth
Once this is done the new expanded model must be swapped in for the base model.pth then combined with the dvae.pth, vocab.json(bpe_tokenizer-vocab.json), base model config.json,
base model speaker_xtts.pth and base model vocoder.json.
I left some print debug statements in the script, they may be nice for the user to see during the process.
"""
import torch
import torch.nn as nn
import json
from TTS.tts.models.xtts import Xtts
from TTS.tts.layers.xtts.trainer.gpt_trainer import GPTTrainerConfig
from TTS.tts.layers.xtts.tokenizer import VoiceBpeTokenizer
config_path = "/alltalk_tts/models/xtts/xttsv2_2.0.3/config.json" # Path to the base model config.json
pretrained_model_path = "/alltalk_tts/models/xtts/xttsv2_2.0.3/model.pth" # Path to the base model.pth
new_tokenizer_path = "/expanded_model/expanded_vocab.json" # Path to the new combined expanded_vocab.json
expanded_model_path = "/expanded_model/expanded_model.pth" # Path to where you want the new expanded_model.pth
# Open and load the configuration file
with open(config_path, "r") as f:
config_dict = json.load(f)
# Create a GPTTrainerConfig object and populate it with the loaded configuration
config = GPTTrainerConfig()
config.from_dict(data=config_dict)
# Function to get the vocabulary size from a tokenizer file
def get_vocab_size(tokenizer_path):
tokenizer = VoiceBpeTokenizer(vocab_file=tokenizer_path)
return len(tokenizer.tokenizer.get_vocab())
# Function to adjust the pretrained model with a new tokenizer
def adjust_pretrained_model(
pretrained_model_path, adjusted_model_path, new_tokenizer_path):
state_dict = torch.load(pretrained_model_path)
pretrained_state_dict = state_dict["model"]
model = Xtts(config)
# Load the pretrained state dictionary into the new model
missing_keys, unexpected_keys = model.load_state_dict(pretrained_state_dict, strict=False)
if missing_keys:
print(f"Missing keys: {missing_keys}")
if unexpected_keys:
print(f"Unexpected keys: {unexpected_keys}")
print("Pretrained model loaded successfully.")
# Create a new tokenizer with the new vocabulary
new_tokenizer = VoiceBpeTokenizer(vocab_file=new_tokenizer_path)
# Get the old and new vocabulary sizes, and the embedding dimension
old_vocab_size = model.gpt.text_embedding.num_embeddings
new_vocab_size = len(new_tokenizer.tokenizer.get_vocab())
embedding_dim = model.gpt.text_embedding.embedding_dim
print(f"Old vocab size: {old_vocab_size}")
print(f"New vocab size: {new_vocab_size}")
print(f"Embedding dimension: {embedding_dim}")
# Adjust the embedding layer with the new vocabulary size
adjust_embedding_layer(model, new_vocab_size, adjusted_model_path)
# Freeze all parameters except the position embeddings
freeze_except_position_embeddings(model)
# Function to adjust the embedding layer for the new vocabulary size
def adjust_embedding_layer(model, new_vocab_size, adjusted_model_path):
old_vocab_size = model.gpt.text_embedding.num_embeddings
embedding_dim = model.gpt.text_embedding.embedding_dim
# Create new embedding and linear layers with the new vocabulary size
new_text_embedding = nn.Embedding(new_vocab_size, embedding_dim)
new_text_head = nn.Linear(embedding_dim, new_vocab_size)
# Copy weights from the old embedding layer to the new one
if new_vocab_size > old_vocab_size:
new_text_embedding.weight.data[:old_vocab_size] = model.gpt.text_embedding.weight.data
new_text_head.weight.data[:old_vocab_size] = model.gpt.text_head.weight.data
new_text_head.bias.data[:old_vocab_size] = model.gpt.text_head.bias.data
new_text_embedding.weight.data[old_vocab_size:].normal_(mean=0.0, std=0.02)
new_text_head.weight.data[old_vocab_size:].normal_(mean=0.0, std=0.02)
new_text_head.bias.data[old_vocab_size:].normal_(mean=0.0, std=0.02)
else:
new_text_embedding.weight.data = model.gpt.text_embedding.weight.data[:new_vocab_size]
new_text_head.weight.data = model.gpt.text_head.weight.data[:new_vocab_size]
new_text_head.bias.data = model.gpt.text_head.bias.data[:new_vocab_size]
model.gpt.text_embedding = new_text_embedding
model.gpt.text_head = new_text_head
checkpoint = {"model": model.state_dict()}
torch.save(checkpoint, adjusted_model_path)
print(f"Adjusted model saved to {adjusted_model_path}")
# Function to freeze all parameters except the position embeddings
def freeze_except_position_embeddings(model):
for param in model.parameters():
param.requires_grad = False
for name, param in model.named_parameters():
if 'pos_embedding' in name:
param.requires_grad = True
# Verify which parameters are frozen and which are not, comment this out if you dont want to debug. You should see only two true values
for name, param in model.named_parameters():
print(f"{name}: requires_grad={param.requires_grad}")
# Expand the pretrained model with the new tokenizer
adjust_pretrained_model(pretrained_model_path, expanded_model_path, new_tokenizer_path)
@@ -0,0 +1,26 @@
# Simple script to remove LJ Speech formatting for the tokenizer
# Combine metadata_train and metadata_eval.csv into a single file then run
import csv
# Input and output file names
input_file = '/alltalkbeta/metadata_eval.csv' # combine metadata_train and metadata_eval.csv
output_file = '/alltalkbeta/dataset.txt' # this goes to the tokenizer
# Read the input CSV and write to the output file
with open(input_file, 'r', newline='', encoding='utf-8') as infile, \
open(output_file, 'w', newline='', encoding='utf-8') as outfile:
# Create CSV reader and writer objects
reader = csv.reader(infile, delimiter='|')
writer = csv.writer(outfile, delimiter='|')
# Skip the header
next(reader, None)
# Process each row
for row in reader:
if len(row) >= 2:
# Write only the second column (index 1) to the output file
writer.writerow([row[1]])
print(f"Processing complete. Output written to {output_file}")
+76
View File
@@ -0,0 +1,76 @@
import os
from pathlib import Path
import gradio as gr
# Define directories
this_dir = Path(__file__).parent.resolve()
main_dir = this_dir.parent.parent.resolve()
# Folder paths
folders = {
"models": main_dir / "models",
"finetune": main_dir / "finetune",
"voices": main_dir / "voices",
"outputs": main_dir / "outputs",
"alltalk_environment": main_dir / "alltalk_environment"
}
def get_folder_size_scandir(folder_path):
total_size = 0
for entry in os.scandir(folder_path):
if entry.is_file(follow_symlinks=False):
try:
total_size += entry.stat(follow_symlinks=False).st_size
except OSError as e:
print(f"Error getting size for file {entry.path}: {e}")
elif entry.is_dir(follow_symlinks=False):
try:
total_size += get_folder_size_scandir(entry.path)
except OSError as e:
print(f"Error accessing directory {entry.path}: {e}")
return total_size
def format_size(size):
# Convert size to a readable format
for unit in ['B', 'KB', 'MB', 'GB', 'TB']:
if size < 1024:
return f"{size:.2f} {unit}"
size /= 1024
def calculate_disk_space():
sizes = {}
for name, path in folders.items():
if path.exists():
folder_size = get_folder_size_scandir(path)
# print(f"Folder: {name}, Total Size: {folder_size} bytes")
sizes[name] = format_size(folder_size)
else:
sizes[name] = "Not present"
return sizes['models'], sizes['finetune'], sizes['voices'], sizes['outputs'], sizes['alltalk_environment']
def disk_space_page():
# Define the layout
with gr.Tab("Disk Space Usage"):
with gr.Row():
models_space = gr.Textbox(label="Models Folder", interactive=False)
finetune_space = gr.Textbox(label="Finetune Folder", interactive=False)
voices_space = gr.Textbox(label="Voices Folder", interactive=False)
outputs_space = gr.Textbox(label="Outputs Folder", interactive=False)
alltalk_env_space = gr.Textbox(label="Alltalk Python Environment", interactive=False)
calculate_button = gr.Button("Calculate Disk Space Usage")
# Define actions for buttons
calculate_button.click(calculate_disk_space, outputs=[models_space, finetune_space, voices_space, outputs_space, alltalk_env_space])
def get_disk_interface():
return disk_space_page
# Example usage in the main script
if __name__ == "__main__":
app = gr.Blocks()
with app:
disk_space_page()
app.launch()
File diff suppressed because it is too large. Load diff
+114
View File
@@ -0,0 +1,114 @@
import os
import json
import sys
import importlib
# Hard-coded paths
this_folder = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", ".."))
config_file = os.path.join(this_folder, "confignew.json")
gradio_pages_folder = os.path.join(this_folder, "system", "gradio_pages", "themes")
theme_list_file = os.path.join(gradio_pages_folder, "theme_list.json")
themes_file_path = os.path.join(gradio_pages_folder, "themes.py")
# Add gradio_pages folder to the system path
sys.path.append(gradio_pages_folder)
def get_class(filename):
with open(filename, "r", encoding="utf8") as file:
for line in file:
if "class " in line:
return line.split("class ")[1].split(":")[0].split("(")[0].strip()
return None
def get_list():
themes_from_files = [
os.path.splitext(name)[0]
for name in os.listdir(gradio_pages_folder)
if name.endswith(".py")
]
try:
with open(theme_list_file, "r", encoding="utf8") as json_file:
themes_from_url = [item["id"] for item in json.load(json_file)]
except FileNotFoundError:
themes_from_url = []
combined_themes = sorted(set(themes_from_files + themes_from_url))
return list(combined_themes)
def select_theme(name):
selected_file = name + ".py"
full_path = os.path.join(gradio_pages_folder, selected_file)
try:
with open(config_file, "r", encoding="utf8") as json_file:
config_data = json.load(json_file)
if not os.path.exists(full_path):
# If the theme is from theme_list.json, update only the class field
config_data["theme"]["file"] = None
config_data["theme"]["class"] = name
message = f"Theme {name} successfully selected, restart AllTalk."
else:
# If the theme file exists locally, update both file and class fields
class_found = get_class(full_path)
if class_found:
config_data["theme"]["file"] = selected_file
config_data["theme"]["class"] = class_found
message = f"Theme {name} successfully selected, restart AllTalk."
else:
message = f"Theme {name} was not found."
with open(config_file, "w", encoding="utf8") as json_file:
json.dump(config_data, json_file, indent=2)
print(message)
return message
except Exception as e:
print(f"[AllTalk TTS] Error selecting theme {name}: {str(e)}")
return message
def read_json():
try:
with open(config_file, "r", encoding="utf8") as json_file:
data = json.load(json_file)
selected_file = data["theme"]["file"]
class_name = data["theme"]["class"]
if selected_file and class_name:
return class_name
elif not selected_file and class_name:
return class_name
else:
return "gradio/base"
except Exception as e:
print(f"[AllTalk TTS] Error reading config.json: {e}")
return "gradio/base"
def load_json():
try:
with open(config_file, "r", encoding="utf8") as json_file:
data = json.load(json_file)
selected_file = data["theme"]["file"]
class_name = data["theme"]["class"]
if selected_file and class_name:
module_name = os.path.splitext(selected_file)[0]
module_spec = importlib.util.spec_from_file_location(module_name, themes_file_path)
module = importlib.util.module_from_spec(module_spec)
module_spec.loader.exec_module(module)
obtained_class = getattr(module, class_name)
instance = obtained_class()
print(f"Theme Loaded: {class_name}")
return instance
elif not selected_file and class_name:
return class_name
else:
print("The theme is incorrect.")
return None
except Exception as e:
print(f"Error Loading: {str(e)}")
return None
@@ -0,0 +1,81 @@
[
{"id": "freddyaboulton/dracula_revamped"},
{"id": "freddyaboulton/bad-theme-space"},
{"id": "gradio/dracula_revamped"},
{"id": "abidlabs/dracula_revamped"},
{"id": "gradio/dracula_test"},
{"id": "abidlabs/dracula_test"},
{"id": "gradio/seafoam"},
{"id": "gradio/glass"},
{"id": "gradio/monochrome"},
{"id": "gradio/soft"},
{"id": "gradio/default"},
{"id": "gradio/base"},
{"id": "abidlabs/pakistan"},
{"id": "dawood/microsoft_windows"},
{"id": "ysharma/steampunk"},
{"id": "ysharma/huggingface"},
{"id": "gstaff/xkcd"},
{"id": "JohnSmith9982/small_and_pretty"},
{"id": "abidlabs/Lime"},
{"id": "freddyaboulton/this-theme-does-not-exist-2"},
{"id": "aliabid94/new-theme"},
{"id": "aliabid94/test2"},
{"id": "aliabid94/test3"},
{"id": "aliabid94/test4"},
{"id": "abidlabs/banana"},
{"id": "freddyaboulton/test-blue"},
{"id": "gstaff/sketch"},
{"id": "gstaff/whiteboard"},
{"id": "ysharma/llamas"},
{"id": "abidlabs/font-test"},
{"id": "YenLai/Superhuman"},
{"id": "bethecloud/storj_theme"},
{"id": "sudeepshouche/minimalist"},
{"id": "knotdgaf/gradiotest"},
{"id": "ParityError/Interstellar"},
{"id": "ParityError/Anime"},
{"id": "Ajaxon6255/Emerald_Isle"},
{"id": "ParityError/LimeFace"},
{"id": "finlaymacklon/smooth_slate"},
{"id": "finlaymacklon/boxy_violet"},
{"id": "derekzen/stardust"},
{"id": "EveryPizza/Cartoony-Gradio-Theme"},
{"id": "Ifeanyi/Cyanister"},
{"id": "Tshackelton/IBMPlex-DenseReadable"},
{"id": "snehilsanyal/scikit-learn"},
{"id": "Himhimhim/xkcd"},
{"id": "shivi/calm_seafoam"},
{"id": "nota-ai/theme"},
{"id": "rawrsor1/Everforest"},
{"id": "SebastianBravo/simci_css"},
{"id": "rottenlittlecreature/Moon_Goblin"},
{"id": "abidlabs/test-yellow"},
{"id": "abidlabs/test-yellow3"},
{"id": "idspicQstitho/dracula_revamped"},
{"id": "kfahn/AnimalPose"},
{"id": "HaleyCH/HaleyCH_Theme"},
{"id": "simulKitke/dracula_test"},
{"id": "braintacles/CrimsonNight"},
{"id": "wentaohe/whiteboardv2"},
{"id": "reilnuud/polite"},
{"id": "remilia/Ghostly"},
{"id": "Franklisi/darkmode"},
{"id": "coding-alt/soft"},
{"id": "xiaobaiyuan/theme_land"},
{"id": "step-3-profit/Midnight-Deep"},
{"id": "xiaobaiyuan/theme_demo"},
{"id": "Taithrah/Minimal"},
{"id": "Insuz/SimpleIndigo"},
{"id": "zkunn/Alipay_Gradio_theme"},
{"id": "Insuz/Mocha"},
{"id": "xiaobaiyuan/theme_brief"},
{"id": "Ama434/434-base-Barlow"},
{"id": "Ama434/def_barlow"},
{"id": "Ama434/neutral-barlow"},
{"id": "dawood/dracula_test"},
{"id": "nuttea/Softblue"},
{"id": "BlueDancer/Alien_Diffusion"},
{"id": "naughtondale/monochrome"},
{"id": "Dagfinn1962/standard"}
]
+284
View File
@@ -0,0 +1,284 @@
from __future__ import annotations
from typing import Iterable
import gradio as gr
# gr.themes.builder()
from gradio.themes.base import Base
from gradio.themes.utils import colors, fonts, sizes
import time
class alltalk(Base):
def __init__(
self,
*,
primary_hue: colors.Color | str = colors.neutral,
secondary_hue: colors.Color | str = colors.neutral,
neutral_hue: colors.Color | str = colors.neutral,
spacing_size: sizes.Size | str = sizes.spacing_md,
radius_size: sizes.Size | str = sizes.radius_md,
text_size: sizes.Size | str = sizes.text_lg,
font: fonts.Font | str | Iterable[fonts.Font | str] = (
"Syne V",
fonts.GoogleFont("Syne"),
"ui-sans-serif",
"system-ui",
),
font_mono: fonts.Font | str | Iterable[fonts.Font | str] = (
"ui-monospace",
fonts.GoogleFont("Nunito Sans"),
),
):
super().__init__(
primary_hue=primary_hue,
secondary_hue=secondary_hue,
neutral_hue=neutral_hue,
spacing_size=spacing_size,
radius_size=radius_size,
text_size=text_size,
font=font,
font_mono=font_mono,
)
self.name = ("alltalk",)
self.secondary_100 = ("#dbeafe",)
self.secondary_200 = ("#bfdbfe",)
self.secondary_300 = ("#93c5fd",)
self.secondary_400 = ("#60a5fa",)
self.secondary_50 = ("#eff6ff",)
self.secondary_500 = ("#3b82f6",)
self.secondary_600 = ("#2563eb",)
self.secondary_700 = ("#1d4ed8",)
self.secondary_800 = ("#1e40af",)
self.secondary_900 = ("#1e3a8a",)
self.secondary_950 = ("#1d3660",)
super().set(
# Blaise
background_fill_primary="#110F0F",
background_fill_primary_dark="#110F0F",
background_fill_secondary="#110F0F",
background_fill_secondary_dark="#110F0F",
block_background_fill="*neutral_800",
block_background_fill_dark="*neutral_800",
block_border_color="*border_color_primary",
block_border_color_dark="*border_color_primary",
block_border_width="1px",
block_border_width_dark="1px",
block_info_text_color="*body_text_color_subdued",
block_info_text_color_dark="*body_text_color_subdued",
block_info_text_size="*text_sm",
block_info_text_weight="400",
block_label_background_fill="*background_fill_primary",
block_label_background_fill_dark="*background_fill_secondary",
block_label_border_color="*border_color_primary",
block_label_border_color_dark="*border_color_primary",
block_label_border_width="1px",
block_label_border_width_dark="1px",
block_label_margin="0",
block_label_padding="*spacing_sm *spacing_lg",
block_label_radius="calc(*radius_lg - 1px) 0 calc(*radius_lg - 1px) 0",
block_label_right_radius="0 calc(*radius_lg - 1px) 0 calc(*radius_lg - 1px)",
block_label_shadow="*block_shadow",
block_label_text_color="*#110F0F",
block_label_text_color_dark="*#110F0F",
block_label_text_weight="400",
block_padding="*spacing_xl",
block_radius="*radius_md",
block_shadow="none",
block_shadow_dark="none",
block_title_background_fill="rgb(255,255,255)",
block_title_background_fill_dark="rgb(255,255,255)",
block_title_border_color="none",
block_title_border_color_dark="none",
block_title_border_width="0px",
block_title_padding="*block_label_padding",
block_title_radius="*block_label_radius",
block_title_text_color="#110F0F",
block_title_text_color_dark="#110F0F",
block_title_text_size="*text_md",
block_title_text_weight="600",
body_background_fill="#110F0F",
body_background_fill_dark="#110F0F",
body_text_color="white",
body_text_color_dark="white",
body_text_color_subdued="*neutral_400",
body_text_color_subdued_dark="*neutral_400",
body_text_size="*text_md",
body_text_weight="400",
border_color_accent="*neutral_600",
border_color_accent_dark="*neutral_600",
border_color_primary="*neutral_800",
border_color_primary_dark="*neutral_800",
button_border_width="*input_border_width",
button_border_width_dark="*input_border_width",
button_cancel_background_fill="*button_secondary_background_fill",
button_cancel_background_fill_dark="*button_secondary_background_fill",
button_cancel_background_fill_hover="*button_cancel_background_fill",
button_cancel_background_fill_hover_dark="*button_cancel_background_fill",
button_cancel_border_color="*button_secondary_border_color",
button_cancel_border_color_dark="*button_secondary_border_color",
button_cancel_border_color_hover="*button_cancel_border_color",
button_cancel_border_color_hover_dark="*button_cancel_border_color",
button_cancel_text_color="#110F0F",
button_cancel_text_color_dark="#110F0F",
button_cancel_text_color_hover="#110F0F",
button_cancel_text_color_hover_dark="#110F0F",
button_large_padding="*spacing_lg calc(2 * *spacing_lg)",
button_large_radius="*radius_lg",
button_large_text_size="*text_lg",
button_large_text_weight="600",
button_primary_background_fill="*primary_600",
button_primary_background_fill_dark="*primary_600",
button_primary_background_fill_hover="*primary_500",
button_primary_background_fill_hover_dark="*primary_500",
button_primary_border_color="*primary_500",
button_primary_border_color_dark="*primary_500",
button_primary_border_color_hover="*primary_400",
button_primary_border_color_hover_dark="*primary_400",
button_primary_text_color="white",
button_primary_text_color_dark="white",
button_primary_text_color_hover="#110F0F",
button_primary_text_color_hover_dark="#110F0F",
button_secondary_background_fill="transparent",
button_secondary_background_fill_dark="transparent",
button_secondary_background_fill_hover="*neutral_800",
button_secondary_background_fill_hover_dark="*neutral_800",
button_secondary_border_color="*neutral_700",
button_secondary_border_color_dark="*neutral_700",
button_secondary_border_color_hover="*neutral_600",
button_secondary_border_color_hover_dark="*neutral_600",
button_secondary_text_color="white",
button_secondary_text_color_dark="white",
button_secondary_text_color_hover="*button_secondary_text_color",
button_secondary_text_color_hover_dark="*button_secondary_text_color",
button_shadow="none",
button_shadow_active="*shadow_inset",
button_shadow_hover="none",
button_small_padding="*spacing_sm calc(2 * *spacing_sm)",
button_small_radius="*radius_lg",
button_small_text_size="*text_md",
button_small_text_weight="400",
button_transition="0.3s ease all",
checkbox_background_color="*neutral_700",
checkbox_background_color_dark="*neutral_700",
checkbox_background_color_focus="*checkbox_background_color",
checkbox_background_color_focus_dark="*checkbox_background_color",
checkbox_background_color_hover="*checkbox_background_color",
checkbox_background_color_hover_dark="*checkbox_background_color",
checkbox_background_color_selected="*secondary_600",
checkbox_background_color_selected_dark="*secondary_600",
checkbox_border_color="*neutral_700",
checkbox_border_color_dark="*neutral_700",
checkbox_border_color_focus="*secondary_500",
checkbox_border_color_focus_dark="*secondary_500",
checkbox_border_color_hover="*neutral_600",
checkbox_border_color_hover_dark="*neutral_600",
checkbox_border_color_selected="*secondary_600",
checkbox_border_color_selected_dark="*secondary_600",
checkbox_border_radius="*radius_sm",
checkbox_border_width="*input_border_width",
checkbox_border_width_dark="*input_border_width",
checkbox_check="url(\"data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e\")",
checkbox_label_background_fill="transparent",
checkbox_label_background_fill_dark="transparent",
checkbox_label_background_fill_hover="transparent",
checkbox_label_background_fill_hover_dark="transparent",
checkbox_label_background_fill_selected="transparent",
checkbox_label_background_fill_selected_dark="transparent",
checkbox_label_border_color="transparent",
checkbox_label_border_color_dark="transparent",
checkbox_label_border_color_hover="transparent",
checkbox_label_border_color_hover_dark="transparent",
checkbox_label_border_width="transparent",
checkbox_label_border_width_dark="transparent",
checkbox_label_gap="*spacing_lg",
checkbox_label_padding="*spacing_md calc(2 * *spacing_md)",
checkbox_label_shadow="none",
checkbox_label_text_color="*body_text_color",
checkbox_label_text_color_dark="*body_text_color",
checkbox_label_text_color_selected="*checkbox_label_text_color",
checkbox_label_text_color_selected_dark="*checkbox_label_text_color",
checkbox_label_text_size="*text_md",
checkbox_label_text_weight="400",
checkbox_shadow="*input_shadow",
color_accent="*primary_500",
color_accent_soft="*primary_50",
color_accent_soft_dark="*neutral_700",
container_radius="*radius_xl",
embed_radius="*radius_lg",
error_background_fill="*background_fill_primary",
error_background_fill_dark="*background_fill_primary",
error_border_color="*border_color_primary",
error_border_color_dark="*border_color_primary",
error_border_width="1px",
error_border_width_dark="1px",
error_text_color="#ef4444",
error_text_color_dark="#ef4444",
form_gap_width="0px",
input_background_fill="*neutral_900",
input_background_fill_dark="*neutral_900",
input_background_fill_focus="*secondary_600",
input_background_fill_focus_dark="*secondary_600",
input_background_fill_hover="*input_background_fill",
input_background_fill_hover_dark="*input_background_fill",
input_border_color="*neutral_700",
input_border_color_dark="*neutral_700",
input_border_color_focus="*secondary_600",
input_border_color_focus_dark="*primary_600",
input_border_color_hover="*input_border_color",
input_border_color_hover_dark="*input_border_color",
input_border_width="1px",
input_border_width_dark="1px",
input_padding="*spacing_xl",
input_placeholder_color="*neutral_500",
input_placeholder_color_dark="*neutral_500",
input_radius="*radius_lg",
input_shadow="none",
input_shadow_dark="none",
input_shadow_focus="*input_shadow",
input_shadow_focus_dark="*input_shadow",
input_text_size="*text_md",
input_text_weight="400",
layout_gap="*spacing_xxl",
link_text_color="*secondary_500",
link_text_color_active="*secondary_500",
link_text_color_active_dark="*secondary_500",
link_text_color_dark="*secondary_500",
link_text_color_hover="*secondary_400",
link_text_color_hover_dark="*secondary_400",
link_text_color_visited="*secondary_600",
link_text_color_visited_dark="*secondary_600",
loader_color="*color_accent",
loader_color_dark="*color_accent",
panel_background_fill="*background_fill_secondary",
panel_background_fill_dark="*background_fill_secondary",
panel_border_color="*border_color_primary",
panel_border_color_dark="*border_color_primary",
panel_border_width="1px",
panel_border_width_dark="1px",
prose_header_text_weight="600",
prose_text_size="*text_md",
prose_text_weight="400",
radio_circle="url(\"data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3ccircle cx='8' cy='8' r='3'/%3e%3c/svg%3e\")",
section_header_text_size="*text_md",
section_header_text_weight="400",
shadow_drop="rgba(0,0,0,0.05) 0px 1px 2px 0px",
shadow_drop_lg="0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)",
shadow_inset="rgba(0,0,0,0.05) 0px 2px 4px 0px inset",
shadow_spread="3px",
shadow_spread_dark="1px",
slider_color="#9E9E9E",
slider_color_dark="#9E9E9E",
stat_background_fill="*primary_500",
stat_background_fill_dark="*primary_500",
table_border_color="*neutral_700",
table_border_color_dark="*neutral_700",
table_even_background_fill="*neutral_950",
table_even_background_fill_dark="*neutral_950",
table_odd_background_fill="*neutral_900",
table_odd_background_fill_dark="*neutral_900",
table_radius="*radius_lg",
table_row_focus="*color_accent_soft",
table_row_focus_dark="*color_accent_soft",
)
+196
View File
@@ -0,0 +1,196 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>OpenAI API/AllTalk TTS API Test</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #1e1e1e;
color: #c7c7c7;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
}
h1 {
color: #ffffff;
text-align: center;
margin-bottom: 20px;
}
.container {
background-color: #2b2b2b;
padding: 20px;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
max-width: 800px;
width: 100%;
}
label {
font-weight: bold;
display: block;
margin: 10px 0 5px;
color: #ffffff;
}
input[type="text"], input[type="number"], textarea, select {
width: calc(100% - 20px);
padding: 10px;
margin-bottom: 20px;
border: 1px solid #555;
border-radius: 4px;
background-color: #3b3b3b;
color: #ffffff;
}
input[type="submit"] {
background-color: #4CAF50;
color: white;
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
}
input[type="submit"]:hover {
background-color: #45a049;
}
.config, .response {
background-color: #3b3b3b;
padding: 20px;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
margin-bottom: 20px;
}
.form-group {
display: flex;
justify-content: space-between;
}
.form-group > div {
flex: 1;
margin-right: 10px;
}
.form-group > div:last-child {
margin-right: 0;
}
</style>
</head>
<body>
<div class="container">
<h1>OpenAI API/AllTalk TTS API Test</h1>
<div class="config form-group">
<div>
<label for="ip">IP Address:</label>
<input type="text" id="ip" name="ip" value="localhost" required>
</div>
<div>
<label for="port">Port Number:</label>
<input type="number" id="port" name="port" value="7851" required>
</div>
</div>
<form id="ttsForm">
<label for="model">Model:</label>
<input type="text" id="model" name="model" value="some-model" required><br>
<label for="input">Input Text:</label>
<textarea id="input" name="input" rows="8" required>Hello, this is a test.</textarea><br>
<p id="charCount">Character count: 21</p>
<div class="form-group">
<div>
<label for="voice">Voice:</label>
<select id="voice" name="voice" required>
<option value="alloy">Alloy</option>
<option value="echo">Echo</option>
<option value="fable">Fable</option>
<option value="nova">Nova</option>
<option value="onyx">Onyx</option>
<option value="shimmer">Shimmer</option>
</select>
</div>
<div>
<label for="response_format">Response Format:</label>
<select id="response_format" name="response_format" required>
<option value="wav">WAV</option>
<option value="mp3">MP3</option>
<option value="ogg">OGG</option>
<option value="flac">FLAC</option>
<option value="aac">AAC</option>
<option value="m4a">M4A</option>
</select>
</div>
<div>
<label for="speed">Speed:</label>
<input type="number" id="speed" name="speed" value="1.0" step="0.1" required><br>
</div>
</div>
<label for="autoplay">Auto-play:</label>
<input type="checkbox" id="autoplay" name="autoplay"><br><br>
<input type="submit" value="Submit"><br><br>
</form>
<div id="response" class="response"></div>
</div>
<script>
// Real-time character count
const inputField = document.getElementById('input');
const charCountDisplay = document.getElementById('charCount');
inputField.addEventListener('input', () => {
const trimmedInput = inputField.value.trim();
charCountDisplay.textContent = `Character count: ${trimmedInput.length}`;
});
document.getElementById('ttsForm').addEventListener('submit', async function (event) {
event.preventDefault();
const formData = new FormData(event.target);
const jsonData = {};
// Sanitize input: trim spaces
formData.forEach((value, key) => {
if (key === 'input') {
value = value.trim().replace(/\s+/g, ' '); // Trim and normalize spaces
}
jsonData[key] = key === 'speed' ? parseFloat(value) : value;
});
const ip = document.getElementById('ip').value;
const port = document.getElementById('port').value;
const url = `http://${ip}:${port}/v1/audio/speech`;
const responseDiv = document.getElementById('response');
responseDiv.innerHTML = 'Sending request...';
try {
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(jsonData),
});
if (response.ok) {
const blob = await response.blob();
const url = URL.createObjectURL(blob);
const audio = new Audio(url);
audio.controls = true;
if (document.getElementById('autoplay').checked) {
audio.autoplay = true;
}
responseDiv.innerHTML = '';
responseDiv.appendChild(audio);
} else {
const errorText = await response.text();
responseDiv.innerHTML = 'Error: ' + errorText;
}
} catch (error) {
responseDiv.innerHTML = 'Error: ' + error.message;
}
});
</script>
</body>
</html>
+51
View File
@@ -0,0 +1,51 @@
from pathlib import Path
import argparse
from OpenSSL import crypto
import sys
def generate_certificate(cert_name: str, output_dir: Path, cn: str = "localhost", days: int = 365):
k = crypto.PKey()
k.generate_key(crypto.TYPE_RSA, 2048)
cert = crypto.X509()
cert.get_subject().CN = cn
cert.set_serial_number(1000)
cert.gmtime_adj_notBefore(0)
cert.gmtime_adj_notAfter(days*24*60*60)
cert.set_issuer(cert.get_subject())
cert.set_pubkey(k)
cert.sign(k, 'sha256')
output_dir.mkdir(parents=True, exist_ok=True)
with open(output_dir / f"{cert_name}_cert.pem", "wb") as f:
f.write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert))
with open(output_dir / f"{cert_name}_key.pem", "wb") as f:
f.write(crypto.dump_privatekey(crypto.FILETYPE_PEM, k))
def main():
print("Certificate Generator")
print("-" * 20)
# Get default paths
default_path = Path(__file__).parent / "certificates"
# Get user input with defaults
cert_name = input(f"Certificate name (default: test_cert): ") or "test_cert"
cn = input(f"Common Name (default: localhost): ") or "localhost"
days = input(f"Valid days (default: 365): ") or "365"
output_dir = input(f"Output directory (default: {default_path}): ") or str(default_path)
try:
days = int(days)
output_path = Path(output_dir)
generate_certificate(cert_name, output_path, cn, days)
print(f"\nSuccess! Certificate files created:")
print(f"- {output_path / f'{cert_name}_cert.pem'}")
print(f"- {output_path / f'{cert_name}_key.pem'}")
except Exception as e:
print(f"\nError: {str(e)}")
sys.exit(1)
if __name__ == "__main__":
main()
+120
View File
@@ -0,0 +1,120 @@
import logging
import os
from pathlib import Path
from typing import Dict, Any, Optional
from datetime import datetime
import ssl
import OpenSSL
from dataclasses import dataclass
@dataclass
class CertificateInfo:
subject: str
issuer: str
valid_from: datetime
valid_until: datetime
serial_number: str
is_valid: bool
class CertificateManager:
def __init__(self, proxy_manager):
self.proxy_manager = proxy_manager
self.logger = logging.getLogger("ProxyCertManager")
self.certs_path = proxy_manager.certs_path
def validate_certificate(self, cert_path: Path) -> Optional[CertificateInfo]:
"""Validate and get information about a certificate"""
try:
with open(cert_path, 'rb') as cert_file:
cert_data = cert_file.read()
x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, cert_data)
valid_from = datetime.strptime(x509.get_notBefore().decode(), '%Y%m%d%H%M%SZ')
valid_until = datetime.strptime(x509.get_notAfter().decode(), '%Y%m%d%H%M%SZ')
now = datetime.now()
return CertificateInfo(
subject=x509.get_subject().CN,
issuer=x509.get_issuer().CN,
valid_from=valid_from,
valid_until=valid_until,
serial_number=str(x509.get_serial_number()),
is_valid=valid_from <= now <= valid_until
)
except Exception as e:
self.logger.error(f"Certificate validation error: {e}")
return None
def install_certificate(self, cert_path: Path, key_path: Path, name: str) -> bool:
try:
import shutil
# Validate certificate first
cert_info = self.validate_certificate(cert_path)
if not cert_info or not cert_info.is_valid:
self.logger.error("Invalid or corrupt certificate")
return False
cert_dest = self.certs_path / f"{name}_cert.pem"
key_dest = self.certs_path / f"{name}_key.pem"
shutil.copy2(cert_path, cert_dest)
shutil.copy2(key_path, key_dest)
# Update config
config = self.proxy_manager.config_manager.get_instance()
config.proxy_settings.gradio_endpoint.cert_name = name
config.proxy_settings.api_endpoint.cert_name = name
config.save()
self.logger.info(f"Certificate '{name}' installed successfully")
return True
except Exception as e:
self.logger.error(f"Certificate installation error: {e}")
return False
def remove_certificate(self, name: str) -> bool:
"""Remove a certificate"""
try:
cert_path = self.certs_path / f"{name}_cert.pem"
key_path = self.certs_path / f"{name}_key.pem"
if cert_path.exists():
cert_path.unlink()
if key_path.exists():
key_path.unlink()
self.logger.info(f"Certificate '{name}' removed successfully")
return True
except Exception as e:
self.logger.error(f"Certificate removal error: {e}")
return False
def get_certificates_status(self) -> Dict[str, Any]:
"""Get status of all installed certificates"""
certificates = {}
for cert_file in self.certs_path.glob("*_cert.pem"):
name = cert_file.name.replace("_cert.pem", "")
cert_info = self.validate_certificate(cert_file)
if cert_info:
certificates[name] = {
"subject": cert_info.subject,
"issuer": cert_info.issuer,
"valid_from": cert_info.valid_from.strftime('%Y-%m-%d %H:%M:%S'),
"valid_until": cert_info.valid_until.strftime('%Y-%m-%d %H:%M:%S'),
"is_valid": cert_info.is_valid,
"days_until_expiry": (cert_info.valid_until - datetime.now()).days
}
return certificates
def check_expiring_certificates(self, days_warning: int = 30) -> Dict[str, int]:
"""Check for certificates nearing expiration"""
expiring = {}
for cert_file in self.certs_path.glob("*_cert.pem"):
name = cert_file.name.replace("_cert.pem", "")
cert_info = self.validate_certificate(cert_file)
if cert_info:
days_left = (cert_info.valid_until - datetime.now()).days
if days_left < days_warning:
expiring[name] = days_left
return expiring
+127
View File
@@ -0,0 +1,127 @@
import logging
import threading
import time
from typing import Dict, Any
import requests
from dataclasses import dataclass, field
from datetime import datetime
@dataclass
class HealthMetrics:
last_check: float = 0
uptime_start: float = 0
gradio_endpoint_up: bool = False
api_endpoint_up: bool = False
consecutive_failures: int = 0
total_restarts: int = 0
response_times: Dict[str, float] = field(default_factory=dict)
class HealthMonitor:
def __init__(self, proxy_manager):
self.proxy_manager = proxy_manager
self.logger = logging.getLogger("ProxyHealthMonitor")
self.metrics = HealthMetrics()
self.monitoring = False
self.monitor_thread = None
self.check_interval = 30 # seconds
def start_monitoring(self):
"""Start health monitoring thread"""
if self.monitoring:
return
self.monitoring = True
self.metrics.uptime_start = time.time()
self.monitor_thread = threading.Thread(target=self._monitor_loop, daemon=True) # Make thread daemon
self.monitor_thread.start()
self.logger.info("Health monitoring started")
def stop_monitoring(self):
"""Stop health monitoring thread"""
if not self.monitoring:
return
self.monitoring = False
if self.monitor_thread and self.monitor_thread.is_alive():
try:
# Give the thread a chance to finish naturally
self.monitor_thread.join(timeout=5)
except Exception as e:
self.logger.warning(f"Could not gracefully stop monitoring thread: {e}")
finally:
self.monitor_thread = None
self.logger.info("Health monitoring stopped")
def _monitor_loop(self):
"""Main monitoring loop"""
while self.monitoring:
self._check_health()
time.sleep(self.check_interval)
def _check_health(self):
"""Check health of proxy endpoints"""
config = self.proxy_manager.config_manager.get_instance()
proxy_settings = config.proxy_settings
self.metrics.last_check = time.time()
try:
# Only check endpoints that are enabled and running
if proxy_settings.gradio_endpoint.enabled == "Enabled":
try:
start_time = time.time()
response = requests.get(
f"http://127.0.0.1:{config.gradio_port_number}/", # Use internal port
timeout=5
)
self.metrics.response_times['gradio'] = time.time() - start_time
self.metrics.gradio_endpoint_up = response.status_code == 200
except Exception as e:
self.logger.debug(f"Gradio endpoint check failed: {e}")
self.metrics.gradio_endpoint_up = False
if proxy_settings.api_endpoint.enabled == "Enabled":
try:
start_time = time.time()
response = requests.get(
f"http://127.0.0.1:{config.api_def.api_port_number}/", # Use internal port
timeout=5
)
self.metrics.response_times['api'] = time.time() - start_time
self.metrics.api_endpoint_up = response.status_code == 200
except Exception as e:
self.logger.debug(f"API endpoint check failed: {e}")
self.metrics.api_endpoint_up = False
if not self.metrics.gradio_endpoint_up and not self.metrics.api_endpoint_up:
self.metrics.consecutive_failures += 1
else:
self.metrics.consecutive_failures = 0
except Exception as e:
self.logger.error(f"Health check failed: {str(e)}")
self.metrics.consecutive_failures += 1
# Only attempt restart if we have multiple complete failures
if self.metrics.consecutive_failures >= 3:
self.logger.warning("Too many consecutive failures, attempting restart")
try:
if self.proxy_manager.stop_proxy() and self.proxy_manager.start_proxy():
self.metrics.total_restarts += 1
self.metrics.consecutive_failures = 0
except Exception as e:
self.logger.error(f"Failed to restart proxy: {e}")
def get_health_status(self) -> Dict[str, Any]:
"""Get current health metrics"""
uptime = time.time() - self.metrics.uptime_start if self.metrics.uptime_start else 0
return {
"status": "healthy" if not self.metrics.consecutive_failures else "degraded",
"uptime": f"{int(uptime/3600)}h {int((uptime%3600)/60)}m",
"last_check": datetime.fromtimestamp(self.metrics.last_check).strftime('%Y-%m-%d %H:%M:%S')
if self.metrics.last_check else "Never",
"gradio_endpoint": "up" if self.metrics.gradio_endpoint_up else "down",
"api_endpoint": "up" if self.metrics.api_endpoint_up else "down",
"response_times": self.metrics.response_times,
"total_restarts": self.metrics.total_restarts
}
+174
View File
@@ -0,0 +1,174 @@
import gradio as gr
import tempfile
from pathlib import Path
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from .proxy_manager import ProxyManager
def create_proxy_interface(proxy_manager: 'ProxyManager'):
"""Create the proxy management interface"""
config = proxy_manager.config_manager.get_instance()
def validate_ports(gradio_port, api_port):
"""Validate port configurations"""
if gradio_port == api_port and gradio_port != 0 and api_port != 0:
return False, "Gradio and API ports cannot be the same!"
if not (0 <= gradio_port <= 65535) or not (0 <= api_port <= 65535):
return False, "Ports must be between 0 and 65535"
return True, "Valid port configuration"
def handle_save_config(proxy_enabled, gradio_enabled, api_enabled,
gradio_port, api_port, startup, external_ip):
# Validate ports first
valid, message = validate_ports(gradio_port, api_port)
if not valid:
return message
config.proxy_settings.proxy_enabled = proxy_enabled
config.proxy_settings.start_on_startup = startup
# Update Gradio endpoint
config.proxy_settings.gradio_endpoint.enabled = gradio_enabled
config.proxy_settings.gradio_endpoint.external_port = int(gradio_port) if gradio_enabled else 0
config.proxy_settings.gradio_endpoint.external_ip = external_ip
# Update API endpoint
config.proxy_settings.api_endpoint.enabled = api_enabled
config.proxy_settings.api_endpoint.external_port = int(api_port) if api_enabled else 0
config.proxy_settings.api_endpoint.external_ip = external_ip
config.save()
return "Configuration saved successfully"
def update_control_states(proxy_enabled):
"""Update enabled/disabled state of controls based on master switch"""
return {
start_button: gr.update(interactive=proxy_enabled),
stop_button: gr.update(interactive=proxy_enabled),
gradio_enabled: gr.update(interactive=proxy_enabled),
api_enabled: gr.update(interactive=proxy_enabled),
start_on_startup: gr.update(interactive=proxy_enabled)
}
def delete_all_certificates():
"""Delete all certificates and reset config"""
try:
# Delete certificate files
for cert_file in proxy_manager.certs_path.glob("*.pem"):
cert_file.unlink()
# Reset config
config = proxy_manager.config_manager.get_instance()
config.proxy_settings.gradio_endpoint.cert_name = ""
config.proxy_settings.api_endpoint.cert_name = ""
config.save()
return "All certificates deleted and config reset"
except Exception as e:
return f"Error deleting certificates: {str(e)}"
with gr.Tab("Proxy Settings"):
with gr.Column():
with gr.Row():
with gr.Group():
proxy_enabled = gr.Checkbox(
label="Enable Proxy System",
value=config.proxy_settings.proxy_enabled,
info="Master switch/safety lockout for proxy functionality"
)
start_on_startup = gr.Checkbox(
label="Start Proxy Automatically on Startup",
value=config.proxy_settings.start_on_startup,
info="Automatically start proxy when app launches"
)
external_ip = gr.Textbox(
label="External IP",
value=config.proxy_settings.gradio_endpoint.external_ip,
info="Use 0.0.0.0 to bind to all interfaces"
)
with gr.Group():
gr.Markdown("API interface Proxy Management")
api_enabled = gr.Dropdown(
choices=["Enabled", "Disabled"],
value="Enabled" if config.proxy_settings.api_endpoint.enabled == "Enabled" else "Disabled",
label="API (TTS Generation) Proxy",
info="Enable or Disable Proxying the API (TTS Generation)"
)
api_port = gr.Number(
value=config.proxy_settings.api_endpoint.external_port,
label="API Port",
info="External port you want to use for the API (TTS Generation)"
)
with gr.Group():
gr.Markdown("Gradio interface Proxy Management")
gradio_enabled = gr.Dropdown(
choices=["Enabled", "Disabled"],
value="Enabled" if config.proxy_settings.gradio_endpoint.enabled == "Enabled" else "Disabled",
label="Gradio Interface Proxy",
info="Enable or Disable Proxying the Gradio interface"
)
gradio_port = gr.Number(
value=config.proxy_settings.gradio_endpoint.external_port,
label="Gradio Interface Port",
info="External port you want to use for the Gradio interface"
)
# Status and control section
with gr.Row():
with gr.Column(scale=2):
status_output = gr.Textbox(
label="Status",
interactive=False,
lines=4
)
with gr.Column(scale=1):
save_button = gr.Button("Save Configuration", variant="primary")
with gr.Row():
start_button = gr.Button("Start Service")
stop_button = gr.Button("Stop Service")
status_button = gr.Button("Check Status")
# Certificate section
with gr.Row():
gr.Markdown("### Certificate Management")
with gr.Row():
with gr.Column(scale=1):
cert_file = gr.File(label="Certificate (.crt/.pem)")
with gr.Column(scale=1):
key_file = gr.File(label="Key (.key)")
with gr.Column(scale=1):
cert_name = gr.Textbox(label="Certificate Name", placeholder="e.g., gradio_cert")
upload_button = gr.Button("Upload Certificate", variant="primary")
delete_button = gr.Button("Delete Certificates", variant="secondary")
# Connect everything
save_button.click(
fn=handle_save_config,
inputs=[
proxy_enabled,
gradio_enabled,
api_enabled,
gradio_port,
api_port,
start_on_startup,
external_ip
],
outputs=status_output
)
proxy_enabled.change(
fn=update_control_states,
inputs=[proxy_enabled],
outputs=[start_button, stop_button, gradio_enabled, api_enabled, start_on_startup]
)
start_button.click(fn=proxy_manager.start_proxy, outputs=status_output)
stop_button.click(fn=proxy_manager.stop_proxy, outputs=status_output)
status_button.click(fn=proxy_manager.get_status, outputs=status_output)
upload_button.click(
fn=proxy_manager.handle_cert_upload,
inputs=[cert_file, key_file, cert_name],
outputs=status_output
)
delete_button.click(fn=delete_all_certificates, outputs=status_output)
return proxy_enabled, start_on_startup, gradio_port, api_port
+94
View File
@@ -0,0 +1,94 @@
import logging
import threading
import time
from typing import Dict, Any
from collections import defaultdict
from dataclasses import dataclass, field
from datetime import datetime, timedelta
@dataclass
class ProxyMetrics:
start_time: float = field(default_factory=time.time)
total_requests: int = 0
active_connections: int = 0
bytes_transferred: int = 0
request_times: Dict[str, float] = field(default_factory=lambda: defaultdict(float))
requests_per_minute: Dict[str, int] = field(default_factory=lambda: defaultdict(int))
status_codes: Dict[str, int] = field(default_factory=lambda: defaultdict(int))
class MetricsCollector:
def __init__(self, proxy_manager):
self.proxy_manager = proxy_manager
self.logger = logging.getLogger("ProxyMetrics")
self.metrics = ProxyMetrics()
self.collecting = False
self.collector_thread = None
self.collect_interval = 60 # seconds
self._lock = threading.Lock()
def start_collecting(self):
"""Start metrics collection"""
if self.collecting:
return
self.collecting = True
self.metrics = ProxyMetrics() # Reset metrics
self.collector_thread = threading.Thread(target=self._collect_loop)
self.collector_thread.daemon = True
self.collector_thread.start()
self.logger.info("Metrics collection started")
def stop_collecting(self):
"""Stop metrics collection"""
self.collecting = False
if self.collector_thread:
self.collector_thread.join()
self.logger.info("Metrics collection stopped")
def _collect_loop(self):
"""Main collection loop"""
while self.collecting:
self._update_metrics()
time.sleep(self.collect_interval)
def _update_metrics(self):
"""Update periodic metrics"""
with self._lock:
# Reset per-minute counters
self.metrics.requests_per_minute.clear()
def record_request(self, endpoint: str, status_code: int, response_time: float, bytes_sent: int):
"""Record metrics for a single request"""
with self._lock:
self.metrics.total_requests += 1
self.metrics.bytes_transferred += bytes_sent
self.metrics.request_times[endpoint] = response_time
self.metrics.status_codes[str(status_code)] += 1
self.metrics.requests_per_minute[endpoint] += 1
def get_current_metrics(self) -> Dict[str, Any]:
"""Get current metrics"""
with self._lock:
uptime = time.time() - self.metrics.start_time
return {
"uptime": str(timedelta(seconds=int(uptime))),
"total_requests": self.metrics.total_requests,
"active_connections": self.metrics.active_connections,
"bytes_transferred": f"{self.metrics.bytes_transferred / 1024 / 1024:.2f} MB",
"average_response_times": {
endpoint: f"{time:.2f}ms"
for endpoint, time in self.metrics.request_times.items()
},
"requests_per_minute": dict(self.metrics.requests_per_minute),
"status_codes": dict(self.metrics.status_codes)
}
def increment_connections(self):
"""Increment active connection count"""
with self._lock:
self.metrics.active_connections += 1
def decrement_connections(self):
"""Decrement active connection count"""
with self._lock:
self.metrics.active_connections = max(0, self.metrics.active_connections - 1)
+235
View File
@@ -0,0 +1,235 @@
import os
import logging
import subprocess
import threading
from pathlib import Path
from typing import Optional, Dict, Any
from dataclasses import asdict
import psutil
from logging.handlers import RotatingFileHandler
import logging
import os
from .security import SecurityManager
from .health_monitor import HealthMonitor
from .cert_manager import CertificateManager
from .metrics import MetricsCollector
class ProxyManager:
def __init__(self, config_manager, base_path: str = None):
self.config_manager = config_manager
# Set up base paths first
self.base_path = Path(base_path) if base_path else Path(__file__).parent
# Create required directories
self.certs_path = self.base_path / "certificates"
self.logs_path = self.base_path / "logs"
self.config_path = self.base_path / "config"
for path in [self.certs_path, self.logs_path, self.config_path]:
path.mkdir(parents=True, exist_ok=True)
# Setup logging before managers
self.setup_logging()
# Initialize managers after paths are created
self.security = SecurityManager(self)
self.health_monitor = HealthMonitor(self)
self.cert_manager = CertificateManager(self)
self.metrics = MetricsCollector(self)
self.proxy_process = None
self.logger.info("Proxy manager initialized successfully")
def setup_logging(self):
"""Setup logging configuration with customized format"""
config = self.config_manager.get_instance()
log_level = getattr(logging, config.proxy_settings.log_level, logging.INFO)
# Configure rotating file handler
log_file = self.logs_path / "proxy.log"
file_handler = RotatingFileHandler(
log_file,
maxBytes=5*1024*1024,
backupCount=5,
encoding='utf-8'
)
# Configure logging formats
file_format = logging.Formatter(
'%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
console_format = logging.Formatter(
'[AllTalk PRX] %(message)s'
)
file_handler.setFormatter(file_format)
# Setup logger
self.logger = logging.getLogger("ProxyManager")
self.logger.setLevel(log_level)
self.logger.addHandler(file_handler)
# Only add console handler if proxy debugging is enabled
if config.debugging.debug_proxy:
console_handler = logging.StreamHandler()
console_handler.setFormatter(console_format)
self.logger.addHandler(console_handler)
self.logger.info("Proxy debug logging enabled")
def _monitor_output(self, pipe, name):
"""Monitor subprocess output and redirect to logger"""
try:
for line in iter(pipe.readline, ''):
line = line.strip()
if line:
if name == "stderr":
self.logger.error(line)
else:
# Pass through with our logging format
print(line) # Direct print for formatted output
except Exception as e:
self.logger.error(f"Error monitoring {name}: {e}")
finally:
pipe.close()
def start_proxy(self) -> bool:
"""Start the proxy server with current configuration"""
if self.proxy_process and self.proxy_process.poll() is None:
self.logger.warning("Proxy already running")
return False
config = self.config_manager.get_instance()
proxy_settings = config.proxy_settings
try:
cmd = [
"python", "-m", "twisted_server",
"--external_ip_a", proxy_settings.api_endpoint.external_ip if proxy_settings.api_endpoint.enabled == "Enabled" else "0",
"--internal_ip_a", "127.0.0.1",
"--external_ip_b", proxy_settings.gradio_endpoint.external_ip if proxy_settings.gradio_endpoint.enabled == "Enabled" else "0",
"--internal_ip_b", "127.0.0.1",
"--cert_file_a", proxy_settings.api_endpoint.cert_name or "0",
"--cert_file_b", proxy_settings.gradio_endpoint.cert_name or "0"
]
# Start process with pipe for output
self.proxy_process = subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
cwd=str(self.base_path),
text=True,
bufsize=1,
env={**os.environ, 'PYTHONUNBUFFERED': '1'}, # Force unbuffered output
universal_newlines=True
)
# Start output monitoring threads
threading.Thread(target=self._monitor_output,
args=(self.proxy_process.stdout, "stdout"),
daemon=True).start()
threading.Thread(target=self._monitor_output,
args=(self.proxy_process.stderr, "stderr"),
daemon=True).start()
if proxy_settings.proxy_enabled:
self.health_monitor.start_monitoring()
self.metrics.start_collecting()
self.logger.info("Proxy server started successfully")
return True
except Exception as e:
self.logger.error(f"Failed to start proxy: {e}")
return False
def stop_proxy(self) -> bool:
"""Stop the proxy server and all monitoring"""
if not self.proxy_process:
self.logger.warning("No proxy process running")
return False
try:
# Stop all monitoring first
self.health_monitor.stop_monitoring()
self.metrics.stop_collecting()
# Stop the main process
process = psutil.Process(self.proxy_process.pid)
for proc in process.children(recursive=True):
proc.terminate()
process.terminate()
try:
process.wait(timeout=5)
except psutil.TimeoutExpired:
process.kill()
self.proxy_process = None
self.logger.info("Proxy server stopped successfully")
return True
except Exception as e:
self.logger.error(f"Failed to stop proxy: {e}")
return False
def get_status(self) -> Dict[str, Any]:
"""Get comprehensive status of the proxy system"""
config = self.config_manager.get_instance()
proxy_config = config.proxy_settings
status = {
"running": self.proxy_process is not None and self.proxy_process.poll() is None,
"config": {
"gradio_endpoint": asdict(proxy_config.gradio_endpoint),
"api_endpoint": asdict(proxy_config.api_endpoint),
"start_on_startup": proxy_config.start_on_startup
},
"certificates": self.cert_manager.get_certificates_status(),
"health": self.health_monitor.get_health_status(),
"metrics": self.metrics.get_current_metrics(),
"security": self.security.get_security_status()
}
return status
def handle_cert_upload(self, cert_file, key_file, name):
"""Handle certificate upload from the interface"""
if not cert_file or not key_file or not name:
return "Please provide both certificate and key files, and a name"
cert_path = Path(cert_file.name)
key_path = Path(key_file.name)
success = self.cert_manager.install_certificate(cert_path, key_path, name)
return "Certificate uploaded successfully" if success else "Failed to upload certificate"
def handle_start(self):
"""Handle proxy start from the interface"""
success = self.start_proxy()
return "Proxy Server: Starting..." if success else "Failed to start proxy server"
def handle_stop(self):
"""Handle proxy stop from the interface"""
success = self.stop_proxy()
return "Proxy Server: Stopped" if success else "Failed to stop proxy server"
def handle_status(self):
"""Handle status request from the interface"""
status = self.get_status()
if status['running']:
return "Proxy Server: Running\n" + \
f"API Endpoint: {'Active' if status['config']['api_endpoint']['enabled'] == 'Enabled' else 'Disabled'}\n" + \
f"Gradio Endpoint: {'Active' if status['config']['gradio_endpoint']['enabled'] == 'Enabled' else 'Disabled'}\n" + \
f"Certificates: {len(status['certificates'])} configured"
else:
return "Proxy Server: Stopped"
def handle_security_event(self, event_type: str, details: Dict[str, Any]):
"""Handle security events from the SecurityManager"""
self.logger.warning(f"Security event: {event_type} - {details}")
# Implement security response logic here
def cleanup(self):
"""Cleanup resources before shutdown"""
self.stop_proxy()
self.logger.info("Proxy manager cleanup completed")
+61
View File
@@ -0,0 +1,61 @@
import logging
from typing import Dict, Any, Set
import time
from collections import defaultdict
from dataclasses import dataclass
from threading import Lock
@dataclass
class SecurityMetrics:
total_requests: int = 0
blocked_requests: int = 0
last_incident: float = 0
blacklisted_ips: Set[str] = None
def __post_init__(self):
if self.blacklisted_ips is None:
self.blacklisted_ips = set()
class SecurityManager:
def __init__(self, proxy_manager):
self.proxy_manager = proxy_manager
self.logger = logging.getLogger("ProxySecurityManager")
self.metrics = SecurityMetrics()
self.rate_limits = defaultdict(lambda: {"count": 0, "reset_time": 0})
self.rate_limit_lock = Lock()
def check_rate_limit(self, ip: str, limit: int = 100, window: int = 60) -> bool:
"""Check if IP has exceeded rate limit"""
with self.rate_limit_lock:
current_time = time.time()
if self.rate_limits[ip]["reset_time"] < current_time:
self.rate_limits[ip] = {"count": 0, "reset_time": current_time + window}
self.rate_limits[ip]["count"] += 1
return self.rate_limits[ip]["count"] <= limit
def is_blacklisted(self, ip: str) -> bool:
"""Check if IP is blacklisted"""
return ip in self.metrics.blacklisted_ips
def add_to_blacklist(self, ip: str, reason: str):
"""Add IP to blacklist"""
self.metrics.blacklisted_ips.add(ip)
self.logger.warning(f"IP {ip} blacklisted: {reason}")
self.metrics.last_incident = time.time()
def remove_from_blacklist(self, ip: str):
"""Remove IP from blacklist"""
self.metrics.blacklisted_ips.discard(ip)
self.logger.info(f"IP {ip} removed from blacklist")
def get_security_status(self) -> Dict[str, Any]:
"""Get current security metrics"""
return {
"total_requests": self.metrics.total_requests,
"blocked_requests": self.metrics.blocked_requests,
"blacklisted_ips": len(self.metrics.blacklisted_ips),
"last_incident": time.strftime('%Y-%m-%d %H:%M:%S',
time.localtime(self.metrics.last_incident))
if self.metrics.last_incident else "None"
}
+218
View File
@@ -0,0 +1,218 @@
import subprocess
import sys
from pathlib import Path
import logging
# Auto-install requirements if missing
def install_requirements():
"""Install missing requirements only if they're not already in sys.modules"""
required_packages = [
"twisted",
"cryptography",
"service_identity",
"requests",
"psutil"
]
for package in required_packages:
if package not in sys.modules:
try:
__import__(package)
except ImportError:
print(f"Package '{package}' is not installed. Installing now...")
subprocess.check_call([sys.executable, "-m", "pip", "install", package])
install_requirements()
from twisted.internet import reactor, ssl
from twisted.web import proxy, server
import argparse
import inspect
# Handle config import for both package and standalone usage
try:
from ...config import AlltalkConfig # Package import
except ImportError:
# Get the path to the root directory (3 levels up from this file)
root_dir = Path(__file__).parent.parent.parent
sys.path.append(str(root_dir))
from config import AlltalkConfig # Standalone import
def initialize_configs():
"""Initialize all configuration instances"""
config_initalize = AlltalkConfig.get_instance()
return config_initalize
# Load in configs
central_config = initialize_configs()
##########################
# Central print function #
##########################
# ANSI color codes
BLUE = "\033[94m"
# MAGENTA = "\033[95m"
YELLOW = "\033[93m"
RED = "\033[91m"
GREEN = "\033[92m"
RESET = "\033[0m"
def print_message(message, message_type="standard", component="PRX"):
"""Centralized print function for AllTalk messages
Args:
message (str): The message to print
message_type (str): Type of message (standard/warning/error/debug_*/debug)
component (str): Component identifier (TTS/ENG/GEN/API/etc.)
"""
prefix = f"[{central_config.branding}{component}] "
if message_type.startswith("debug_"):
debug_flag = getattr(central_config.debugging, message_type, False)
if not debug_flag:
return
if message_type == "debug_func" and "Function entry:" in message:
message_parts = message.split("Function entry:", 1)
print(
f"{prefix}{BLUE}Debug{RESET} {YELLOW}{message_type}{RESET} Function entry:{GREEN}{message_parts[1]}{RESET} twisted_server.py"
)
else:
print(f"{prefix}{BLUE}Debug{RESET} {YELLOW}{message_type}{RESET} {message}")
elif message_type == "debug":
print(f"{prefix}{BLUE}Debug{RESET} {message}")
elif message_type == "warning":
print(f"{prefix}{YELLOW}Warning{RESET} {message}")
elif message_type == "error":
print(f"{prefix}{RED}Error{RESET} {message}")
else:
print(f"{prefix}{message}")
def debug_func_entry():
"""Print debug message for function entry if debug_func is enabled"""
if central_config.debugging.debug_func:
current_func = inspect.currentframe().f_back.f_code.co_name
print_message(f"Function entry: {current_func}", "debug_func")
class ProxyToInternalPort(proxy.ReverseProxyResource):
def __init__(self, target_host, target_port):
super().__init__(target_host, target_port, b"")
self.logger = logging.getLogger("ProxyManager")
def proxyClientConnectionFailed(self, connector, reason):
print_message(f"Connection failed: {reason}", message_type="debug_proxy")
return proxy.ReverseProxyResource.proxyClientConnectionFailed(self, connector, reason)
def proxyClientConnectionMade(self, connector):
print_message(f"Connection established to {self.host}:{self.port}", message_type="debug_proxy")
return proxy.ReverseProxyResource.proxyClientConnectionMade(self, connector)
def getChild(self, path, request):
try:
decoded_path = path.decode('utf-8', 'ignore')
client_addr = request.getClientAddress()
ip = client_addr.host if hasattr(client_addr, 'host') else 'unknown'
method = request.method.decode('utf-8', 'ignore')
print_message(f"{GREEN}Request: {RED}{method} {decoded_path}{GREEN} from {RESET}{ip} {GREEN}Forwarding to:{RESET} {self.host}:{self.port} {RED}{decoded_path}{RESET}", message_type="debug_proxy")
#print_message(f"Forwarding to: {self.host}:{self.port}{decoded_path}", message_type="debug_proxy")
except Exception as e:
print_message(f"Error in getChild: {str(e)}", message_type="error")
child = proxy.ReverseProxyResource(self.host, self.port, self.path + b'/' + path)
return child
def check_certificates(cert_file_base):
"""Check if both key and cert files exist for the given certificate base name."""
debug_func_entry()
if cert_file_base != "0":
cert_path = Path("certificates") # Add base path
key_file = cert_path / f"{cert_file_base}_key.pem"
cert_file = cert_path / f"{cert_file_base}_cert.pem"
if not key_file.exists() or not cert_file.exists():
return False
return True
return False
def run_proxy(external_ip_a, internal_ip_a, external_ip_b, internal_ip_b, cert_file_a, cert_file_b):
debug_func_entry()
proxies_started = False
api_port = central_config.api_def.api_port_number
gradio_port = central_config.gradio_port_number
api_port_external = central_config.proxy_settings.api_endpoint.external_port
gradio_port_external = central_config.proxy_settings.gradio_endpoint.external_port
print_message("Starting proxy setup with the following parameters:", message_type="debug_proxy")
print_message(f" |- External IP API : {'[DISABLED]' if external_ip_a == '0' else f'{external_ip_a}:{api_port_external}'} -> {internal_ip_a}:{api_port}", message_type="debug_proxy")
print_message(f" |- External IP Gradio : {'[DISABLED]' if external_ip_b == '0' else f'{external_ip_b}:{gradio_port_external}'} -> {internal_ip_b}:{gradio_port}", message_type="debug_proxy")
print_message(f" |- Certificate File A : {cert_file_a} {'[No Certificate So Disabled]' if cert_file_a == '0' else ''}", message_type="debug_proxy")
print_message(f" |- Certificate File B : {cert_file_b} {'[No Certificate So Disabled]' if cert_file_b == '0' else ''}", message_type="debug_proxy")
# Gradio Proxy
if external_ip_b != "0" and central_config.proxy_settings.gradio_endpoint.enabled == "Enabled":
if cert_file_b != "0" and check_certificates(cert_file_b):
sslContextB = ssl.DefaultOpenSSLContextFactory(
f"certificates/{cert_file_b}_key.pem",
f"certificates/{cert_file_b}_cert.pem"
)
proxy_gradio = ProxyToInternalPort(internal_ip_b, gradio_port)
proxy_site_gradio = server.Site(proxy_gradio)
reactor.listenSSL(gradio_port_external, proxy_site_gradio, sslContextB, interface=external_ip_b)
print_message(f"Gradio SSL Proxy : {GREEN}From{RESET} {external_ip_b}:{gradio_port_external} {GREEN}->{RESET} {internal_ip_b}:{gradio_port} {GREEN}is now active.{RESET}")
else:
proxy_gradio = ProxyToInternalPort(internal_ip_b, gradio_port)
proxy_site_gradio = server.Site(proxy_gradio)
reactor.listenTCP(gradio_port_external, proxy_site_gradio, interface=external_ip_b)
print_message(f"Gradio HTTP Proxy : {GREEN}From{RESET} {external_ip_b}:{gradio_port_external} {GREEN}->{RESET} {internal_ip_b}:{gradio_port} {GREEN}is now active.{RESET}")
proxies_started = True
else:
print_message(f"Gradio Proxy is {RED}DISABLED{RESET}")
# API Proxy
if external_ip_a != "0" and central_config.proxy_settings.api_endpoint.enabled == "Enabled":
if cert_file_a != "0" and check_certificates(cert_file_a):
sslContextA = ssl.DefaultOpenSSLContextFactory(
f"certificates/{cert_file_a}_key.pem",
f"certificates/{cert_file_a}_cert.pem"
)
proxy_api = ProxyToInternalPort(internal_ip_a, api_port)
proxy_site_api = server.Site(proxy_api)
reactor.listenSSL(api_port_external, proxy_site_api, sslContextA, interface=external_ip_a)
print_message(f"API SSL Proxy : {GREEN}From{RESET} {external_ip_a}:{api_port_external} {GREEN}->{RESET} {internal_ip_a}:{api_port} {GREEN}is now active.{RESET}")
else:
proxy_api = ProxyToInternalPort(internal_ip_a, api_port)
proxy_site_api = server.Site(proxy_api)
reactor.listenTCP(api_port_external, proxy_site_api, interface=external_ip_a)
print_message(f"API HTTP Proxy : {GREEN}From{RESET} {external_ip_a}:{api_port_external} {GREEN}->{RESET} {internal_ip_a}:{api_port} {GREEN}is now active.{RESET}")
proxies_started = True
else:
print_message(f"API Proxy is {RED}DISABLED{RESET}")
if not proxies_started:
print_message(f"No proxies were started. {RED}Both{RESET} API and Gradio proxies are {RED}DISABLED{RESET}.", message_type="warning")
return
reactor.run()
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--external_ip_a", required=True, help="External IP Address A ('0' to disable)")
parser.add_argument("--internal_ip_a", required=True, help="Internal IP Address A")
parser.add_argument("--external_ip_b", required=True, help="External IP Address B ('0' to disable)")
parser.add_argument("--internal_ip_b", required=True, help="Internal IP Address B")
parser.add_argument("--cert_file_a", required=True, help="Certificate file base name for External IP A (without '_key' or '_cert', or '0' for HTTP only)")
parser.add_argument("--cert_file_b", required=True, help="Certificate file base name for External IP B (without '_key' or '_cert', or '0' for HTTP only)")
args = parser.parse_args()
run_proxy(
external_ip_a=args.external_ip_a,
internal_ip_a=args.internal_ip_a,
external_ip_b=args.external_ip_b,
internal_ip_b=args.internal_ip_b,
cert_file_a=args.cert_file_a,
cert_file_b=args.cert_file_b
)
@@ -0,0 +1,49 @@
coqui-tts==0.24.3
openai-whisper
ffmpeg-python>=0.2.0
filelock>=3.16.1
fuzzywuzzy
gradio==4.44.1
importlib_metadata>=7.1.0
inputimeout>=1.0.4
Jinja2>=3.1.0
librosa>=0.10.2.post1
local_attention==1.9.10
onnxruntime-gpu>=1.18.0
pydantic>=2.7.0
python-Levenshtein>=0.25.1
praat-parselmouth>=0.4.0
pyworld>=0.3.0
sounddevice>=0.4.7
soundfile>=0.12.0
spacy>=3.7.1
torchcrepe>=0.0.2
tqdm>=4.66.0
unidic-lite>=1.0.8
uvicorn>=0.29.0
pillow==10.3.0
fastapi==0.112.2
starlette
pypinyin
pyee
aiofiles
h11
gradio
gradio_client
httpx
httpcore
websockets
pydub
semantic_version
ffmpy
tomlkit
python-multipart
hangul_romanize
word2number
cutlet==0.4.0
fugashi==1.3.1
piper-tts; sys_platform == "linux"
plotly==5.24.1
scipy==1.14.1
pyOpenSSL>=24.2.1
langdetect>=1.0.9
-173
View File
@@ -1,173 +0,0 @@
absl-py==2.1.0
aiofiles==23.2.1
aiohttp==3.9.3
aiosignal==1.3.1
altair==5.2.0
annotated-types==0.6.0
anyascii==0.3.2
anyio==4.3.0
attrs==23.2.0
audioread==3.0.1
av==11.0.0
Babel==2.14.0
bangla==0.0.2
blinker==1.7.0
blis==0.7.11
bnnumerizer==0.0.2
bnunicodenormalizer==0.1.6
catalogue==2.0.10
certifi==2024.2.2
cffi==1.16.0
charset-normalizer==3.3.2
click==8.1.7
cloudpathlib==0.16.0
colorama==0.4.6
coloredlogs==15.0.1
confection==0.1.4
contourpy==1.2.0
coqpit==0.0.17
ctranslate2==4.1.0
cutlet==0.4.0
cycler==0.12.1
cymem==2.0.8
Cython==3.0.9
dateparser==1.1.8
decorator==5.1.1
docopt==0.6.2
einops==0.7.0
encodec==0.1.1
exceptiongroup
fastapi==0.110.0
faster-whisper==1.0.1
ffmpy==0.3.2
filelock==3.13.3
Flask==3.0.2
flatbuffers==24.3.25
fonttools==4.50.0
frozenlist==1.4.1
fsspec==2024.3.1
fugashi==1.3.1
fuzzywuzzy>=0.18.0
g2pkk==0.1.2
gradio==3.50.2
gradio_client==0.6.1
grpcio==1.62.1
gruut==2.2.3
gruut-ipa==0.13.0
gruut-lang-de==2.0.0
gruut-lang-en==2.0.0
gruut-lang-es==2.0.0
gruut-lang-fr==2.0.2
h11==0.14.0
hangul-romanize==0.1.0
httpcore==1.0.4
httpx==0.27.0
huggingface-hub==0.22.1
humanfriendly==10.0
idna==3.6
importlib_metadata==7.1.0
importlib_resources==6.4.0
inflect==7.0.0
itsdangerous==2.1.2
jaconv==0.3.4
jamo==0.4.1
jieba==0.42.1
Jinja2==3.1.3
joblib==1.3.2
jsonlines==1.2.0
jsonschema==4.21.1
jsonschema-specifications==2023.12.1
kiwisolver==1.4.5
langcodes==3.3.0
lazy_loader==0.3
librosa==0.10.1
llvmlite==0.42.0
Markdown==3.6
MarkupSafe==2.1.5
matplotlib==3.8.3
mojimoji==0.0.13
mpmath==1.3.0
msgpack==1.0.8
multidict==6.0.5
murmurhash==1.0.10
networkx==2.8.8
nltk==3.8.1
num2words==0.5.13
numba==0.59.1
numpy==1.26.4
nvidia-cublas-cu11>=11.11.3.6
nvidia-cudnn-cu11>=9.0.0.312
onnxruntime==1.17.1
orjson==3.9.15
packaging==24.0
pandas==1.5.3
pillow==10.2.0
platformdirs==4.2.0
pooch==1.8.1
preshed==3.0.9
protobuf==5.26.0
psutil==5.9.8
pycparser==2.21
pydantic==2.6.4
pydantic_core==2.16.3
pydub==0.25.1
pynndescent==0.5.11
pyparsing==3.1.2
pypinyin==0.51.0
pyreadline3==3.4.1
pysbd==0.3.4
python-crfsuite==0.9.10
python-dateutil==2.9.0.post0
python-Levenshtein>=0.25.0
python-multipart==0.0.9
pytz==2024.1
PyYAML==6.0.1
referencing==0.34.0
regex==2023.12.25
requests==2.31.0
rpds-py==0.18.0
safetensors==0.4.2
scikit-learn==1.4.1.post1
scipy==1.12.0
semantic-version==2.10.0
six==1.16.0
smart-open==6.4.0
sniffio==1.3.1
sounddevice==0.4.6
soundfile==0.12.1
soxr==0.3.7
spacy==3.7.4
spacy-legacy==3.0.12
spacy-loggers==1.0.5
srsly==2.4.8
starlette==0.36.3
SudachiDict-core==20240109
SudachiPy==0.6.8
sympy==1.12
tensorboard==2.16.2
tensorboard-data-server==0.7.2
thinc==8.2.3
threadpoolctl==3.4.0
tokenizers==0.15.2
toolz==0.12.1
torch>=2.2.0
torchaudio>=2.2.0
tqdm==4.66.2
trainer==0.0.36
transformers==4.39.1
TTS==0.22.0
typer==0.9.4
typing_extensions==4.10.0
tzdata==2024.1
tzlocal==5.2
umap-learn==0.5.5
Unidecode==1.3.8
unidic-lite==1.0.8
urllib3==2.2.1
uvicorn==0.29.0
wasabi==1.1.2
weasel==0.3.4
websockets==11.0.3
Werkzeug==3.0.1
yarl==1.9.4
zipp==3.18.1
@@ -0,0 +1 @@
git+https://github.com/SWivid/F5-TTS.git
@@ -1,171 +0,0 @@
absl-py==2.1.0
aiofiles==23.2.1
aiohttp==3.9.3
aiosignal==1.3.1
altair==5.2.0
annotated-types==0.6.0
anyascii==0.3.2
anyio==4.3.0
attrs==23.2.0
audioread==3.0.1
av==11.0.0
Babel==2.14.0
bangla==0.0.2
blinker==1.7.0
blis==0.7.11
bnnumerizer==0.0.2
bnunicodenormalizer==0.1.6
catalogue==2.0.10
certifi==2024.2.2
cffi==1.16.0
charset-normalizer==3.3.2
click==8.1.7
cloudpathlib==0.16.0
colorama==0.4.6
coloredlogs==15.0.1
confection==0.1.4
contourpy==1.2.0
coqpit==0.0.17
ctranslate2==4.1.0
cutlet==0.4.0
cycler==0.12.1
cymem==2.0.8
Cython==3.0.9
dateparser==1.1.8
decorator==5.1.1
docopt==0.6.2
einops==0.7.0
encodec==0.1.1
fastapi==0.110.0
faster-whisper==1.0.1
ffmpy==0.3.2
filelock==3.13.3
Flask==3.0.2
flatbuffers==24.3.25
fonttools==4.50.0
frozenlist==1.4.1
fsspec==2024.3.1
fugashi==1.3.1
fuzzywuzzy>=0.18.0
g2pkk==0.1.2
gradio==3.50.2
gradio_client==0.6.1
grpcio==1.62.1
gruut==2.2.3
gruut-ipa==0.13.0
gruut-lang-de==2.0.0
gruut-lang-en==2.0.0
gruut-lang-es==2.0.0
gruut-lang-fr==2.0.2
h11==0.14.0
hangul-romanize==0.1.0
httpcore==1.0.4
httpx==0.27.0
huggingface-hub==0.22.1
humanfriendly==10.0
idna==3.6
importlib_metadata==7.1.0
importlib_resources==6.4.0
inflect==7.0.0
itsdangerous==2.1.2
jaconv==0.3.4
jamo==0.4.1
jieba==0.42.1
Jinja2==3.1.3
joblib==1.3.2
jsonlines==1.2.0
jsonschema==4.21.1
jsonschema-specifications==2023.12.1
kiwisolver==1.4.5
langcodes==3.3.0
lazy_loader==0.3
librosa==0.10.1
llvmlite==0.42.0
Markdown==3.6
MarkupSafe==2.1.5
matplotlib==3.8.3
mojimoji==0.0.13
mpmath==1.3.0
msgpack==1.0.8
multidict==6.0.5
murmurhash==1.0.10
networkx==2.8.8
nltk==3.8.1
num2words==0.5.13
numba==0.59.1
numpy>=1.17.0,<1.29.0
nvidia-cublas-cu11>=11.11.3.6
nvidia-cudnn-cu11>=9.0.0.312
onnxruntime==1.17.1
orjson==3.9.15
packaging==24.0
pandas==1.5.3
pillow==10.2.0
platformdirs==4.2.0
pooch==1.8.1
preshed==3.0.9
protobuf==5.26.0
psutil==5.9.8
pycparser==2.21
pydantic==2.6.4
pydantic_core==2.16.3
pydub==0.25.1
pynndescent==0.5.11
pyparsing==3.1.2
pypinyin==0.51.0
pyreadline3==3.4.1
pysbd==0.3.4
python-crfsuite==0.9.10
python-dateutil==2.9.0.post0
python-Levenshtein>=0.25.0
python-multipart==0.0.9
pytz==2024.1
PyYAML==6.0.1
referencing==0.34.0
regex==2023.12.25
requests==2.31.0
rpds-py==0.18.0
safetensors==0.4.2
scikit-learn==1.4.1.post1
scipy==1.12.0
semantic-version==2.10.0
six==1.16.0
smart-open==6.4.0
sniffio==1.3.1
sounddevice==0.4.6
soundfile==0.12.1
soxr==0.3.7
spacy==3.7.4
spacy-legacy==3.0.12
spacy-loggers==1.0.5
srsly==2.4.8
starlette==0.36.3
SudachiDict-core==20240109
SudachiPy==0.6.8
sympy==1.12
tensorboard==2.16.2
tensorboard-data-server==0.7.2
thinc==8.2.3
threadpoolctl==3.4.0
tokenizers==0.15.2
toolz==0.12.1
torch>=2.2.0
torchaudio>=2.2.0
tqdm==4.66.2
trainer==0.0.36
transformers==4.39.1
typer==0.9.4
typing_extensions==4.10.0
tzdata==2024.1
tzlocal==5.2
umap-learn==0.5.5
Unidecode==1.3.8
unidic-lite==1.0.8
urllib3==2.2.1
uvicorn==0.29.0
wasabi==1.1.2
weasel==0.3.4
websockets==11.0.3
Werkzeug==3.0.1
yarl==1.9.4
zipp==3.18.1
@@ -0,0 +1 @@
git+https://github.com/huggingface/parler-tts.git
+38 -171
View File
@@ -1,172 +1,39 @@
absl-py==2.1.0 coqui-tts==0.24.3
aiofiles==23.2.1 filelock>=3.13.4
aiohttp==3.9.3
aiosignal==1.3.1
altair==5.2.0
annotated-types==0.6.0
anyascii==0.3.2
anyio==4.3.0
attrs==23.2.0
audioread==3.0.1
av==11.0.0
Babel==2.14.0
bangla==0.0.2
blinker==1.7.0
blis==0.7.11
bnnumerizer==0.0.2
bnunicodenormalizer==0.1.6
catalogue==2.0.10
certifi==2024.2.2
cffi==1.16.0
charset-normalizer==3.3.2
click==8.1.7
cloudpathlib==0.16.0
colorama==0.4.6
coloredlogs==15.0.1
confection==0.1.4
contourpy==1.2.0
coqpit==0.0.17
ctranslate2==4.1.0
cutlet==0.4.0
cycler==0.12.1
cymem==2.0.8
Cython==3.0.9
dateparser==1.1.8
decorator==5.1.1
docopt==0.6.2
einops==0.7.0
encodec==0.1.1
fastapi==0.110.0
faster-whisper==1.0.1
ffmpy==0.3.2
filelock==3.13.3
Flask==3.0.2
flatbuffers==24.3.25
fonttools==4.50.0
frozenlist==1.4.1
fsspec==2024.3.1
fugashi==1.3.1
fuzzywuzzy>=0.18.0 fuzzywuzzy>=0.18.0
g2pkk==0.1.2 ffmpeg-python>=0.2.0
gradio==3.50.2 gradio==4.44.1
gradio_client==0.6.1 importlib_metadata>=7.2.1
grpcio==1.62.1 inputimeout>=1.0.4
gruut==2.2.3 Jinja2>=3.1.4
gruut-ipa==0.13.0 librosa>=0.10.2.post1
gruut-lang-de==2.0.0 local_attention==1.9.10
gruut-lang-en==2.0.0 openai-whisper
gruut-lang-es==2.0.0 onnxruntime-gpu>=1.18.1
gruut-lang-fr==2.0.2 pydantic>=2.8.2
h11==0.14.0 python-Levenshtein>=0.25.1
hangul-romanize==0.1.0 praat-parselmouth>=0.4.4
httpcore==1.0.4 pyworld>=0.3.4
httpx==0.27.0 sounddevice>=0.4.7
huggingface-hub==0.22.1 soundfile>=0.12.1
humanfriendly==10.0 spacy>=3.7.1
idna==3.6 torchcrepe>=0.0.2
importlib_metadata==7.1.0 tqdm>=4.66.5
importlib_resources==6.4.0 unidic-lite>=1.0.8
inflect==7.0.0 uvicorn>=0.29.0
itsdangerous==2.1.2 pillow==10.3.0
jaconv==0.3.4 pypinyin>=0.52.0
jamo==0.4.1 hangul_romanize>=0.1.0
jieba==0.42.1 word2number>=1.1
Jinja2==3.1.3 cutlet==0.4.0
joblib==1.3.2 fugashi==1.3.1
jsonlines==1.2.0 ./system/config/fairseq-0.12.4-cp311-cp311-win_amd64.whl; sys_platform == "win32"
jsonschema==4.21.1 ./system/config/fairseq-0.12.3.1-cp311-cp311-linux_x86_64.whl; sys_platform == "linux"
jsonschema-specifications==2023.12.1 piper-tts; sys_platform == "linux"
kiwisolver==1.4.5 piper-tts; sys_platform == "darwin"
langcodes==3.3.0 piper-phonemize==1.1.0; sys_platform == "darwin"
lazy_loader==0.3 fastapi==0.112.2
librosa==0.10.1 plotly==5.24.1
llvmlite==0.42.0 scipy==1.14.1
Markdown==3.6 pyOpenSSL>=24.2.1
MarkupSafe==2.1.5 langdetect>=1.0.9
matplotlib==3.8.3
mojimoji==0.0.13
mpmath==1.3.0
msgpack==1.0.8
multidict==6.0.5
murmurhash==1.0.10
networkx==2.8.8
nltk==3.8.1
num2words==0.5.13
numba==0.59.1
numpy==1.26.4
nvidia-cublas-cu11>=11.11.3.6
nvidia-cudnn-cu11>=9.0.0.312
onnxruntime==1.17.1
orjson==3.9.15
packaging==24.0
pandas==1.5.3
pillow==10.2.0
platformdirs==4.2.0
pooch==1.8.1
preshed==3.0.9
protobuf==5.26.0
psutil==5.9.8
pycparser==2.21
pydantic==2.6.4
pydantic_core==2.16.3
pydub==0.25.1
pynndescent==0.5.11
pyparsing==3.1.2
pypinyin==0.51.0
pyreadline3==3.4.1
pysbd==0.3.4
python-crfsuite==0.9.10
python-dateutil==2.9.0.post0
python-Levenshtein>=0.25.0
python-multipart==0.0.9
pytz==2024.1
PyYAML==6.0.1
referencing==0.34.0
regex==2023.12.25
requests==2.31.0
rpds-py==0.18.0
safetensors==0.4.2
scikit-learn==1.4.1.post1
scipy==1.12.0
semantic-version==2.10.0
six==1.16.0
smart-open==6.4.0
sniffio==1.3.1
sounddevice==0.4.6
soundfile==0.12.1
soxr==0.3.7
spacy==3.7.4
spacy-legacy==3.0.12
spacy-loggers==1.0.5
srsly==2.4.8
starlette==0.36.3
SudachiDict-core==20240109
SudachiPy==0.6.8
sympy==1.12
tensorboard==2.16.2
tensorboard-data-server==0.7.2
thinc==8.2.3
threadpoolctl==3.4.0
tokenizers==0.15.2
toolz==0.12.1
torch>=2.2.0
torchaudio>=2.2.0
tqdm==4.66.2
trainer==0.0.36
transformers==4.39.1
TTS==0.22.0
typer==0.9.4
typing_extensions==4.10.0
tzdata==2024.1
tzlocal==5.2
umap-learn==0.5.5
Unidecode==1.3.8
unidic-lite==1.0.8
urllib3==2.2.1
uvicorn==0.29.0
wasabi==1.1.2
weasel==0.3.4
websockets==11.0.3
Werkzeug==3.0.1
yarl==1.9.4
zipp==3.18.1
+35 -24
View File
@@ -1,25 +1,36 @@
numpy>=1.22.0 coqui-tts==0.24.3
soundfile>=0.12.1 ffmpeg-python>=0.2.0
uvicorn>=0.24.0.post1 filelock>=3.16.1
transformers>=4.37.1
TTS>=0.22.0
torch>=2.1.0
torchaudio>=2.1.0
fastapi>=0.104.1
Jinja2>=3.1.2
requests>=2.31.0
tqdm>=4.66.1
importlib-metadata>=4.8.1
packaging>=23.2
pydantic>=1.10.13
sounddevice>=0.4.6
python-multipart>=0.0.6
cutlet>=0.3.0
unidic-lite>=1.0.8
faster-whisper>=0.10.0
pandas>=1.5.0
nvidia-cublas-cu11>=11.11.3.6
nvidia-cudnn-cu11>=9.0.0.312
fuzzywuzzy>=0.18.0 fuzzywuzzy>=0.18.0
python-Levenshtein>=0.25.0 importlib_metadata>=7.1.0
spacy>=3.7.2 inputimeout>=1.0.4
Jinja2>=3.1.0
librosa>=0.10.2.post1
local_attention>=1.9.0
onnxruntime-gpu>=1.18.0
openai-whisper
pydantic>=2.7.0
python-Levenshtein>=0.25.1
praat-parselmouth>=0.4.0
pyworld>=0.3.0
sounddevice>=0.4.7
soundfile>=0.12.0
spacy>=3.7.1
torchcrepe>=0.0.2
tqdm>=4.66.0
unidic-lite>=1.0.8
uvicorn>=0.29.0
pypinyin>=0.52.0
hangul_romanize>=0.1.0
word2number>=1.1
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.3.1-cp311-cp311-linux_x86_64.whl; sys_platform == "linux"
piper-tts; sys_platform == "linux"
piper-tts; sys_platform == "darwin"
piper-phonemize==1.1.0; sys_platform == "darwin"
plotly==5.24.1
scipy==1.14.1
pyOpenSSL>=24.2.1
langdetect>=1.0.9
@@ -0,0 +1,5 @@
jsonlines>=4.0.0
networkx>=3.0.0
protobuf==4.25.3
typing_extensions>=4.9.0
pillow==10.3.0
@@ -0,0 +1,4 @@
filelock>=3.16.1
pydantic>=2.7.0
pytest>=8.3.3
pytest-cov>=6.0.0
File diff suppressed because it is too large. Load diff
-159
View File
@@ -1,159 +0,0 @@
#tts_media_control {
/* order: 100; */
/* width: 40px;
height: 40px;
margin: 0;
padding: 1px; */
outline: none;
border: none;
cursor: pointer;
/* transition: 0.3s;
opacity: 0.7; */
display: flex;
align-items: center;
/* justify-content: center; */
}
#ttsExtensionMenuItem {
transition: 0.3s;
opacity: 0.7;
}
#ttsExtensionMenuItem:hover {
opacity: 1;
filter: brightness(1.2);
}
#tts_media_control:hover {
opacity: 1;
filter: brightness(1.2);
}
.voice_preview {
margin: 0.25rem 0.5rem;
display: flex;
justify-content: space-between;
align-items: center;
gap: 0.5rem;
}
.voice_preview .voice_name {
text-align: left;
flex: 1;
}
.voice_preview .voice_lang {
width: 4rem;
text-align: left;
}
.voice_preview .fa-play {
cursor: pointer;
}
.tts-button {
margin: 0;
outline: none;
border: none;
cursor: pointer;
transition: 0.3s;
opacity: 0.7;
align-items: center;
justify-content: center;
}
.tts-button:hover {
opacity: 1;
}
.tts_block {
display: flex;
align-items: baseline;
column-gap: 5px;
flex-wrap: wrap;
}
.tts_custom_voices {
display: flex;
align-items: baseline;
gap: 5px;
}
.novel_tts_hints {
font-size: calc(0.9 * var(--mainFontSize));
display: flex;
flex-direction: column;
gap: 5px;
margin-bottom: 5px;
}
.at-settings-row {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
}
.at-settings-option {
flex: 1;
margin: 0 10px;
}
.at-endpoint-option {
flex: 1;
margin: 0 10px;
margin-right: 25px;
width: 38%;
}
.at-website-row {
display: flex;
justify-content: start;
align-items: center;
margin-top: 10px;
margin-bottom: 10px;
}
.at-website-option {
flex: 1;
margin-right: 10px;
margin-left: 10px;
}
.at-settings-separator {
margin-top: 10px;
margin-bottom: 10px;
padding: 18x;
font-weight: bold;
border-top: 1px solid #e1e1e1; /* Grey line */
border-bottom: 1px solid #e1e1e1; /* Grey line */
text-align: center;
}
.at-status-message {
flex: 1;
margin: 0 10px;
}
.at-model-endpoint-row {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
}
.at-model-option, .endpoint-option {
flex: 1;
margin: 0 10px;
margin-left: 10px;
}
.at-endpoint-option {
width: 38%;
}
#at-status_info {
color: lightgreen;
}
Loaded 100 of 586 files, more files were not shown because too many files have changed in this diff. Show more