CUDA12対応のonnxruntimeあるある

Pythonユーザでonnxruntime使ってよくあるトラブル。

最新のonnxruntime-gpuを入れたのにCUDA(CUDA Execution Provider)対応できない件。

 

NVIDIA - CUDA | onnxruntime

Install ONNX Runtime | onnxruntime

 

公式に書いてあるんだけど

onnxruntimeの1.17(1.17.1も同様)では想定しているCUDAは12.2とされているんだけど、デフォルトで配布されているバイナリはまだCUDA11.8でビルドされている。

CUDA12対応のバイナリは以下のコマンドで入る。

pip install onnxruntime-gpu --extra-index-url https://aiinfra.pkgs.visualstudio.com/PublicPackages/_packaging/onnxruntime-cuda-12/pypi/simple/

 

NuGet(所謂Visual Studioとかで使うパッケージマネージャー)でも同様なのでCUDA12使う人は気を付けて下さい。上記リンク先にインストール方法書かれています。

比べて、Appleシリコンの方はデフォルトに吸収されたのでpip install onnxruntimeだけで今はCoreML使えます。

 

---

追記(03/16):

NVIDIA - TensorRT | onnxruntime

TensorRT Execution Providerを使う場合でもTensorRTのバージョンが指定されている。

これ以外だと色々とトラブルが発生することがある。

もちろんソースを持ってきて自分の環境用にバイナリを作ればいいんだろうけどそれぞれバージョン上がるたびに毎回それも手間ですね。

そのうちバージョン間互換性も増してくると思われるがCUDA界隈は絶賛更新中なので大変。

ですが、CUDA Execution Providerより性能出るのでせっかくなら使ってみましょう。

以上の場合まだ、zlib dllが必要なバージョンなのでお忘れなく。

AobaZeroで遊ぼう21(バージョン43リリース記念編)

AobaZeroネタは随分と御無沙汰です。

前回から2年近くになりますか。

bleu48.hatenablog.com

 

その間の更新で目ぼしいのを上げますと

2022年7月 v37 平均playout数が772から1568に

2022年11月 学習率を大きくして序盤や早い投了棋譜の学習割合を減らす

2022年12月 v39 cPUCTを動的に変更、王が逃げる手1手を延長。棋譜にNNの生のValueとPolicyを記録するように。

2023年3月 互角の局面の学習確率を減らす

2023年12月 v41 平均playout数を1600から3200に

2024年1月 先手勝ちの学習確率を減らす(先手勝率7割超のため)

2024年2月 v43 WindowsNVIDIAのドライバを更新したときのエラーとCPU内蔵のGPU(Intel Iris Xe)でもOpenCLが動作するように修正

 

2022年7月と2023年12月と2回のplayout数の倍増で元の4倍になっています。

これで教師データが相当強くなりますが棋譜生成速度が随分と遅くなり更新頻度が落ちることになります。特に2023年12月の変更の効果は先月に入ってからやっと効果が出てきたかどうかという雰囲気です。

教師データ生成に参加できるのですが、個人的には新規マシンの負荷テストに用いて長いときは2,3日ぶん回しています。電竜戦のハードウェア統一選の前に負荷テストを簡単にしておこうとして、NVIDIAのドライバアップデートから正常動作しなくなったのに気づき報告しておりましたら先月末にv43で対応いただきました。OpenCLの型定義の件で同様のことがAoba駒落ちでもありましたのでこちらの更新もお願いしておきました。

AobaZero

Aoba駒落ち

Aoba駒落ちもv27で対応いただきました。最新のGPUで強くなるということです。

 

新ネタとして仕入れた8700Gでもテストしてみたところ、700nps程度は出ることが確認できました。

8700Gの話その1(Ryzen AI評価の基準確認) - 48's diary

floodgateに放り込んでいたのですが長時間走らせていたためか途中から異常がみられ連敗しておりました。レート計測を乱した件各方面にお詫びします。

v41でもv43でも見られましたのでその間の修正とは無関係な不具合のようですが、以前の5700GなどのAPUでも熱暴走的な挙動は見られましたので同様の熱暴走かもしれません。確認した温度は常に60度程度なので断定は避けますが、長時間運用向きではないとしておきます。

記憶の範囲では安定動作している間のレートはkld_avg_3200pを上回っておりました。固定10秒ですので7000p相当と考えれば妥当です。

 

