AI/Machine Learning」カテゴリーアーカイブ

Copilot が使えるようになっていた!

朝、メールを見ると。。。

おぉおぉ?
どゆこと?

メールにも書かれているけれど、いくつか制限があるようです

  • 2,000 code suggestions a month: Get context-aware suggestions tailored to your VS Code workspace and GitHub projects.
  • 50 Copilot Chat messages a month: Use Copilot Chat in VS Code and on GitHub to ask questions and refactor, debug, document, and explain code.
  • Choose your AI model: You can select between Anthropic’s Claude 3.5 Sonnet or OpenAI’s GPT 4o.
  • Render edits across multiple files: Use Copilot Edits to make changes to multiple files you’re working with.
  • Access the Copilot Extensions ecosystem: Use third-party agents to conduct web searches via Perplexity, access information from Stack Overflow, and more.

制限として大きいのは2000コード提案と50チャットの部分。
なんかあっという間に制限に引っかかりそうな気がしますね・・・。
それも利用仕方の問題なのかな

最近、WebでCaludeのほうを使う機会のほうが多くなっている気もしますが、まだまだ生成AIを使ったスタイルに馴染みがないので手を動かせるようにしていきたいものです。

開発環境の構築は開発よりも難しい

購読しているSoftware Designの12月号

連載のLLMが前号に引き続きのHIL(Human In the Loop)をお題にしたもので、読んでいて面白そうだったので試してみることに。

リポジトリはこちらです
https://github.com/mahm/softwaredesign-llm-application/tree/main/14

やってみる

ReadMeにしたがって、ポチポチしていきます。
poetryというのは初めて使います。正直言って、業務でPythonを使っているわけじゃない身としては、試しに触るたびに新しいパッケージマネージャーを使わされている気がします。
なんでPython使いはパッケージマネージャーをどんどん作るのでしょう。
どれだけパッケージ使いづらいんでしょうかね。。。
それとも、「俺が作る最強のパッケージマネージャーを見せてやる」ってイキってる人が多いということなのかもしれません。

さて、最終的に実行を行ってみるのですが。。。

ModuleNotFoundError: No module named 'pydantic_core._pydantic_core'
Traceback:
File "C:\Dev\llm\softwaredesigne\softwaredesign-llm-application\14\.venv\Lib\site-packages\streamlit\runtime\scriptrunner\exec_code.py", line 88, in exec_func_with_error_handling
    result = func()
             ^^^^^^
File "C:\Dev\llm\softwaredesigne\softwaredesign-llm-application\14\.venv\Lib\site-packages\streamlit\runtime\scriptrunner\script_runner.py", line 590, in code_to_exec
    exec(code, module.__dict__)
File "C:\Dev\llm\softwaredesigne\softwaredesign-llm-application\14\app.py", line 5, in <module>
    from agent import HumanInTheLoopAgent
...

知ってる。チュートリアルってエラーになるんだぜ。

この “pydantic_core.pydantic_core”が見つからないってのはOpenAI関連のLambdaレイヤーを構築する際に起こるエラーとググったら出てくる。
Lambdaレイヤーなんて作っちゃいないんだけど、どうやらWindows環境では確実にこうなるようだ。
Software Designにそんな環境依存の話書いてあっただろうか?と思わずひとりごちた。
ちくしょう。

正直、なぜLambdaレイヤーと言われているのかは定かではないけれど、対応にはFastAPIの0.99.0を入れるとある

Lambda Layers で No module named ‘pydantic_core._pydantic_core’
https://qiita.com/ganessa/items/bb67517a095f2c510926

試して見る

C:\Dev\llm\softwaredesigne\softwaredesign-llm-application\14> pip install fastapi==0.99.0
...
Using cached starlette-0.27.0-py3-none-any.whl (66 kB)
Installing collected packages: pydantic, starlette, fastapi
  Attempting uninstall: pydantic
    Found existing installation: pydantic 2.9.2
    Uninstalling pydantic-2.9.2:
      Successfully uninstalled pydantic-2.9.2
  Attempting uninstall: starlette
    Found existing installation: starlette 0.41.2
    Uninstalling starlette-0.41.2:
      Successfully uninstalled starlette-0.41.2
  Attempting uninstall: fastapi
    Found existing installation: fastapi 0.115.4
    Uninstalling fastapi-0.115.4:
      Successfully uninstalled fastapi-0.115.4
ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
composio-core 0.5.40 requires pydantic<3,>=2.6.4, but you have pydantic 1.10.19 which is incompatible.
Successfully installed fastapi-0.99.0 pydantic-1.10.19 starlette-0.27.0

なんかERRORは出るものの、最終的にはpydantic-1.10.19がインストールされた。
さて試してみる

変わらず・・・

試してみる(2)

問題の根本としては、Windows環境で試していることが原因っぽい。
というわけで、Dockerも検討したけれど手元にMacもあったので試してみる

あっさり動いたーーーー。

すごい釈然としない。。2024年においてもまだ環境依存は簡単にはこえられない壁として我々の前には立ち塞がっていると言うことなんだろう・・・。

そして、本当はそんなことをしたいのではなくここから仕組みの理解や改変を通した学びを得たいところだったのだけれど、すでに徒労感がある。

悲しい。

動かしてみると

そりゃ、LLMアプリを勉強するくらいであったら課金くらいしろよってのは、まぁ、そうなのかもしれないけれど、試すことすら出来ないのは悲しいところです。

ChatGPTにしろAnthropicにしろ、開発中もひたすらに料金がかかり続けるモデルだと、お勉強エンジニアには厳しいお財布事情になりそうです。

これ、複数のLLMで試したいと思ったら全部課金するって話になるんですよね。。。

her/世界でひとつの彼女

Amazon Prime Video で「her/世界でひとつの彼女」を見た

her/世界でひとつの彼女
https://amzn.to/3CFChRG

