[Python]LightGBMを使おうとしたら、WinError126が出て困った話
タイトルにはPythonと付けたけど、ほぼWindowsのお話。
起きたこと
機械学習でもやってみるかーってVS Code入れて、Python用拡張機能入れて…
ただ、ちょっと僕の環境はVisual Studio 2019も入ってて、そっちのPython環境を汚したくないなって思ったんで、venvを作ってそこにpip install jupyter
、pip install lightgbm
を行って環境を作りました。
さぁ、次はPythonのコード書いて実行をしたわけですけど、すぐに
「[WinError 126] 指定されたモジュールが見つかりません。」
で止まってしまいました。はい。
これの解決方法がこの記事の趣旨です。
具体的には以下のようなスタックトレースが出力されました。
Z:\TEMP\ipykernel_11536\4041817684.py in <module>
1 import numpy as np
2 import pandas as pd
----> 3 import lightgbm as lgb
4
5 import warnings
d:\VSCode\Python\testj\.venv\lib\site-packages\lightgbm\__init__.py in <module>
6 from pathlib import Path
7
----> 8 from .basic import Booster, Dataset, Sequence, register_logger
9 from .callback import early_stopping, log_evaluation, print_evaluation, record_evaluation, reset_parameter
10 from .engine import CVBooster, cv, train
d:\VSCode\Python\testj\.venv\lib\site-packages\lightgbm\basic.py in <module>
108
109
--> 110 _LIB = _load_lib()
111
112
d:\VSCode\Python\testj\.venv\lib\site-packages\lightgbm\basic.py in _load_lib()
99 if len(lib_path) == 0:
100 return None
--> 101 lib = ctypes.cdll.LoadLibrary(lib_path[0])
102 lib.LGBM_GetLastError.restype = ctypes.c_char_p
103 callback = ctypes.CFUNCTYPE(None, ctypes.c_char_p)
C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\lib\ctypes\__init__.py in LoadLibrary(self, name)
440
441 def LoadLibrary(self, name):
--> 442 return self._dlltype(name)
443
444 cdll = LibraryLoader(CDLL)
C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\lib\ctypes\__init__.py in __init__(self, name, mode, handle, use_errno, use_last_error)
362
363 if handle is None:
--> 364 self._handle = _dlopen(self._name, mode)
365 else:
366 self._handle = handle
OSError: [WinError 126] 指定されたモジュールが見つかりません。
環境
- Windows 7 64bit
- Visual Studio Code
- Python 3.7.5
- venv
- Jupyter Notebook
- LightGBM
エラーの原因
結論から言うと、pip install lightgbm
でインストールされたlib_lightgbm.dllの動作に必要な依存関係のDLLが、僕のマシンに無いので出てます。
解決方法
どうやらpip installで入れたLightGBMは「Microsoft Visual C++ 2015 再頒布可能パッケージ」が動作に必要なんですね。(2022年1月時点)
方法A 「Microsoft Visual C++ 2015 再頒布可能パッケージ」をインストールする
よって、Microsoftダウンロードセンターへ行き、上記のパッケージを検索して出てきたやつをインストールしましょう。(32bit用と64bit用がありますが、この際両方入れておいていいです。)
これで問題が解決したなら方法Bはやらなくてかまいません。
方法B LightGBMのGitHubへ行き、別のlib_lightgbm.dllをダウンロードして入れ替える
まあ、上記の方法で解決するならわざわざ記事は作らなかったんですが、たまたま僕のマシンはVisual Studio 2019等々が入っていたため、「Visual Studio 2015、2017、2019 用 Microsoft Visual C++ 再頒布可能パッケージ」が既にインストールされていました。
すると、なんと「Microsoft Visual C++ 2015 再頒布可能パッケージ」はインストールできません。(じゃあ、何でDLL足りねーんだよ!)
その場合は、GitHubのLightGBMのページへ行き、右側にあるReleasesページへ飛んで、lib_lightgbm.dllをダウンロードしましょう。おっと、pip installで入れたバージョンと同じやつにしましょう。忘れた場合はpip list
で見れます。
後は先ほどのスタックトレースで表示されたLightGBMのインストール場所に行くと、lib_lightgbm.dllがあるので、ダウンロードしてきたDLLと入れ替えます。
僕の場合は以下の場所になります。
d:\VSCode\Python\testj\.venv\lib\site-packages\lightgbm\
終わり
いかがでしたか?エラーは出なくなったでしょうか?
まあ世の中どんぴしゃの同じ原因もあれば、ちょっと自分の問題とは違うな…なんてことありますよね。
だから、この先に付録としてエラーを解決するために行った調査の軌跡を載せておきます。
付録1 最初に調べること
まずはエラーの文言でググりますよね「lightgbm WinError 126」などで検索しました。
すると、stackoverflowで同じようなエラーで困っている人がいました。解決策は「vcomp140.dllを入れろ」と…こういう時、vcomp140.dllへのLinkが貼られていますが、素性の知れないDLLをダウンロードして入れるのは止めましょう。(ダメ、絶対)
vcomp140.dllについて調べてみると、「Microsoft Visual C++ 2015 再頒布可能パッケージ」の一部だとわかりました。
ただ、僕の場合は「もう入れてあったような気がするけど…」と思うわけですが、一応確認しました。
- コントロールパネルを開き、「プログラムと機能」からインストールされているソフトの一覧を表示して確認しました。
→あった。ちょっと名前は「2015-2019 再頒布可能パッケージ」になっているけど。 - 同時にC\Windows以下を「vcomp140.dll」で検索しました。
→あった。(system32以下に1つ、SysWOW64以下に1つ。つまり、32bit用と64bit用です)
付録2 環境変数PATHの確認
どうやら「DLLはあるけど動かない」雰囲気がしますね。
なので次は環境変数PATHの確認をしました。確かに、実行環境はvenvの仮想環境下にあり、Jupyter Notebookです。もしかしたら、上手くWindowsのDLLを探せてないのかもしれません。
次のコードを問題のエラーが出るコードの先頭に追加するか、別のJupyterのセルに書き実行しました。
import os
print(os.getenv('PATH'))
すると、以下を得ました。
d:\VSCode\Python\testj\.venv\lib\site-packages\pywin32_system32;D:\VSCode\Python\testj\.venv\lib\site-packages\pywin32_system32;D:\VSCode\Python\testj\.venv\Scripts;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files\dotnet\;d:\VSCode\Python\testj\.venv\lib\site-packages\numpy\.libs;d:\VSCode\Python\testj\.venv\lib\site-packages\scipy\.libs
横にクソ長くてすいません。でもこれは僕のマシンの結果なので、詳しく見る必要はないです。
それで、先ほど調べたvcomp140.dllの場所「C:\Windows\system32」が上記に含まれているか、確認しました。
→あった。
付録3 lib_lightgbm.dllの依存関係を調べる
どうやら、環境変数に問題はないようです。でも、動きません。
さらに情報を集めるうちに、LightGBMの本体は「lib_lightgbm.dll」というDLLだとわかりました。
確かに、venvがある場所を検索するとlib_lightgbm.dllがありました。
なるほど、こいつが動かないのか?
であれば、DependenciesというソフトでDLLの依存関係を調べましょう。GitHubのDependenciesのページ
DependenciesGui.exeを起動し、問題のlib_lightgbm.dllをD&Dします。
すると、?マークが付いたDLLが(たまたま僕のマシンでは2つ)ありました。
- api-ms-win-core-winrt-l1-1-0.dll
- api-ms-win-core-winrt-string-l1-1-0.dll
おっ、足りないDLLがはっきりしたようですね。vcomp140.dllも必要だと表示されていますが、それはあるので?マークは付いていません。
足りない2つのDLLについて調べてみると、どちらも「Microsoft Visual C++ 2015 再頒布可能パッケージ」に含まれるようです。
「堂々巡りやめろ!!」
また、同じ原因に戻って来ちゃったわけですが、「api-ms-win-core-winrt-l1-1-0.dll」を僕のマシンで探してみると、確かにありません。とすると、少なくとも動かない原因ははっきりしました。
付録4 2015年って古くないか?
lib_lightgbm.dllに必要なDLLが無いから動かない。
でも、必要なDLLちょっと古くないか?もっと、最新のビルドであれば「Microsoft Visual C++ 2015 再頒布可能パッケージ」を要求してこないのでは?ということに気づき、調査中に見つけたGitHubのLightGBMのページを思い出したわけです。
そこにあるlib_lightgbm.dllの依存関係を調べると、上記の2つのDLLは必要なくなっています。他に?マークもありません。これはもしかして…動く?
こうして見つかったのが方法Bでした。いやー参ったね。
なんで「Microsoft Visual C++ 2015 再頒布可能パッケージ」にあったファイルが、
「Visual Studio 2015、2017、2019 用 Microsoft Visual C++ 再頒布可能パッケージ」に無いのか…
まあ僕の環境が変だったというオチかもしれません。
この記事が誰かの助けになればと思って書きました。
Discussion