PipenvでPytorchをインストールするときにPipfile.lockを生成する【python】

#概要
`pipenv`で`PyTorch`をインストールするとき、普通にやると`Pipfile.lock`の生成に失敗するので、回避策を調べました。
#環境

```
% sw_vers
ProductName:	macOS
ProductVersion:	11.5.2

% pipenv --version
pipenv, version 2021.5.29
jiro@JiroMBA gpt2test % 
```

#問題
`pipenv`で`PyTorch`（cpuバージョン）をインストールしてみます。


```
mkdir test
cd test
pipenv --python 3.9.6
pipenv install torch torchvision torchaudio
```

以下のようなエラーメッセージが表示され、`Pipfile.lock`の生成に失敗します。

```
Pipfile.lock not found, creating...
Locking [dev-packages] dependencies...
Locking [packages] dependencies...
Building requirements...
Resolving dependencies...
✘ Locking Failed! 
[ResolutionFailure]:   File "/Users/jiro/.pyenv/versions/3.8.6/lib/python3.8/site-packages/pipenv/resolver.py", line 741, in _main
[ResolutionFailure]:       resolve_packages(pre, clear, verbose, system, write, requirements_dir, packages, dev)
[ResolutionFailure]:   File "/Users/jiro/.pyenv/versions/3.8.6/lib/python3.8/site-packages/pipenv/resolver.py", line 702, in resolve_packages
[ResolutionFailure]:       results, resolver = resolve(
[ResolutionFailure]:   File "/Users/jiro/.pyenv/versions/3.8.6/lib/python3.8/site-packages/pipenv/resolver.py", line 684, in resolve
[ResolutionFailure]:       return resolve_deps(
[ResolutionFailure]:   File "/Users/jiro/.pyenv/versions/3.8.6/lib/python3.8/site-packages/pipenv/utils.py", line 1397, in resolve_deps
[ResolutionFailure]:       results, hashes, markers_lookup, resolver, skipped = actually_resolve_deps(
[ResolutionFailure]:   File "/Users/jiro/.pyenv/versions/3.8.6/lib/python3.8/site-packages/pipenv/utils.py", line 1110, in actually_resolve_deps
[ResolutionFailure]:       resolver.resolve()
[ResolutionFailure]:   File "/Users/jiro/.pyenv/versions/3.8.6/lib/python3.8/site-packages/pipenv/utils.py", line 835, in resolve
[ResolutionFailure]:       raise ResolutionFailure(message=str(e))
[pipenv.exceptions.ResolutionFailure]: Warning: Your dependencies could not be resolved. You likely have a mismatch in your sub-dependencies.
  First try clearing your dependency cache with $ pipenv lock --clear, then try the original command again.
 Alternatively, you can use $ pipenv install --skip-lock to bypass this mechanism, then run $ pipenv graph to inspect the situation.
  Hint: try $ pipenv lock --pre if it is a pre-release dependency.
ERROR: Could not find a version that matches torchaudio (from -r /var/folders/qz/d2c_grsx75x9b2k6ddzdzm400000gn/T/pipenvc6ijypsfrequirements/pipenv-jjm_60mg-constraints.txt (line 2))
No versions found
Was https://pypi.org/simple reachable?
```

なお、`list`を見ると、インストール自体は成功しているようです。

```
% pipenv run pip list
Package           Version
----------------- --------
numpy             1.21.2
Pillow            8.3.2
pip               21.2.4
setuptools        58.0.4
torch             1.9.1
torchaudio        0.9.1
torchvision       0.10.1
typing-extensions 3.10.0.2
wheel             0.37.0
```

サンプルコードの実行も可能です。

```Python:test.py
import torch
x = torch.rand(5, 3)
print(x)
```

```
pipenv run python test.py 
tensor([[0.0173, 0.9192, 0.5948],
        [0.0191, 0.2524, 0.0639],
        [0.3142, 0.1915, 0.7991],
        [0.7958, 0.7331, 0.0553],
        [0.0725, 0.1236, 0.4415]])
```

したがって使えないということはないのですが、`Pipfile.lock`の生成ができないと困る場面もあるかもしれませんし、他のライブラリを追加するたびに同様のエラーが出続けて煩わしいです。
回避策を探します。

#解決方法
[stack overflow](https://stackoverflow.com/questions/63974588/how-to-install-pytorch-with-pipenv-and-save-it-to-pipfile-and-pipfile-lock)で同じ質問をしている方がいました。

1人目のアンサーにある、`.whl`を直接DLするようにPIpfileに情報を追記する方法で解決できました。

`.whl`のDLリンクは以下から探せます。
https://download.pytorch.org/whl/torch_stable.html

今回の場合、普通に`pipenv install`すると以下がインストールされていましたので、これに対応する`.whl`を探します。

```
torch             1.9.1
torchaudio        0.9.1
torchvision       0.10.1
```

上記のバージョン情報と、`macos`, `x86_64`が含まれている`.whl`を探します。
`cpXX` (XXは二桁の数字）はなるべく数字の大きいもの（2021/10/12時点ではcp39）を選んだらうまくいきました。

Pipfileを編集（または作成）します。

```
% cat Pipfile
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]
torch = {version = "==1.9.1", file = "https://download.pytorch.org/whl/cpu/torch-1.9.1-cp39-none-macosx_10_9_x86_64.whl"}
torchvision = {version = "==0.10.1", file = "https://download.pytorch.org/whl/torchvision-0.10.1-cp39-cp39-macosx_10_9_x86_64.whl"}
torchaudio = {version = "==0.9.1", file = "https://download.pytorch.org/whl/torchaudio-0.9.1-cp39-cp39-macosx_10_9_x86_64.whl"}
pyperclip = "*"

[dev-packages]

[requires]
python_version = "3.9"
```
Pipfileに基づきインストールすると、Pipfle.lockの生成に成功します。

```
% pipenv install
```

途中経過を見たい場合、以下のようにします。

```
% pipenv install --verbose
```

#参考
https://pytorch.org/get-started/locally/
https://self-development.info/pytorch%e3%81%ae%e7%b0%a1%e5%8d%98%e9%81%8e%e3%81%8e%e3%82%8b%e3%82%a4%e3%83%b3%e3%82%b9%e3%83%88%e3%83%bc%e3%83%ab%e3%80%90python%e3%81%a7%e6%a9%9f%e6%a2%b0%e5%ad%a6%e7%bf%92%e3%80%91/