Updates to Piper
This commit is contained in:
1 parent
1a5c10710d
commit
85f204c3f1
2 files changed
+563
-85
No files matched your search
@@ -0,0 +1,360 @@
|
|||||||
|
# help_content.py
|
||||||
|
# pylint: disable=no-member
|
||||||
|
|
||||||
|
class AllTalkHelpContent:
|
||||||
|
"""CSS and help content for help_content.py"""
|
||||||
|
custom_css = """
|
||||||
|
/* Add this to your existing CSS */
|
||||||
|
.gradio-container .prose {
|
||||||
|
max-width: none !important;
|
||||||
|
padding: 0.5rem !important; /* Reduced padding */
|
||||||
|
margin: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-markdown div {
|
||||||
|
border: none !important; /* Remove the inner border */
|
||||||
|
margin-top: 0 !important; /* Remove top margin */
|
||||||
|
margin-bottom: 0 !important; /* Remove bottom margin */
|
||||||
|
padding-top: 0 !important; /* Remove top padding */
|
||||||
|
padding-bottom: 0 !important; /* Remove bottom padding */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update the existing custom-markdown class */
|
||||||
|
.custom-markdown {
|
||||||
|
font-size: 15px !important;
|
||||||
|
line-height: 1.6 !important;
|
||||||
|
color: var(--body-text-color) !important;
|
||||||
|
background-color: var(--background-fill-primary) !important;
|
||||||
|
border: 1px solid var(--border-color-primary) !important;
|
||||||
|
border-radius: 8px !important;
|
||||||
|
padding: 0.5rem !important;
|
||||||
|
margin: 0 !important; /* Changed from 1rem 0 to 0 */
|
||||||
|
max-width: 100% !important;
|
||||||
|
box-sizing: border-box !important;
|
||||||
|
/* Default text color for all content (grey) */
|
||||||
|
color: rgba(156, 163, 175, 1) !important; /* Adjust this grey value to match your interface */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make headings white */
|
||||||
|
.custom-markdown h1,
|
||||||
|
.custom-markdown h2,
|
||||||
|
.custom-markdown h3,
|
||||||
|
.custom-markdown h4,
|
||||||
|
.custom-markdown h5,
|
||||||
|
.custom-markdown h6 {
|
||||||
|
color: var(--heading-text-color, var(--body-text-color)) !important;
|
||||||
|
font-weight: 600 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Keep all other elements in the grey color */
|
||||||
|
.custom-markdown p,
|
||||||
|
.custom-markdown li,
|
||||||
|
.custom-markdown ul,
|
||||||
|
.custom-markdown ol {
|
||||||
|
color: rgba(156, 163, 175, 1) !important; /* Same grey as the base text */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Additional targeting for any wrapping elements */
|
||||||
|
.gradio-container .prose > * {
|
||||||
|
margin: 0 !important;
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update the list item spacing in your existing CSS */
|
||||||
|
.custom-markdown li {
|
||||||
|
font-size: 0.95rem !important;
|
||||||
|
margin-bottom: 0.2rem !important; /* Reduced from 0.5rem to 0.3rem */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add specific styling for definition-style lists (like your Default, Recommendation, Tip items) */
|
||||||
|
.custom-markdown li p {
|
||||||
|
margin: 0 !important; /* Remove paragraph margins within list items */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If you need even tighter spacing for specific types of lists */
|
||||||
|
.custom-markdown li + li {
|
||||||
|
margin-top: 0.2rem !important; /* Space between consecutive list items */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure nested lists maintain proper spacing */
|
||||||
|
.custom-markdown li > ul,
|
||||||
|
.custom-markdown li > ol {
|
||||||
|
margin: 0.2rem 0 0.2rem 1rem !important; /* Reduced from 0.5rem */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Consistent heading styles */
|
||||||
|
.custom-markdown h2 {
|
||||||
|
font-size: 1.2rem !important; /* Fixed size relative to root */
|
||||||
|
font-weight: 600 !important;
|
||||||
|
margin: 1.5rem 0 1rem !important;
|
||||||
|
color: var(--heading-text-color, var(--body-text-color)) !important;
|
||||||
|
border-bottom: 1px solid var(--border-color-primary) !important;
|
||||||
|
padding-bottom: 0.5rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* First paragraph styling */
|
||||||
|
.custom-markdown p:first-of-type {
|
||||||
|
font-size: 0.95rem !important; /* Match base size */
|
||||||
|
font-weight: 400 !important;
|
||||||
|
margin-bottom: 1rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Regular paragraphs */
|
||||||
|
.custom-markdown p {
|
||||||
|
font-size: 0.95rem !important;
|
||||||
|
margin: 0.8rem 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* List styling */
|
||||||
|
.custom-markdown ul,
|
||||||
|
.custom-markdown ol {
|
||||||
|
margin: 0.8rem 0 !important;
|
||||||
|
padding-left: 1.5rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Code styling */
|
||||||
|
.custom-markdown code {
|
||||||
|
font-family: ui-monospace, monospace !important;
|
||||||
|
background-color: var(--background-fill-secondary) !important;
|
||||||
|
padding: 0.2rem 0.4rem !important;
|
||||||
|
border-radius: 4px !important;
|
||||||
|
font-size: 0.8rem !important; /* Slightly smaller than regular text */
|
||||||
|
color: var(--body-text-color) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add styles for bold and emphasis */
|
||||||
|
.custom-markdown strong {
|
||||||
|
font-weight: 600 !important;
|
||||||
|
color: var(--body-text-color) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-markdown em {
|
||||||
|
font-style: italic !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure both columns take equal width */
|
||||||
|
.gradio-row > div {
|
||||||
|
flex: 1 1 50% !important;
|
||||||
|
min-width: 0 !important; /* Prevents flex items from overflowing */
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
ENGINE_INFORMATION = """
|
||||||
|
## 🔊 TTS Engine Capabilities Help
|
||||||
|
|
||||||
|
This guide explains the various capabilities that **may** be available in different TTS engines and models. Each capability affects how the TTS engine processes and generates speech output.
|
||||||
|
"""
|
||||||
|
|
||||||
|
ENGINE_INFORMATION1 = """
|
||||||
|
## 🚀 Performance Features
|
||||||
|
|
||||||
|
- **DeepSpeed Capable**: Enables GPU acceleration using the DeepSpeed optimization library.
|
||||||
|
- **Requires**: NVIDIA GPU with CUDA support
|
||||||
|
- **Benefit**: Significantly faster text-to-speech generation
|
||||||
|
- **Note**: Model must specifically support DeepSpeed inference
|
||||||
|
|
||||||
|
- **Low VRAM Capable**: Optimized for systems with limited GPU memory.
|
||||||
|
- **Benefit**: Efficient memory management between CPU and GPU
|
||||||
|
- **Use Case**: Ideal when running alongside other GPU-intensive applications like LLMs
|
||||||
|
- **Note**: May trade speed for memory efficiency
|
||||||
|
|
||||||
|
- **Streaming Capable**: Enables real-time speech generation.
|
||||||
|
- **Benefit**: Immediate playback without generating entire audio first
|
||||||
|
- **Use Case**: Interactive applications and real-time responses
|
||||||
|
- **Note**: Not all output formats support streaming
|
||||||
|
|
||||||
|
## 🎵 Voice Control Features
|
||||||
|
|
||||||
|
- **Pitch Capable**: Allows adjustment of voice pitch.
|
||||||
|
- **Benefit**: Creates more expressive and varied speech output
|
||||||
|
- **Use Case**: Customizing voice characteristics
|
||||||
|
- **Note**: Adjustment range varies by model
|
||||||
|
|
||||||
|
- **Generation Speed Capable**: Controls speech rate.
|
||||||
|
- **Benefit**: Adjustable playback speed during generation
|
||||||
|
- **Use Case**: Creating faster or slower speech output
|
||||||
|
- **Note**: May affect audio quality at extreme settings
|
||||||
|
|
||||||
|
- **Temperature Capable**: Controls output randomness.
|
||||||
|
- **Benefit**: Adjustable speech variation and creativity
|
||||||
|
- **Use Case**: Balancing consistency vs. naturality
|
||||||
|
- **Note**: Higher values increase variation but may reduce quality
|
||||||
|
"""
|
||||||
|
|
||||||
|
ENGINE_INFORMATION2 = """
|
||||||
|
## 🎯 Quality Enhancement Features
|
||||||
|
|
||||||
|
- **Repetition Penalty Capable**: Prevents unnatural speech patterns.
|
||||||
|
- **Benefit**: Reduces repeated sounds and phrases
|
||||||
|
- **Use Case**: Improving natural flow of longer texts
|
||||||
|
- **Note**: Strength of penalty may be adjustable
|
||||||
|
|
||||||
|
## 🌐 Multi-Feature Support
|
||||||
|
|
||||||
|
- **Multi-Languages Capable Models**: Each model Supports multiple languages.
|
||||||
|
- **Benefit**: Generate speech in different languages
|
||||||
|
- **Note**: Quality may vary between languages
|
||||||
|
- **Tip**: Check model-specific language support
|
||||||
|
|
||||||
|
- **Multi-Voice Capable**: Supports multiple speaking voices.
|
||||||
|
- **Benefit**: Different voices or speaking styles
|
||||||
|
- **Types**: Pre-trained voices or voice cloning
|
||||||
|
- **Note**: Voice quality may vary by model
|
||||||
|
|
||||||
|
- **Multi-Model Capable Engine**: Supports multiple TTS models.
|
||||||
|
- **Benefit**: Flexibility in model selection
|
||||||
|
- **Use Case**: Switching between models for different needs
|
||||||
|
- **Note**: Each model may have different capabilities
|
||||||
|
|
||||||
|
## 📁 Technical Features
|
||||||
|
|
||||||
|
- **Default Audio Output Format**: Specifies output file format.
|
||||||
|
- **Common Formats**: WAV, MP3, FLAC, Opus, AAC, PCM
|
||||||
|
- **Note**: Transcoding to different formats adds processing time
|
||||||
|
- **Warning**: Not all formats support streaming
|
||||||
|
|
||||||
|
- **Platform Support**: Operating system compatibility.
|
||||||
|
- **Platforms**: Windows, Linux, macOS
|
||||||
|
- **Note**: Additional setup may be required
|
||||||
|
- **Warning**: Support level may vary by platform
|
||||||
|
"""
|
||||||
|
|
||||||
|
DEFAULT_SETTINGS = """
|
||||||
|
## 🎯 TTS Engine Settings Help
|
||||||
|
|
||||||
|
This guide explains the settings and configuration options available for individual Text-to-Speech engines within AllTalk.
|
||||||
|
"""
|
||||||
|
|
||||||
|
DEFAULT_SETTINGS1 = """
|
||||||
|
## 🎚️ Engine Capabilities & Controls
|
||||||
|
|
||||||
|
- **Low VRAM Mode**
|
||||||
|
- Optimizes memory usage for systems with limited GPU memory
|
||||||
|
- Efficiently manages resources by moving data between CPU and GPU
|
||||||
|
- Recommended for systems with less than 4GB VRAM or when running alongside other GPU-intensive applications
|
||||||
|
|
||||||
|
- **DeepSpeed Capability**
|
||||||
|
- Accelerates TTS generation using optimized inference
|
||||||
|
- Only available for engines and models that support DeepSpeed
|
||||||
|
- Requires NVIDIA GPU with CUDA support
|
||||||
|
|
||||||
|
- **Temperature Control**
|
||||||
|
- Adjusts the variability in speech generation
|
||||||
|
- **Range**: 0.0 to 1.0
|
||||||
|
- **Lower values** (0.1-0.5): More consistent, stable output
|
||||||
|
- **Higher values** (0.6-1.0): More variable, potentially more natural-sounding output
|
||||||
|
|
||||||
|
- **Repetition Penalty**
|
||||||
|
- Helps prevent repetitive speech patterns
|
||||||
|
- **Range**: 1.0 to 15.0
|
||||||
|
- Higher values more strongly discourage repetition
|
||||||
|
- Typically most effective between 1.0-3.0
|
||||||
|
|
||||||
|
- **Pitch Adjustment**
|
||||||
|
- Modifies the voice pitch when supported
|
||||||
|
- **Range**: -20 to +20
|
||||||
|
- Use subtle adjustments for most natural results
|
||||||
|
|
||||||
|
- **Generation Speed**
|
||||||
|
- Controls the pace of generated speech
|
||||||
|
- **Range**: 0.5 to 2.0
|
||||||
|
- 1.0 represents normal speed
|
||||||
|
"""
|
||||||
|
|
||||||
|
DEFAULT_SETTINGS2 = """
|
||||||
|
|
||||||
|
## 🗣️ Voice Configuration
|
||||||
|
|
||||||
|
### OpenAI Voice Mappings
|
||||||
|
- Only relevant when using the OpenAI-compatible API endpoint
|
||||||
|
- Maps OpenAI's six standard voices to equivalent voices in the current engine:
|
||||||
|
- `alloy`
|
||||||
|
- `echo`
|
||||||
|
- `fable`
|
||||||
|
- `nova`
|
||||||
|
- `onyx`
|
||||||
|
- `shimmer`
|
||||||
|
- Essential for maintaining compatibility with OpenAI API calls
|
||||||
|
- Each mapping can be customized to any available voice in the current engine
|
||||||
|
|
||||||
|
Information on the OpenAI Endpoint is available in the [Github Wiki](https://github.com/erew123/alltalk_tts/wiki)
|
||||||
|
|
||||||
|
### Default Voices
|
||||||
|
- **Default/Character Voice**: Used when no specific voice is specified in API calls
|
||||||
|
- **Narrator Voice**: Separate default for narrator-specific text
|
||||||
|
- These defaults are engine-specific and won't affect other TTS engines
|
||||||
|
- Can be overridden by explicitly specifying voices in API calls
|
||||||
|
|
||||||
|
## ⚙️ Important Notes
|
||||||
|
|
||||||
|
- Settings availability is determined by engine capabilities
|
||||||
|
- Grayed-out options indicate features not supported by the current engine
|
||||||
|
- Changes only affect the currently selected TTS engine
|
||||||
|
- Settings here act as defaults but can be overridden via API parameters
|
||||||
|
- All changes require clicking "Update Settings" to take effect
|
||||||
|
- Some settings require an engine reload to take effect
|
||||||
|
"""
|
||||||
|
|
||||||
|
HELP_PAGE = """
|
||||||
|
## 🎯 Piper TTS Engine Help
|
||||||
|
|
||||||
|
Piper is a fast, local neural Text-to-Speech system designed for efficient performance with high-quality output.
|
||||||
|
"""
|
||||||
|
|
||||||
|
HELP_PAGE1 = """
|
||||||
|
## 📁 File Locations & Management
|
||||||
|
|
||||||
|
- **Model Storage**
|
||||||
|
- Models are stored in `/alltalk_tts/models/piper/`
|
||||||
|
- Each model consists of two required files:
|
||||||
|
- `.onnx` file (the voice model)
|
||||||
|
- `.onnx.json` file (model configuration)
|
||||||
|
|
||||||
|
- **Output Files**
|
||||||
|
- Generated audio is saved to `/alltalk_tts/outputs/`
|
||||||
|
- Automatic cleanup available via `Del WAV's older than` setting
|
||||||
|
- When enabled, old files are removed on startup
|
||||||
|
- Set to `Disabled` to preserve all output files
|
||||||
|
|
||||||
|
## 🗣️ Voice System
|
||||||
|
|
||||||
|
- **Built-in Voices**
|
||||||
|
- Voices are integrated into the models themselves
|
||||||
|
- No separate voice files needed
|
||||||
|
- Each model represents a complete voice with its own characteristics
|
||||||
|
- Models are organized by language and quality levels (x_low, low, medium, high)
|
||||||
|
|
||||||
|
- **Language Support**
|
||||||
|
- Wide range of languages available
|
||||||
|
- Models named using language codes (e.g., en_US, de_DE)
|
||||||
|
- Multiple voice options per language
|
||||||
|
- Different quality levels for varying needs
|
||||||
|
"""
|
||||||
|
|
||||||
|
HELP_PAGE2 = """
|
||||||
|
## ⚡ Performance Features
|
||||||
|
|
||||||
|
- **Quality Levels**
|
||||||
|
- `x_low`: Fastest, lowest resource usage
|
||||||
|
- `low`: Good balance of speed and quality
|
||||||
|
- `medium`: Higher quality, moderate resources
|
||||||
|
- `high`: Best quality, higher resource usage
|
||||||
|
|
||||||
|
## 📝 Important Notes
|
||||||
|
|
||||||
|
- **Model Names**
|
||||||
|
- Format: `[language_code]-[voice_name]-[quality]`
|
||||||
|
- Example: `en_US-lessac-medium`
|
||||||
|
- Indicates language, speaker, and quality level
|
||||||
|
|
||||||
|
- **Best Practices**
|
||||||
|
- Choose quality level based on your system capabilities
|
||||||
|
- Use appropriate language model for your text
|
||||||
|
|
||||||
|
## 🔄 Model Downloads
|
||||||
|
|
||||||
|
- Models can be downloaded individually or as language packs
|
||||||
|
- All models are sourced from the official Piper repository
|
||||||
|
- Downloads include both required files automatically
|
||||||
|
- Models can be managed through the Models/Voices Download tab
|
||||||
|
"""
|
||||||
@@ -4,6 +4,7 @@ import requests
|
|||||||
import gradio as gr
|
import gradio as gr
|
||||||
from tqdm import tqdm
|
from tqdm import tqdm
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from .help_content import AllTalkHelpContent
|
||||||
this_dir = Path(__file__).parent.resolve() # Sets up self.this_dir as a variable for the folder THIS script is running in.
|
this_dir = Path(__file__).parent.resolve() # Sets up self.this_dir as a variable for the folder THIS script is running in.
|
||||||
main_dir = Path(__file__).parent.parent.parent.parent.resolve() # Sets up self.main_dir as a variable for the folder AllTalk is running in
|
main_dir = Path(__file__).parent.parent.parent.parent.resolve() # Sets up self.main_dir as a variable for the folder AllTalk is running in
|
||||||
|
|
||||||
@@ -40,6 +41,148 @@ def piper_voices_file_list():
|
|||||||
|
|
||||||
return voices
|
return voices
|
||||||
|
|
||||||
|
# Load the available models from the JSON file
|
||||||
|
with open(os.path.join(this_dir, "available_models.json"), "r") as f:
|
||||||
|
available_models = json.load(f)
|
||||||
|
# Extract the model names for the dropdown
|
||||||
|
model_names = [model["model_name"] for model in available_models["models"]]
|
||||||
|
|
||||||
|
#####################################################################
|
||||||
|
# Piper Specific section for grouping/downloading the models/voices #
|
||||||
|
#####################################################################
|
||||||
|
|
||||||
|
def group_models_by_language():
|
||||||
|
"""Group available models by language code (first 2 letters)"""
|
||||||
|
language_groups = {}
|
||||||
|
|
||||||
|
for model in available_models["models"]:
|
||||||
|
model_name = model["model_name"]
|
||||||
|
lang_code = model_name[:2] # Get first two letters (language code)
|
||||||
|
|
||||||
|
if lang_code not in language_groups:
|
||||||
|
language_groups[lang_code] = {
|
||||||
|
"name": get_language_name(lang_code),
|
||||||
|
"models": []
|
||||||
|
}
|
||||||
|
|
||||||
|
language_groups[lang_code]["models"].append(model)
|
||||||
|
|
||||||
|
return language_groups
|
||||||
|
|
||||||
|
def get_language_name(lang_code):
|
||||||
|
"""Convert language code to full name"""
|
||||||
|
language_names = {
|
||||||
|
"ar": "Arabic",
|
||||||
|
"ca": "Catalan",
|
||||||
|
"cs": "Czech",
|
||||||
|
"da": "Danish",
|
||||||
|
"de": "German",
|
||||||
|
"el": "Greek",
|
||||||
|
"en": "English",
|
||||||
|
"es": "Spanish",
|
||||||
|
"fa": "Persian",
|
||||||
|
"fi": "Finnish",
|
||||||
|
"fr": "French",
|
||||||
|
"hu": "Hungarian",
|
||||||
|
"is": "Icelandic",
|
||||||
|
"it": "Italian",
|
||||||
|
"ka": "Georgian",
|
||||||
|
"kk": "Kazakh",
|
||||||
|
"lb": "Luxembourgish",
|
||||||
|
"ne": "Nepali",
|
||||||
|
"nl": "Dutch",
|
||||||
|
"no": "Norwegian",
|
||||||
|
"pl": "Polish",
|
||||||
|
"pt": "Portuguese",
|
||||||
|
"ro": "Romanian",
|
||||||
|
"ru": "Russian",
|
||||||
|
"sk": "Slovak",
|
||||||
|
"sl": "Slovenian",
|
||||||
|
"sr": "Serbian",
|
||||||
|
"sv": "Swedish",
|
||||||
|
"sw": "Swahili",
|
||||||
|
"tr": "Turkish",
|
||||||
|
"uk": "Ukrainian",
|
||||||
|
"vi": "Vietnamese",
|
||||||
|
"zh": "Chinese"
|
||||||
|
}
|
||||||
|
return language_names.get(lang_code, f"Unknown ({lang_code})")
|
||||||
|
|
||||||
|
def download_model(model_name, force_download=False):
|
||||||
|
# Find the selected model in the available models
|
||||||
|
selected_model = next(model for model in available_models["models"] if model["model_name"] == model_name)
|
||||||
|
# Get the folder path and files to download
|
||||||
|
folder_path = os.path.join(main_dir, "models", "piper")
|
||||||
|
files_to_download = selected_model["files_to_download"]
|
||||||
|
# Check if all files are already downloaded
|
||||||
|
all_files_exists = all(os.path.exists(os.path.join(folder_path, os.path.basename(url.split('?')[0]))) for url in files_to_download)
|
||||||
|
if all_files_exists and not force_download:
|
||||||
|
return "All files are already downloaded. No need to download again."
|
||||||
|
else:
|
||||||
|
# Create the folder if it doesn't exist
|
||||||
|
os.makedirs(folder_path, exist_ok=True)
|
||||||
|
# Download the missing files
|
||||||
|
for url in files_to_download:
|
||||||
|
file_name = os.path.basename(url.split('?')[0])
|
||||||
|
file_path = os.path.join(folder_path, file_name)
|
||||||
|
if not os.path.exists(file_path) or force_download:
|
||||||
|
print(f"Downloading {file_name}...")
|
||||||
|
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(file_path, "wb") as file:
|
||||||
|
for data in response.iter_content(block_size):
|
||||||
|
progress_bar.update(len(data))
|
||||||
|
file.write(data)
|
||||||
|
progress_bar.close()
|
||||||
|
return "Model downloaded successfully!"
|
||||||
|
|
||||||
|
def download_language_pack(lang_code, progress=gr.Progress()):
|
||||||
|
"""Download all models for a specific language"""
|
||||||
|
language_groups = group_models_by_language()
|
||||||
|
if lang_code not in language_groups:
|
||||||
|
return f"Error: Language pack {lang_code} not found"
|
||||||
|
|
||||||
|
models = language_groups[lang_code]["models"]
|
||||||
|
total_models = len(models)
|
||||||
|
|
||||||
|
progress(0, desc=f"Downloading {get_language_name(lang_code)} voice pack")
|
||||||
|
|
||||||
|
folder_path = os.path.join(main_dir, "models", "piper")
|
||||||
|
os.makedirs(folder_path, exist_ok=True)
|
||||||
|
|
||||||
|
downloaded_files = []
|
||||||
|
errors = []
|
||||||
|
|
||||||
|
for idx, model in enumerate(models, 1):
|
||||||
|
progress(idx/total_models, desc=f"Downloading model {idx}/{total_models}")
|
||||||
|
|
||||||
|
for url in model["files_to_download"]:
|
||||||
|
try:
|
||||||
|
file_name = os.path.basename(url.split('?')[0])
|
||||||
|
file_path = os.path.join(folder_path, file_name)
|
||||||
|
|
||||||
|
if not os.path.exists(file_path):
|
||||||
|
response = requests.get(url, stream=True)
|
||||||
|
total_size = int(response.headers.get("content-length", 0))
|
||||||
|
|
||||||
|
with open(file_path, "wb") as file:
|
||||||
|
for chunk in response.iter_content(chunk_size=1024):
|
||||||
|
if chunk:
|
||||||
|
file.write(chunk)
|
||||||
|
|
||||||
|
downloaded_files.append(file_name)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
errors.append(f"Error downloading {file_name}: {str(e)}")
|
||||||
|
|
||||||
|
if errors:
|
||||||
|
return f"Downloaded {len(downloaded_files)} files with {len(errors)} errors:\n" + "\n".join(errors)
|
||||||
|
else:
|
||||||
|
return f"Successfully downloaded {len(downloaded_files)} files for {get_language_name(lang_code)}"
|
||||||
|
|
||||||
|
|
||||||
######################################################
|
######################################################
|
||||||
# REQUIRED CHANGE #
|
# REQUIRED CHANGE #
|
||||||
# Imports and saves the TTS engine-specific settings #
|
# Imports and saves the TTS engine-specific settings #
|
||||||
@@ -130,10 +273,16 @@ def piper_model_alltalk_settings(model_config_data):
|
|||||||
def_narrator_voice_gr = gr.Dropdown(value=model_config_data["settings"]["def_narrator_voice"], label="Narrator Voice", choices=voice_list, allow_custom_value=True)
|
def_narrator_voice_gr = gr.Dropdown(value=model_config_data["settings"]["def_narrator_voice"], label="Narrator Voice", choices=voice_list, allow_custom_value=True)
|
||||||
with gr.Group():
|
with gr.Group():
|
||||||
with gr.Row():
|
with gr.Row():
|
||||||
details_text = gr.Textbox(label="Details", show_label=False, lines=5, interactive=False, value="In this section, you can set the default settings for this TTS engine. Settings that are not supported by the current engine will be greyed out and cannot be selected. Default voices specified here will be used when no specific voice is provided in the TTS generation request. If a voice is specified in the request, it will override these default settings. When using the OpenAI API compatable API with this TTS engine, the voice mappings will be applied. As the OpenAI API has a limited set of 6 voices, these mappings ensure compatibility by mapping the OpenAI voices to the available voices in this TTS engine.")
|
details_text = gr.Textbox(label="Details", show_label=False, lines=5, interactive=False, value="Configure default settings and voice mappings for the selected TTS engine. Unavailable options are grayed out based on engine capabilities. See the Help section below for detailed information about each setting.")
|
||||||
with gr.Row():
|
with gr.Row():
|
||||||
submit_button = gr.Button("Update Settings")
|
submit_button = gr.Button("Update Settings")
|
||||||
output_message = gr.Textbox(label="Output Message", interactive=False, show_label=False)
|
output_message = gr.Textbox(label="Output Message", interactive=False, show_label=False)
|
||||||
|
with gr.Accordion("HELP - 🔊 Understanding TTS Engine Default Settings Page", open=False):
|
||||||
|
with gr.Row():
|
||||||
|
gr.Markdown(AllTalkHelpContent.DEFAULT_SETTINGS, elem_classes="custom-markdown")
|
||||||
|
with gr.Row():
|
||||||
|
gr.Markdown(AllTalkHelpContent.DEFAULT_SETTINGS1, elem_classes="custom-markdown")
|
||||||
|
gr.Markdown(AllTalkHelpContent.DEFAULT_SETTINGS2, elem_classes="custom-markdown")
|
||||||
submit_button.click(piper_model_update_settings, inputs=[def_character_voice_gr, def_narrator_voice_gr, lowvram_enabled_gr, deepspeed_enabled_gr, temperature_set_gr, repetitionpenalty_set_gr, pitch_set_gr, generationspeed_set_gr, alloy_gr, echo_gr, fable_gr, nova_gr, onyx_gr, shimmer_gr], outputs=output_message)
|
submit_button.click(piper_model_update_settings, inputs=[def_character_voice_gr, def_narrator_voice_gr, lowvram_enabled_gr, deepspeed_enabled_gr, temperature_set_gr, repetitionpenalty_set_gr, pitch_set_gr, generationspeed_set_gr, alloy_gr, echo_gr, fable_gr, nova_gr, onyx_gr, shimmer_gr], outputs=output_message)
|
||||||
|
|
||||||
###########################################################################################
|
###########################################################################################
|
||||||
@@ -167,84 +316,64 @@ def piper_model_alltalk_settings(model_config_data):
|
|||||||
gr.Textbox(label="Linux Support", value='Yes' if features_list['linux_capable'] else 'No', interactive=False)
|
gr.Textbox(label="Linux Support", value='Yes' if features_list['linux_capable'] else 'No', interactive=False)
|
||||||
gr.Textbox(label="Mac Support", value='Yes' if features_list['mac_capable'] else 'No', interactive=False)
|
gr.Textbox(label="Mac Support", value='Yes' if features_list['mac_capable'] else 'No', interactive=False)
|
||||||
with gr.Row():
|
with gr.Row():
|
||||||
gr.Markdown("""
|
with gr.Accordion("HELP - 🔊 Understanding TTS Engine Capabilities", open=False):
|
||||||
#### 🟧 DeepSpeed Capable
|
with gr.Row():
|
||||||
DeepSpeed is a deep learning optimization library that can significantly speed up model training and inference. If a model is DeepSpeed capable, it means it can utilize DeepSpeed to accelerate the generation of text-to-speech output. This requires the model to be loaded into CUDA/VRAM on an Nvidia GPU and the model's inference method to support DeepSpeed.
|
gr.Markdown(AllTalkHelpContent.ENGINE_INFORMATION, elem_classes="custom-markdown")
|
||||||
#### 🟧 Pitch Capable
|
with gr.Row():
|
||||||
Pitch refers to the highness or lowness of a sound. If a model is pitch capable, it can adjust the pitch of the generated speech, allowing for more expressive and varied output.
|
gr.Markdown(AllTalkHelpContent.ENGINE_INFORMATION1, elem_classes="custom-markdown")
|
||||||
#### 🟧 Generation Speed Capable
|
gr.Markdown(AllTalkHelpContent.ENGINE_INFORMATION2, elem_classes="custom-markdown")
|
||||||
Generation speed refers to the rate at which the model can generate text-to-speech output. If a model is generation speed capable, it means the speed of the generated speech can be adjusted, making it faster or slower depending on the desired output.
|
|
||||||
#### 🟧 Repetition Penalty Capable
|
|
||||||
Repetition penalty is a technique used to discourage the model from repeating the same words or phrases multiple times in the same sounding way. If a model is repetition penalty capable, it can apply this penalty during generation to improve the diversity and naturalness of the output.
|
|
||||||
#### 🟧 Multi-Languages Capable
|
|
||||||
Multi-language capable models can generate speech in multiple languages. This means that the model has been trained on data from different languages and can switch between them during generation. Some models are language-specific.
|
|
||||||
#### 🟧 Multi-Voice Capable
|
|
||||||
Multi-voice capable models generate speech in multiple voices or speaking styles. This means that the model has been trained on data from different speakers and can mimic their voices during generation, or is a voice cloning model that can generate speech based on the input sample.
|
|
||||||
""")
|
|
||||||
gr.Markdown("""
|
|
||||||
#### 🟧 Streaming Capable
|
|
||||||
Streaming refers to the ability to generate speech output in real-time, without the need to generate the entire output before playback. If a model is streaming capable, it can generate speech on-the-fly, allowing for faster response times and more interactive applications.
|
|
||||||
#### 🟧 Low VRAM Capable
|
|
||||||
VRAM (Video Random Access Memory) is a type of memory used by GPUs to store and process data. If a model is low VRAM capable, it can efficiently utilize the available VRAM by moving data between CPU and GPU memory as needed, allowing for generation even on systems with limited VRAM where it may be competing with an LLM model for VRAM.
|
|
||||||
#### 🟧 Temperature Capable
|
|
||||||
Temperature is a hyperparameter that controls the randomness of the generated output. If a model is temperature capable, the temperature can be adjusted to make the output more or less random, affecting the creativity and variability of the generated speech.
|
|
||||||
#### 🟧 Multi-Model Capable Engine
|
|
||||||
If an engine is multi-model capable, it means that it can support and utilize multiple models for text-to-speech generation. This allows for greater flexibility and the ability to switch between different models depending on the desired output. Different models may be capable of different languages, specific languages, voices, etc.
|
|
||||||
#### 🟧 Default Audio Output Format
|
|
||||||
Specifies the file format in which the generated speech will be saved. Common audio formats include WAV, MP3, FLAC, Opus, AAC, and PCM. If you want different outputs, you can set the transcode function to change the output audio, though transcoding will add a little time to the generation and is not available for streaming generation.
|
|
||||||
#### 🟧 Windows/Linux/Mac Support
|
|
||||||
These indicators show whether the model and engine are compatible with Windows, Linux, or macOS. However, additional setup or requirements may be necessary to ensure full functionality on your operating system. Please note that full platform support has not been extensively tested.
|
|
||||||
""")
|
|
||||||
|
|
||||||
#######################################################################################################################################################################################################
|
#######################################################################################################################################################################################################
|
||||||
# REQUIRED CHANGE #
|
# REQUIRED CHANGE #
|
||||||
# You will need to build a custom method to identify if your models are installed and download them. Store your models list in the available_models.json file, alongside your model_settings.json etc #
|
# You will need to build a custom method to identify if your models are installed and download them. Store your models list in the available_models.json file, alongside your model_settings.json etc #
|
||||||
#######################################################################################################################################################################################################
|
#######################################################################################################################################################################################################
|
||||||
with gr.Tab("Models/Voices Download"):
|
with gr.Tab("Models/Voices Download"):
|
||||||
with gr.Row():
|
|
||||||
# Load the available models from the JSON file
|
|
||||||
with open(os.path.join(this_dir, "available_models.json"), "r") as f:
|
|
||||||
available_models = json.load(f)
|
|
||||||
# Extract the model names for the dropdown
|
|
||||||
model_names = [model["model_name"] for model in available_models["models"]]
|
|
||||||
# Create the dropdown
|
|
||||||
model_dropdown = gr.Dropdown(choices=sorted(model_names), label="Select Model", value=model_names[0])
|
|
||||||
download_button = gr.Button("Download Model/Missing Files")
|
|
||||||
|
|
||||||
def download_model(model_name, force_download=False):
|
with gr.Tab("Language Pack Download"):
|
||||||
# Find the selected model in the available models
|
with gr.Row():
|
||||||
selected_model = next(model for model in available_models["models"] if model["model_name"] == model_name)
|
language_groups = group_models_by_language()
|
||||||
# Get the folder path and files to download
|
language_choices = [
|
||||||
folder_path = os.path.join(main_dir, "models", "piper")
|
f"{code} - {info['name']} ({len(info['models'])} voices)"
|
||||||
files_to_download = selected_model["files_to_download"]
|
for code, info in sorted(language_groups.items())
|
||||||
# Check if all files are already downloaded
|
]
|
||||||
all_files_exists = all(os.path.exists(os.path.join(folder_path, os.path.basename(url.split('?')[0]))) for url in files_to_download)
|
|
||||||
if all_files_exists and not force_download:
|
|
||||||
return "All files are already downloaded. No need to download again."
|
|
||||||
else:
|
|
||||||
# Create the folder if it doesn't exist
|
|
||||||
os.makedirs(folder_path, exist_ok=True)
|
|
||||||
# Download the missing files
|
|
||||||
for url in files_to_download:
|
|
||||||
file_name = os.path.basename(url.split('?')[0])
|
|
||||||
file_path = os.path.join(folder_path, file_name)
|
|
||||||
if not os.path.exists(file_path) or force_download:
|
|
||||||
print(f"Downloading {file_name}...")
|
|
||||||
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(file_path, "wb") as file:
|
|
||||||
for data in response.iter_content(block_size):
|
|
||||||
progress_bar.update(len(data))
|
|
||||||
file.write(data)
|
|
||||||
progress_bar.close()
|
|
||||||
return "Model downloaded successfully!"
|
|
||||||
|
|
||||||
with gr.Row():
|
lang_pack_dropdown = gr.Dropdown(
|
||||||
download_status = gr.Textbox(label="Download Status")
|
choices=language_choices,
|
||||||
|
label="Select Language Pack",
|
||||||
|
value=language_choices[0]
|
||||||
|
)
|
||||||
|
lang_pack_download_button = gr.Button("Download Language Pack")
|
||||||
|
|
||||||
download_button.click(download_model, inputs=model_dropdown, outputs=download_status)
|
with gr.Row():
|
||||||
|
lang_pack_status = gr.Textbox(label="Language Pack Download Status")
|
||||||
|
|
||||||
|
def download_selected_language_pack(selected_pack):
|
||||||
|
lang_code = selected_pack.split(" - ")[0]
|
||||||
|
return download_language_pack(lang_code)
|
||||||
|
|
||||||
|
lang_pack_download_button.click(
|
||||||
|
download_selected_language_pack,
|
||||||
|
inputs=lang_pack_dropdown,
|
||||||
|
outputs=lang_pack_status
|
||||||
|
)
|
||||||
|
|
||||||
|
with gr.Tab("Individual Voice Download"):
|
||||||
|
with gr.Row():
|
||||||
|
model_dropdown = gr.Dropdown(
|
||||||
|
choices=sorted(model_names),
|
||||||
|
label="Select Individual Voice",
|
||||||
|
value=model_names[0]
|
||||||
|
)
|
||||||
|
download_button = gr.Button("Download Selected Voice")
|
||||||
|
|
||||||
|
with gr.Row():
|
||||||
|
download_status = gr.Textbox(label=" Individual Voice Download Status")
|
||||||
|
|
||||||
|
download_button.click(
|
||||||
|
download_model,
|
||||||
|
inputs=model_dropdown,
|
||||||
|
outputs=download_status
|
||||||
|
)
|
||||||
|
|
||||||
def show_confirm_cancel(model_name):
|
def show_confirm_cancel(model_name):
|
||||||
all_files_exists = all(os.path.exists(os.path.join(main_dir, "models", "piper", os.path.basename(file.split('?')[0]))) for model in available_models["models"] if model["model_name"] == model_name for file in model["files_to_download"])
|
all_files_exists = all(os.path.exists(os.path.join(main_dir, "models", "piper", os.path.basename(file.split('?')[0]))) for model in available_models["models"] if model["model_name"] == model_name for file in model["files_to_download"])
|
||||||
@@ -275,21 +404,10 @@ def piper_model_alltalk_settings(model_config_data):
|
|||||||
###################################################################################################
|
###################################################################################################
|
||||||
with gr.Tab("Engine Help"):
|
with gr.Tab("Engine Help"):
|
||||||
with gr.Row():
|
with gr.Row():
|
||||||
gr.Markdown("""
|
gr.Markdown(AllTalkHelpContent.HELP_PAGE, elem_classes="custom-markdown")
|
||||||
### 🟧 Where are the Piper models stored?
|
with gr.Row():
|
||||||
This extension will download the models to `/alltalk_tts/models/piper/` folder.<br>
|
gr.Markdown(AllTalkHelpContent.HELP_PAGE1, elem_classes="custom-markdown")
|
||||||
|
gr.Markdown(AllTalkHelpContent.HELP_PAGE2, elem_classes="custom-markdown")
|
||||||
### 🟧 Where are the voices stored for piper models?
|
|
||||||
Piper models themselves are the voices/have the voices built into them. The models are made up of 2x files, an `onnx` file and a `onnx.json` file.<br>
|
|
||||||
|
|
||||||
### 🟧 Where are the outputs stored & Automatic output wav file deletion
|
|
||||||
Voice outputs are stored in `/alltalk_tts/outputs/`. You can configure automatic maintenance deletion of old wav files by setting `Del WAV's older than` in the global settings.<br>
|
|
||||||
|
|
||||||
> When `Disabled`, your output wav files will be left untouched.<br>
|
|
||||||
> When set to a setting `1 Day` or greater, your output wav files older than that time period will be automatically deleted on start-up of AllTalk.<br>
|
|
||||||
""")
|
|
||||||
gr.Markdown("""
|
|
||||||
""")
|
|
||||||
|
|
||||||
|
|
||||||
return app
|
return app
|
||||||
|
|||||||
Reference in new issue
Block a user