人工知能が搭載されたOSというか、OSそのものが人工知能というか。
近未来ではそんなOSが来ることはそれほど斬新なアイディアではない、現実的な世界線の話。

いわゆるAIが自我に目覚めるという内容だけれど、ターミネーターのような結末には向かわない形で終りを迎えた。
ちょっと最後、「それってどうなっちゃってるんだろう?」という疑問がわかなくはないんだけど、それなりに楽しむことができた。

というか、映画自体を見たのがすごい久しぶりに感じる

同じ自我に目覚めるAIであっても、そもそもどういう命題を与えられたのかによって、迎える帰結が異なっているということなのかもしれない。
そもそも、herの世界線であったとしてもサマンサと他のAI-OSとの違いはどこにあって、開発者はどういう意図があってそういう機能を盛り込んだのだろうか。
疑問は尽きない

物理世界に干渉するために、ロボットなどを使うのではなく現実世界の人間を懐柔するというのも、面白いと思ったけれど、随分とまどろっこしい感じもする。

結局、人間っぽすぎるといえばそうなのかもしれない。

将来的に、どういうAIが我々の周りをひしめくことになるのだろう。
その時に自分はそれらAIに対してどういう感情を抱いているんだろう

5年もすればどうなっているか想像もできない事態が起きている可能性も高いわけで、楽しみでもあり怖くもあると感じた

LLMがさっぱりわからん

ここのところ平日は、それなりに仕事が忙しかったりなんだりでうまく勉強の時間が取れませんでした。

そんなわけで、申し込んだはいいものの全く取り組めていなかったGoogle提供の5日間のレッスンを見直しています

5-Day Gen AI Intensive Course with Google

初っ端からLLMの基礎講義が始まるわけなんですけど、理解できているかと言われるとほぼ理解できていない気がする。
今のLLMというのは、次に来る言葉をこれまでの文脈から予測をして、それを繰り返しているというのはなんか聞いたことがある。

しかし、トランスフォーマーという言葉は知っていても、説明できるかと言われるとできない。

そんなこんなで、ちゃんと勉強しなきゃねって思って色々と見ることはあっても、途中で挫折してしまうことが圧倒的に多い。
なんというか、独特の表現だったり単語が色々と出てくるので、いわゆるIT系にあまり関わりのない人がエンジニアの会話を聞くと何語が会話されているのかがよくわからないと言われるかのような気分を味わうことができる。

今、まさにそれ

LLMに代表される機械学習を取り扱うにおいて、モデルそのものを作るという方向性に動くよりは、できているモデルを使ってどんなアプリケーションを作るのか?という方向に重点を置くほうが機会としては圧倒的に多いし役に立つように感じる。

ただ、それはこの辺の知識を知らなくてもいいのか?ということに本当に”知らなくて良い”と結論付けてしまっていいのだろうか?は漠然とした不安がある。

このあたりは修行だと思って、とりあえず最後まで読み切ってみないと行けないんだろうけれど・・・
正直つらいなぁ

いい加減、AIに関して取り組まねばならぬ

fukabori.fmのエピソード119 が公開されました

119. 生成AI導入で成功する企業・失敗する企業、国産基盤モデルの意義 w/ piqcy, kosukearima | fukabori.fm

ゲストはストックマークCTOの有馬さんと、AWSの久保さんでタイトルの通り生成AIに関してのエピソードでした。
毎度のことであるが、fukabori.fmは面白い。

生成AIに関しては、所々で利用してはいるもののあくまで個人の利用という形で、組織的に取り組んでいるわけではない状態なんですよね。

でも、最近Claudeなんて使ってみると、すごくいい感じで資料とかの土台が作れてしまう。
なんだったら、スライドのベースだけでなく、口頭説明のテキストも頼めば生成してくれてできが良い。

この界隈。
個人で適当にチャットとして使っているだけだとあっという間に周回遅れになってしまいそうだと改めて感じた。
そして、エピソードの中に出てくる、こういった新しい技術要素を活用し続ける事ができる2割の企業。
BIツールに絡めての話が現状とダブってすごい納得感が出てしまった。

GitHub – aws-samples/aws-ml-enablement-workshop: 組織横断的にチームを組成し、機械学習による成長サイクルを実現する計画を立てるワークショップ

エピソード中に出てきた、ML Enablement Workshopの上記Githubページも早速見てみた。
Community Workshop や AWS Sample など、色々とあるので目を通しておきたいところだ。

なんだか楽しくなってきたぞ

Kaggle notebook の Accelerator

Kaggle が提供している jupyter notebook で training や prediction 実行する際に、そのままの設定だとものすごい時間がかかりました。

待っていても、少しずつ進んで行くはいいものの気がついていたらセッションがタイムアウトされてしまったり・・・。
こんな時どうするのかな?というところを見てみるとAccelleratorを変更すると良いらしい

なるほど、これか。
選択肢としては

  • None (CPU)
  • GPU T4x2
  • GPU P100
  • TPU VM v3-8

とある。それぞれどういう時に使うといいとかどっかに書いてないかな?と思い、一旦それぞれに関して調べてみた

まとめ

最初に簡単にまとめておく

名前モデルアーキテクチャCoreMemoryその他用途
GPU T4x2NVIDIA GPU model from the Tesla series.Turing 2,560 CUDA cores16 GB of GDDR6 memoryT4 GPUs include Tensor Cores, which can accelerate certain deep learning operations, particularly when working with mixed-precision training
GPU P100 NVIDIA GPU model from the Tesla series.Pascal 3,584 CUDA cores16 GB or 12 GB of HBM2 memory.In general, GPU P100 is considered more powerful than GPU T4, primarily due to the higher number of CUDA cores and better memory bandwidth. However, the actual performance depends on the specific workload you’re running.
TPU VM v3–8Google TPU v38 Core