同タイミングでIntel Iris Xe(i5 1240P)でも同様なテストをしたところこちらは400nps程度で200戦ほどでレート3608といったところです。固定時間10秒としましたので、KL情報量制御を加えた方がレートにして100程度は有意に強いと言えるでしょう。

 

徐々に二番絞りのアドバンテージはなくなってきている感じですね。

今年の選手権ではどうなることやら。

 

8700Gの話その1(Ryzen AI評価の基準確認)

色々とイベントがある合間にRyzen 7 8700Gを仕入れておりました。

まぁ,個人的に最近のホットな話題であり,世間的には世界初のNPU搭載デスクトップCPUとして一部マニアの注目を集めております。

AMD Ryzen™ AI - Windows Laptops with AI Built In

 

前世代のAPU(5700G)でのAI性能は以前から試しており今回はこの辺基準で8700Gを評価していきます。

APUでDirectML - 48's diary

比較対象としてMacのCoreMLも簡単にテストしてあります。こちらもNPU搭載機です。

CoreMLの実験(dGPU無い勢) - 48's diary

 

NPUって何かって話はこの辺でしてありますが,今年はAI関連ソフトウェアが一気に普及帯のPCでも動くようになっていくと思われます。(実際は2,3年はかかると思います)

2024年のキーワードNPUの話 - 48's diary

 

で,Ryzen 7 8700Gですが出た直後に有無を言わさず発注したので5万円台の後半でした。すぐに前半もしくは4万円台に落ちると思います。

ソケットはAM5ですのでAMDの対応マザーは多くありますが気を付けないといけないのはBIOSのアップデートを行わないと動作しないものがマーケットに多くあります。今後出荷されるようなマザーボードは出荷時に対応されると思いますが,私がそうであるように他のCPUをもってBIOS更新を行う必要がありました。

 

起動してしまえばなんてことは無い普通のAPU機です。リテールファンで問題なく冷却可能な省電力(65W)でGPU内蔵のCPUとして申し分ありません。うっかり500Wの電源で組んでしまいましたが,AsrockのDesk miniとかで組むのが良い感じになるでしょう。

で,上記実験と比較するためにDirectMLでテストを行っています。

現状雑感ですが,Macや5700Gの1.5~2倍近いパフォーマンスと言って良いでしょう。

これは他のゲーミングベンチマークを取っているところでも似たような評価です。

 

内蔵GPURadeon 780Mと呼称されているのでnibanshiboriを同名でfloodgateに放り込んでみました。

Player Statistics

レートは3800台ですので以前GTX1060などで記録した付近です。パフォーマンス的にはGTX1060を超えているので安定するともう少し上かもしれません。もう驚く必要はないですが他のモデルと精度が違うのは明白ですね。

特筆すべき一局があったので記録しておきます。GTOはレート4500 overですので相当なスペックのPCかと思います。二番絞りは探索ノードが少ないときに後手番で振り飛車しがちなのですが,これも後手四間飛車です。で,勝ってしまっています。

GTO vs. ns_780m (2024-02-15 16:00)

これ500nps程度なので20秒使う手がありますが,そこで精々10000ノードの探索なのです。

 

この辺はさておき現状のDirectMLは恐らくRyzen AI未対応ですので,今後の対応でどこまで向上するかの基準となると考えています。CUDA界隈でも新しいハードウェアが出てからソフトウェア対応する間の過渡期で結構なパフォーマンス向上がありますので,その辺を期待しております。特にRyzen AIに限らずNPU対応は今年の多くのソフトウェアの課題となると思います。楽しみですね。

 

---

追記:

floodgateにおいて200戦近く行い最終レートが3900付近でした。

dGPU無しでの到達レートとしては最高レベルかと思います。

加えてその間熱暴走など皆無ですので8700GはAI用途でも連続高負荷で問題ないと判断します。

 

この辺りから比べて随分とレートを上げました。

非GPU勢DL組 - 48's diary

 

 

 

 

 

 

 

 

Go 1.22のrange over int

今月リリースされたGo 1.22でrange over intと言う拡張と言うか表記表現が加わった。

 

よく使われるforループは以前以下のような書き方をしていた。

    for i := 0; i < N; i++ {
    // ループの中
    }

