雑記: 自分のパッケージを TestPyPI(PyPI のテスト環境)に登録するまで

外部パッケージに依存しない単純なパッケージを TestPyPI(PyPI のテスト環境)に登録するまでの作業記録です。参考文献 [1] の公式チュートリアルにしたがいました。公式チュートリアルにしたがってつまづく点はあまりないですが、公式チュートリアルではテストがないのでテストもしました。ファイル一式はこちらです。

  1. Python のプロジェクトをパッケージングする — Python Packaging User Guide
    • 公式チュートリアルです。英語版をみて作業したのですが後から日本語版の存在に気付きました。
  2. PEP 621 – Storing project metadata in pyproject.toml | peps.python.org
    • pyproject.toml の project キーには PEP 621 で規定された内容を指定する必要があるとあります。
  3. python - When would the -e, --editable option be useful with pip install? - Stack Overflow
    • パッケージをローカルでテストしながら開発するプラクティスがわからなくて調べただけです。
  4. How to do I delete/edit a package and its release file list in test.pypi.org? - Stack Overflow
    • TestPyPI にアップロードしたパッケージを削除できるか調べたら削除はできました。しかしやってみてわかったのですが、パッケージの一部のバージョンもしくは全部のバージョンを削除して再度削除したバージョンをアップロードすると「This filename has already been used」といわれ拒絶されます。ファイルは削除できても歴史改変はできなかったです。
  5. pypi - How long does a Python package stay on testpypi? - Stack Overflow
    • TestPyPI インデックスは永続的ではないといわれますが、ではどれくらい保持されるのか気になったのですが、3 年前の時点で PyPI 管理者が「現在無期限に保持しているが、無期限に保持されることを期待すべきではない」といっています。

ファイル一式を用意する
ファイル一式はこちらにある通りですがツリーを描くと以下です。

cookies_utilities/
├── pyproject.toml
├── LICENSE
├── README.md
├── src/
│   └── cookies_utilities/
│       ├── __init__.py
│       └── timer.py
└── tests/
    └── test_timer.py

今回 timer.py に Timer というクラスを実装しました。このクラスは時間を計測したい処理の前後で press() していくと時刻を記録してくれ、最後に show() するとラップタイム一覧とトータルタイムを表示してくれます。こうかいていて「これは Timer ではなく Stopwatch なのでは」と気付きましたが後の祭りです。

さておきこの Timer(Timer ではない)をどこでも誰にでも pip install で手に入れてもらうようにするためには上のツリーのようなファイル一式を用意します。あまり得体の知れないファイルはないですが、パッケージングも Poetry も経験がないと pyproject.toml については得体が知れないのでこれについてメモします。

pyproject.toml について

  • build-system キーには、いくつかあるビルドツールから好きなものを指定します。今回はチュートリアルにしたがって hatchling を指定しました。
    • ただビルドを終えて pip list しても自分の環境に hatchling が導入された形跡がなかったのですが、チュートリアル「pip のようなビルドフロントエンドが、ビルド作業の一環として、一時的で隔離された仮想環境に自動的にインストールしてくれることでしょう」とありました。そもそもビルド時に画面に「Installing packages in isolated environment... (hatchling)」と表示されていました。
  • project キーには PEP 621 [2] で定義されたメタデータを指定します。
    • [2] には指定すべきメタデータとして name, version, description, readme, requires-python, license, authors, keywords, classifiers, urls などとあり、さらに続いています。これらのメタデータは (Test)PyPI 上に表示されるのはもちろん、ビルド時・アップロード時・インストール時に適宜利用されます。例えば、ビルド後にパッケージファイル名のバージョンをかき換えてアップロードしようとすると「メタデータがないですよ」と拒絶されます。捏造はできないようです。
    • ただ上記に太字でかいたうち keywords はチュートリアルでも指定していないし、私はさらに urls も指定しませんでしたが支障はありませんでした。他のキーにも省けるものがあるかもしれないですが私は試しません。
    • 個々のキーに得体の知れないものはあまりないですが、classifiers は Python3 系、MIT ライセンス、OS 非依存のパッケージであれば私と同じ(というかチュートリアルと同じ)ように記述すればよいようです。

ローカルでテストする
チュートリアルではいきなりパッケージングしていきますが、テストしないのはどうかと思うのでテストします。といっても editable モード(コード変更が即座に反映されるモード)でカレントディレクトリをパッケージとしてインストールして、tests 以下のテストコードを Python 標準の unittest で実行するだけです。

