端の知識の備忘録

技術メモになりきれない、なにものか達の供養先

さよなら徳島、よろしく大阪

概要

仕事の部署移動で徳島から大阪に引っ越すことになった。転職はしておらず、仕事の内容としても創薬でIT関連なのは変わらないのだが、研究所のIT企画的な立場ではなく研究者扱いでAI・データサイエンスを利用したin silico創薬を担当することになりそう。

修士を卒業して新卒入社して以来5年半徳島の独身寮に住んでいたが、ようやく生活の95%の時間を会社の敷地内で過ごす生活から環境を変えることになった。しばらく目新しいことがなく更新の滞っていたブログを久々に書いてみる。

徳島での生活

特に徳島での生活に不満はなかった。というのも、ほぼ家から出ないインドアアラサー独身男性なので、とりあえずまともな速度でインターネットが使えていれば生きていける。

振り返ると会社の寮というのはすさまじい福利厚生である。この物価高の時代に家賃、光熱費、水道代、朝夜の食事込みで月3万程度で生活ができていた。風呂トイレといった水場が各部屋になかったのは多少不便だが、逆に言うとそれらの掃除を自分でしなくていいので楽でもある。あらゆる通販は寮の管理事務所がいつでも受け取ってくれたし、ご飯も美味しいし毎日違うメニューが何も考えずとも出てくる。

おかげさまでKaggle含め自己研鑽の時間をたっぷりとることもできたし、趣味のゲームや旅行にかける時間もお金も余裕があった。

とはいえさすがに5年以上も同じ環境に身を置くと飽きが来るのも事実である。生活に不必要なものを買いすぎてかなり手狭になったのもあり、そろそろ寮を出ようと思っていたところに今回の部署移動が舞い込んできたので渡りに船であった。

仕事の話はあまり詳しくは書けないが、いわゆるデジタル活用推進的な仕事に対してトップダウンな組織体制が敷かれず、今年は私を採用してくれた上司が転職してしまうなど、色々思うこともあったので、仕事内容の変更も含め良い機会と思い人事異動を承諾した。念のため断っておくと、これは会社に不満があるというわけではなく、薬を作るというミッションに対してのリソース配分や戦略を考えると何がベストかは神のみぞ知るところなので、私個人がこの会社でできることを最大化するために現時点では最適な行動であると信じている。

最後に松茂のバス停まで歩いたときに橋からの写真を撮ったが、徳島に初めて来たときに空が広く感じたのを思い出した。必要なものは揃うし人は適度に少ないし、生活するのに良い場所だったと思う。

大阪にちょっと住んでみて

とりあえず引っ越してきて1週間ほど経った。当たり前の話であるが徳島に比べて大阪は都会であり、公共交通機関がまともに機能している環境は自分のような東京で育った人間にとって大変ありがたい。

まだ生活用品を買いに少し出かけたり、転入や免許証の住所変更に行ったりした程度であるが、10分程度待てば来る電車やバスに乗って目的地に行ける。当然家具屋電気屋本屋何でもあるので、すぐに必要なものを通販で頼んで数日待つ必要もない。

大阪の郊外にマンションを借りることにしたのだが、徳島の寮に比べて部屋が3倍くらい広くなった。おかげで寮にいたころにはサイズの問題で買えなかったものを中心に、また色々買い物をし始めている。

いろいろ買ったもの

現時点で家具が揃っておらずデスク回りも整っていないが、調子に乗ってメイン用の45インチのウルトラワイドモニター⁺サブに過剰な31インチの4K OLEDモニターや憧れのアーロンチェア、65インチのOLEDテレビ、お風呂用の防水タブレットなどをブラックフライデーで爆買いした。

これら買ったもののレビューは1か月くらい使ってみてまとめて書くことにする。

今後どうするか

私生活は一段と自由が利くようになり多分しばらくは楽しめる気がするが、部屋を完成させたらいよいよ目標がなくなってしまいそうなのが怖いところ。

元々いつか学生向けの金銭支援のために奨学金を作りたいと思っていたので、一通り生活用品が揃ったらそろそろ無駄遣いをやめたほうがいいかもしれない。まあ、自分自身の奨学金すら完済していないのでまだまだ先の話だが。

会社では既存業務の延長にあるものも多少はあるが、専門ではないDrug Designにかかわることになるので、最低限知識をつけていきたいところ。計算化学、BIのチームと今まで以上に近い位置に来たので、とりあえず会話できるように家でLab codeの「In silico創薬実践書」を勉強し始めたりしている。

zenn.dev

最近は大分社会人に擦れてきてモチベーションが下がっていたが、これを機に気分を上げて楽しく生きていきたいと思う。

MSI RTX5090 VANGUARDを入手できたのでゲーミング・機械学習性能を測定する

まえがき

2025/3/15(土)、滅多に週末外に出ることがない私は珍しく大阪・難波に遠征していた。舞台版邪神ちゃんを見に行くためである。

せっかく難波に行くのであればということで、ほとんど期待はせずにRTX5090を探しながらPCパーツ屋を巡っていた。

RX9070やRTX5080は普通に在庫している店舗があり、ちょっとは流通改善しているんだなーなどと思いながらもRTX5090はない。流石にあるわけないと思っていたのだが、ジョーシンに2枚のRTX5090、MSIのVANGUARDとSUPRIM LIQUIDが売られているではないか!価格は前者が52万、後者は58万円とMSIの希望小売価格であった。

とはいえ、RTX4090を持っているのもあり、Ada世代の性能の向上を考えると出せて45万までかな……と思っていたので、一旦グッと堪えて他のショップを巡ることに。

RTX5090のほかにもASUSから最近発売されたStrix Halo搭載タブレットのGZ302EAの実機展示(ジョーシンにあった)を見てみたり、RTX5090を買うことになったら必要になるATX3.1電源を物色してみたり、1時間ほど日本橋をぶらぶらとしていた。

そのときもずっとRTX5090を買うか買うまいか、ドル円の動向、トランプリスク、そろそろ在庫が増えてくる可能性、間もなく始まるGTC、買ったとしてRTX4090をどうするか、本当にMSIでいいのか、間もなく30になる独身男がこんなフリーダムにお金を使ってて大丈夫なのか、いっそのこともう売れててくれないかな、などなど苦しい脳内会議が繰り広げられていたのだが、いざジョーシンに戻ってみるとまだそこには2枚のRTX5090が鎮座していた。

冷静に考えれば待つべきと思っていたものの、やはり見てしまうと欲しくなる。店内を数分回りながら三度GPUコーナーを通り過ぎたとき、理性を欲望が上回り、私は財布を取り出しながら店員さんにこれくださいと言ってしまったのであった。……「ある」のがいけない!「ある」のがいけない!

空冷派なので52万のMSI RTX5090 VANGUARD LAUNCH EDITIONを選択。

早く買わないと高くなる・いつまでも買えない雰囲気に煽られて値段に見合わないものを買う資本主義的ゲームに参加してしまうのは悔しいが、結局買えるときに買うのが正解かと自分を納得させる。

値段が高いのはMSIが仕切値を上げているため、それも元をたどればNVIDIAのチップやGDDR7の値段が高いのが原因であるそうなので、とりあえず定価で通常販売してくれたジョーシンには感謝しかありません。

更に、せっかく買ったRTX5090が燃えてしまっても困るので、ケーブルに温度センサーがついているらしいATX3.1電源であるAsrock PG-1300G(44,000円)も合わせて買った。

非常に高い買い物になったものの、買ってしまったものは有効活用していくしかない。だいぶ思うところが多い買い物であったため前置きが長くなったが、とりあえずいつもやっているゲーム系のベンチマークと、機械学習のトレーニング・インファレンス性能をViT、GPT2、Gemma3モデルで測定してみた。