iがループ変数で0からN-1までN回のループとなる。

Pythonなどでは既にある記法であるが以下のような表現が可能になった。

    for i := range N {
    // ループの中
    }

ベンチマークなどのループ変数のiを参照しないケースであれば,さらに以下のように省略も可能である。

  for range N {
    // ループの中
    }

 

ということで少し試してみた。

以前から制作している将棋エンジンの対応可能なループを全てrange over intに書き換えてみたところ,ベンチマーク上は特に変化が無かった。

整数の固定ループ化で速度向上を期待していたところ微妙なところむしろ遅くなった印象である。

 

心当たりはループ変数の扱いの変化である。

Go 1.22ではforループ時のループ変数を別アドレスに取るように変更になった。聞きかじったレベルの理由としては,Goでよく実装されるループ中のgoroutineでループ変数を参照する場合参照時には次のループに入っているケースが多く,よくある対応としてループ内変数に一時保存して参照しなくてはならない。この対応を不要にするためにアドレスを個々に与えているようである。

しかしながら,これをやってしまうとN回ループにN個の整数を別アドレスに確保する,つまりリスト生成をしてしまうことになる。せっかくの高速化チャンスである固定ループが台無しになっていると思われる。

 

まぁ,Goの使われ方を考える限り間違った対応でもないしこのレベルの速度を気にするのはHPC分野の人くらいだろう。Goでコーデックの類も書かれているらしいが気にならないのだろうか。

 

メモ化再帰とデコレータ

何故か知らないが土曜の夜に妙なキーワードがトレンド入りしていた。

 

 

プログラミングコンペが行われていた時間らしく同スキルを求めるような出題であったようである。詳しくは知らない。

 

せっかくの機会なので簡単に復習しておく。

Pythonには鉄板のメモ化ライブラリが存在する。

functools --- 高階関数と呼び出し可能オブジェクトの操作 — Python 3.12.2 ドキュメント

 

from functools import cache

@cache
def fib(n):
    if n < 2:
        return n
    else:
        return fib(n - 1) + fib(n - 2)

for i in range(40):
    print(fib(i))

 

キャッシュサイズに制限を加えたければlru_cacheを使うと良い。

上記は簡単なプログラムであるが@cacheのデコレータの部分をコメントアウトするとどういう挙動になるかどうか試して頂きたい。

 

フィボナッチ数列再帰呼び出しで典型的な課題であるが,数学的な定義でプログラミングすると上記のようになる。メモ化されていないとそれ以前の数列の値を再帰的に計算しなおすことになるがこれが不変であることからキャッシュに保存しておくことで劇的に速くなる。

 

メモ化情報を揮発性のRAMで残すのが上記の手法であるが,不揮発性のストレージなどに残す場合もあり,こういった場合はメモ化の永続化と言われる。一般的にはKVSのデータベースが使われることが多い。

ゲームAI界隈だと同じ局面が何度も見られた場合に以前の計算結果を流用するという意味で,定跡データベースというものがこれに当たるが,こちらは対戦前に計算しておいて溜めておくという計算リソースの前借という表現が適当であろう。

 

キャッシュが何をしているかと言えば,(ほぼ)同等コードが下記のようになる。

 

def cache2(f):
    table = {}
    def f2(*args):
        if not args in table:
            table[args] = f(*args)
        return table[args]
    return f2

@cache2
def fib(n):
    if n < 2:
        return n
    else:
        return fib(n - 1) + fib(n - 2)

for i in range(40):
    print(fib(i))

 

ついでにデコレータも復習しておこう。

デコレータも上記のように自分で作ることが出来るが意味は下記のようになる。見通しが悪くならず後置してよければデコレータを使わずに同じ意味だ。

def cache2(f):
    table = {}
    def f2(*args):
        if not args in table:
            table[args] = f(*args)
        return table[args]
    return f2

def fib(n):
    if n < 2:
        return n
    else:
        return fib(n - 1) + fib(n - 2)

fib = cache2(fib)

for i in range(40):
    print(fib(i))

 

どちらかと言うとBlogにコードを貼る復習になった感じである。

探索無しのゲームAIの話

ゲームAI界隈で話題になったらしい。

またDeepMindに追いつかれた気分です。

arxiv.org

 