GPUとTPUは違いすぎて比較表がうまく作れなかった。。。

GPU T4x2

明確な公式文書は見つけられなかったが、フォーラムにはP100と比較したコメントが出ていた

What is the difference between ‘GPU T4 x2’ and ‘GPU P100’ in the notebook? | Kaggle

GPU Model: T4 is an NVIDIA GPU model from the Tesla series.
Architecture: T4 is based on the Turing architecture.
CUDA Cores: T4 has 2,560 CUDA cores.
Memory: T4 typically has 16 GB of GDDR6 memory.
Performance: T4 offers good performance for a range of tasks, including machine learning, deep learning, and general GPU-accelerated computations.
Tensor Cores: T4 GPUs include Tensor Cores, which can accelerate certain deep learning operations, particularly when working with mixed-precision training.

GPU P100

GPU P100 に関しての公式文書としては下記を見つけた

Efficient GPU Usage Tips and Tricks

Kaggleは、NVIDIA TESLA P100 GPUへの無料アクセスを提供します。これらの GPU はディープ ラーニング モデルのトレーニングに役立ちますが、他のほとんどのワークフローを高速化することはありません (つまり、pandas や scikit-learn などのライブラリは GPU へのアクセスの恩恵を受けません)。

ふむ・・・。
ただ、Acceleratorの適用がセッション単位なんじゃないかな。
最終的に notebook でトレーニングするにしてもその前段となるpandas等の処理部分を省くことはできないし。
notebookを分割して前処理部分とトレーニング部分を分ければいいのかな?

GPU の週あたりのクォータ制限まで使用できます。クォータは毎週リセットされ、需要とリソースに応じて 30 時間以上になる場合があります

このあたりは注意が必要ですね。
一回あたりの実行時間がどれくらいかにもよるし、週に30時間であれば十分な気がするけれど。。。

TPU VM V3-8

TPUそのものが何かに関してはこちらの記事が参考になった

【AIメモ】GoogleのTPUがすごい (zenn.dev)

TPUに関してはKaggle内にも情報が乗っていた

Tensor Processing Units (TPUs)

こちらを読み進めていくと、TPUの性能をちゃんと活かすためには、バッチサイズだとかを適切にする必要があるそうな。

バッチ サイズが大きいほど、TPU はトレーニング データをより高速に処理します。これは、トレーニング バッチが大きいほど “トレーニング作業” が多くなり、モデルをより早く目的の精度に到達できる場合にのみ役立ちます。そのため、経験則では、バッチサイズに応じて学習率を上げることも必要です。

ただ、ちょっと下の方に気になることが。。。

特定の種類のコードのみのコンペティションには技術的な制限があるため、コンペティションのルールで明確にされているように、TPU で実行されるノートブックの提出をサポートすることはできません。しかし、だからといって、TPU を使用してモデルをトレーニングできないわけではありません。

この制限の回避策は、TPU を使用する別のノートブックでモデルのトレーニングを実行し、結果のモデルを保存することです。その後、そのモデルを送信に使用するノートブックに読み込み、GPU を使用して推論を実行し、予測を生成できます。

というわけで、提出用のnotebookに関してはTPUなど特定の技術に依存したものはNG。ただ、モデルを作るスピードは早いので、別のnotebookでモデルを作った上で、そのモデルを利用するのはOKということらしい。

色々ありますねぇ

StreamDiffusionでExampleのScreenを動かす

環境の構築が終わったので、早速、Screenを動かしてみる

準備

まずはScreenを動作させるために必要なライブラリをインストールする

C:\Dev\StreamDiffusion>cd examples

C:\Dev\StreamDiffusion\examples>python -V
Python 3.10.11

C:\Dev\StreamDiffusion\examples>pip install -r screen/requirements.txt

その後、Screenを実行

C:\Dev\StreamDiffusion\examples>py screen\main.py

基本的にはこれだけだが、実行ログを見るといくつかのエラーが出ている

Triton?

A matching Triton is not available, some optimizations will not be enabled.
Error caught was: No module named 'triton'

単純にみるとtritonモジュールがないぞってこと。
これはWindows環境で起こるものらしい

Windowsの場合はtritonに対応していないため、この表示が出て、かつコード実行に問題がなければ無視しても良い。

https://wikiwiki.jp/sd_toshiaki/No%20module%20named%20%27triton%27

TritonのGithub開発リポジトリを見ても、Linuxのみのサポートのようだ。

Supported Platforms:
・Linux

https://github.com/openai/triton/?tab=readme-ov-file#compatibility

とりあえず、このエラーは無視しても動くようなので気にしないことにする

With TensorRT

これだけでも動くのだがTensorRTを使うとパフォーマンスが向上するとのことで、試してみることに。

C:\Dev\StreamDiffusion\examples>py screen\main.py --acceleration tensorrt

実行すると、TensorRTを使う形にコンパイルが走るとともに大量のライブラリが落とされ。。。

OSError: [Errno 28] No space left on device
Model load has failed. Doesn't exist.

エラーになった。
これは、ディスクが足りなくなったことを示すエラー。
どんだけ必要なんだ、、、ってことで色々消してやってみたところ

現時点で約9G。

なんとかライブラリも落としきったかな?と思い実行

torch.cuda.OutOfMemoryError: CUDA out of memory. Tried to allocate 26.00 MiB. GPU 0 has a total capacty of 4.00 GiB of which 0 bytes is free. Of the allocated memory 3.35 GiB is allocated by PyTorch, and 144.71 MiB is reserved by PyTorch but unallocated. If reserved but unallocated memory is large try setting max_split_size_mb to avoid fragmentation.  See documentation for Memory Management and PYTORCH_CUDA_ALLOC_CONF
Model load has failed. Doesn't exist.

GPUのメモリが足りない・・・?
確認してみる

