如何在torchaudio中加载bytes类型的WAV音频对象?
问题
我尝试将名为audio的bytes类型对象加载为torchaudio对象,代码如下:
def convert_audio(audio, target_sr: int = 16000): wav, sr = torchaudio.load(audio) #(...) 其他代码
我没找到torchaudio加载bytes音频对象的相关文档,它似乎只支持路径字符串。但我的应用需要节省IO操作,不能写入再读取.wav文件,只能直接处理音频对象。请问这种情况有什么解决办法吗?
直接使用audio时,出现如下错误:
Exception has occurred: AttributeError (note: full exception trace is shown but execution is paused at: _run_module_as_main) 'bytes' object has no attribute 'seek'. You can only torch.load from a file that is seekable. Please pre-load the data into a buffer like io.BytesIO and try to load from it instead. File "/home/felipe/.local/lib/python3.10/site-packages/torch/serialization.py", line 348, in _check_seekable f.seek(f.tell())
使用BytesIO时:
Exception has occurred: UnpicklingError (note: full exception trace is shown but execution is paused at: _run_module_as_main) invalid load key, '\x00'. File "/home/felipe/.local/lib/python3.10/site-packages/torch/serialization.py", line 1002, in _legacy_load magic_number = pickle_module.load(f, **pickle_load_args) File "/home/felipe/.local/lib/python3.10/site-packages/torch/serialization.py", line 795, in load return _legacy_load(opened_file, map_location, pickle_module, **pickle_load_args) File "/home/felipe/Coding projects/silero/stt.py", line 35, in convert_audio wav,sr = torch.load(io.BytesIO(audio)) File "/home/felipe/Coding projects/silero/stt.py", line 60, in transcribe input = prepare_model_input(convert_audio(audio), File "/home/felipe/Coding projects/silero/psgui.py", line 97, in <module> transcripton = stt.transcribe('en',audio) File "/usr/lib/python3.10/runpy.py", line 86, in _run_code exec(code, run_globals) File "/usr/lib/python3.10/runpy.py", line 196, in _run_module_as_main (Current frame) return _run_code(code, main_globals, None,
解决方案
- 核心问题是用错了方法:
torch.load()是用来加载PyTorch序列化的模型或张量文件的,不是处理音频数据的工具。正确做法是用torchaudio.load()配合io.BytesIO包装bytes对象。 - 修正后的代码示例:
import io import torchaudio def convert_audio(audio, target_sr: int = 16000): # 将bytes数据包装成可seek的类文件对象 audio_buffer = io.BytesIO(audio) # 直接用torchaudio加载buffer wav, sr = torchaudio.load(audio_buffer) # 按需重采样到目标采样率 if sr != target_sr: wav = torchaudio.functional.resample(wav, sr, target_sr) return wav, target_sr
- 原理:
torchaudio.load()本身支持传入可seek的类文件对象,把bytes包装成BytesIO后,就满足了读取要求,完全不需要写入本地文件,能节省IO开销。
内容的提问来源于stack exchange,提问作者plshelpmeout
相关产品推荐
相关产品推荐

