pytorch / audio

Data manipulation and transformation for audio signal processing, powered by PyTorch
https://pytorch.org/audio
BSD 2-Clause "Simplified" License
2.55k stars 655 forks source link

PyInstaller and torchaudio leads to RuntimeError on Windows #2470

Closed Aztorius closed 2 years ago

Aztorius commented 2 years ago

🐛 Describe the bug

When running this sample on Windows :

import torch
data = torch.hub.load(repo_or_dir='snakers4/silero-vad', model='silero_vad')

It doesn't work on Windows after PyInstaller. The error is :

Using cache found in C:\Users\xxx/.cache\torch\hub\snakers4_silero-vad_master
Traceback (most recent call last):
  File "test_torchaudio.py", line 2, in <module>
  File "torch\hub.py", line 404, in load
    model = _load_local(repo_or_dir, model, *args, **kwargs)
  File "torch\hub.py", line 430, in _load_local
    hub_module = _import_module(MODULE_HUBCONF, hubconf_path)
  File "torch\hub.py", line 76, in _import_module
    spec.loader.exec_module(module)
  File "<frozen importlib._bootstrap_external>", line 850, in exec_module
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "C:\Users\xxx/.cache\torch\hub\snakers4_silero-vad_master\hubconf.py", line 4, in <module>
    from utils_vad import (init_jit_model,
  File "C:\Users\xxx/.cache\torch\hub\snakers4_silero-vad_master\utils_vad.py", line 2, in <module>
    import torchaudio
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
  File "PyInstaller\loader\pyimod03_importers.py", line 495, in exec_module
  File "torchaudio\__init__.py", line 2, in <module>
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
  File "PyInstaller\loader\pyimod03_importers.py", line 495, in exec_module
  File "torchaudio\functional\__init__.py", line 25, in <module>
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
  File "PyInstaller\loader\pyimod03_importers.py", line 495, in exec_module
  File "torchaudio\functional\functional.py", line 1146, in <module>
  File "torchaudio\_internal\module_utils.py", line 133, in requires_sox
  File "torchaudio\_internal\module_utils.py", line 129, in is_sox_available
  File "torch\_ops.py", line 167, in __getattr__
    op = torch._C._jit_get_operation(qualified_op_name)
RuntimeError: No such operator torchaudio::is_sox_available
[8228] Failed to execute script 'test_torchaudio' due to unhandled exception!

Maybe PyInstaller execute the torchaudio decorator @_mod_utils.requires_sox(). This obviously causes a crash on Windows because of the missing sox backend.

Before using PyInstaller (by running the .py file directly) it works without any issue.

Versions

Collecting environment information... PyTorch version: 1.11.0+cpu Is debug build: False CUDA used to build PyTorch: None ROCM used to build PyTorch: N/A

OS: Microsoft Windows 10 Professionnel GCC version: Could not collect Clang version: Could not collect CMake version: Could not collect Libc version: N/A

Python version: 3.9.12 (tags/v3.9.12:b28265d, Mar 23 2022, 23:52:46) [MSC v.1929 64 bit (AMD64)] (64-bit runtime) Python platform: Windows-10-10.0.19044-SP0 Is CUDA available: False CUDA runtime version: No CUDA GPU models and configuration: No CUDA Nvidia driver version: No CUDA cuDNN version: No CUDA HIP runtime version: N/A MIOpen runtime version: N/A Is XNNPACK available: True

Versions of relevant libraries: [pip3] numpy==1.22.1 [pip3] torch==1.11.0 [pip3] torchaudio==0.11.0 [conda] Could not collect

mthrok commented 2 years ago

Hi @Aztorius

I have never used PyInstaller, but I think it's related to the fact that C++ libraries is not packaged properly.

I think you need something similar to https://stackoverflow.com/a/47528057 Checkout torchaudio/lib directory of your installation (not source). You should see C++ library files there. The combination of the files found there differs from distributions from distributions. Then add the files to the hook.

Aztorius commented 2 years ago

I'm running some tests. The folder tochaudio/lib is empty in my installation folder (pip site-packages). I just found those warnings when running pyinstaller :

2234 WARNING: lib not found: c10.dll dependency of C:\Users\xxx\AppData\Local\Programs\Python\Python39\lib\site-packages\torchaudio\_torchaudio.pyd
2234 WARNING: lib not found: torch_cpu.dll dependency of C:\Users\xxx\AppData\Local\Programs\Python\Python39\lib\site-packages\torchaudio\_torchaudio.pyd
2406 WARNING: lib not found: torch_python.dll dependency of C:\Users\xxx\AppData\Local\Programs\Python\Python39\lib\site-packages\torch\_C.cp39-win_amd64.pyd

Those dlls are inside torch/lib folder. I'm trying to include them with hooks with no success so far.

mthrok commented 2 years ago

There are couple of conflicting observations I am making;

  1. A sane package installation contain both torchaudio/lib/libtorchaudio and torchaudio/_torchaudio. According to the output of your collect_env, the package you are using is torchaudio-0.11.0-cp39-cp39-win_amd64.whl, and I checked that the package contains both torchaudio/_torchaudio.pyd and torchaudio/lib/libtorchaudio.pyd, so if it is installed properly, libtorchaudio.pyd should exist.
  2. requires_sox decorator function is designed to work without sox backend, and it assumes both torchaudio/lib/libtorchaudio and torchaudio/_torchaudio exist or neither. The reason why requires_sox is failing with No such operator torchaudio::is_sox_available is because _torchaudio.pyd exists but libtorchaudio.pyd does not. In this case libtorchaudio.pyd was not dlopen-ed. This happens if libtorchaudio.pyd does not exist. (Which is the original issue for PyInstaller) But you mentioned that it works fine without PyInstaller. So I expected that libtorchaudio.pyd exists in your package install, but The folder tochaudio/lib is empty. In this case, I'd expect that the same issue would happen for pip installation.

In your PIP installation, what would happen if you try import torchaudio._torchaudio?

Aztorius commented 2 years ago

Ok, so let me recap. In my pip installed torchaudio package :

After using pyinstaller :

I suppose that I am missing the torchaudio/lib/libtorchaudio.pyd. I will try to include it with a hook. So you are right assuming that requires_sox is failing because of the missing libtorchaudio.pyd.

Aztorius commented 2 years ago

Ok, just tried to manually copy the missing lib/libtorchaudio.pyd and now it is working.

Aztorius commented 2 years ago

One working solution is to add torchaudio.lib.libtorchaudio as a hidden import to pyinstaller. It should be possible to include this in the torchaudio package for future pyinstaller users. Thank you for the help.

mthrok commented 2 years ago

Grad that it helps.