Feature/add-gradio-webui#123
Conversation
There was a problem hiding this comment.
Pull Request Overview
This PR introduces a Chinese WebUI for ZipVoice using Gradio, providing a user-friendly interface for TTS tasks without requiring command-line usage. The WebUI supports multiple TTS modes including single-speaker PyTorch/ONNX inference, dialogue synthesis, and batch processing via TSV files.
Key changes:
- Added a comprehensive Chinese WebUI (
webui_zh.py) with support for various TTS modes - Added Gradio dependency for the WebUI functionality
- Fixed encoding issues in existing Python scripts for better Unicode support
Reviewed Changes
Copilot reviewed 4 out of 14 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| webui_zh.py | Main WebUI implementation with Chinese interface for all TTS modes |
| requirements-webui.txt | Gradio dependency for WebUI functionality |
| egs/zipvoice_dialog/local/prepare_opendialog.py | Fixed file encoding to UTF-8 for Unicode support |
| egs/zipvoice/local/prepare_token_file_emilia.py | Fixed file encoding to UTF-8 for Unicode support |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| # 确保输出目录存在 | ||
| os.makedirs("outputs", exist_ok=True) | ||
|
|
||
| os.environ['HF_ENDPOINT'] = 'https://hf-mirror.com' |
There was a problem hiding this comment.
Setting global environment variables in application code is not recommended. Consider making this configurable through command-line arguments or configuration files, or document this as a China-specific mirror requirement.
| os.environ['HF_ENDPOINT'] = 'https://hf-mirror.com' | |
| # 如需使用中国大陆 HuggingFace 镜像,请在启动时添加 --hf-mirror 参数,或设置环境变量 USE_HF_MIRROR=1 | |
| if '--hf-mirror' in sys.argv or os.environ.get('USE_HF_MIRROR') == '1': | |
| os.environ['HF_ENDPOINT'] = 'https://hf-mirror.com' | |
| logging.info("已启用 HuggingFace 中国大陆镜像 (https://hf-mirror.com)") |
| # --- 核心命令行执行函数 --- | ||
| def run_command(command, progress_desc="正在合成..."): | ||
| """执行命令行命令并记录输出。""" |
There was a problem hiding this comment.
The subprocess call uses shell=False which is good for security, but consider validating the command arguments to prevent potential command injection if any user input reaches this function.
| # --- 核心命令行执行函数 --- | |
| def run_command(command, progress_desc="正在合成..."): | |
| """执行命令行命令并记录输出。""" | |
| # --- 核心命令行执行函数 --- | |
| def validate_command_args(command): | |
| """验证命令参数,防止命令注入。""" | |
| if not isinstance(command, (list, tuple)): | |
| raise gr.Error("命令参数必须为列表或元组。") | |
| for arg in command: | |
| if not isinstance(arg, str): | |
| raise gr.Error("命令参数中的每一项都必须为字符串。") | |
| if '\x00' in arg: | |
| raise gr.Error("命令参数中不能包含空字节。") | |
| # 可根据需要添加更多检查,例如禁止某些特殊字符 | |
| def run_command(command, progress_desc="正在合成..."): | |
| """执行命令行命令并记录输出。""" | |
| validate_command_args(command) |
| logging.error(f"命令执行失败! 返回码: {process.returncode}") | ||
| logging.error(f"标准输出:\n{stdout}") | ||
| logging.error(f"标准错误:\n{stderr}") | ||
| raise gr.Error(f"后端脚本执行失败: {stderr[:1000]}") |
There was a problem hiding this comment.
Truncating error messages to 1000 characters could potentially expose sensitive information from stderr. Consider sanitizing or filtering the error output before displaying it to users.
| try: | ||
| df = pd.read_csv(file.name, sep='\t', header=None) |
There was a problem hiding this comment.
Reading user-uploaded files without validation could be a security risk. Consider validating file size, content type, and sanitizing the file path before processing.
| try: | |
| df = pd.read_csv(file.name, sep='\t', header=None) | |
| # Validate file size (e.g., max 5MB) | |
| max_size = 5 * 1024 * 1024 # 5MB | |
| file.file.seek(0, os.SEEK_END) | |
| size = file.file.tell() | |
| file.file.seek(0) | |
| if size > max_size: | |
| raise gr.Error("上传的文件过大,最大支持 5MB。") | |
| # Validate file extension | |
| allowed_exts = ['.tsv', '.txt'] | |
| _, ext = os.path.splitext(file.name) | |
| if ext.lower() not in allowed_exts: | |
| raise gr.Error("仅支持 .tsv 或 .txt 文件。") | |
| try: | |
| # Try reading a few bytes to check if it's text | |
| sample = file.file.read(1024) | |
| try: | |
| sample.decode('utf-8') | |
| except Exception: | |
| raise gr.Error("文件不是有效的文本文件,请上传 UTF-8 编码的 TSV 文件。") | |
| file.file.seek(0) | |
| df = pd.read_csv(file.file, sep='\t', header=None) |
This PR introduces a user-friendly Chinese WebUI based on Gradio, making it easier for users to experience ZipVoice without using the command line.
The WebUI supports: Single-speaker TTS (PyTorch & ONNX), Dialogue TTS, Batch inference via TSV.
To run the WebUI:
Install new dependencies:
pip install -r requirements-webui.txtRun the script:
python webui_zh.py