Files
llm-in-text/backend/tests/quick_verify.py
ydy0615 7985fe9641 feat(tts): add api endpoints and optimization for apple silicon
Introduce a comprehensive TTS/ASR module that:
- Adds /v1/tts-asr/config, /status, /warmup, /tts, /asr endpoints with detailed JSON responses
- Implements Apple‑Silicon detection, device selection (MPS/CUDA/CPU), and memory limiting logic
- Supports selectable model size, quantization, and offline mode via environment variables
- Adds robust audio validation and multi‑path resampling fallback
- Provides new README sections for API usage, device detection, and performance benchmarking
- Includes a full testing suite: unit tests, integration tests, macOS simulation and performance reports
- Updates backend dependencies and CI scripts
- Adds new front‑end views and components for Univer editor integration

All changes are backward compatible; new features are exposed through environment variables and new API routes.
2026-04-06 11:14:09 +08:00

189 lines
6.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
快速验证脚本
验证TTS/ASR模块修复是否正确应用
运行方式:
python backend/tests/quick_verify.py
"""
import os
import sys
from pathlib import Path
# 设置控制台编码
if sys.platform == 'win32':
import io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8')
# 确保可以导入backend模块
script_path = Path(__file__).resolve()
project_root = script_path.parent.parent.parent
sys.path.insert(0, str(project_root))
print(f"项目根目录: {project_root}")
print(f"脚本路径: {script_path}")
def check_file_exists(filepath: str, description: str) -> bool:
"""检查文件是否存在"""
full_path = project_root / filepath
exists = full_path.exists()
status = "[OK]" if exists else "[FAIL]"
print(f"{status} {description}: {filepath} (完整路径: {full_path})")
return exists
def check_function_exists(module_name: str, function_name: str) -> bool:
"""检查函数是否存在"""
try:
module = __import__(module_name, fromlist=[function_name])
exists = hasattr(module, function_name)
status = "[OK]" if exists else "[FAIL]"
print(f"{status} 函数存在: {module_name}.{function_name}")
return exists
except Exception as e:
print(f"[FAIL] 导入失败: {module_name} - {e}")
return False
def check_environment_variable(var_name: str, expected_default: str) -> bool:
"""检查环境变量默认值"""
try:
# 清除可能存在的环境变量
original_value = os.environ.get(var_name)
if var_name in os.environ:
del os.environ[var_name]
# 重新导入模块
if 'backend.tts_asr' in sys.modules:
del sys.modules['backend.tts_asr']
from backend.tts_asr import (
TTS_ASR_DEVICE, TTS_ASR_MODEL_SIZE, TTS_ASR_QUANTIZE,
TTS_ASR_OFFLINE_MODE, TTS_ASR_WARMUP, TTS_ASR_WARMUP_TIMEOUT,
TTS_ASR_IDLE_TIMEOUT, TTS_ASR_MPS_MEMORY_LIMIT_MB
)
var_map = {
'TTS_ASR_DEVICE': TTS_ASR_DEVICE,
'TTS_ASR_MODEL_SIZE': TTS_ASR_MODEL_SIZE,
'TTS_ASR_QUANTIZE': TTS_ASR_QUANTIZE,
'TTS_ASR_OFFLINE_MODE': TTS_ASR_OFFLINE_MODE,
'TTS_ASR_WARMUP': TTS_ASR_WARMUP,
'TTS_ASR_WARMUP_TIMEOUT': TTS_ASR_WARMUP_TIMEOUT,
'TTS_ASR_IDLE_TIMEOUT': TTS_ASR_IDLE_TIMEOUT,
'TTS_ASR_MPS_MEMORY_LIMIT_MB': TTS_ASR_MPS_MEMORY_LIMIT_MB,
}
actual_value = var_map.get(var_name)
if var_name == 'TTS_ASR_MODEL_SIZE':
expected = 'auto'
elif var_name == 'TTS_ASR_QUANTIZE':
expected = False
elif var_name == 'TTS_ASR_OFFLINE_MODE':
expected = False
elif var_name == 'TTS_ASR_WARMUP':
expected = True
elif var_name == 'TTS_ASR_WARMUP_TIMEOUT':
expected = 120
elif var_name == 'TTS_ASR_IDLE_TIMEOUT':
expected = 0
elif var_name == 'TTS_ASR_MPS_MEMORY_LIMIT_MB':
expected = 8192
else:
expected = expected_default
matches = actual_value == expected
status = "[OK]" if matches else "[FAIL]"
print(f"{status} 环境变量默认值: {var_name} = {actual_value} (预期: {expected})")
return matches
except Exception as e:
print(f"[FAIL] 检查环境变量失败: {var_name} - {e}")
return False
def main():
print("="*70)
print("TTS/ASR模块快速验证")
print("="*70)
checks = []
# 1. 检查文件
print("\n[1] 文件检查")
print("-"*70)
checks.append(check_file_exists("backend/tts_asr.py", "主模块文件"))
checks.append(check_file_exists("backend/tests/test_tts_asr_unit.py", "单元测试"))
checks.append(check_file_exists("backend/tests/test_tts_asr_integration.py", "集成测试"))
checks.append(check_file_exists("backend/tests/simulate_macos.py", "macOS模拟工具"))
checks.append(check_file_exists("backend/tests/TESTING_GUIDE.md", "测试指南"))
checks.append(check_file_exists("backend/TTS_ASR_MACOS_FIX.md", "修复文档"))
# 2. 检查核心函数
print("\n[2] 核心函数检查")
print("-"*70)
checks.append(check_function_exists("backend.tts_asr", "_is_apple_silicon"))
checks.append(check_function_exists("backend.tts_asr", "_detect_device_capabilities"))
checks.append(check_function_exists("backend.tts_asr", "_get_recommended_model_size"))
checks.append(check_function_exists("backend.tts_asr", "_validate_audio_data"))
checks.append(check_function_exists("backend.tts_asr", "_resample_audio_robust"))
checks.append(check_function_exists("backend.tts_asr", "_check_model_cached"))
# 3. 检查数据类
print("\n[3] 数据类检查")
print("-"*70)
checks.append(check_function_exists("backend.tts_asr", "DeviceCapabilities"))
checks.append(check_function_exists("backend.tts_asr", "ModelStatus"))
# 4. 检查环境变量
print("\n[4] 环境变量默认值检查")
print("-"*70)
checks.append(check_environment_variable("TTS_ASR_DEVICE", "auto"))
checks.append(check_environment_variable("TTS_ASR_MODEL_SIZE", "auto"))
checks.append(check_environment_variable("TTS_ASR_QUANTIZE", "false"))
checks.append(check_environment_variable("TTS_ASR_OFFLINE_MODE", "false"))
# 5. 检查常量
print("\n[5] 常量检查")
print("-"*70)
try:
from backend.tts_asr import WHISPER_MODEL_SIZES, APPLE_SILICON_DEFAULT_SIZE
expected_sizes = ['tiny', 'base', 'small', 'medium', 'large', 'turbo']
sizes_match = list(WHISPER_MODEL_SIZES.keys()) == expected_sizes
status = "[OK]" if sizes_match else "[FAIL]"
print(f"{status} WHISPER_MODEL_SIZES: {list(WHISPER_MODEL_SIZES.keys())}")
checks.append(sizes_match)
size_match = APPLE_SILICON_DEFAULT_SIZE == 'small'
status = "[OK]" if size_match else "[FAIL]"
print(f"{status} APPLE_SILICON_DEFAULT_SIZE: {APPLE_SILICON_DEFAULT_SIZE}")
checks.append(size_match)
except Exception as e:
print(f"[FAIL] 常量检查失败: {e}")
checks.extend([False, False])
# 汇总结果
print("\n" + "="*70)
print("验证结果")
print("="*70)
total = len(checks)
passed = sum(checks)
print(f"通过: {passed}/{total}")
if all(checks):
print("\n[SUCCESS] 所有验证通过TTS/ASR模块修复已正确应用。")
return 0
else:
print("\n[FAILED] 部分验证失败,请检查上述错误。")
return 1
if __name__ == '__main__':
sys.exit(main())