Pytorch+CUDAをpipenv環境にて構築する手順（Windows11での例）

# 今回のポイント
:::note info
pipではなく、pipenvを使う場合、PyTorchのインストールコマンドを少し修正する必要があるが、修正のポイントを明示する。
* [o]```pipenv install ... --index <URL>``` --- これを使うこと
* [x]```pipenv install ... --extra-index-url <URL>``` --- セキュリティリスクのために利用できなくなっている
* [x]```pipenv install ... --index-url <URL>``` --- こちらも利用できず、エラーになる

Windows11での例を提示するが、基本Linuxでも同じ（WSL2のUbuntuでも同じ）
ネット上で検索すると古い書式で実行しようとして躓いている記事が散見されるし、ChatGPT等の生成AIも間違えて教えてくれるので、厄介。
※**2022年3月23日にセキュリティリスクのために変更された**とあり、当方では2023年10月の時点でインストール方法が変化したことを確認している。
* Specifying Package Indexes
https://pipenv.pypa.io/en/latest/indexes.html

* GUIDE: How to install PyTorch via Pipenv (and how to add other 3rd Party Repositories). #4961
https://github.com/pypa/pipenv/issues/4961
※上記URLの2022/08/25の記事以降に記載されています。
:::

:::note info
Pipenvでの仮想環境の入った[.venv]フォルダを仮想環境フォルダ内に設置する方法も併記した。
:::

:::note info
VS-Codeにて特定フォルダ内のJupyter-notebook形式（.ipynb）実行環境を、特定の[.venv]仮想環境に固定したい場合のメモを追記した。[2025/02/12]
:::

# 前準備
1. GPUのドライバを最新版にしておく
https://www.nvidia.com/ja-jp/drivers/
2. 搭載されているGPUに応じて制約を確認する
https://developer.nvidia.com/cuda-gpus
3. ドライバのバージョンにて利用可能なCUDAのバージョンをチェックする。
https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html
4. Pythonのインストール（インストールされていない場合）
https://www.python.org/
:::note warn
※初回のインストールの場合「**Add Python *** to PATH**」にチェックを入れてインストールすること！！
:::

# Pipenv関連の設定
## 1. pipのアップグレード
``` DOS:Windows
python -m pip install --upgrade pip
```
※Linuxの場合
``` console:Linux
python3 -m pip install --upgrade pip
```
    