まとめ

  • 新しいモデルであるMSI VANGUARDであるが、ちゃんと600W近い消費電力にも静かに対応できるよいクーラーだと思う。ただ高い。
  • ゲーム系のベンチマークではすでに各所で報告されているように、RTX4090比で大体10~40%程度の性能向上が見られる。
    • 明確に性能は上がっているのだが、現状RTX5090がないと満足にプレイできないゲームは存在しないと思うので、もはやゲーム用に買うものではない気もする。
  • 機械学習系のベンチマークでも大体10~40%程度の性能向上が見られている。
    • 特にLanguage ModelのトレーニングではGPU使用率がしっかり100%に張り付いており、性能向上幅が大きかった。同時に、消費電力もものすごいことになっており、ほぼTDP上限の570Wを記録していた。これを常時ぶん回すのは正直ちょっと怖いですね……。
  • 価格性能比を考えると、やはりRTX5090は45万くらいまでが適正価格かな……というのが正直な感想
    • とはいえ、VRAMが32GBあるというのは代えがたいメリットなので、機械学習用であれば持ってて損はないのは間違いない。

総評としては、NVIDIAのMSRPで買えない限りは、RTX4090からの買い替えはコスパが悪いとはっきり言って良いと思う。サプライズは無く、各種サイトでベンチが取られている通りの性能である。それに勝る理由(マルチフレーム生成による超高FPSでゲームしたい、32GBのVRAMが欲しい)があれば、今後ハイエンドGPUの行く末がどうなるのか全くわかりませんし、買えるときに買うしかないですね。

ギャラリー

MSI VANGUARDはVENTUS、GAMINGと最高位のSUPRIMの間に位置するグレードの、空冷のハイクラスモデルとのこと(MSIのラインナップの説明はこの記事がわかりやすい)。基本的にOC性能は求めず価格とチップの種類重視で、値段の高いカスタムクーラーのGPUを買うことはない自分にとって初めての高級なモデルでもある。 さすがに52万もするだけあって、箱の豪華さが段違いである。ジッパーを引っ張って外装を開けるギミック付き。

今回買ったのはLaunch Editionという初回限定版みたいなやつで、MSIのマスコットであるLucky君のランダムフィギュアが同梱されている。シークレットもあるらしいが、私はHollywood Lucky君がついてきました。しかし、52万もするグラボのおまけに対して"...collect them all."とは冗談も大概にしてほしい。

形状は直方体で重さも相まってレンガのようである。

今まで使っていたRTX4090(ZOTAC TRINITY OC)と比べると、思ったほど大きさに差がないが重さがだいぶ違う(1.96kg vs 2.41kg)。身近なものと比較すると2Lペットボトルよりもデカく重いのだが、これは果たしてマザボに刺していいものなのだろうか。

もともと電源としてはCoolerMaster MWE GOLD 1250 V2を持っていたのだが、あいにくATX3.0の電源であるため、万全を期すため(万が一故障したときにケチをつけられて保証受けられないみたいなことにならないように)、ATX3.1規格かつ12V-2x6コネクタに温度センサーがついていて加熱時に電源供給を遮断する機能を搭載したAsrockのPG-1300Gを購入した。 ちょうど日本橋パソコン工房に在庫があったため店頭購入したのだが、Steel LegendマウスパッドとTaichi Tシャツがおまけでついてきた。

ちなみに、非常にCPU12Vケーブルが細くて取り回しが良かったです。

環境

今回GPU換装のついでに、セールで買っておいたがめんどくさくて放置していた4TBのSSDに換装し、OSの再インストールも実施してクリーンな環境で測定を行った。

価格は購入当時のものですが、CPUとかはもうちょい安いタイミングもあったと思います

  • PCケース:Fractal Design Torrent ¥30,800
  • 電源: Asrock PG-1300G ¥44,800
  • マザーボード: MSI X670-P WIFI ¥29,776
  • メモリ: Micron 4800MHz 2x32GB ¥25,980
  • CPU: Ryzen9 7950X3D ¥111,800
  • GPU: MSI RTX5090 VANGUARD SOC ¥519,800 or ZOTAC RTX4090 Trinity OC ¥301,020
  • SSD: WD BLACK 850X ¥39,435
  • CPUクーラー: DeepCool Assassin IV ¥15,000
  • OS: Windows 11 Pro ¥24,000

CPU、メモリが世代遅れになってしまったが、現行ハイエンドのコンシューマ?向けPCであると思う。合計金額は占めて¥841,391と、いよいよ中古車も多少種類を選びながら買えるくらいの金額になりました。冗談じゃないですね。

BTOだとRTX5090搭載マシンが駿河屋ですら95万とかするらしいので、このクラスになると自作したほうがBTOよりも安くなりそう。新しいCPUでもう少し良いマザボ・メモリとか選んだらあんま変わらないか?とも思いますが、このクラスのマシンを必要とする人はそれぞれこだわりポイントがあると思うので、調整が利く自作やフルカスタムの価値はあると思います。

(2025/3/26 追記) ツクモのG-GEARで9950X3D搭載モデルも税込み85万とのことなので、これであればBTOで買ってもいいかもしれませんね。

【TSUKUMO】G-GEAR、NVIDIA GeForce RTX 5090を搭載したゲーミングPCの新モデルを発売 - 【TSUKUMO(ツクモ)】プレスリリース

また、今回RTX5090に換装したところ、なぜか2枚目、3枚目のM.2 SSDが認識しなくなってしまった。MSI X670-P WIFIは安かったので買ったのだが、USBも不安定だし割と似たようなM.2・USB周りの不具合がほかの人からも報告されているようで、あんまり良い板じゃなかったですね。Zen6発売までは持たせたいが……。

本当はOptane 905P上にDual bootのUbuntu環境があったのだが、そのような事情からネイティブなLinux環境でのベンチマークはいったん棚上げとした。今回の機械学習ベンチマークはWSL2上で実行したものです

また、MSI VANGUARD のファン設定は”Silent"にしています。

CUDA12.8でのPyTorchインストールについて

RTX50シリーズではCUDA12.8以上が必要なため、現状のStable ReleaseのPyTorch(CUDA 12.6)をインストールしてもAssertionError: Torch not compiled with CUDA enabledが発生してしまう。

forums.developer.nvidia.com

を見たところ、PyTorchのNightlyビルドにCUDA 12.8用のwhlがあるようである。

したがって、次のようなコマンドでNightly版のCUDA12.8対応PyTorchをインストールしました。

pip install --pre torch torchaudio torchvision --index-url https://download.pytorch.org/whl/nightly/cu128

また、機械学習系ベンチではTransformersリポジトリのExampleコードを使っていますが、これらはInstall from sourceでないと動かないので、

git clone https://github.com/huggingface/transformers.git
cd transformers
pip install .

でインストールする必要があります。

ベンチマーク

目次

GPU-Z

GPU-Zを見てみましたが、噂のROP欠けはとりあえず無さそう。今世代のRTX5090の最大の特徴と思われる、GDDR7+豪勢な512bitメモリバスによる1792GB/sという超高速なVRAM転送帯域が目を引きます。

一つ気になるのが、PCIe5.0x16がないはずのX670なのに5.0でリンクしているっぽいことです。

3DMark

すべてのベンチでちゃんと性能向上が見られています。特にGPU性能が重要となる新しく重めのベンチのほうが差が付きますね。

ベンチ中RTX5090が示した最高温度は65度程度でしたので、MSI VANGUARDの冷却性能も問題ないと思われます(部屋が寒かったのもあるかもしれませんが)。

RTX4090 RTX5090 ratio
Fire Strike Ultra 24285 32291 1.330
Time Spy Extreme 17309 21768 1.258
Port Royal 25600 37404 1.461
Steel Nomad Light 43104 46932 1.089
Steel Nomad 9188 14070 1.532