pip uninstall cookies_utilities  # uninstall the package if already installed
pip install -e .  #  install the package in editable mode
python -m unittest discover tests -v  # test

パッケージをビルドする
パッケージをビルド(ファイル一式を圧縮)します。つまづくことはないと思います。

pip install --upgrade build  # upgrade 'build'
python -m build

以下のようにパッケージが生成されます。

./dist/cookies_utilities-0.0.1.tar.gz
./dist/cookies_utilities-0.0.1-py3-none-any.whl

パッケージを TestPyPI にアップロードする

パッケージができたのでアップロードしたいですが、予め TestPyPI にアカウント登録する必要があります。
画面にしたがってアカウント登録できると思いますが、適当な TOTP アプリが必要です。github.com も今年に入って2段階認証を求めるようになったので、その関係で TOTP アプリを導入した方は同じアプリを利用できると思います。画面に 2 次元コードが出たらアプリでスキャンします。

また、おそらく TOTP アプリとの連携前に 8 つのリカバリーコードを生成して手元に保存すると思います。その後即座にそのうち1つの入力を求められるので好きな1つだけ入力します。画面をよく読まずに全部入力するとリカバリーコードを生成し直すことになるのでそういうことはやめます。

その辺の手順を終えると API トークン(pypi- から始まるながい文字列)が生成できるようになるので生成して手元に保存します。そして以下のようにパッケージをアップロードします。