## 2. 初めてPipenvを使う場合
### 2-1. pipenvのインストール
``` console:Windows/Linux
pip install pipenv
```
### 2-2. pipenvの環境変数設定
環境変数「PIPENV_VENV_IN_PROJECT」を「True」に設定
> **設定変更手順**
>【Windowsスタート・右クリック】→【システム】
>→（画面内）【システムの詳細設定】
>→【システムのプロパティ】ダイアログ表示
>→（右下）【環境変数...】
>→【環境変数】ダイアログ表示
>→【システム環境変数】→【新規...】にて
>変数名： **PIPENV_VENV_IN_PROJECT**
>変数値*： **True**
>と設定する。
>> *boolean属性なのでTrueの代わりに、**true**, **yes**, **1** ないし **on** でも良い。設定解除は **false**, **no**, **0**, ないし **off** になる
>>[参考：PIPENV_VENV_IN_PROJECTの設定詳細](https://pipenv.pypa.io/en/stable/configuration.html?highlight=PIPENV_VENV_IN_PROJECT#pipenv.environments.Setting.PIPENV_VENV_IN_PROJECT)
   
![pipenv-1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504878/026364ae-23e2-f7e2-0a1f-3089a12ad319.jpeg)

:::note warn
※既にpipenvを使っていて「Pipfile」および「.venv」が「c:/users/[利用者]/」直下に存在する場合には、無理に切り換えないこと。

<details><summary>どうしても切り換えたい場合</summary>

1. 「c:/users/[利用者]/Pipfile」を<b>利用中の仮想環境フォルダ</b>内にコピー
1. ```pipenv --rm```で切替前の仮想環境を削除
1. 「c:/users/[利用者]/Pipfile」を削除（※）
1. 下記手順で「PIPENV_VENV_IN_PROJECT」環境変数を設定（ないし変更）して切替
1. 切替後、<b>利用中の仮想環境フォルダ</b>に入り```pipenv install```を実行すればコピーしておいた「Pipfile」の設定に従って「.venv」が<b>利用中の仮想環境フォルダ</b>に再構築される。
[※削除しないと落とし穴にはまります]
<a href="https://zenn.dev/enven/scraps/2ee85d47a33916">pipenvでプロジェクトを初期作成しようとするとあらぬところにvenvフォルダが生成される.</a>
[※仮想環境がどこにあるか不明な場合は下記を参照のこと]
<a href="https://zenn.dev/shimo_s3/articles/6a0a2901454bd0">[小ネタ]pipenvのvenvとPipfileの対応を確認して不要なものを消したい</a>
</details>
:::

## 3. pipenvのアップグレード（2回目以降にPipenvを使う場合）
``` console:Windows/Linux
pip install -U pipenv
```
## 4. 切り換えたいPythonのインストール
https://www.python.org/
切り換えたいPythonは予めWindowsにインストールしておく。
※Linuxの場合<b>pyenv</b>等で切り換えたいバージョンのPythonをインストールしておく。

:::note warn
**最新のPythonを（追加）インストールする場合**、パスを環境変数へ追加するように設定しておく必要がある。
<details><summary>設定関連の詳細</summary>

* インストール時に【**Add Python *** to PATH**】にチェックを入れる（オプション指定時であれば【**add python to environment variables**】にチェックを入れる）
* インストール後に「修正インストール」で後から修正も可能。
</details>
:::
:::note warn
**以前の（インストール済みよりも古い）バージョンを追加インストールする場合**、パスを環境変数へは追加しない。
<details><summary>設定関連の詳細</summary>

* 【**Add Python *** to PATH**】のチェックは外しておく
* オプション指定時であれば【**add python to environment variables**】のチェックは外しておく
※仮想環境外では「py」コマンド(py.exe)で起動するpythonを切り換えることができるが、pathの設定を変えるものではない。
[参考]
https://qiita.com/landwarrior/items/1b5e0f9af5316a025fe0
https://qiita.com/mkgask/items/d741578efb13aac7db0e
</details>
:::
## 5. Pipenv --python [バージョン]　にて仮想環境構築
仮想環境を構築するフォルダを新たに作成し、該当フォルダに移動し、構築用コマンドを実行する。
Python 3.12.*** を使う仮想環境を構築したい場合、
``` console:Windows/Linux
mkdir [仮想環境構築用ディレクトリ名]
cd [仮想環境構築用ディレクトリ名]
pipenv --python 3.12
```
# PyTorchのインストール
PyTorchのサイトにて自身の環境に合うインストールコマンドを入手する。
※WSL2でのUbuntuの場合にはOSに【Linux】を指定する。
https://pytorch.org/get-started/locally/
``` :PyTorch環境の選択
PyTorch Build: 【Stable(***)】
YourOS: 【Windows】
Package: 【Pip】
Language: 【Python】
Compute Platform: 【CUDA ***】←　自身の環境に応じたバージョン、ないしCPUを選択
```
![pipenv-pytorch.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504878/b83d1b95-6a9f-3f97-d263-40fc9ff46058.jpeg)

::: note info
上記にて表示される【Run this Command】の **「pip3」を「pipenv」に変更し、さらに「-url」を削除したコマンド** を実行する。（urlが入らない形式の場合、「pip3」を「pipenv」に修正するだけで良い）
:::

``` console:Windows/Linux
例 
[修正前]
pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118

[修正後]
pipenv install torch torchvision torchaudio --index https://download.pytorch.org/whl/cu118
```
※Pytorchの場合、システムにインストールされているCUDAとは無関係に上記のコマンドで指定されたCUDAが仮想環境内にインストールされ、自動的に切り替わってくれる。

※インストール時の画面（例）

![pipenv-pytorch2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504878/a492f4c8-5714-6d55-a0bd-3ed3ba7cb0c4.jpeg)


# 仮想環境構築後のテスト
構築した仮想環境に入る。
``` console:Windwos/Linux
cd [構築した仮想環境のフォルダ]
pipenv shell
```
下記を実行する。

``` python:cuda_check.py
import torch

cuda_is_available = torch.cuda.is_available()

print(f'torch_version = {torch.__version__}')
print(f'cuda_available = {cuda_is_available}')
if cuda_is_available:
    print(f'cuda_device_count = {torch.cuda.device_count()}')
    print(f'cuda_GPU_Num = {torch.cuda.current_device()}')
    print(f'GPU_Name = {torch.cuda.get_device_name()}')
    print(f'GPU_Compute_Capability = {torch.cuda.get_device_capability()}')
```
``` console:Windows/Linux
python cuda_check.py
```
実行例
※PythonおよびCUDAの異なるバージョンを構築した場合の例
``` console:テスト例
PS:tc241p311cu118 > pipenv shell
Launching subshell in virtual environment...
PowerShell 7.4.5
[venv]PS:tc241p311cu118 > python cuda_check.py
torch_version = 2.4.1+cu118
cuda_available = True
cuda_device_count = 1
cuda_GPU_Num = 0
GPU_Name = NVIDIA GeForce RTX 3090
GPU_Compute_Capability = (8, 6)
[venv]PS:tc241p311cu118 > exit
PS:tc241p311cu118 > cd ..\tc241p312\
PS:tc241p312 > pipenv shell
Launching subshell in virtual environment...
PowerShell 7.4.5
[venv]PS:tc241p312 > python cuda_check.py
torch_version = 2.4.1+cu121
cuda_available = True
cuda_device_count = 1
cuda_GPU_Num = 0
GPU_Name = NVIDIA GeForce RTX 3090
GPU_Compute_Capability = (8, 6)
[venv]PS:tc241p312 >
```

# VS-Codeにて特定フォルダ内のJupyter-notebook形式（.ipynb）実行環境を、特定の[.venv]仮想環境に固定したい場合```.venv```へのジャンクションを利用する

Jupyter-notebook形式（.ipynb）のpythonプログラムが入った特定フォルダの仮想環境を固定して使いたい場合がある。
その場合、上記で作成した```.venv```フォルダへのジャンクション（ソフトリンク）を目的とするフォルダ内に埋め込み、目的フォルダをVS-Codeで開くことで、仮想環境設定を非常に楽に行える。
VS-Codeで動作確認していて、不足するライブラリでエラーが発生すれば、Windows Terminal等のコマンドウィンドウから```pipenv install [ライブラリ]```を実行し、VS-Codeの該当セルを再度実行するだけである。インストールのためにわざわざエディタを閉じたり、動作途中のコードを閉じることなく、シームレスにテストを行うことができる。

``` doc:Junction設定例（PowerShellの場合、ターゲットフォルダ内で）
cmd /c mklink /j .venv [仮想環境名]\.venv\
```

``` doc:Junction設定例（コマンドプロンプトの場合、ターゲットフォルダ内で）
mklink /j .venv [仮想環境名]\.venv\
```
:::note warn
```.venv```ジャンクション（ソフトリンク）の入ったディレクトリ内で、pipenv関連コマンドは実行しないこと。
自動的に```pipfile```が作られてしまいます。
ジャンクション元（ソフトリンク元）の```.venv```と```Pipfile```,```Pipfile.lock```は変更されない様ですが、注意して下さい。
:::

# pipenv仮想環境のセキュリティチェック
インストール前にはライブラリが正規のものか、インストール後にはライブラリの脆弱性を確認すること。

``` doc:脆弱性チェック
pipenv check
```
オプション類については下記を参照

https://fig.io/manual/pipenv/check
=== 2025/02/12 16:47 追記 ===
python 3.12.7, torch 2.5.1+cu118 環境で、```pipfile update```後にチェックしたら
 ```No known security vulnerabilities found.```
 と問題は消失していました。
 
=== 2024/10/06 10:33 追記 ===
念のため、PyTorch環境をチェックしてみたら、ver2.4.0, ver2.4.1にて脆弱性が含まれていることが判った。
> 分散トレーニングを開始するマスター ノードが侵害され、機密性の高い AI 関連データが盗まれる可能性

Ver2.2以降へのアップデートで対応可能なような記述だが、脆弱性がFixされたという情報にはなっておらず、そのまま持続している様子。

![PyTorch-脆弱性2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504878/4f43edc0-6f25-a341-f35e-eb5d87a8bab9.jpeg)

https://data.safetycli.com/v/71670/742/
https://jp.tenable.com/plugins/nessus/200978
https://huntr.com/bounties/39811836-c5b3-4999-831e-46fee8fcade3

# 生成AIが提示する「誤ったコマンドの例」
※正しくは[```--index <URL>```]で、少なくとも本記事執筆時の1年前には変更されている。現時点で下記の状況であり、そのうちに変化するだろうけれど、生成AIが如何に表在的な情報のみに頼ってコードを検証していないかの実録としてここに記録しておく。
> ChatGPT-4o, Gemini-1.5Flash, Microsoft Copilot
> [```--extra-index-url <URL>```]
> Claude 3.5 Sonnet
> [```--index-url <URL>```]

ChatGPT-4o
![pipenv-pytoch-chatGPT-4o.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504878/f0bf119e-4968-46a5-e2c4-afe379352f97.jpeg)

Gemini-1.5Flash
![pipenv-pytoch-Gemini.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504878/1a0951c3-6caf-a9cf-b2c6-b91c8a242b41.jpeg)

Microsoft Copilot
![pipenv-pytoch-copilot.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504878/c74de0e0-c4ad-c39c-e097-80afa9f3c613.jpeg)

Claude 3.5 Sonnet
![pipenv-pytoch-Claude.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504878/a425600e-de61-6e11-c8fe-3a0d44bd3806.jpeg)

上記いずれも下記のようなインストール時エラーとなります。
![pipenv-pytoch-GenAI-error-1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504878/3786fb06-5be8-87a5-5074-e7307e788bdb.jpeg)
![pipenv-pytoch-GenAI-error-2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504878/cc2b0bf3-82e2-1525-b75b-93a538791467.jpeg)


# 【参考資料】
1. https://www5.dent.niigata-u.ac.jp/~nisiyama/grad/python/pipenv-sys-install-GPU-j.pdf
2. https://www5.dent.niigata-u.ac.jp/~nisiyama/grad/Pipenv-PyTorch.pdf
3. Specifying Package Indexes
https://pipenv.pypa.io/en/latest/indexes.html
4. GUIDE: How to install PyTorch via Pipenv (andhow to add other 3rd Party Repositories). #4961
https://github.com/pypa/pipenv/issues/4961
5. 【図で理解】PipenvによるPython仮想環境の管理
https://qiita.com/mtitg/items/3aa5e5c6d1c1cf6fd3c2
6. Pipenv Commands
https://pipenv.pypa.io/en/latest/commands.html