また、PCIe5.0x16でリンクしている疑惑の確認のため、PCIe Feature Testも実施。96.37GB/sというPCIe4.0x16を超える速度が出ているので、本当にPCIe5.0x16でリンクしている?のかもしれません。やっぱこのマザボちょっとおかしい気もする。

FF14 黄金のレガシー

もうFF14ベンチは軽すぎてあまり測定する意味はないですが、最低FPSも平均FPSも着実に向上しているので、最高のエオルゼアライフを送りたければRTX5090を買ってもいいのではないでしょうか

RTX4090 RTX5090 ratio
score 28689 33245 1.160
Min FPS 88 92 1.045
Ave FPS 199.5 230.4 1.155
RTX4090 RTX5090 ratio
score 19353 25352 1.310
Min FPS 82 95 1.159
Ave FPS 136.4 173.5 1.271

MH Wilids

最近流行りのモンハンワイルズベンチマークも実施。ちなみに私は笛使いです。

RTX50世代の特徴であるFrame GenerationをオンにするとRTX4090との差が開いているように見えます。そんなに高いFPSが必要なゲームではないですが(なんならFPSが高いと連続ヒット系の攻撃の判定が減ってダメージ減るとか聞いた気がする)、RTX5090があると4K最高画質でも144Hzのモニターを持て余さなくて済みそうです。

また、4時間くらい実際にウルトラ設定/3440x1440解像度でプレイしながら温度を見てみましたが、大体消費電力350W、ファンスピード30%、コア温度60度、メモリ温度65度くらいで安定していました。

  • 3440x1440, 最高設定, レイトレ高, Frame Generation OFF
RTX4090 RTX5090 ratio
score 33436 35256 1.054
Ave FPS 98.75 103.58 1.048
  • 3440x1440, 最高設定, レイトレ高, Frame Generation ON
RTX4090 RTX5090 ratio
score 26405 31804 1.204
Ave FPS 155.14 186.78 1.204
  • 3840x2160, 最高設定, レイトレ高, Frame Generation OFF
RTX4090 RTX5090 ratio
score 28831 33495 1.162
Ave FPS 84.41 98.34 1.165
  • 3840x2160, 最高設定, レイトレ高, Frame Generation ON
RTX4090 RTX5090 ratio
score 20991 27372 1.304
Ave FPS 123.23 160.25 1.301

ViT

huggingface/transformersのExampleにあるrun_image_classification.pyを、次のコマンドで実行。

github.com

python run_image_classification.py \
    --dataset_name beans \
    --output_dir ./beans_outputs/ \
    --remove_unused_columns False \
    --label_column_name labels \
    --do_train \
    --do_eval \
    --learning_rate 2e-5 \
    --num_train_epochs 5 \
    --per_device_train_batch_size 8 \
    --per_device_eval_batch_size 8 \
    --logging_strategy steps \
    --logging_steps 10 \
    --eval_strategy epoch \
    --save_strategy epoch \
    --load_best_model_at_end True \
    --save_total_limit 3 \
    --seed 1337

samples_per_secondで比較するとなぜかRTX4090のが速くなってしまった。かなりBatch Sizeを小さく実験をしてしまったので、性能差が見にくくなってしまったかも。実行中のGPU使用率は50%程度で、消費電力も300W程とあまりHWを使い切れていない感じでした。

RTX5090のみBS=128で実行してみましたが、若干処理速度が上がりましたね。

  • RTX4090
***** train metrics *****
  epoch                    =         5.0
  total_flos               = 373122447GF
  train_loss               =        0.22
  train_runtime            =  0:00:46.43
  train_samples_per_second =     111.328
  train_steps_per_second   =      13.997

***** eval metrics *****
  epoch                   =        5.0
  eval_accuracy           =      0.985
  eval_loss               =     0.0761
  eval_runtime            = 0:00:00.55
  eval_samples_per_second =    239.898
  eval_steps_per_second   =     30.664
  • RTX5090
***** train metrics *****
  epoch                    =         5.0
  total_flos               = 373122447GF
  train_loss               =      0.2201
  train_runtime            =  0:00:50.98
  train_samples_per_second =      101.41
  train_steps_per_second   =       12.75
***** eval metrics *****
  epoch                   =        5.0
  eval_accuracy           =     0.9774
  eval_loss               =     0.0795
  eval_runtime            = 0:00:00.62
  eval_samples_per_second =    212.545
  eval_steps_per_second   =     27.167
  • RTX5090(BS=128)
***** train metrics *****
  epoch                    =         5.0
  total_flos               = 373122447GF
  train_loss               =      0.7684
  train_runtime            =  0:00:41.50
  train_samples_per_second =     124.555
  train_steps_per_second   =       1.084
***** eval metrics *****
  epoch                   =        5.0
  eval_accuracy           =     0.9699
  eval_loss               =     0.5824
  eval_runtime            = 0:00:00.58
  eval_samples_per_second =    228.145
  eval_steps_per_second   =      3.431

GPT2 Language Modeling

huggingface/transformersのExampleにあるrun_clm.pyを、次のコマンドで実行。

github.com

python run_clm.py \
    --model_name_or_path openai-community/gpt2 \
    --dataset_name wikitext \
    --dataset_config_name wikitext-2-raw-v1 \
    --per_device_train_batch_size 4 \
    --per_device_eval_batch_size 4 \
    --do_train \
    --do_eval \
    --output_dir /tmp/test-clm

このトレーニング中にはほぼずっとフルロードでGPUが稼働しており、消費電力は最大580Wに達していました。

学習中だんだん温度は上がる様子が見られ70度を超えることもありましたが、ファンスピード的にはだいぶ余裕があり、40%程度で70度安定という感じです。

さすがに性能を発揮しきれるケースにおいては、RTX4090と比べて性能が大きく上がっていることが確認できました。

  • RTX4090
***** train metrics *****
  epoch                    =        3.0
  total_flos               =  3384472GF
  train_loss               =     3.0904
  train_runtime            = 0:04:14.13
  train_samples            =       2318
  train_samples_per_second =     27.363
  train_steps_per_second   =      6.847

***** eval metrics *****
  epoch                   =        3.0
  eval_accuracy           =     0.4274
  eval_loss               =     3.0433
  eval_runtime            = 0:00:02.81
  eval_samples            =        240
  eval_samples_per_second =     85.321
  eval_steps_per_second   =      21.33
  perplexity              =    20.9749
  • RTX5090
***** train metrics *****
  epoch                    =        3.0
  total_flos               =  3384472GF
  train_loss               =     3.0908
  train_runtime            = 0:03:05.92
  train_samples            =       2318
  train_samples_per_second =     37.403
  train_steps_per_second   =      9.359

***** eval metrics *****
  epoch                   =        3.0
  eval_accuracy           =     0.4276
  eval_loss               =     3.0436
  eval_runtime            = 0:00:02.17
  eval_samples            =        240
  eval_samples_per_second =    110.518
  eval_steps_per_second   =      27.63
  perplexity              =      20.98

LLM Inference(Gemma3-12b, 4b@bfloat16)

最後にGemma3を使った推論速度の検証を行いました。

google/gemma-3-12b-itに記載されているHuggingFaceを使った推論コードをもとに、蜂と花の画像に対する説明をさせた時の出力トークン数と推論時間を測定した結果を以下に示します。

精度はbfloat16を使っています。出力サンプルは次のような感じで、大体100トークンくらいの文章が生成されていました。

Overall Impression: The image is a close-up shot of a vibrant garden scene, focusing on pink cosmos flowers and a busy bumblebee. The composition is natural and slightly blurred in the background, drawing attention to the central flower and insect. Main Elements: * Cosmos Flowers: The primary focus is on several pink cosmos flowers. They have delicate, slightly ruffled petals in varying shades of pink. The central flower

  • Gemma3-12b-it

