Files
llm-in-text/backend/TTS_ASR_MACOS_FIX.md
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

8.1 KiB
Raw Blame History

TTS/ASR macOS适配修复说明

修复概述

本次修复彻底重构了backend/tts_asr.py针对macOS和Apple Silicon (M1/M2/M3)进行了全面优化。

主要改进

1. 增强的设备检测 (_detect_device_capabilities)

改进前问题:

  • 简单的张量乘法测试不足以验证MPS设备实际可用性
  • 缺少内存限制检测
  • Apple Silicon没有特殊处理

改进后:

  • 使用DeviceCapabilities结构化存储设备信息
  • 更全面的MPS测试1000x1000矩阵运算
  • 自动检测Apple Silicon并调整内存限制
  • 根据系统内存动态设置MPS内存阈值默认60%
  • 支持设备能力降级MPS→CPU, CUDA→CPU

验证方法:

# 在Python环境中测试
from tts_asr import _detect_device_capabilities
caps = _detect_device_capabilities()
print(f"Device: {caps.device}")
print(f"MPS Available: {caps.mps_available}")
print(f"Apple Silicon: {_is_apple_silicon()}")

2. 模型大小选择和量化支持

新增环境变量:

  • TTS_ASR_MODEL_SIZE: 选择Whisper模型大小

    • tiny: 最小模型,最快但准确度较低
    • base: 基础模型,平衡性能和准确度
    • small: 推荐用于Apple Silicon
    • medium: 中等模型
    • large: 大模型,最高准确度
    • turbo: large-v3-turbo (原默认模型)
    • auto: 自动选择Apple Silicon默认small
  • TTS_ASR_QUANTIZE: 启用INT8量化减少内存占用

Apple Silicon优化:

  • 自动检测并推荐small模型
  • 考虑MPS内存限制选择合适模型

验证方法:

# 查看推荐的模型大小
from tts_asr import _get_recommended_model_size
print(_get_recommended_model_size())  # Apple Silicon: "small"

3. 离线模式支持

新增环境变量:

  • TTS_ASR_OFFLINE_MODE: 启用离线模式
    • 启动前检查模型是否已缓存
    • 缓存不存在时优雅失败而非崩溃

验证方法:

# 启用离线模式
export TTS_ASR_OFFLINE_MODE=true
python backend/main.py

# 检查模型缓存
python -c "from tts_asr import _check_model_cached; print(_check_model_cached('openai/whisper-small'))"

4. 健壮的音频处理

改进前问题:

  • librosa.resample失败时无回退
  • 缺少音频数据验证

改进后:

  • _validate_audio_data(): 验证音频数据有效性
  • _resample_audio_robust(): 多重回退重采样
    1. 优先使用librosa.resample
    2. 回退到torchaudio.transforms.Resample
    3. 最后使用NumPy线性插值

验证方法:

import numpy as np
from tts_asr import _resample_audio_robust

# 测试重采样
audio = np.random.randn(16000).astype(np.float32)
resampled = _resample_audio_robust(audio, 16000, 48000)
print(f"Original: {len(audio)}, Resampled: {len(resampled)}")

5. 改进的错误处理和降级

降级路径:

MPS推理失败 → 标记MPS不可用 → 清理MPS缓存 → 降级到CPU
CUDA推理失败 → 标记CUDA不可用 → 清理CUDA缓存 → 降级到CPU

日志改进:

  • 详细记录设备检测过程
  • 明确标注降级原因
  • 显示模型大小、量化状态、离线模式等配置

6. 新增API端点

GET /v1/tts-asr/config:

{
  "environment": {
    "TTS_ASR_DEVICE": "auto",
    "TTS_ASR_MODEL_SIZE": "auto",
    "TTS_ASR_QUANTIZE": false,
    "TTS_ASR_OFFLINE_MODE": false,
    ...
  },
  "device": {
    "current": "mps",
    "mps_available": true,
    "cuda_available": false,
    "is_apple_silicon": true,
    "mps_memory_limit_mb": 8192
  },
  "model": {
    "tts": "hexgrad/Kokoro-82M",
    "asr_current_size": "small",
    "asr_recommended_size": "small",
    "available_sizes": ["tiny", "base", "small", "medium", "large", "turbo"]
  }
}

环境变量完整列表

变量名 说明 默认值 示例
TTS_ASR_DEVICE 设备选择 auto mps, cuda, cpu
TTS_ASR_MODEL_SIZE ASR模型大小 auto tiny, base, small, medium, large, turbo
TTS_ASR_QUANTIZE INT8量化 false true, false
TTS_ASR_OFFLINE_MODE 离线模式 false true, false
TTS_ASR_WARMUP 启动预热 true true, false
TTS_ASR_WARMUP_TIMEOUT 预热超时(秒) 120 60, 180
TTS_ASR_IDLE_TIMEOUT 空闲卸载(秒) 0 300, 600
TTS_ASR_MPS_MEMORY_LIMIT_MB MPS内存限制(MB) 8192 4096, 16384