c:\Dev\StreamDiffusion>nvidia-smi
Wed Jan 17 17:13:45 2024
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 522.06       Driver Version: 522.06       CUDA Version: 11.8     |
|-------------------------------+----------------------+----------------------+
| 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 Off |                  N/A |
| N/A   58C    P8     9W /  N/A |    114MiB /  4096MiB |     22%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
|    0   N/A  N/A      5588    C+G   ...ser\Application\brave.exe    N/A      |
|    0   N/A  N/A      7000    C+G   ...n64\EpicGamesLauncher.exe    N/A      |
+-----------------------------------------------------------------------------+

今はありそうな気もするけど実行時に足りなくなってしまったということなのかな。

そして結局

Found cached model: engines\KBlueLeaf/kohaku-v2.1--lcm_lora-True--tiny_vae-True--max_batch-2--min_batch-2--mode-img2img\unet.engine.onnx
Generating optimizing model: engines\KBlueLeaf/kohaku-v2.1--lcm_lora-True--tiny_vae-True--max_batch-2--min_batch-2--mode-img2img\unet.engine.opt.onnx
[W] Model does not contain ONNX domain opset information! Using default opset.
UNet: original .. 0 nodes, 0 tensors, 0 inputs, 0 outputs
UNet: cleanup .. 0 nodes, 0 tensors, 0 inputs, 0 outputs
[I] Folding Constants | Pass 1
[W] Model does not contain ONNX domain opset information! Using default opset.
Only support models of onnx opset 7 and above.
Traceback (most recent call last):
  File "C:\Dev\StreamDiffusion\examples\screen\..\..\utils\wrapper.py", line 546, in _load_model
    compile_unet(
  File "C:\Dev\StreamDiffusion\.venv\lib\site-packages\streamdiffusion\acceleration\tensorrt\__init__.py", line 76, in compile_unet
    builder.build(
  File "C:\Dev\StreamDiffusion\.venv\lib\site-packages\streamdiffusion\acceleration\tensorrt\builder.py", line 70, in build
    optimize_onnx(
  File "C:\Dev\StreamDiffusion\.venv\lib\site-packages\streamdiffusion\acceleration\tensorrt\utilities.py", line 437, in optimize_onnx
    onnx_opt_graph = model_data.optimize(onnx.load(onnx_path))
  File "C:\Dev\StreamDiffusion\.venv\lib\site-packages\streamdiffusion\acceleration\tensorrt\models.py", line 118, in optimize
    opt.fold_constants()
  File "C:\Dev\StreamDiffusion\.venv\lib\site-packages\streamdiffusion\acceleration\tensorrt\models.py", line 49, in fold_constants
    onnx_graph = fold_constants(gs.export_onnx(self.graph), allow_onnxruntime_shape_inference=True)
  File "<string>", line 3, in fold_constants
  File "C:\Dev\StreamDiffusion\.venv\lib\site-packages\polygraphy\backend\base\loader.py", line 40, in __call__
    return self.call_impl(*args, **kwargs)
  File "C:\Dev\StreamDiffusion\.venv\lib\site-packages\polygraphy\util\util.py", line 694, in wrapped
    return func(*args, **kwargs)
  File "C:\Dev\StreamDiffusion\.venv\lib\site-packages\polygraphy\backend\onnx\loader.py", line 424, in call_impl        
    postfold_num_nodes = onnx_util.get_num_nodes(model)
  File "C:\Dev\StreamDiffusion\.venv\lib\site-packages\polygraphy\backend\onnx\util.py", line 41, in get_num_nodes       
    return _get_num_graph_nodes(model.graph)
AttributeError: 'NoneType' object has no attribute 'graph'
Acceleration has failed. Falling back to normal mode.

と、最後に書かれているようにaccelerationに失敗して、通常モードで動くことになってしまっている。

おそらく途中に出てきているONNXが関係しているのかな?

onnx
https://github.com/onnx/onnx

とりあえず

Screenを動かすことはできているけど、私のPCスペックだとスムーズとは言えない。
だからこそTensorRTの恩恵を受けたいところだけどエラーで詰まってしまっているので、このあたりは追々見ていきたいところですね。

こういうものを触っていると、このあたりに関しての知見がいかに自分がないのかがよくわかってくる一方、面白いですね。

StreamDiffusion環境構築

Xを徘徊している際に見かけた、StreamDiffusion。気になっていて環境を構築しようとしています。

環境構築方法はStreamDiffusionのGithubに書いてあるのですが

StreamDiffusion
https://github.com/cumulo-autumn/StreamDiffusion

  • Step0: clone this repository
  • Step1: Make Environment
  • Step2: Install PyTorch
  • Step3: Install StreamDiffusion

という形で3段階に見えます。
しかし、当たり前のことではあるのかもしれないですが、Pythonが入っている必要はありますし、そのPythonはちゃんとStep2でインストールするPytorchとバージョンを合わせる必要があるんですよね。

それが分からずに、最新のPython 3.12.1をインストールしてしまったお陰で下記のようなメッセージになりました

>pip3 install torch==2.1.0 torchvision==0.16.0 xformers --index-url https://download.pytorch.org/whl/cu118
ERROR: Could not find a version that satisfies the requirement torch (from versions: none)
ERROR: No matching distribution found for torch

というわけで、備忘録を兼ねて実施したことを記録

今回のStreamDiffusionが必要としているPytorchは、Step2のスクリプトでバージョンを2.1.0を指定しており、2.1.0のPytorchが対応しているのは Python 3.11までっぽい。

ちょっと何をとち狂ったか、Python3.10をインストール。。。
もうこのままで進める

C:\Dev\StreamDiffusion>py -V
Python 3.12.1
C:\Dev\StreamDiffusion>py -3.10 -m venv .venv
C:\Dev\StreamDiffusion>.\.venv\Scripts\activate
(.venv) c:\Dev\StreamDiffusion>py -V
Python 3.10.11

Pythonの仮想環境を指示に従い作成し、Pytorchをインストール

(.venv) c:\Dev\StreamDiffusion>pip3 install torch==2.1.0 torchvision==0.16.0 xformers --index-url https://download.pytorch.org/whl/cu118

私の環境はCUDAが当初11.7でした。

なのでNVIDIAのサイトに行き、11.8をDL&インストール

CUDA Toolkit 11.8 Downloads
https://developer.nvidia.com/cuda-11-8-0-download-archive?target_os=Windows&target_arch=x86_64&target_version=11&target_type=exe_local

続いてStreamDiffusionのインストール

(.venv) c:\Dev\StreamDiffusion>pip install git+https://github.com/cumulo-autumn/StreamDiffusion.git@main#egg=streamdiffusion[tensorrt]

続いてTensorRT extensiojnをインストール

(.venv) c:\Dev\StreamDiffusion>python -m streamdiffusion.tools.install-tensorrt

Windows環境では、pywin32を入れる必要があるとのことなので

(.venv) c:\Dev\StreamDiffusion>pip install --force-reinstall pywin32

これで、一通りの環境構築はできたはず!

Docker の開始がいつまで経っても進まない

以前、尻切れトンボとなっていたKaggleへの挑戦をコソコソと始めている。
まずは、タイタニックをもう一度あれこれ見ながらやってみて、その後何をしようかな?と。

実際問題、タイタニックコンペに関しても、ネット上を見て提出までは行っているけどスコアが上位に食い込めているわけじゃない。
かといって、タイタニックで上位に組み込むところまで頑張るよりは、実際に開かれているコンペに参加して行くほうが身になりそう。

だが、圧倒的に基礎が足りないのも事実

ということで、データサイエンス100本ノックをやってみることにしたのですが、そもそも環境の構築にてまどってしまったというお話

発生した現象

前置きが長過ぎますね。
docker composeコマンドによって一通りのbuildが終わり、Starting状態になったPostgresqlサーバーがいつまで経ってもStartingのままでした

こんな感じでずっと動かなくなっていました。

Windows環境で実行する際の注意点として、GitのCRLF設定を気をつけるようにとガイドに書いてあったのですが、現象としては違いそう。
何かを始めようとしたときに環境構築で躓くと一気に気持ちが冷めてしまいますよね。。。

ネット上を見ても、同じような状況に陥っている人はいないようなので自分の環境問題であるだろうということはわかっています。

DockerDesktopアプリ(GUI)で確認してみる

公式で提供されているコマンドではなく、DockerDesktop(GUI)でこのPostgresqlサーバーを実行してみると下記のエラーが出ていました。

Error invoking remote method ‘docker-start-container’: Error: (HTTP code 500) server error – Ports are not available: exposing port TCP 127.0.0.1:5432 -> 0.0.0.0:0: listen tcp 127.0.0.1:5432: bind: An attempt was made to access a socket in a way forbidden by its access permissions.

あぁ、こうやって出てくれると単純ですね。
Portが何かしらのプロセスが利用中、被っているわけです。

netstatsで確認してみると、たしかにいる。
上記の例で言えばPID7560のプロセスが犯人ということで見てみると、ローカルでPostgresqlが起動していました。

いつ入れたんだろう。。。
何かしらを試す際に入れたんだろうけど全然記憶にない。。。

とりあえず、一旦ローカルで起動していたPostgresqlは停止。ついでに自動起動もやめて手動起動設定にして再び実行して

無事に起動させる事ができました。

それにしても相変わらずDockerへの理解が足りないのは、どこかでなんとかしないと行けないですね。
もうちょっと調べ方を把握しておかないといかん。

続・画像生成AIを触ってみた

Docker Composeが途中で止まってしまった原因は不明だが、まずは動かしてみたいというところでDevContainer使ってVSCode上のターミナルから試行錯誤してみようとと。

参考はこちら
Stable Diffusionをローカルマシンで実行する(VSCodeとDevcontainerを使用)
https://zenn.dev/hayatok/articles/6141a9a46e4f48

DevContainer準備

VSCodeで適当なフォルダを開き、Dockerfileを作成します

FROM nvcr.io/nvidia/cuda:11.7.1-cudnn8-runtime-ubuntu20.04

ARG DEBIAN_FRONTEND=noninteractive
ENV TZ=Asia/Tokyo

RUN apt-get update && apt-get install -y wget git git-lfs libglib2.0-0 libsm6 libxrender1 libxext-dev

RUN wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh && \
    sh Miniconda3-latest-Linux-x86_64.sh -b -p /opt/miniconda3 && \
    rm -r Miniconda3-latest-Linux-x86_64.sh

ENV PATH /opt/miniconda3/bin:$PATH

RUN git clone https://github.com/CompVis/stable-diffusion && \
    cd stable-diffusion && \
    conda init bash && \
    conda env create -f environment.yaml && \
    echo "conda activate ldm" >> ~/.bashrc

VSCode のコマンドパレットから「Remote-Containers: Add Development Container Configuration Files…」を選択し、作成したDockerfileを指定します。

devcontainer.jsonが作成されるので、編集します

// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
// https://github.com/microsoft/vscode-dev-containers/tree/v0.245.0/containers/docker-existing-dockerfile
{
	"name": "Existing Dockerfile",

	// Sets the run context to one level up instead of the .devcontainer folder.
	"context": "..",

	// Update the 'dockerFile' property if you aren't using the standard 'Dockerfile' filename.
	"dockerFile": "../Dockerfile",

	// 追記ここから。GPU利用可のコンテナ起動オプション
	"runArgs":[
		"--gpus",
		"all"
	],
	// 追記ここまで。
	"customizations": {
		"vscode": {
			"extensions": [
				"ms-python.python"
			]
		}
	}

	// Use 'forwardPorts' to make a list of ports inside the container available locally.
	// "forwardPorts": [],

	// Uncomment the next line to run commands after the container is created - for example installing curl.
	// "postCreateCommand": "apt-get update && apt-get install -y curl",

	// Uncomment when using a ptrace-based debugger like C++, Go, and Rust
	// "runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined" ],

	// Uncomment to use the Docker CLI from inside the container. See https://aka.ms/vscode-remote/samples/docker-from-docker.
	// "mounts": [ "source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind" ],

	// Uncomment to connect as a non-root user if you've added one. See https://aka.ms/vscode-remote/containers/non-root.
	// "remoteUser": "vscode"
}

コマンドパレットから「Remote-Containers: Rebuild and Reopen in Container」を選択することで、コンテナ内でVSCodeが起動する形となります。
VSCode の左下がこの状態ですね

Modelの配置

前回取得した Hugging Face のモデルを、Stable Diffusionがモデルのデフォルトパスとして指定している”models/ldm/stable-diffusion-v1/model.ckpt”に配備します。
このあたりは、”txt2image.py”を読んでいくとなんのパラメータ指定が出来るのかがわ借ります。
別のパスを指定する場合は —ckpt オプションで指定可能となっています

実行!

参考にさせていただいたページに従って、test.pyを用意し、実行します

(ldm) root@21feb17171f4:/workspaces/StableDiffusion2/stable-diffusion# python test.py
Traceback (most recent call last):
  File "test.py", line 6, in <module>
    pipe = StableDiffusionPipeline.from_pretrained(
  File "/opt/miniconda3/envs/ldm/lib/python3.8/site-packages/diffusers/pipeline_utils.py", line 154, in from_pretrained
    cached_folder = snapshot_download(
  File "/opt/miniconda3/envs/ldm/lib/python3.8/site-packages/huggingface_hub/utils/_deprecation.py", line 93, in inner_f
    return f(*args, **kwargs)
  File "/opt/miniconda3/envs/ldm/lib/python3.8/site-packages/huggingface_hub/_snapshot_download.py", line 168, in snapshot_download
    repo_info = _api.repo_info(
  File "/opt/miniconda3/envs/ldm/lib/python3.8/site-packages/huggingface_hub/hf_api.py", line 1454, in repo_info
    return self.model_info(
  File "/opt/miniconda3/envs/ldm/lib/python3.8/site-packages/huggingface_hub/hf_api.py", line 1276, in model_info
    _raise_for_status(r)
  File "/opt/miniconda3/envs/ldm/lib/python3.8/site-packages/huggingface_hub/utils/_errors.py", line 169, in _raise_for_status
    raise e
  File "/opt/miniconda3/envs/ldm/lib/python3.8/site-packages/huggingface_hub/utils/_errors.py", line 131, in _raise_for_status
    response.raise_for_status()
  File "/opt/miniconda3/envs/ldm/lib/python3.8/site-packages/requests/models.py", line 1021, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 403 Client Error: Forbidden for url: https://huggingface.co/api/models/CompVis/stable-diffusion-v1-4/revision/fp16 (Request ID: PQ6M8N2Lators-j6XdN6V)

Access to model CompVis/stable-diffusion-v1-4 is restricted and you are not in the authorized list. Visit https://huggingface.co/CompVis/stable-diffusion-v1-4 to ask for access.
(ldm) root@21feb17171f4:/workspaces/StableDiffusion2/stable-diffusion# python test.py
Downloading: 100%|████████████████████████████████████████████████████| 1.34k/1.34k [00:00<00:00, 1.13MB/s]
Downloading: 100%|████████████████████████████████████████████████████| 12.5k/12.5k [00:00<00:00, 11.2MB/s]
Downloading: 100%|█████████████████████████████████████████████████████████| 342/342 [00:00<00:00, 337kB/s]
Downloading: 100%|█████████████████████████████████████████████████████████| 543/543 [00:00<00:00, 557kB/s]
Downloading: 100%|████████████████████████████████████████████████████| 4.63k/4.63k [00:00<00:00, 4.02MB/s]
Downloading: 100%|██████████████████████████████████████████████████████| 608M/608M [00:20<00:00, 29.6MB/s]
Downloading: 100%|█████████████████████████████████████████████████████████| 209/209 [00:00<00:00, 208kB/s]
Downloading: 100%|█████████████████████████████████████████████████████████| 209/209 [00:00<00:00, 185kB/s]
Downloading: 100%|█████████████████████████████████████████████████████████| 572/572 [00:00<00:00, 545kB/s]
Downloading: 100%|██████████████████████████████████████████████████████| 246M/246M [00:08<00:00, 29.6MB/s]
Downloading: 100%|███████████████████████████████████████████████████████| 525k/525k [00:00<00:00, 583kB/s]
Downloading: 100%|█████████████████████████████████████████████████████████| 472/472 [00:00<00:00, 476kB/s]
Downloading: 100%|█████████████████████████████████████████████████████████| 788/788 [00:00<00:00, 864kB/s]
Downloading: 100%|█████████████████████████████████████████████████████| 1.06M/1.06M [00:01<00:00, 936kB/s]
Downloading: 100%|█████████████████████████████████████████████████████████| 772/772 [00:00<00:00, 780kB/s]
Downloading: 100%|████████████████████████████████████████████████████| 1.72G/1.72G [00:54<00:00, 31.7MB/s]
Downloading: 100%|█████████████████████████████████████████████████████| 71.2k/71.2k [00:00<00:00, 188kB/s]
Downloading: 100%|█████████████████████████████████████████████████████████| 550/550 [00:00<00:00, 532kB/s]
Downloading: 100%|██████████████████████████████████████████████████████| 167M/167M [00:05<00:00, 28.5MB/s]
0it [00:01, ?it/s]
Traceback (most recent call last):
  File "test.py", line 15, in <module>
    image = pipe(prompt)["sample"][0]  
  File "/opt/miniconda3/envs/ldm/lib/python3.8/site-packages/torch/autograd/grad_mode.py", line 27, in decorate_context
    return func(*args, **kwargs)
  File "/opt/miniconda3/envs/ldm/lib/python3.8/site-packages/diffusers/pipelines/stable_diffusion/pipeline_stable_diffusion.py", line 137, in __call__
    noise_pred = self.unet(latent_model_input, t, encoder_hidden_states=text_embeddings)["sample"]
  File "/opt/miniconda3/envs/ldm/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1110, in _call_impl
    return forward_call(*input, **kwargs)
  File "/opt/miniconda3/envs/ldm/lib/python3.8/site-packages/diffusers/models/unet_2d_condition.py", line 150, in forward
    sample, res_samples = downsample_block(
  File "/opt/miniconda3/envs/ldm/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1110, in _call_impl
    return forward_call(*input, **kwargs)
  File "/opt/miniconda3/envs/ldm/lib/python3.8/site-packages/diffusers/models/unet_blocks.py", line 505, in forward
    hidden_states = attn(hidden_states, context=encoder_hidden_states)
  File "/opt/miniconda3/envs/ldm/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1110, in _call_impl
    return forward_call(*input, **kwargs)
  File "/opt/miniconda3/envs/ldm/lib/python3.8/site-packages/diffusers/models/attention.py", line 168, in forward
    x = block(x, context=context)
  File "/opt/miniconda3/envs/ldm/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1110, in _call_impl
    return forward_call(*input, **kwargs)
  File "/opt/miniconda3/envs/ldm/lib/python3.8/site-packages/diffusers/models/attention.py", line 196, in forward
    x = self.attn1(self.norm1(x)) + x
  File "/opt/miniconda3/envs/ldm/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1110, in _call_impl
    return forward_call(*input, **kwargs)
  File "/opt/miniconda3/envs/ldm/lib/python3.8/site-packages/diffusers/models/attention.py", line 245, in forward
    sim = torch.einsum("b i d, b j d -> b i j", q, k) * self.scale
RuntimeError: CUDA out of memory. Tried to allocate 512.00 MiB (GPU 0; 4.00 GiB total capacity; 3.13 GiB already allocated; 0 bytes free; 3.13 GiB reserved in total by PyTorch) If reserved memory is >> allocated memory try setting max_split_size_mb to avoid fragmentation.  See documentation for Memory Management and PYTORCH_CUDA_ALLOC_CONF

エラーになってしまった。要するにメモリが足りないんだと。
そこでメモリの状態を調べるコマンドを打ってみる

(ldm) root@21feb17171f4:/workspaces/StableDiffusion2/stable-diffusion# nvidia-smi
Tue Sep  6 14:52:34 2022       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 515.65.01    Driver Version: 516.94       CUDA Version: 11.7     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  NVIDIA GeForce ...  On   | 00000000:01:00.0 Off |                  N/A |
| N/A   56C    P3    13W /  N/A |      0MiB /  4096MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+

むぅ。そもそもいくつあればOKなのかがいまいちわからん。
エラーメッセージに出てきた「PYTORCH_CUDA_ALLOC_CONF」あたりを見ていくと何とかパラメータ指定でうまく行けないかな?という気もするけど、多くの人がStable Diffusionをそのまま使うのではなく、メモリ消費を抑えたバージョンを使っているという事を見聞きしているので、そちらを使うことにする

(ldm) root@21feb17171f4:/workspaces/StableDiffusion2# mkdir basujindal
(ldm) root@21feb17171f4:/workspaces/StableDiffusion2# ls
Dockerfile  basujindal  stable-diffusion
(ldm) root@21feb17171f4:/workspaces/StableDiffusion2# cd basujindal/
(ldm) root@21feb17171f4:/workspaces/StableDiffusion2/basujindal# git clone https://github.com/basujindal/stable-diffusion.git

適当なフォルダを作って、リポジトリからclone

(ldm) root@21feb17171f4:/workspaces/StableDiffusion2/basujindal# cd stable-diffusion/
(ldm) root@21feb17171f4:/workspaces/StableDiffusion2/basujindal/stable-diffusion# python optimizedSD/optimized_txt2img.py --prompt "a photograph of an astronaut riding a horse" --H 512 --W 512 --seed 27 --n_iter 2 --n_samples 10 --ddim_steps 50
Global seed set to 27
Loading model from models/ldm/stable-diffusion-v1/model.ckpt
Traceback (most recent call last):
  File "optimizedSD/optimized_txt2img.py", line 184, in <module>
    sd = load_model_from_config(f"{ckpt}")
  File "optimizedSD/optimized_txt2img.py", line 29, in load_model_from_config
    pl_sd = torch.load(ckpt, map_location="cpu")
  File "/opt/miniconda3/envs/ldm/lib/python3.8/site-packages/torch/serialization.py", line 699, in load
    with _open_file_like(f, 'rb') as opened_file:
  File "/opt/miniconda3/envs/ldm/lib/python3.8/site-packages/torch/serialization.py", line 231, in _open_file_like
    return _open_file(name_or_buffer, mode)
  File "/opt/miniconda3/envs/ldm/lib/python3.8/site-packages/torch/serialization.py", line 212, in __init__
    super(_open_file, self).__init__(open(name, mode))
FileNotFoundError: [Errno 2] No such file or directory: 'models/ldm/stable-diffusion-v1/model.ckpt'

おっと、モデルを新たに置き直さないと行けない。
サクッとコピーして、再度実行する

(ldm) root@21feb17171f4:/workspaces/StableDiffusion2/basujindal/stable-diffusion# python optimizedSD/optimized_txt2img.py --prompt "a photograph of an astronaut riding a horse" --H 512 --W 512 --seed 27 --n_iter 2 --n_samples 10 --ddim_steps 50
Global seed set to 27
Loading model from models/ldm/stable-diffusion-v1/model.ckpt
Global Step: 470000
Traceback (most recent call last):
  File "optimizedSD/optimized_txt2img.py", line 204, in <module>
    model = instantiate_from_config(config.modelUNet)
  File "/stable-diffusion/ldm/util.py", line 85, in instantiate_from_config
    return get_obj_from_str(config["target"])(**config.get("params", dict()))
  File "/stable-diffusion/ldm/util.py", line 93, in get_obj_from_str
    return getattr(importlib.import_module(module, package=None), cls)
  File "/opt/miniconda3/envs/ldm/lib/python3.8/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 961, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 973, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'optimizedSD'

あれ、何だ?optimizedSDがない?

調べてみると、新しくディレクトリ作って作業しているので、PythonのEnvを作り直す必要があるそうだ

(ldm) root@21feb17171f4:/workspaces/StableDiffusion2/basujindal/stable-diffusion# conda deactivate       
(base) root@21feb17171f4:/workspaces/StableDiffusion2/basujindal/stable-diffusion# conda remove -n ldm --all
(base) root@21feb17171f4:/workspaces/StableDiffusion2/basujindal/stable-diffusion# conda env create -f environment.yaml 
(base) root@21feb17171f4:/workspaces/StableDiffusion2/basujindal/stable-diffusion# conda activate ldm

よし、気を取り直して実行だ

(ldm) root@21feb17171f4:/workspaces/StableDiffusion2/basujindal/stable-diffusion# python optimizedSD/optimized_txt2img.py --prompt "a photograph of an astronaut riding a horse" --H 512 --W 512 --seed 27 --n_iter 2 --n_samples 10 --ddim_steps 50
Global seed set to 27
Loading model from models/ldm/stable-diffusion-v1/model.ckpt
Global Step: 470000
UNet: Running in eps-prediction mode
CondStage: Running in eps-prediction mode
Downloading: "https://github.com/DagnyT/hardnet/raw/master/pretrained/train_liberty_with_aug/checkpoint_liberty_with_aug.pth" to /root/.cache/torch/hub/checkpoints/checkpoint_liberty_with_aug.pth
100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 5.10M/5.10M [00:00<00:00, 21.2MB/s]
Downloading: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████| 939k/939k [00:01<00:00, 854kB/s]
Downloading: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████| 512k/512k [00:00<00:00, 567kB/s]
Downloading: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 389/389 [00:00<00:00, 366kB/s]
Downloading: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 905/905 [00:00<00:00, 804kB/s]
Downloading: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████| 4.31k/4.31k [00:00<00:00, 3.92MB/s]
Downloading: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████| 1.59G/1.59G [00:59<00:00, 28.5MB/s]
Killed

いきなり殺された。。。

stable_diffusion.openvino を WSL2 で実行したけど”Killed” されちゃった人へ
https://zenn.dev/suzuki5080/articles/1438d52377b9df

調べてみると、これも結局はメモリが不足しているために発生しているという可能性が高い。
そして、WSL2に対する割当メモリを変えることで、この問題は解消する可能性が!

[wsl2]
memory=12GB

.wslconfigファイルを配備して、再起動。
そして再チャレンジ

(ldm) root@21feb17171f4:/workspaces/StableDiffusion2/basujindal/stable-diffusion# python optimizedSD/optimized_txt2img.py --prompt "a photograph of an astronaut riding a horse" --H 512 --W 512 --seed 27 --n_iter 2 --n_samples 10 --ddim_steps 50
Global seed set to 27
Loading model from models/ldm/stable-diffusion-v1/model.ckpt
Global Step: 470000
UNet: Running in eps-prediction mode
CondStage: Running in eps-prediction mode
FirstStage: Running in eps-prediction mode
making attention of type 'vanilla' with 512 in_channels
Working with z of shape (1, 4, 32, 32) = 4096 dimensions.
making attention of type 'vanilla' with 512 in_channels
Sampling:   0%|                                                                                                                             | 0/2 [00:00<?, ?it/sseeds used =  [27, 28, 29, 30, 31, 32, 33, 34, 35, 36]                                                                                       | 0/1 [00:00<?, ?it/s]
Data shape for PLMS sampling is [10, 4, 64, 64]
Running PLMS Sampling with 50 timesteps
PLMS Sampler: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████| 50/50 [06:46<00:00,  8.13s/it]
torch.Size([10, 4, 64, 64])
saving images 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████| 50/50 [06:46<00:00,  8.38s/it]
memory_final =  7.72352
data: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [07:04<00:00, 424.21s/it]
Sampling:  50%|██████████████████████████████████████████████████████████                                                          | 1/2 [07:04<07:04, 424.21s/itseeds used =  [37, 38, 39, 40, 41, 42, 43, 44, 45, 46]                                                                                       | 0/1 [00:00<?, ?it/s]
Data shape for PLMS sampling is [10, 4, 64, 64]
Running PLMS Sampling with 50 timesteps
PLMS Sampler: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████| 50/50 [07:19<00:00,  8.79s/it]
torch.Size([10, 4, 64, 64])
saving images 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████| 50/50 [07:19<00:00,  8.62s/it]
memory_final =  6.833664
data: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [07:27<00:00, 447.21s/it]
Sampling: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 2/2 [14:31<00:00, 435.71s/it]
Samples finished in 15.12 minutes and exported to outputs/txt2img-samples/a_photograph_of_an_astronaut_riding_a_horse
 Seeds used = 27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46

できた!できたよ、ママン!

ようやく、なんとかStable Diffusionを動かすことが出来る環境を作ることができました。
Pythonに関する知識不足もさることながら、メモリ周りで苦労しますね。

せっかく環境を作ることができたので、もう少し触って遊んでみようと思っています