VRAMに収まらないサイズのモデルなので、RAMにも重みがロードされています。このあたり、メモリの帯域幅が広くなっていることもあるのか、RTX4090と比べてRTX5090の方が速い結果が出ました。とはいえ実用的な速度ではないので、量子化したモデルを使うべきでしょう。

RTX4090 RTX5090 ratio
モデルロード時間 19.05 13.94 0.732
生成時間 190.95 129.67 0.679
速度 0.52 0.77 1.48
  • Gemma3-4b-it

こちらのモデルは24GBのVRAMでもモデルが乗り切るものです。RTX5090のGPU使用率も50%程度で性能が出し切れておらず、推論時間も短くてあまり差が出なかったようです。

RTX4090 RTX5090 ratio
モデルロード時間 6.03 5.50 0.912
生成時間 3.80 3.53 0.929
速度 26.33 28.29 1.074

おわりに

まだまだいろいろ検証したい内容はありますが、長くなりすぎたので一旦この辺で止めときます。

これからまたコンペやらなんやらで使って行くつもりなので、そこで性能検証できた内容があればまた新しい記事を書くかも。

しかし、RTX4090をどうしようかが悩みどころ。サブのEPYCマシンに載せれば普通に一線級の性能が出るのでそっちで使ってもいいのですが、さすがに資金を回収したい気持ちも強い。

ただ、売価が30万近くとなると最近特に治安が悪そうなメルカリで売るのは怖いし、下手すると確定申告も必要になりそうだし、かといって普通に買取依頼すると20万くらいにしかならないので悔しいし……。

買えて嬉しいのは間違いないのですが、素直に喜べない要素が多いのが残念ですね。

48コアで300ドルの謎のZen2 CPU, EPYC 7K62を買ってみた

まえがき

2020年のK40m購入から始まり、GPUをP40にしたりサーバー用マザボを導入したりMI50を試してみたりと徐々に進化を続けてきたホームラボ環境。

hashicco.hatenablog.com

またふとebayを見ていると、なんと300ドルで48コア、しかもZen2のCPUが売られているのを発見。

型番はEPYC 7K62と見たことのない命名ルールで、どうやらAMDのEPYC 7642のOEM版のようだ。

https://www.reddit.com/r/homelab/comments/1dssl0m/which_motherboards_support_epyc_rome_7k62/

普通のEPYC 7642や競合となりそうな3000番代ThreadripperのCPUと比べても数割安い金額なので、これはかなりお買い得。

Epyc 7642 for sale | eBay

どっかのデータセンターでリプレースされたものが放出されたのか、この数ヶ月でそれなりの数出回っているっぽい。

現在利用しているマザボであるH11SSL-iでもZen2 CPUはサポートされているので、これは試してみる価値ありと考えてポチってみた。

まとめ

  • 300ドル(2024年8月末購入時)で48コアのZen2 EPYC 7K62 CPUを購入。以前7551Pと使っていたマザボH11SSL-iとの組み合わせで無事に起動を確認
  • ついでにCPUクーラーとしてDynatronのA35を米尼で購入。
  • Phoronix Test Suiteでいくつかベンチマークを実行。今まで使っていた7551Pと比べて1世代分の進化と1.5倍のコア数があることもあり、かなりの性能向上が見られた
  • コア単価で見ると群を抜いて安く、安めのマザボでも動くので、高コスパなホームサーバーを構築する際には2024年現在かなりおすすめできるといえよう

しかしマザボ、256GBメモリ、48コアCPU合わせて10万ちょっとで買えるのだからすごい時代になったものだ。重たいマルチコア処理を日常的に行う人であれば簡単に元が取れるだろうし、鯖向けCPUを自宅で動かすのに抵抗のないパワーユーザーであれば購入検討してみてください。

ギャラリー

CPUはこんな感じ。SP3ソケットなのはZen1と変わらず。7K62という印字が確かにある。

もともと中古の水冷クーラーを使っていたが取り回しが悪く使いにくかったので、ちょっと気になっていた産業用クーラーメーカーのDynatronの製品を試してみた。無骨でなかなか格好いい。

システム情報

  • openbenchmarkのシステム情報

  • lshwの結果
ubuntu@ubuntu-Super-Server:~$ sudo lshw -C cpu
  *-cpu
       description: CPU
       product: AMD EPYC 7K62 48-Core Processor
       vendor: Advanced Micro Devices [AMD]
       physical id: 2c
       bus info: cpu@0
       version: 23.49.0
       serial: Unknown
       slot: CPU
       size: 1500MHz
       capacity: 3300MHz
       width: 64 bits
       clock: 100MHz
       capabilities: lm fpu fpu_exception wp vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp x86-64 constant_tsc rep_good nopl nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba ibrs ibpb stibp vmmcall fsgsbase bmi1 avx2 smep bmi2 cqm rdt_a rdseed adx smap clflushopt clwb sha_ni xsaveopt xsavec xgetbv1 cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local clzero irperf xsaveerptr rdpru wbnoinvd arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif v_spec_ctrl umip rdpid overflow_recov succor smca sev sev_es amd_ppin cpufreq
       configuration: cores=48 enabledcores=48 microcode=137367674 threads=96

ベンチマーク

Phoronix Test Suiteでいくつかベンチマークを実行。7551Pの結果を自分で取るのを忘れてしまったのだが、OpenBenchmarking.orgで公開されている7551か7551Pの結果と比較してみる。あと、参考値として7950Xの結果も転載して載せておく。

インストールは次の記事を参考にして、phoronix-test-suite list-recommended-testsProcessor Testsからいくつか選んで実行している。

dev.classmethod.jp

結果としては、旧世代の7551Pと比べて1世代分の進化と1.5倍のコア数があることもあり、かなりの性能向上が見られた。

また、一部Cache系ベンチマークなどではアーキテクチャの違いもあるのか7950Xに大きく劣るものの、概ね現世代の1桁後半万円、16コアのコンシューマCPUと比較してもほとんどのベンチで上回る性能を発揮している。もちろん、48コアをしっかり使い切れるアプリケーションでないと意味がないですが、5万でこの性能が出るなら十分だろう。

注: 本環境では若干遅めのメモリ(2133MHz)を使っているのでその点ご了承ください。

Timed Linux Kernel Compilation(Fewer is better)

https://openbenchmarking.org/result/2409115-NE-BUILDLINU47

項目 7551 7950X 7K62
defconfig 52 53 51.31
allmodconfig 1027 651 516.18

compress-7zip(Higher is better)

https://openbenchmarking.org/result/2409114-NE-COMPRESS736

項目 7551 7950X 7K62
compression 115838 182389 214261
decompression 133753 177177 175451

openssl(Higher is better)

https://openbenchmarking.org/result/2409111-NE-OPENSSLLO27

注: 7551Pの結果がなかった。

項目 7950X 7K62
SHA256 34748143805 33841133080
SHA512 11279544014 15466609297
RSA4096-sign 14454 11022.7
RSA4096-verify 380133 716442.8
ChaCha20 132915172864 129956744397
AES-128-GCM 258049517394 182569143227
AES-256-GCM 221082106458 162018783597
ChaCha20-Poly1305 94272191214 84309747797

c-ray(Fewer is better)

https://openbenchmarking.org/result/2409113-NE-CRAYLOG5569

項目 7551 7950X 7K62
Resolution 4K 142 113 77.02
Resolution 5K 254 209 136.82
Resolution 1080p 36 28 19.54

GraphicsMagick(Higher is better)

https://openbenchmarking.org/result/2409110-NE-GRAPHICSM18

項目 7551 7950X 7K62
Swirl 216 251 295
Rotate 118 176 103
Sharpen 71 60 123
Enhanced 87 96 128
Resizing 171 342 295
Noise-Gaussian 114 120 109
HWB Color Space 283 295 204

