venvのトップディレクトリにPyTorchの重みファイル(pth)を置いちゃダメって話

横着したらハマったので自戒を込めてメモ。

まとめ

  • Pythonには「サイト固有の設定フック」という機能がある
    • venv環境のトップディレクトリに入っている .pth ファイルを読み込んで処理する
  • PyTorchの学習済み重みファイル(拡張子 .pth)を置いていると上記機能と衝突して誤動作する
    • エラーでpython.exeが実行できなくなる。pipコマンドもエラーで実行できなくなる
  • venv環境と作業ディレクトリはツリーを分けよう(戒め)

サイト固有の設定フック機能

  • venv環境の直下とlib\site-packagesディレクトリに入っている .pth ファイルを読み込むらしい
    • 後述するsite.pyにprint文を埋め込んで上記2ディレクトリが対象になっていることを確認した
  • .pthファイルにはパス名が書かれている前提っぽい

エラーの内容

venvのトップディレクトリ(以下の例だとE:\soft\env_torch直下)に重みファイル(.pth)を置いてからpython.exeを実行しようとすると以下のようなエラーになる。

(env_torch) E:\soft\env_torch>python
Fatal Python error: init_import_size: Failed to import the site module
Python runtime state: initialized
Traceback (most recent call last):
  File "E:\soft\Python38\lib\site.py", line 580, in <module>
    main()
  File "E:\soft\Python38\lib\site.py", line 563, in main
    known_paths = venv(known_paths)
  File "E:\soft\Python38\lib\site.py", line 495, in venv
    addsitepackages(known_paths, [sys.prefix])
  File "E:\soft\Python38\lib\site.py", line 350, in addsitepackages
    addsitedir(sitedir, known_paths)
  File "E:\soft\Python38\lib\site.py", line 208, in addsitedir
    addpackage(sitedir, name, known_paths)
  File "E:\soft\Python38\lib\site.py", line 164, in addpackage
    for n, line in enumerate(f):
UnicodeDecodeError: 'cp932' codec can't decode byte 0x8a in position 2: illegal multibyte sequence

PyTorchの重みファイルはバイナリファイルだが、これをパス名が記載されているテキストファイルとして読み込もうとしてエラーになっているっぽい。

エラーメッセージは文字コード関連のメッセージだが騙されてはいけない。環境変数PYTHONUTF8を設定しても無駄である。

pythonもpipも実行できなくなるので問題のデバッグ自体がつらくなるので注意。今回はsite.pyを直接編集してprint文を埋め込んでデバッグした。

結論

  • venv環境の直下にはPyTorchの重みファイルを置いてはいけない
  • そもそも作業ディレクトリを別ツリーに分けておけば回避できる(横着はよくなかった)

一応.ptファイルなら誤動作しないと思われるが、そこは問題の本質ではないと思う。論文の実装コードで自動ダウンロードが走ったりすることがあるし。