Skip to content

fix(onnx): load non-.wav audio paths with librosa instead of pydub - #3865

Merged
LauraGPT merged 1 commit into
modelscope:mainfrom
tanishqbaweja:fix/onnx-non-wav-paths
Nov 10, 2026
Merged

LauraGPT merged 1 commit into
modelscope:mainfrom
tanishqbaweja:fix/onnx-non-wav-paths

Conversation

@tanishqbaweja

Copy link
Copy Markdown
Contributor

Summary

Fixes #3864

In funasr_onnx, load_data sends every path that does not end in .wav through pydub.AudioSegment.from_mp3, exports the result to <name>.wav next to the input and loads that file. #2159 and #2186 added this to Paraformer (inherited by ContextualParaformer and SeacoParaformer), the streaming Paraformer, Fsmn_vad and SenseVoiceSmall.

  • pydub is not a funasr-onnx dependency. On a clean install, every .mp3, .flac or .ogg path raises ModuleNotFoundError: No module named 'pydub', including the en.mp3 of demo_sencevoice_small.py.
  • With pydub but no ffmpeg, the conversion only prints 转换失败:.... The wrapper then raises FileNotFoundError for <name>.wav, a file that was never passed. If a different <name>.wav is in the same folder, it loads that file with no error.
  • With pydub and ffmpeg, from_mp3 forces the MP3 demuxer, so .flac, .ogg and .m4a paths still fail the same way (ffmpeg: Invalid data found when processing input). Only .mp3 converts, and its export overwrites any existing <name>.wav next to the input.

Repro without model files (the full script is in the issue): for a 3 s talk.flac, Paraformer.__new__(Paraformer).load_data("talk.flac", 16000) raises the ModuleNotFoundError. With pydub 0.25.1, no ffmpeg and a 1 s talk.wav in the folder, it returns 16000 samples instead of 48000.

librosa is already a dependency. It reads these formats through soundfile and falls back to audioread for files soundfile cannot open. This PR deletes the conversion (the wrapper diff only removes lines), so these wrappers load every path with librosa.load(path, sr=fs), as funasr_torch and Fsmn_vad_online already do. .wav paths and arrays load as before.

The test, test_onnx_wrappers_read_non_wav_paths in tests/test_runtime_eval_native.py, writes FLAC, OGG and MP3 files with soundfile next to a different 1 s talk.wav. It checks that:

  • the load_data of all six wrappers equals librosa.load(path, sr=16000);
  • the native-fixture Paraformer decodes the path the same way as the loaded waveform;
  • no file in the folder changes.

Formats the installed libsndfile cannot write are skipped. test-runtime-eval.yml already runs this file for funasr_onnx changes.

Type of change

  • Bug fix
  • Documentation
  • Example or demo
  • Runtime or deployment
  • Benchmark or evaluation
  • Model/training change

Validation

Windows 11, CPU, Python 3.11.17 with torch 2.10.0+cpu, numpy 2.4.6, onnx 1.19.0, onnxruntime 1.23.2, librosa 0.11.0 and soundfile 0.14.0 (libsndfile 1.2.2). Neither pydub nor ffmpeg was installed, except where noted: the pydub-and-ffmpeg results above and the .m4a check below used ffmpeg 8.1.3 on PATH.

python -m pytest -q tests/test_runtime_eval_cli.py tests/test_runtime_eval_native.py
  • main (20f26b7) with the new test: 3 failed, 52 passed, all three failures with ModuleNotFoundError: No module named 'pydub'. With pydub 0.25.1 on the path, the same 3 tests fail because load_data returns the 16000 samples of talk.wav.
  • This branch: 55 passed. The new test also passes with pydub on the path.

I also installed funasr-onnx built from this branch into a fresh Python 3.12.15 venv with numpy 1.26.4 and onnxruntime 1.23.2, without torch or pydub:

  • The funasr-onnx package workflow's test scripts pass. On Windows, test_funasr_onnx_release.py needs PYTHONUTF8=1, on main too.

  • The six wrappers' load_data returns librosa.load(path, sr=16000) for FLAC, OGG and MP3 paths. The package built from main raises the ModuleNotFoundError instead.

  • python -m compileall funasr examples tests

  • Docs or links checked

  • Runtime/deployment command tested (above)

black --line-length=100 (24.4.0) leaves the test unchanged, and git diff --check is clean.

User impact

funasr_onnx users can pass .mp3, .flac or .ogg paths without installing pydub and ffmpeg (the SenseVoiceSmall demo's en.mp3, for example). They get the audio of the file they passed, and nothing is written next to it.

Notes for reviewers

load_data in the funasr_onnx Paraformer (inherited by
ContextualParaformer and SeacoParaformer), streaming Paraformer,
Fsmn_vad and SenseVoiceSmall sent every path that does not end in
.wav through pydub.AudioSegment.from_mp3, exported the result to
<stem>.wav next to the input and loaded that file. pydub is not a
funasr-onnx dependency, so on a clean install every .mp3, .flac or
.ogg path raised ModuleNotFoundError: No module named 'pydub', also
for the en.mp3 input of demo_sencevoice_small.py. With pydub but
without ffmpeg, the conversion only printed its exception and the
wrapper then loaded <stem>.wav: a FileNotFoundError for a file that
was never passed or, when a different <stem>.wav sat next to the
input, that recording, without an error.

librosa, already a dependency, reads these formats through soundfile
and falls back to audioread for files libsndfile cannot decode. Drop
the conversion and load every path with librosa.load, as funasr_torch
and Fsmn_vad_online already do.

Extend tests/test_runtime_eval_native.py: for FLAC, OGG and MP3 files
next to a different <stem>.wav, the load_data of each wrapper must
return librosa.load(path, sr=16000), the native-fixture Paraformer
must decode the path like the loaded waveform, and no file in the
directory may change.

@LauraGPT LauraGPT left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Validated exact head a3b21c4ef3485780c389e2eddff789df05f24b84 against base 20f26b7c4905d010768ec91206149df2a90104b6.

  • Baseline with the new regression: 3 failed (FLAC/OGG/MP3, missing pydub); exact head: 55 passed across test_runtime_eval_cli.py and test_runtime_eval_native.py.
  • Real NVIDIA L20Z validation used ONNX Runtime 1.23.2 with CUDAExecutionProvider: the synthetic native fixture produced identical results for the requested FLAC path and its loaded waveform, with 10 CUDA nodes / 0 CPU nodes in the profile. The neighboring same-stem WAV and input bytes were unchanged.
  • Exact-head hosted checks are green: Python 3.11/3.12 and runtime-eval 3.10/3.12.

Scope: synthetic fixture and wrapper/runtime behavior only; no pretrained weights, external network, ASR-quality, Nano, or production-service claim.

@LauraGPT
LauraGPT merged commit 7651777 into modelscope:main Nov 10, 2026
4 checks passed
@LauraGPT LauraGPT mentioned this pull request Nov 11, 2026
LauraGPT added a commit that referenced this pull request Nov 11, 2026
Publish the already accepted #3865 standalone wrapper fixes with hosted regression coverage.

Signed-off-by: LauraGPT <zhifu.gzf@alibaba-inc.com>
LauraGPT added a commit that referenced this pull request Nov 11, 2026
Accept tested standalone package bytes and the already accepted exact-source #3865 runtime evidence.

Signed-off-by: LauraGPT <zhifu.gzf@alibaba-inc.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

funasr_onnx: .mp3/.flac/.ogg paths raise ModuleNotFoundError (pydub) or load a different <name>.wav

2 participants