cachebench(Higher is better)

https://openbenchmarking.org/result/2409114-NE-CACHEBENC24

項目 7551 7950X 7K62
Read 7628 14090 8391.21
Write 37987 82631 46623.97
Read/Modify/Write 41606 149088 90643.11

pbzip2(Fewer is better)

https://openbenchmarking.org/result/2409114-NE-CACHEBENC24

項目 7551 7950X 7K62
BZIP2 Compression 6 3 4.054023

Transformers高速化ライブラリvLLMのAsyncLLMEngineを利用した非同期高速文章生成

概要

先日までKaggleのAIMOコンペ(数学の問題をLLMに解かせて正答率を競う)に参戦していました。結果は初のチーム参加でメンバーに助けられつつ運もあり、なんとか銀メダルを取れました!これでMasterにリーチがかかりましたが、金メダルは未だ取れる気がしないので遠い道のりです……。

www.kaggle.com

このコンペについて、近い内に同様のコンペが開催予定なこともあり上位解法があまり出ていない状態なので、どのような手法が良かったのかまだわかっていないのですが、とりあえず公開されている情報を元にすると、

  • LLMとしてはほぼほぼ全員が数学問題に特化したLLMであるDeepseek-Math-7Bを利用している
  • LLMが出力したPythonコードを実行するインタープリターを実装することで、LLMのハルシネーションによる計算ミスを防ぐパイプラインが有力であった
  • LLMの出力を比較的高い温度で複数回サンプリングすることで、多様な解答を得つつ最も回答数が多いものを選択することで、精度を高めることができる

という点がベースラインとなっているコンペでした。

(2024/7/11 追記) 1st ソリューション公開されました。H100x8を使ったフルパラメータチューニングという常人には真似できない凄まじい解法!どうやらHFとMistral AIの人たちのチームらしい。

www.kaggle.com

その中で、最後の点について、通常のHugging Face Transformersではなく、vLLMというライブラリを利用することで文章生成を高速化し、サンプリング回数を増やすことができるというディスカッションがありました。

www.kaggle.com

全くこのvLLMの存在を知らなかったのですが、使ってみるとたしかに速い。更に、非同期推論用のラッパーであるAsyncLLMEngineを利用することで、GPUを遊ばせることなくフルに動かすことができ、通常のTransformersの最大20倍以上の速度で文章生成を行うことができました。

ただ、vLLMのドキュメントが少なく、特に日本語情報は殆どなさそう。更に、AsyncLLMEngineの使い方に至っては公式ドキュメントにもわかりやすい動作例がないため、少しvLLMの使い方をまとめることとします。

まとめ

ここに動作サンプル(Kaggle Notebook)を用意しましたので、単に使うだけならこれをご参照ください。

www.kaggle.com

いま私のソリューションは書いている途中なので、これもできたら共有します。

(20240707追記)ソリューション公開しました。

www.kaggle.com

今後、KaggleでTransformersを使うときには、推論時にvLLMを使うことで大幅に時間短縮が可能になるかもしれませんので、試す価値アリだと思います。

vLLMについて

Geminiに作らせた要約を一部訂正したものです。

高速: 最先端のサービングスループット、PagedAttentionによる効率的なアテンションキーと値メモリの管理、受信リクエストの連続バッチング、CUDA/HIPグラフと量子化による高速なモデル実行により、高速な処理を実現します。

柔軟性と使いやすさ: 人気のHugging Faceモデルとのシームレスな統合、並列サンプリング、ビームサーチなどのさまざまなデコーディングアルゴリズムを備えた高スループットサービング、分散推論用のテンソル並列サポート、ストリーミング出力、OpenAI互換APIサーバー、NVIDIA GPUAMD GPUIntel CPUとGPUのサポート、接頭辞キャッシュサポート(実験的)、マルチloraサポート(実験的)など、柔軟で使いやすい設計になっています。

「人気のHugging Faceモデルとのシームレスな統合」ということで、ほとんどHuggingFaceのTransformersと同じAPIを持ちつつ、裏側でPagedAttention等の高速化技術を使って推論速度を上げてくれるような機能も持っており、最小限の変更でノートの実行時間を減らすこともできます。

公式Exampleより抜粋。一番シンプルなLLM APIを使うことで対応しているモデルであれば、"facebook/opt-125m"のようにHuggingFace Hubのパス指定で当該のモデルを呼び出し、HF transformersのgenerateメソッドっぽく文章生成をすることができます。

from vllm import LLM, SamplingParams
sampling_params = SamplingParams(temperature=0.8, top_p=0.95)

llm = LLM(model="facebook/opt-125m")
outputs = llm.generate(prompts, sampling_params)

近いライブラリというと、Deepspeedが挙げられるかもしれません。

インストール

活発にアップデートされているライブラリなのですぐにインストール方法が変わりそうですが、とりあえず20240706現在、0.4.0post1をKaggleでインストールする方法を載せておきます。

Kaggle DatasetにWhlがあるので、これを使ってインストールします

!pip uninstall -y torch
!pip install --no-index --find-links=/kaggle/input/vllm-whl -U vllm
!pip install /kaggle/input/vllm-additional-packages/grpcio-1.60.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

一般的なインストールのガイダンスは次を参照してください。

docs.vllm.ai

AsyncLLMEngineについて

今回フォーカスするのは、非同期推論用のAPIであるAsyncLLMEngineです。

とりあえず公式ドキュメントの記載は以下にあります。

docs.vllm.ai

非同期推論なので、ここに載っているExampleをそのまま使うことはできず、async/awaitを使ったコードを書く必要があります。

そこで、簡単に動作確認ができるサンプルを作成しました。このサンプルは、2つのプロンプトに対して100回ずつサンプリングを行い、その結果をファイルに書き出すというものです。

from vllm import AsyncLLMEngine, SamplingParams
from vllm.engine.arg_utils import AsyncEngineArgs

import asyncio
import time
import uuid

st = time.time()


example_inputs = [
    {
        "prompt": "About 200 words, please give me some tourist information about Tokyo.",
        "temperature": 0.9,
    },
    {
        "prompt": "About 200 words, please give me some tourist information about Osaka.",
        "temperature": 0.9,
    },
]


async def gen(engine, example_input, id):
    results_generator = engine.generate(
        example_input["prompt"],
        SamplingParams(temperature=example_input["temperature"],max_tokens=300, min_tokens=200,),
        id,
    )

    final_output = None

    async for request_output in results_generator:
        final_output = request_output

    prompt = final_output.prompt
    text_output = [output.text for output in final_output.outputs]
    return text_output[0]


async def main():
    engine = AsyncLLMEngine.from_engine_args(
        AsyncEngineArgs(
            model="/kaggle/input/llama-2/pytorch/7b-chat-hf/1",
            dtype="half",
            enforce_eager=True,
            gpu_memory_utilization=0.99,
            swap_space=3,
            max_model_len=1024,
            kv_cache_dtype="fp8_e5m2",
            tensor_parallel_size=2,
            disable_log_requests=True
        )
    )

    results = []

    for example_input in example_inputs:
        tasks = []
        for i in range(100):
            tasks.append(asyncio.create_task(gen(engine, example_input, uuid.uuid4())))

        res = [await task for task in tasks]

        results.append(res)

    with open("async_res.txt", "w") as f:
        for r in results:
            f.writelines(r)


if __name__ == "__main__":
    asyncio.run(main())

    print("Async vLLM inference time: ", time.time() - st)

パラメータについて

AsyncEngineArgsというクラスでLLMの設定、プロンプトとともに渡すSamplingParamsでサンプリングの設定を行うことが可能です。

詳しくは公式ドキュメントを参照いただければと思いますが、とりあえずKaggle上でT4x2を利用する際に、私は次のような設定を利用していました。

