追記
Poetry 1.5.0 はリリースされました。
がクリティカルなIssueがあり、コードベース修正されているのですがお手元のコードで問題が発生するなら1.5.1 を待つべきでしょう。
問題
現状のPoetry (1.4.2) は特定の使い方をしようとしたときにすごく困る部分がある。
例えば以下のようなpyproject.txt では初回のインストールは 228.9s かかった。
[tool.poetry] name = "test" version = "0.1.0" description = "" authors = ["test <test@gmail.com>"] [tool.poetry.dependencies] python = ">=3.9" torch = { url = "https://download.pytorch.org/whl/cpu/torch-1.8.1%2Bcpu-cp39-cp39-linux_x86_64.whl" } torchvision = { url = "https://download.pytorch.org/whl/cpu/torchvision-0.9.1%2Bcpu-cp39-cp39-linux_x86_64.whl"} onnx_graphsurgeon = { version = "==0.3.16", source = "nvidia" } onnx-simplifier = "==0.3.6" opencv-python = "*" Pillow = "*" pandas = "*" pycocotools = "*" pytest = "*" scikit-learn = "==1.0.1" scipy = "*" [tool.poetry.dev-dependencies] [[tool.poetry.source]] name = "nvidia" url = "https://pypi.ngc.nvidia.com" default = false secondary = true [build-system] requires = ["poetry-core>=1.0.0"] build-backend = "poetry.core.masonry.api"
ちなみに同じような記述をした requirements.txt を pip
でインストールしようとするとインストール時間を含めて 40s くらいで終わる(上の時間はバージョン解決のみ)。
上の pyproject.toml が遅いのは種があって、NVIDIAが公開している pypi レポジトリを追加しているところがミソ。
NVIDIAのpypiのようにpypi.org以外のpypiレポジトリを追加した場合、Poetryのバージョン依存解決が非常に遅くなることが知られている。
ちなみにlockファイルが作られた後はバージョン解決はすでに終わっているので今回の話は関係がなく、高速に動作するハズ。
原因は default=false
で指定したpypiレポジトリにもパッケージの探索のためにpypi.orgにしかないパッケージも都度存在するかどうか問い合わせてしまう、というもの。
poetry install -vvv
実行してみると問い合わせしたログが表示される。
ログの一部抜粋
.... [urllib3.connectionpool] Starting new HTTPS connection (1): developer.download.nvidia.com:443 [urllib3.connectionpool] https://developer.download.nvidia.com:443 "GET /compute/redist/scipy/ HTTP/1.1" 404 433 Source (nvidia): No packages found for scipy Source (nvidia): 0 packages found for scipy * Source (PyPI): 1 packages found for scikit-learn 1.0.1 [urllib3.connectionpool] https://developer.download.nvidia.com:443 "GET /compute/redist/scikit-learn/ HTTP/1.1" 404 433 Source (nvidia): No packages found for scikit-learn Source (nvidia): 0 packages found for scikit-learn 1.0.1 Source (PyPI): 158 packages found for pytest * [urllib3.connectionpool] https://developer.download.nvidia.com:443 "GET /compute/redist/pytest/ HTTP/1.1" 404 433 Source (nvidia): No packages found for pytest Source (nvidia): 0 packages found for pytest * Source (PyPI): 7 packages found for pycocotools * [urllib3.connectionpool] https://developer.download.nvidia.com:443 "GET /compute/redist/pycocotools/ HTTP/1.1" 404 433 Source (nvidia): No packages found for pycocotools Source (nvidia): 0 packages found for pycocotools * Source (PyPI): 93 packages found for pandas * ...
ちなみにNVIDIAのpypiにしかないonnx_graphsurgeonをpyproject.tomlから削除すると削除すると、 依存解決のかかる時間は 6.9s まで短くなる!
解決策
Poetry 1.5 を待つ
Poetry 1.5では sourceに対して secondary
フィールドはDeprecatedになり、 supplemental
なsourceを追加できるようになる。
supplemental
に指定されたsourceは特定のPackageをインストールしようとするときにだけ使用されるようになるため、↑の問題は解決される(ハズ)。
追記
現状のmasterの1.5dev0 Candidateをビルドして使ってみると、依存解決は 10.4s で終わった。ハヤイ! sourceの記述を以下のように変更する
[[tool.poetry.source]] name = "nvidia" url = "https://pypi.ngc.nvidia.com" priority = "supplemental"
poetry-private-repo-plugin を使う
このプラグインを使うと、特定のパッケージの探索に特定のsourceだけを使うことを強制できる。
Poetry 1.5を待てねぇ!という人はこちらを利用するしかないと思う。
その他
他にも1.5でダウンロード済みのはずのwhlを何回もダウンロードしてしまう問題が解決されるはずで、poetry install
がより高速になることが期待できる。
何回もバージョン依存解決しないとはいえ、、、高速な方がうれしいヨネ?
エコシステムとしてのPythonは高速に依存解決を行うにはsetup.pyが不利になっている。
setup.py の中に依存ライブラリが記述されることになっている && setup.pyは当然スクリプトで動的に依存ライブラリ部分を買えるかもしれないので、setup.pyを実行してみないと依存ライブラリが何なのかわからない。
僕もよくわかっていないこと:metadataをつかえばこれをダウンロードするだけで依存ライブラリがわかるはずだけど、まだそこまで使われてない? METADATAの仕様としてPEP658があるはずなのだけど。