pip install --upgrade twine
python -m twine upload --repository testpypi dist/*

このとき名前とパスワードを訊かれますが、TestPyPI のアカウント名とパスワードを入力するのではなく、名前には __token__ と入力しパスワードに先の API トークンを入力します。
それでパッケージがアップロードできますが、「同名同バージョンのパッケージを以前にアップロードしている場合(削除済みであっても)」「メタデータが不正な場合」はアップロードを拒絶されます。

無事アップロードできると画面に URL が表示されます。その URL に行くと自分のパッケージの情報とインストールコマンドが表示されているのでインストールして楽しみます。
https://test.pypi.org/project/cookies-utilities/0.0.3/

pip install -i https://test.pypi.org/simple/ cookies-utilities==0.0.3
python
>>> import cookies_utilities as cu
>>> timer = cu.Timer()
>>> timer.press('train start')
>>> timer.press('test start')
>>> timer.press('end')
>>> timer.show()
time1(train start-test start): 7.476s
time2(test start-end): 5.493s
total: 12.969s

雑記: Windows 11 上の CUDA と PyTorch のアップグレード

アップグレードをしたメモです。
OS は Windows 11、Python は 3.10.4、コマンドはすべて Git Bash 上で実行しています。
関連記事は Anaconda を利用していますが今回は別のマシンで直接システム環境にインストールしています。

目標とする CUDA のバージョンを確認する

  • PyTorch のウェブサイトから目標とする CUDA のバージョンを確認する。
    • この記事を書いている現在の PyTorch の Stable 版 (2.0.1) は CUDA 11.7 か 11.8 に対応している。念のため以下をみても torch-2.0.1 でそれ例外の CUDA バージョンに対応する wheel はない。

現在の GPU の型番、ドライバのバージョン、CUDA のバージョンを確認する

  • コマンド nvidia-smi でドライバのバージョンと GPU の型番が表示されるが GPU の型番は NVIDIA GeForce ... と見切れている。ドライバのバージョンは 512.15 である。
    なお、これをみると CUDA Version: 11.6 とあるがこれは CUDA ドライバ API のバージョンであり、今回あげたい CUDA ランタイム API のバージョンではない [2]。しかし、CUDA ランタイム API と同じかもっと高くあってもらわなければならないのでドライバのバージョンアップが必要であることがわかる。
    +-----------------------------------------------------------------------------+
    | NVIDIA-SMI 512.15 Driver Version: 512.15 CUDA Version: 11.6 |
    |-------------------------------+----------------------+----------------------+
    | GPU Name TCC/WDDM | Bus-Id Disp.A | Volatile Uncorr. ECC |
    | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
    | | | MIG M. |
    |===============================+======================+======================|
    | 0 NVIDIA GeForce ... WDDM | 00000000:01:00.0 On | N/A |
    | N/A 57C P8 9W / N/A | 1166MiB / 6144MiB | 17% Default |
    | | | N/A |
    +-------------------------------+----------------------+----------------------+
  • 改めてコマンド nvidia-smi -LGPU の型番を確認する。NVIDIA GeForce GTX 1060 である。
    GPU 0: NVIDIA GeForce GTX 1060 (ry
  • コマンド nvcc -V で CUDA Toolkit のバージョンを確認する。11.3 である。
    Cuda compilation tools, release 11.3, V11.3.58
  • GPU の型番とドライバのバージョンは以下の方法でも確認できるが、コマンドで確認すればよい。
    • 「タスク マネージャー > パフォーマンス タブ > GPU」に GPU の型番が表示されている。
    • 「コントロール パネル > プログラム > プログラムと機能」から「NVIDIA グラフィックス ドライバー」のバージョンを確認する。

ドライバのバージョンとCUDA のバージョンを決めてインストールする

  • 今回、CUDA 11.7 か 11.8、およびそれ以上のドライバがほしい。
  • が、それらが GeForce GTX 1060 をサポートしていなかったらだめなので確認する。
  • ドライバダウンロードページにいって手元の GPU の型番と OS を入力する (下図)。
    「ダウンロード タイプ」が何か忘れてしまったがどちらでもいいはずである。
  • するとバージョン 536.67 のドライバ (下記リンク) が示唆されるが、
    https://www.nvidia.co.jp/download/driverResults.aspx/209432/jp
    追加情報タブからリンクがあるリリースノートを CUDA で検索すると CUDA ドライバ API のバージョンは 12.2 なのでちゃんと 11.8 以上である。なのでダウンロードしておく。
  • CUDA 11.8 もダウンロードしておく。
    https://developer.nvidia.com/cuda-toolkit-archive
  • ドライバ、CUDA の順にインストールする。画面の指示にしたがうだけである。
    再起動を促されたら再起動する。
  • インストールすると nvidia-smi nvcc -V の結果がちゃんと変わる。
    あと GPU の型番も見切れなくなっている。
    +---------------------------------------------------------------------------------------+
    | NVIDIA-SMI 536.67 Driver Version: 536.67 CUDA Version: 12.2 |
    |-----------------------------------------+----------------------+----------------------+
    | GPU Name TCC/WDDM | Bus-Id Disp.A | Volatile Uncorr. ECC |
    | Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
    | | | MIG M. |
    |=========================================+======================+======================|
    | 0 NVIDIA GeForce GTX 1060 WDDM | 00000000:01:00.0 On | N/A |
    | N/A 50C P0 24W / 78W | 736MiB / 6144MiB | 1% Default |
    | | | N/A|
    +-----------------------------------------+----------------------+----------------------+
    Cuda compilation tools, release 11.8, V11.8.89

cuDNN をダウンロードして配置する

関連記事のときは cuDNN をダウンロードして配置していた。
which nvcc でバイナリが配置されているフォルダ bin の場所がわかる。
/c/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v11.8/bin/nvcc
ちなみに echo $PATH で PATH を表示すると上記の bin までのパスが勝手に追加されていた(それも過去のバージョンの CUDA より先になるように追加されていた)。

それで bin の横並びに include があるが過去のバージョンの CUDA と違い確かに cudnn.h が入っていない。
/c/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v11.8/include
cuDNN のダウンロードはどのような条件下で必要なのかわからないがダウンロードして配置しておく。

以下から for CUDA 11.x 系の最新の cuDNN をダウンロードする。
ダウンロードにはメールアドレスの登録が必要だが以前にもダウンロードしているので登録されていた。
cuDNN Archive | NVIDIA Developer
ダウンロードしたら解凍してファイル一式を対応するフォルダに移動する [3]。

PyTorch をインストールする
PyTorch のウェブサイトに戻って CUDA 11.8 を選択して実行すべきコマンドを取得する。なくてもいいのかもしれないが -U を入れておく。
pip install -U torch torchvision torchaudio \
--index-url https://download.pytorch.org/whl/cu118

PyTorch を動作確認する
そもそもバージョンを確認する。

import torch
print(torch.__version__)
print(torch.cuda.is_available())
2.0.1+cu118
True

雑記

動画に内容はないです。
[2023/07/06] 口の開閉を音量に対応させる修正をしました(無音時に口が動いてしまうのを解消しました)。
埋め込みが3つありますが2つ目は iPhone で生成すべく video タグにするテストです。
3つ目は2つ目が iPhone で再生できたが音が出なかったのでフレームレートを 24 → 30 に変えるテストです。
→ だめでした。→ 後に音声コーデックの問題であると判明し動画生成ツール側で対応しました(コミット)。