engine = AsyncLLMEngine.from_engine_args(
    AsyncEngineArgs(
        model=MODEL_NAME,
        dtype="half",  # ここは指定しなくてもturing世代なら自動的にfp16になるらしい。より新しいGPUならbfloat16をデフォルトでは使ってくれる
        enforce_eager=True,  # Pytorchのeager modeを強制するかどうか。これは参考にしたノートブックがTrueにしていたのでそのまま利用している。
        gpu_memory_utilization=0.99,  # KVキャッシュ含めGPUのメモリをどこまで使うか。Kaggleであれば0.99でも問題ないが、もし映像出力も行っているGPUを使う場合はここを減らさないとマシン自体が落ちるので注意。
        swap_space=3,  # デフォルトは4だが、メインメモリのOOMで落ちたことがあったので3にしている
        kv_cache_dtype="fp8_e5m2",  # auto, fp8, fp8_e5m2, fp8_e4m3から選べる。fp8_e5m2のほうが<s>仮</s>指数部が大きいので<s>精度が高いらしい</s>数値のレンジが大きい。 (20240708)訂正。fp8_e5m2を使っているというディスカッションがあったのでそれに則ってこちらを使っているが、どっちが良いかはケース次第?
        tensor_parallel_size=2,  # ここの数を変えるだけで複数GPUを利用してくれる。
        max_model_len=1024,
        disable_log_requests=True,  # これをTrueにしないとログがめちゃくちゃ出る
    )
)

AIMOコンペでは、コードフェンス内のPythonコードをcode.pyというファイルに書き出して、そのコードをsubprocessで実行するという手法が取られていたので、stop_wordsによる生成停止を行います。

Transformersと似たようにリスト型でstop_wordsが可能ですが、include_stop_str_in_outputをTrueにすることでstop_wordsを含めた文章を返してくれるようになり、Transformersの標準的な出力と互換性を保つことができます。

SamplingParams(
    temperature=0.9,
    top_p=1,
    max_tokens=2048,
    stop=[
        "```output",
        "```python",
        "```\nOutput",
        ")\n```",
        "``````output",
    ],
    include_stop_str_in_output=True,
)

句読点のない日本語の文章に句読点を挿入するBERTモデルを作る

概要

Whisperなどで日本語の文字起こしをした後の文章にほとんど句読点が入っておらず、そのまま文字起こし文章を結合すると利用しにくいことがありました。

そこで何らかの手法で句読点を挿入したいと思ったのですが意外と手軽な古典的な手法が見つかりませんでした。このようなタスクはpunctuation restorationと呼ばれるタスクのようです。

ちょっと調べて見つかったのは次のような日本語BERTモデルのMask Fillを逐語的に適応していく方法でした。

qiita.com

この手法でもできなくはないのですが思ったほど精度が良くないこと、さらに処理時間が文章の長さに比例してだんだん無視できないレベルになるので、もう少し効率的な方法がないかと考えました。

実のところChatGPTに適当に「次の句読点の入っていない文章に適当に句読点を挿入してください」という指示を出せばいい感じに句読点を入れてくれるのですが、わざわざこれだけのためにChatGPTを使うのもなぁと思い、BERTモデルを自分で作ってみることにしたというお話。

作成したコード、Weightは下記リポジトリにあります。

huggingface.co

ちょっとした解説

学習データとして次のKaggle データセットを利用しました。夏目漱石の「明暗」の読み上げを行った音声データと文章データが含まれています。このうち文章データのみを利用してBERTモデルを学習しました。

https://www.kaggle.com/datasets/bryanpark/japanese-single-speaker-speech-dataset/data?select=transcript.txt

基本的なコンセプトとしては、句読点がちゃんと入っている文章において、句読点の前の文字であるか否かをラベルとして付与します。

例えば、「今日は、いい天気。」という文章に対して、

[[0,0,1,0,0,0,0],[0,0,0,0,0,0,1]]

のようなラベルを付与し、BERTに対しては「今日はいい天気」という文章を入力として与え、句or読点の前の文字であるか否かを予測させるという流れです。実際にはTokenizerによりスペシャトークンが付与されるので位置がずれますが、基本的な考え方はこのような感じです。

ベースのモデルとしてはtohoku-nlp/bert-base-japanese-char-v3を利用し、出力のhidden layerを取り出して、その後に全結合層を追加したモデルを作ります。

huggingface.co

それぞれのトークンのhidden stateに対し共通のlinear layerを適応し、「、」の前であるか「。」の前であるかを意味する2次元の出力を得る形となり、最終的な出力形状は(num_tokens, 2)となります。

class punctuation_predictor(torch.nn.Module):
    def __init__(self, base_model):
        super().__init__()
        self.base_model = base_model
        self.linear = torch.nn.Linear(768, 2)

    def forward(self, input_ids, attention_mask):
        last_hidden_state = self.base_model(
            input_ids=input_ids, attention_mask=attention_mask
        ).last_hidden_state
        # get last hidden state token by token and apply linear layer
        return self.linear(last_hidden_state)

で、出来上がったものとしては、次のようにprocess_long_textという関数に生で句読点の入っていない日本語を入力すると、適当に句読点を入れてくれるもの。

process_long_text(
        "句読点ありバージョンを書きました句読点があることで僕は逆に読みづらく感じるので句読点無しで書きたいと思います"
    )

先ほどのQiitaの記事で紹介されていた文章で比較してみます。

本実装

句読点ありバージョンを書きました。句読点があることで僕は逆に読みづらく感じるので、句読点無しで書きたいと思います。

学習データは地の文にあまり点が入っていないうえ近代文学なこともあり、結構かけ離れた文章のはずですがそこそこ上手く句読点を入れてくれているように見えます。

自分で使う分には対象の文字起こし文章10000文字くらいをChatGPTに投げて教師データを作成し、専用モデルを学習させることで割と実用的な精度が出ることを確認しています。

今回の文章の量(2000センテンス)であればRTX4090 1枚でだいたい1epoch 45秒, 10epochで10分くらいで学習が終わるので、そこまで時間がかからないのも良いところです。

GPTを使うには文が多すぎる場合などに活用できるモデルというイメージです。

ChatGPT4

句読点ありバージョンを書きました。句読点があることで、僕は逆に読みづらく感じるので、句読点無しで書きたいと思います。

Qiitaで紹介されていた"cl-tohoku/bert-base-japanese-char"のMask Fillを利用する方法

句読点ありバージョンを書きました句読点があることで僕は逆に、読みづらく感じるので、句読点無しで書きたいと思います。

【ベンチマーク編】 Radeon Instinct MI50を買って機械学習用に使ってみる【ROCm】

まえがき

ROCmを試すためにRadeon Instinct MI50を買ってみて、PyTorchで使えるようにセットアップをしたのが前回。

hashicco.hatenablog.com

今回は取ったベンチマークの結果をご紹介!

まとめ

  • ROCmは本当にほぼコード変更無しでCUDA用のTensorFlow、PyTorch、Transformersのコードが動く。素晴らしい。
  • 1GPUであればMI50のほうがP40よりも速い。特にFP16を利用する場合は4割くらい早く、結構実用的。
  • 2GPUだとあまりまともな速度が出ない。処理速度に波があるような挙動を示すため、Gradientの集約に時間がかかっているのかも。
    • Infinity fabric connectorをつけるとか、PCIe4であればもう少しマシになるのかも。
    • 2GPUをうまく使うならDDPでトレーニングするよりも、別プロセスで別のモデルを同時に2つトレーニングするように使うほうが実用的と思われる。
  • SDXL1.0でも512x512で7.3 sec/枚(FP16)の画像生成速度と、P40の10.9 sec/枚よりも4割以上速い。画像生成で遊ぶならMI50は悪くないと思う。

ということで、MI50は結構使えるGPUと言える。ただ、2GPUでDDPトレーニングをするような場合はあまり速度が出ないので買うなら1枚がオススメ。