機械学習で完成したモデルの強さが探索無しでチェスのグランドマスター級だそうです。

将棋の方はほぼ一年前なのですが,うちの二番絞りが探索無しでプロ棋士級になっています。

コンピュータ将棋界隈で恐らく最も大きな深層学習モデルを使っており最高精度を誇ります。

 

bleu48.hatenablog.com

bleu48.hatenablog.com

 

最高到達レートで2949ですので人類でこのレベルになるのはプロ級しかおりません。

3000超えたプレイヤーも見たのですが次のときにはBANされていたのでソフト指しなのでしょう。YouTuberで2800台の方はおります。

奨励会時代の藤井さんが一瞬近い値を出したとかいう話は真偽不明ですが噂で聞いたことがあります。

 

旧型PCの0.1秒未満・探索無しでこのレベルに到達してしまうほどには機械学習の教師データも世の中に揃ってきたと言えます。強化学習の練習問題としては次を探す時期に来たのかもしれません。

そう言えば囲碁の方はまだ欧州上位級(2,3段?)でしたね。

 

ちょっと追記しておくと,floodgate上では上記の探索無し二番絞りのレートはそれほどでもありません。理由は明白で将棋の場合最終盤で詰む詰まないを読むのは古典的な探索AIの得意とするところで随分古くから人間を凌駕しており,これがあるかないかで全く終盤の強さが変わります。(これは将棋強い人なら分かると思います。最終盤の古典AIは間違えません。)

ということで,これが全く無いモデルでもそこそこ戦えているのが驚異的と見るのが正確な表現かと思います。探索無しで詰将棋を結構解くことが出来ている二番絞りのモデルは正直オーパーツ的ですらあると言えます。

 

対AI戦でレートがあまりよくなくても対人戦ではそこまで相手の終盤力が無いので勝てると言う感じでしょうか。チェスは終盤の方が簡単になるのでそこは楽ですね。

第2回マイナビニュース杯電竜戦ハードウェア統一戦(予選)

本年度は多方面で過労気味で本戦のまとめも遅れてしまいました。

第4回電竜戦本戦 - 48's diary

大手メディアでも本まとめの先手勝率に関して取り上げて頂いたようで将棋界での反響も大きいものかと思います。

 

で,ハードウェア統一戦に関して昨年度は運営準備に走り回りなんとか開催にこぎつけた感じでした。

電竜戦マイナビニュース杯ハードウェア統一戦開幕 - 48's diary

結果的にも様々な戦型を含む多くの棋譜を残せたこともあり非常に有意義な大会であったと個人的にも満足しています。

第1回マイナビニュース杯電竜戦ハードウェア統一戦の戦型分析 - 48's diary

多くの将棋関係者からも後々になりましたがコメント頂きました。

 

問題点と言うほどのことでもないのですが,運営メンバーである私が決勝に残っているのがどうも公平な大会に見えないとの指摘がありましたので,本年度はノータッチで昨年のものをそのまま使うと言うサンドバッグ役を担当します。

まぁ,単に勝ちたければうちの敗着棋譜を分析してそのまま指しても勝てるということです。

また,年越しの間のリモート操作で不手際な感じがするとのことで今年度は年明けの1月12日に開幕としました。

 

開幕前にアナウンスしなければならないところでしたが

既に予選を終えてしまいました。

電竜戦

www.youtube.com

解説の窪田先生が交通トラブルで結局どこから中継に参加されたのか分かりませんがなんとか間に合われたようで少し肝を冷やしました。

 

予選リーグ表は240戦の膨大な組み合わせを自動化して行われており詳細分析的なものは今後行わると思います。運営トラブルも昨年は少しあったものの今年はほぼ皆無です。

【予選】第2回マイナビニュース杯電竜戦ハードウェア統一戦 勝敗表

(少しは分析してからブログにしようと思ったのでなお遅れてしまいました)

 

雑感として全勝も全敗も居ない接戦と言うのは昨年と変わりません。一部Daigorillaが一勝しかできていない事象がありますが何らかの設定ミスかもしれません。しかしながら,後手番の水匠に大きな逆転勝ちをしているなど必ずしも強い弱いと一元的に扱えないという事実を示してくれました。総当たりリーグの主催者としては非常に面白い結果と言えます。

 

で,2月4日の本日に決勝トーナメントの初戦があります。