macOS使用建议

推荐配置

Apple Silicon (M1/M2/M3) 8GB内存:

export TTS_ASR_MODEL_SIZE=small
export TTS_ASR_MPS_MEMORY_LIMIT_MB=4096

Apple Silicon (M1/M2/M3) 16GB+内存:

export TTS_ASR_MODEL_SIZE=medium
export TTS_ASR_MPS_MEMORY_LIMIT_MB=8192

内存紧张时:

export TTS_ASR_MODEL_SIZE=tiny
export TTS_ASR_QUANTIZE=true

性能优化建议

  1. 首次运行: 建议不使用离线模式,让模型自动下载

  2. 后续运行: 启用离线模式避免网络延迟

    export TTS_ASR_OFFLINE_MODE=true
    
  3. 长期运行服务: 设置空闲超时自动卸载模型

    export TTS_ASR_IDLE_TIMEOUT=600  # 10分钟后卸载
    
  4. 调试模式: 查看详细设备检测日志

    import logging
    logging.getLogger("tts_asr").setLevel(logging.DEBUG)
    

验证步骤非Mac环境

由于你不在Mac环境下可以使用以下方法验证代码逻辑

1. 代码静态检查

# 检查Python语法
python -m py_compile backend/tts_asr.py

# 检查导入
python -c "import backend.tts_asr"

2. 单元测试模拟

# 模拟Apple Silicon环境
import os
import platform

# 模拟Darwin/arm64
original_system = platform.system
original_machine = platform.machine

def mock_system():
    return "Darwin"

def mock_machine():
    return "arm64"

platform.system = mock_system
platform.machine = mock_machine

# 测试Apple Silicon检测
from tts_asr import _is_apple_silicon
assert _is_apple_silicon() == True

# 恢复原始函数
platform.system = original_system
platform.machine = original_machine

3. 环境变量测试

import os
os.environ['TTS_ASR_MODEL_SIZE'] = 'small'
os.environ['TTS_ASR_QUANTIZE'] = 'true'

# 重新加载模块
import importlib
import backend.tts_asr
importlib.reload(backend.tts_asr)

from backend.tts_asr import TTS_ASR_MODEL_SIZE, TTS_ASR_QUANTIZE
assert TTS_ASR_MODEL_SIZE == 'small'
assert TTS_ASR_QUANTIZE == True

4. API端点测试需要运行服务

# 启动服务
python backend/main.py

# 测试配置端点需要API Key
curl -X GET "http://localhost:8001/v1/tts-asr/config" \
  -H "X-API-Key: your-secret-key-here"

# 测试状态端点
curl -X GET "http://localhost:8001/v1/tts-asr/status" \
  -H "X-API-Key: your-secret-key-here"

依赖更新

已在backend/requirements.txt中添加:

  • psutil: 系统内存检测
  • torchaudio: 音频重采样备选方案

安装新依赖:

pip install -r backend/requirements.txt

向后兼容性

所有改动保持向后兼容:

  • 现有API端点未改变
  • 默认行为与原版一致
  • 新功能通过环境变量启用

已知限制

  1. MPS float16: 在某些操作上可能不稳定代码默认使用float32
  2. 8-bit量化: 仅在CPU和CUDA环境支持MPS不支持
  3. Core ML: 预留了扩展点但未实现(需要额外依赖)

未来改进方向

  1. 集成Core ML作为备选推理后端
  2. 支持torch.compile (PyTorch 2.0+)
  3. 实现模型自动下载的进度显示
  4. 添加更多音频格式支持

问题排查

模型加载失败

  1. 检查网络连接
  2. 尝试关闭离线模式: export TTS_ASR_OFFLINE_MODE=false
  3. 查看详细日志: 设置logging.getLogger("tts_asr").setLevel(logging.DEBUG)

MPS内存不足

  1. 使用更小的模型: export TTS_ASR_MODEL_SIZE=tiny
  2. 启用量化: export TTS_ASR_QUANTIZE=true
  3. 降低内存限制: export TTS_ASR_MPS_MEMORY_LIMIT_MB=4096

音频处理失败

  1. 检查音频格式支持WAV
  2. 确保音频采样率≥8000Hz
  3. 查看日志中的详细错误信息

修复完成日期: 2026-04-06
修改文件:

  • backend/tts_asr.py (主要重构)
  • backend/requirements.txt (添加依赖)
  • README.md (更新文档)