P40と比べると、MI50のほうが速度は速いがVRAMが少ない。LLMで遊ぶ用ならメモリ量が第一なのでP40、Diffusion系の画像生成なら必要VRAMも比較的少ないモデルも多いし原理的に計算が重いと思うのでMI50のが良いかもしれません。

ROCm起因のトラブルもないわけではないのでちょっと玄人向けかもしれませんが、性能も3万円とは思えないほどなので、MI50は機械学習で遊ぶ用としてお家に1枚あっても損はないGPUかもしれない。

VRAM 32GB版が安く買えるなら間違いなくコスパ最強と言えると思うが、入手しやすい16GBに関しては必要なVRAM量を考えてP40とMI50のどちらか選ぶのが悩ましいところである。

ちなみに、Redditに「MI50機械学習用にどうよ?」的なスレッドもあったので、購入検討時にはこちらも確認するといいだろう(私は読まずに買ってしまいましたが)

https://www.reddit.com/r/LocalLLaMA/comments/1b5ie1t/interesting_cheap_gpu_option_instinct_mi50/

P40とMI50のスペック

www.techpowerup.com

www.techpowerup.com

ベンチマーク

行ったベンチマークは以下の通り。P40に関しても新しくベンチを取り直し、なるべく公正な比較になるようにしています。

  • FP32 画像分類モデルトレーニング(transformers pytorch exampleのrun_image_classification.py)
  • FP16 言語モデルレーニング(transformers pytorch exampleのrun_clm.py)
  • SDXL1.0 画像生成

環境

P40, MI50

  • CPU: EPYC 7551P 32Cores
  • MEM: DDR4 2133 256GB
  • M/B: H11SSL-i
  • SSD: SATA 1TB
  • OS: Ubuntu22.04

RTX4090

  • CPU: R9 7950X3D 16Cores
  • MEM: DDR5 4800 64GB
  • M/B: MSI X670-P WIFI
  • SSD: M.2 PCIe4 2TB
  • OS: Win11 Pro(WSL2 Ubuntu 22.04)

FP32 画像分類モデルトレーニン

transformersをGitHubからクローンしてくることで利用可能なexamplesを実行します。とりあえずROCmでも問題なく実行できました。

https://github.com/huggingface/transformers/blob/main/examples/pytorch/image-classification/run_image_classification.py

GPU train_samples_per_second eval_samples_per_second train ratio(MI50x1=1) eval ratio(MI50x1=1)
MI50x1 35.686 90.745 1 1
MI50x2 33.933 69.598 0.9509 0.7000
P40x1 31.508 76.755 0.8829 0.8458
P40x2 37.566 74.594 1.0532 0.8219
RTX4090 101.406 197.71 2.8416 2.1787

結果、MI50は1枚のほうが速いという結果に。

1枚勝負ならP40よりもTrainでもEvalでも速いことがわかった。P40x2のTrainでは流石に負けるがその差は僅か。

FP16 言語モデルレーニン

使ったExampleは次のURLのもの。VRAM量の関係からBatch sizeを4に落として実行しました。

https://github.com/huggingface/transformers/blob/main/examples/pytorch/language-modeling/run_clm.py

GPU train_samples_per_second eval_samples_per_second train ratio(MI50x1=1) eval ratio(MI50x1=1)
MI50x1 7.015 19.792 1 1
MI50x2 5.595 11.597 0.7976 0.5859
P40x1 4.582 12.63 0.6532 0.6381
P40x2 6.485 12.787 0.9244 0.6461
RTX4090 19.049 52.211 2.7155 2.6380

結果、1枚のMI50がP40x2よりも速いことがわかった。

レーニングのベンチマーク結果からは、少なくともMI50 1枚は同価格帯のP40よりも性能が高く、VRAM量を気にしなければコスパが高いと言えるだろう。

なんなら30万するRTX4090の1/3~1/2くらいの性能は出ているので、コンペなどでも意外と使えなくもないかもしれない。

SDXL1.0 画像生成

automatic1111のWebUIから、sd_xl_base_1.0による512x512の画像を1枚生成するときの速度を比較。5回生成したときの実行時間の平均を取りました。

P40におけるセットアップは前回ブログでも紹介した次の記事を参照。

https://pc.watch.impress.co.jp/docs/column/ubuntu/1493536.html

ROCmにおけるセットアップは公式のAMD用ガイドを参考にしました。

https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Install-and-Run-on-AMD-GPUs#running-natively

基本的には前回のセットアップ編で記載したvenv環境で./webui.sh --precision full --no-half --listenまたは./webui.sh --upcast-sampling --listenのどちらかのコマンドを実行すれば良いです。

  • MI50(--precision full --no-half): 8.4s
  • MI50(--upcast-sampling): 7.3s
  • P40(オプション無し): 10.9s

いずれにおいてもP40よりも早く推論できています。VRAMの使用量は--precision full --no-halfで88%、--upcast-samplingで47%と、SDXLをなんのオプションも付けずに動かす分にはFP32でもメモリは足りています。

よく画像生成用に買われているRTX3060よりも安く、メモリも多く、しかも結構速いということで、冷却の問題を解決できるパワーユーザーならMI50はアリだと思いました

【セットアップ編】Radeon Instinct MI50を買って機械学習用に使ってみる【ROCm】

まえがき

しばらく大きな買い物をしていなかったが、仕事からの現実逃避をしているとふと思う。「ROCm、試してみたいなー」

ということで、ebayを開きめぼしいGPUを探してみたところ、$200以下のお手頃価格で一応ギリギリ最新のROCm 6.0.2にもメンテナンスサポートされているMI50を発見。

送料も考えて2枚まとめて買ってみたので、数回に分けてROCmのインストールから機械学習用の環境構築、以前に買った同価格帯の中古サーバー用GPUの先輩であるNVIDIA P40との比較までを書いていこうと思う。

今回はセットアップ編ということで、取り付けとROCmインストールでrocm-smiが動くところ、PyTorch上でGPUが認識されるまでを書いていく。

hashicco.hatenablog.com

  • P40の記事

hashicco.hatenablog.com

  • 取り付け時のXポストたち

まとめ

  • ebayでMI50 16GBが1枚$190で買えました。2つ買って送料、消費税込でだいたい70,000円くらい

    • MI25も似たようなスペックですがMI50のほうがアーキテクチャが少し新しく(MI25がgfx900, MI50がgfx906)、メモリバス幅が倍なので、大した金額差ではないしMI50を選択しました。
  • 今回冷却用にArcticの新しいファン(S8038-10K)を買いました。こいつが中々のモンスターで、80mmファンで500~10000rpmのPWM制御が可能、MAX102cfmというスペック。

    • 10000rpmだとノイズもやばいXに動画を上げときましたが、見るときは音量注意
    • 5000rpmくらいに抑えると結構な風量の割に音も耐えられる感じなので、ipmitoolを使ってファンコントロールしました。
    • 1個$16ですが、米アマで4個まとめ買いして大体送料込み12000円くらい
  • ROCmのインストールは拍子抜けするほど簡単!コマンド数行でつつがなく終了したので、下手するとNVIDIAのドライバとCUDAインストールよりも簡単だったかもしれない。

  • 買ってしばらくして気づいたのですが、私の買ったMI50はどうやらRadeon VIIのVBIOSが焼かれているようで、PCからはRadeon VIIとして認識されてるっぽい

    • 購入先はebayのcomputewarehouseというショップ。現在MI50のVBIOSをもらえないか問い合わせ中
    • (20240410 追記) computewarehouseの担当者と連絡が取れ、MI50のVBIOS Flasherをいただくことができた。まだ試せていないが、もしうまくいったらなにか書く予定。
    • MI50をRadeonVIIにする改造は結構広く行われているようなのでまあこのまま使ってもいいのだが、FP64の性能が半分になるらしい。
    • オリジナルをそのまま使いたい気持ちもあるので可能ならVBIOSを書き換えたいのですが、MI50のものはどこを探しても発見できず……。
  • マシンとしては前回作成したEPYCマシンのP40を載せ替え、SSDをサラのに交換したものを使ったのだが、M/BのH11SSL-iでのファン制御は結構苦戦した。

    • 結果的にBMCを最新にアップデートすることでipmitoolによるファンの固定値制御がうまくワークするようになった
  • ちょっとしたトラブルとして、GPU2枚のうち1枚、付いていないはずのGPUファンの表示上の速度が過負荷時に異常に下がって報告されてしまい、システム異常を示すと思われる凄まじいビープ音を発する現象が確認された

    • おそらくRadeonVIIのVBIOSが焼かれていることが原因と思われる。
    • 結局rocm-smiでファン回転数を固定値とすることで問題は解消した。

