ITADN

[Bug] Windows 下使用 torchaudio>=2.9.0 进行 TTS 音频转换时报错 PermissionError [WinError 32]

#5261OpenTodyZhao 创建于 19 天前
T
TodyZhaocommented
### System Info / 系統信息 Describe the bug (描述 Bug) 在 Windows 系统上,当 torchaudio 版本 >= 2.9.0 时,Xinference 的 TTS 功能在将生成的音频张量保存为字节流时会抛出 PermissionError: [WinError 32]。这是因为底层代码使用了 tempfile.NamedTemporaryFile 并且在文件句柄未完全释放时尝试读取或删除它,触发了 Windows 的文件锁定机制。 To Reproduce (复现步骤) 在 Windows 系统上安装 Xinference(确保 torchaudio 版本 >= 2.9.0)。 启动 Xinference 并加载一个 TTS 模型(例如 ChatTTS)。 调用 /v1/audio/speech API 请求语音合成。 观察后台日志,会出现 [WinError 32] 另一个程序正在使用此文件 的报错,导致无法正常返回音频。 Expected behavior (预期行为) TTS 请求应该顺利完成,将音频文件转换为字节流并返回给客户端,不抛出任何文件权限/锁定异常。 Environment (环境信息) OS: Windows 11 (也存在于 Win10) Python version: 3.12 Xinference version: (填上你当前使用的版本号,比如 v0.15.0 或你安装的版本) torchaudio version: 2.9.0+ (任何大于等于 2.9.0 的版本) Error logs (错误日志) Traceback (most recent call last ): File ".../xinference/deploy/utils.py", line XXX, in audio_to_bytes with tempfile.NamedTemporaryFile(suffix="." + response_format) as f: torchaudio.save(f.name, tensor, sample_rate, format=response_format) # 接下来尝试读取或删除时会失败 ... PermissionError: [WinError 32] 另一个程序正在使用此文件,进程无法访问。 Root Cause Analysis & Suggested Fix (根因分析与修复建议) 根因分析: 在 xinference/deploy/utils.py 的 audio_to_bytes 函数中,针对 torchaudio >= 2.9.0 的分支使用了 tempfile.NamedTemporaryFile。在 Windows 上,torchaudio.save 底层 C++ 库可能会保持对文件的句柄占用,导致随后 Python 尝试读取文件内容或当离开 with 作用域自动删除文件时触发 WinError 32。 修复建议: 建议避免使用 NamedTemporaryFile 默认的自动删除机制,或者使用时间戳/随机字符串生成临时文件名,并在 try...finally 块中显式释放和清理。 以下是我本地测试通过的修改方案(使用时间戳命名并显式读取,避免锁冲突): # 替换原有的 torchaudio >= 2.9.0 分支代码 import os import time import tempfile temp_dir = tempfile.gettempdir() temp_file_name = os.path.join( temp_dir, f"xinference_tts_{int(time.time() * 1000)}.{response_format}" ) try: if response_pcm: torchaudio.save( temp_file_name, tensor, sample_rate, format="wav", encoding="PCM_S", ) with open(temp_file_name, "rb") as f: wav_bytes = f.read() return _extract_pcm_from_wav_bytes(wav_bytes) else: torchaudio.save( temp_file_name, tensor, sample_rate, format=response_format ) with open(temp_file_name, "rb") as f: return f.read() except Exception as e: logger.error(f"Failed to save audio to {temp_file_name}: {e}") raise finally: # 可以在这里选择性地清理文件 # if os.path.exists(temp_file_name): # os.remove(temp_file_name) pass ### Running Xinference with Docker? / 是否使用 Docker 运行 Xinfernece? - [ ] docker / docker - [x] pip install / 通过 pip install 安装 - [ ] installation from source / 从源码安装 ### Version info / 版本信息 v:3.0.0 ### The command used to start Xinference / 用以启动 xinference 的命令 @echo off chcp 65001 >nul title Xinference 本地服务端 color 0A set TMPDIR=D:\AI_Tools\Xinference\tmp set TEMP=D:\AI_Tools\Xinference\tmp set TMP=D:\AI_Tools\Xinference\tmp :: 1. 进入工作目录 cd /d D:\AI_Tools\Xinference :: 2. 激活虚拟环境 call xinference_env\Scripts\activate.bat :: 3. 设置 HuggingFace 国内镜像 (加速模型下载) set HF_ENDPOINT=https://hf-mirror.com :: 4. 打印提示信息 echo ========================================================== echo Xinference 正在启动中... 请勿关闭此窗口! echo 启动成功后,请打开浏览器访问: http://127.0.0.1:9997 echo 如需停止服务,请按键盘上的 Ctrl + C echo ========================================================== echo. :: 5. 启动 Xinference xinference-local -H 127.0.0.1 -p 9997 :: 6. 异常退出保护 echo. echo *** 服务已停止,请检查上方报错信息。 *** pause ### Reproduction / 复现过程 在 Windows 系统上安装 Xinference(确保 torchaudio 版本 >= 2.9.0)。 启动 Xinference 并加载一个 TTS 模型(例如 ChatTTS)。 调用 /v1/audio/speech API 请求语音合成。 观察后台日志,会出现 [WinError 32] 另一个程序正在使用此文件 的报错,导致无法正常返回音频。 ### Expected behavior / 期待表现 TTS 请求应该顺利完成,将音频文件转换为字节流并返回给客户端,不抛出任何文件权限/锁定异常。
0 条评论