次から詳しい説明です。興味のある方はどうぞ。

カードの取り付け

  • MI50

今回はアメリカからの発送で受取まで約3週間くらいかかりました。

カードの見た目が中々カッコよくていい感じ。P40と並べて撮影してみても、Radeon Instinct MI50のほうがモダンで高級感があります。

  • S8038-10K

80mm, 38mm厚のマッシブなファンです。まるで120mmファンのような102CFM、強力な51mmH2Oというものすごい静圧ファン。

  • ファンを取り付ける

いつも通り段ボールを使って無理くりブラケットを作ります。カードの上部に出っ張りがあり加工が中々難しかった……。

本当は上部にInfinity fabric connectorの繋ぐ場所があるのですが、肝心のコネクタ自体が買える値段で売ってなかったので使いません。

  • 出来上がったもの

前回作ったEPYCマシンに2枚のMI50を刺します。段ボールの見栄えが悪いし下手すると燃えそうなので真似する場合はあくまで自己責任で!

OS準備とファン制御

今回OSはUbuntu 22.04を使います。ROCm 6.0.2は20.04または22.04対応とのこと。

OSインストールについては、いつも通りEtcherにISOを焼いて新しいSSDをにインストールします。

で、あとはROCmをセットアップ……と行きたいところですが、ファン制御をしないことには10000RPM近くでGPUファンが回るのでとても煩くて作業できません!

ということでファン制御の方法を調べてみるとipmitoolというコマンドで制御できるらしい。

hassiweb.gitlab.io

指定する0x30や0x45などのHexコードの意味はよくわかりませんが、とりあえずファンモードをFullにしたうえで、ファン回転数を手動設定すればいいらしい。

GPU用とその他のファンで制御を分けたかったので、本来の使い方とは違いますがFANA, BコネクタにGPU用のS8038-10Kを接続し、他のファンはFAN1~5に接続します。こうすることで、GPUファンはペリフェラル用のファンゾーン(0x01)で制御できるようになります。

# ファンモードの変更。0x01がFullを意味するらしい
sudo ipmitool raw 0x30 0x45 0x01 0x01

# ファン回転数の手動設定。後ろから2つ目のHexがファンゾーン。今回はペリフェラルの方を制御したいので0x01を指定。
# ファンの回転数は一番うしろのHexで指定。0x00~0xFFの256段階で指定できる。今回は約5000RPMをターゲットにするので0x32を指定
sudo ipmitool raw 0x30 0x70 0x66 0x01 0x01 0x32

……が、何度このコマンドを実行しても一時的にファン回転数が下がるもののまた最大に戻るという挙動が発生。煩すぎてまともに作業できないので一旦電源を落として情報を探したところ、次のフォーラムでBMCのアップデートを行うことが推奨されていた。

forums.servethehome.com

結局こちらの内容がドンピシャで、BMCをアップデートしたらちゃんと上記コマンドでファン回転数を制御できるようになりました

ちなみに、BMCのアップデートファイルはこちらで配布されています。H11SSL-Iで検索したら出てきたv2.09に更新しました。

www.supermicro.com

ROCmのインストールとPyTorchセットアップ

で、ここが本題になるはずだったのだが、あまりにも簡単にインストールできてしまったので取り立てて書くことはなく、基本的に公式ページの内容通りに作業すれば良い

最終的にTransformersのExamplesで性能検証をしていきたいので、huggingfaceのAMDページにあるインストラクションに従って作業していきます。

huggingface.co

1. Confirm you have a supported AMD hardware platform

私の買ったMI50はギリギリサポート中。Deprecated - Support will be removed in a future release.だそうです。

rocm.docs.amd.com

2. Install ROCm driver, libraries and tools

次のページを参考にインストール。

rocm.docs.amd.com

今回はAMDGPU Installerという方法を試します。基本は上記のページのコマンドを利用しますが、特にグラフィック出力は使わないので--usecaserocmのみにしておきます。

sudo apt update
wget https://repo.radeon.com/amdgpu-install/6.0.2/ubuntu/jammy/amdgpu-install_6.0.60002-1_all.deb
sudo apt install ./amdgpu-install_6.0.60002-1_all.deb
sudo amdgpu-install --usecase=rocm

20GBくらいダウンロードが行われますが、特にエラーもなく正常終了。

3. Install Machine Learning Frameworks

pipからのインストールがおすすめされています。

とりあえずvenvで仮想環境を切ったうえで、下記コマンドを実行していきます。

PyTorchは専用の--index-urlを指定し、TensorFlowはtensorflow-rocmという別名パッケージを指定してインストールするだけ。

pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/rocm5.7
pip install tensorflow-rocm
pip install transformers

これも特に問題なく実行できました。

4. ユーザーのグループ追加

rocm系のコマンドの実行にはユーザーをrendervideoというグループに参加させる必要があります。

sudo usermod -aG render USER名
sudo usermod -aG video USER名

で、最後にマシンをリブートします。リブートしないとPyTorchからGPUが見えませんでした。

5. rocm-smiの内容確認

で、ここまでやれば普通にrocm-smiというnvidia-smi的なコマンドを実行できるようになります。

表示内容は次のスクショみたいな感じ。GPU使用率、VRAM使用率など確認できます。

6. PyTorchからのGPU認識確認

で、PyTorchからどのようにROCmデバイスを利用するかといえば、基本的には普通にcudaデバイスと同じ扱いで良いようです。つまり、すでにNVIDIA GPUで動いているコードであれば特に変更する必要はなく、modelとデータを全部.to("cuda")で同じデバイス上に送っておけばOK。

ということで、GPU認識の確認もいつもどおりの次のコマンドでOK。次のスクショのような感じで確認できます。

import torch
print(torch.cuda.is_available())
print(torch.cuda.device_count())
print(torch.cuda.get_device_name())

拍子抜けするほど簡単に、なんの問題もなく2枚のMI50(RadeonVII)が認識されました。

ファンスピードを固定する

まとめにも書いたが、RadeonVIIのVBIOSが焼かれているからかもしれないが、高負荷時に存在しないはずの表示上のファンスピードが極端に遅くなり、下限に達したためかけたたましいビープ音を鳴らしたことがありました。

結果、rocm-smiの --setfan でファンスピードを固定値にしたところ問題が解消。どのみちファンはGPUカードに刺さっていないのでそこそこ高め(私はとりあえず100に設定。255段階っぽい。)に設定しておけばOKだろう。

manpages.debian.org

次回予告

次回はP40とガチンコベンチマークバトルの予定!全部データは取ってあり記事を書くだけなので、なるべく早めに上げたいと考えています。

とりあえず簡潔に言うとMI50はP40に対してそんなに性能的優位は示せていない。とはいえ、VRAMいらず単にStableDiffusionを動かすだけとかならもしかしたら最もコスパの良いGPUになるかも?といった感じ。詳細は乞うご期待。