端の知識の備忘録

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

家パチ・家スロを買ってみた + スロのデータカウンターをArduinoで自作する

概要

家は広くなったものの買うものが無くなってきた30歳独身オタクとして、とうとう来るところまで来てしまった感のある買い物。

ここ1年くらいで友人に連れられて若干パチを打っていたのですが、球がランダムに跳ねながらヘソに入る様子を眺めつつ、たまに視覚・聴覚・触覚に強烈に訴えかける刺激が加えられ、うまくいけばお金が増える、という単純ながら人間の射幸心を巧妙に操作するその仕組みは確かに「面白い」。どちらかというと薬物とかに近い面白さな気がするが、良いように言うと頭が空っぽになり中々チルな感じとも言えなくもない。

ただ、10回ほど打って思ったのが、とにかく今の台は荒いし釘もキツ過ぎて楽しいよりもストレスのほうがデカい。最終的な収支は本当にトントンくらいだったが半日打つと収支はほとんど±50K以上で、40000発勝ちに脳を焼かれたかと思ったらその後-50Kが3連続続くとか、こんなものを続けていたら頭がおかしくなってしまう。

ということでホールで打つのは一旦引退し、ストレスを排し頭を空っぽにする機械として実機を家においてみることにしたお話。

おまけにデータカウンターがマイコンボードで自作できるという記事があったので、うちに転がっていたArduino Leonardoを使って自作してみることにした話も付け加えておく

kinketsu-patron.com

まとめ

  • 買った台は次の2台
    • パチンコ: CR聖戦士ダンバイン256ver: 44,000円@メルカリ
      • 家庭用電源、循環加工済み。別途パチンコを固定するためのこんな台も買った。
    • スロット: パチスロマクロスデルタ: 37,262円@A-slot
      • 家庭用電源、コイン不要機付き
  • 実機を置く台としては段ボール製のシンプルスタンドを購入
  • 重さ的に一人で設置できるのか大分不安だったが、163cm/50kgチビガリの自分でもなんとか設置できた。
    • スロットは何とか自力で持ち上がったのでそんなに設置には苦戦せず。パチンコのほうが大分重いので手こずったが、倒した状態で片側を持ち上げるとかしながら気合で対処した。可能なら友人を召喚しましょう。
  • 自作カウンターはArduinoとブレッドボード、抵抗数個があれば簡単に作れる
    • 外部集中端子というIN/OUTや当たりの情報を出力する基板がついているので、そこから得られる信号を受け取るような仕組み
      • パチンコのほうはまだ信号の受け取り方がわかっておらずカウンターを作れていない
    • pyserialでArduinoから情報を受け取りSQLiteに保存し、Flaskでウェブアプリとして表示するような仕組みを作成することで、タブレットから台のデータを見れるようにした

いずれにせよ、ゲーム機が平気で7万とかする時代にこれだけデカくてちゃんとした遊技機が3万とかで買えるのはお得感がある。理解のある人しか家に入れられないようにはなるが、それを厭わない人なら1台くらい持っててもいいのかも。

設置例

もう終わりだよこの家

台の選定、購入時の懸念点について

既に友人が家パチを導入しており台によるが3万代から買えると聞いていたので、1日の負け額より少ないじゃん!みたいな考えで安めの台からパチ・スロ1台ずつを買うことにした。どうせ今年の8月に邪神ちゃんのスロが出る予定でこれの実機はいつか買うつもりなので、その予行練習も兼ねている。

パチンコのほうは好きな作品であるダンバインの台を買うことにした。すでにホールに存在しないが妙に評判のいい1を打ってみたかったのもあり、メルカリで役物も動作する256ver.が出ていたので送料込み44,000円で購入。古い台ということもありあまり綺麗ではなかったが、軽く清掃したうえでとりあえず無事に動いている。

スロットのほうはA-slotでGWセールをやっていたので安い台で知っている版権のものを買うことにした。定番として北斗・エヴァ・まどマギも考えたが、あえて普通には打たなさそうなマイナー目なマクロスデルタを選択。送料、コイン不要機込みとGWセールのおまけで段ボールスタンドもついて37,262円で購入できた。こちらは専門店の品ということもあり非常に状態が良く、清掃も必要なかった。

で、未経験の状態からいざ実機を買うとなるといくつか不安となる点があった。ということで購入前に考えていたことと、実際に買ってみてどうだったかをまとめておく。

  • 台の重さはどれくらいなのか?一人で設置できるのか?
    • 公式サイトなどで重さが公開されていることはあまりないが、ネットで調べるとパチンコは40kg前後、スロットは30kg前後のものが多いようだった。
    • 163cm/50kgのチビガリの自分でもなんとか設置できたので、普通の成人男性なら問題なく設置できると思う。理解のある友人がいるなら呼んだほうがいいだろう。
  • 家パチ・家スロ用語: 家庭用電源?循環加工?役物停止?コイン不要機?音量調整?
    • パチの場合: 家庭用電源、循環加工、音量調整が必須オプション。役物停止加工はお好みで。
    • スロの場合: 家庭用電源、音量調整が必須オプション。コイン不要機は無くてもメダルがあれば遊べるのかもしれないが、音や管理の面倒さを考えるとこれも必須級のオプションだと思う。
      • スマスロの場合は別途ユニットが必要らしいので注意。
  • 騒音問題
    • パチもスロも音楽やSEは調整可能なので意外と気にならない(駆動音以下にできるという意味で、音量MAXとかにするなら別)。それより問題は駆動音
      • パチンコのほうは役物が動くときの音、球の打ち出し音が結構大きい。
      • スロットのほうはそこまで気にならないが、リールの回転はそれなりに振動がある。メダルを使う場合はさらに煩いと思うので、音を気にする場合はコイン不要機は必須だと思う。
    • 一応振動防止のカーペットを敷いてみたが、どれだけ下に響いているかはわからない。今のところ苦情が来たことはないが、とりあえず20時以降に打つのは控えている。
      • 2階以上に住んでいる人は良く考えて買ったほうがいいと思う。
  • 必要な付属品
    • 上記の筐体加工以外にも、必要に応じて実機を置くためのスタンドや、パチンコ台を固定する台も必要。
    • スタンドは段ボール製のものが5,000円程度で売っている。耐荷重は100kg以上あるので、パチンコ・スロット両方とも問題なく置けると思う。
    • パチンコ台の固定台は中古で買う場合ついていることもあると思うが、ない場合は別途買う必要がある。適当な木製板で自作してもいいかもしれないが、専用のものも売っている
    • パチンコの場合循環加工をしていても数十発分の球は必要。これも多分中古で買う場合はついてくると思うが、ない場合は別途買う必要がある。
    • 台を開けるための流通鍵はついてきていることが多いと思う。

とりあえず買う分には結構気楽に買えるが、買ったもののまともに稼働できるかは環境次第だと思う。最初からガチな金属ラックやデータカウンターなどの周辺機器を揃えると意外な制限にぶち当たり処分が大変になる可能性もあるので、まずは簡易スタンドと安い台を買ってみて、環境的に問題なさそうなら周辺機器を揃えていくのがいいと思う。

データカウンターの自作

このサイトを大いに参考にさせていただいたが、スロットのデータ出力は単純なリレーのON/OFF信号なので、電圧をかけた上でArduinoのデジタルピンで受け取るような仕組みを作れば簡単にカウンターが作れるらしい。

家にLeonardが余って転がっていたのでこいつを使うこととし、動作確認として次のようなコードでシグナルをカウントすることができると思う。

// --- ピン割り当て (Leonardoの割り込み対応ピンを使用) ---
const int PIN_IN  = 0; // 外部集中端子の1番
const int PIN_OUT = 1; // 外部集中端子の2番
const int PIN_RB  = 2; // 外部集中端子の3番
const int PIN_BB  = 3; // 外部集中端子の4番

// --- カウンタ変数 (割り込み内で変更するため volatile を指定) ---
volatile unsigned int count_IN  = 0;
volatile unsigned int count_OUT = 0;
volatile unsigned int count_RB  = 0;
volatile unsigned int count_BB  = 0;

// --- チャタリング防止用の時間記録変数 ---
volatile unsigned long last_time_IN  = 0;
volatile unsigned long last_time_OUT = 0;
volatile unsigned long last_time_RB  = 0;
volatile unsigned long last_time_BB  = 0;
const unsigned long DEBOUNCE_DELAY   = 50; // チャタリング防止時間(ミリ秒)。実機に合わせて調整

// --- データ送信用のフラグ ---
volatile bool data_updated = false;

// ==========================================
// 割り込み処理関数 (ISR)
// ※割り込み処理内ではSerial.printなどは使わず、最小限の処理にする
// ==========================================
void isr_IN() {
  unsigned long current_time = millis();
  if (current_time - last_time_IN > DEBOUNCE_DELAY) {
    count_IN++;
    last_time_IN = current_time;
    data_updated = true;
  }
}

void isr_OUT() {
  unsigned long current_time = millis();
  if (current_time - last_time_OUT > DEBOUNCE_DELAY) {
    count_OUT++;
    last_time_OUT = current_time;
    data_updated = true;
  }
}

void isr_RB() {
  unsigned long current_time = millis();
  if (current_time - last_time_RB > DEBOUNCE_DELAY) {
    count_RB++;
    last_time_RB = current_time;
    data_updated = true;
  }
}

void isr_BB() {
  unsigned long current_time = millis();
  if (current_time - last_time_BB > DEBOUNCE_DELAY) {
    count_BB++;
    last_time_BB = current_time;
    data_updated = true;
  }
}

// ==========================================
// 初期設定
// ==========================================
void setup() {
  // シリアル通信の初期化
  Serial.begin(9600);
  
  // 【重要】Leonardo特有の処理:USBシリアル接続が確立するまで待機
  while (!Serial) {
    ; // シリアルモニタが開かれるまで待つ
  }
  Serial.println("System Start!");

  // ピンのモード設定
  // 外部プルアップ回路がある場合は INPUT、無い場合は INPUT_PULLUP にしてください
  pinMode(PIN_IN,  INPUT); 
  pinMode(PIN_OUT, INPUT);
  pinMode(PIN_RB,  INPUT);
  pinMode(PIN_BB,  INPUT);

  // 外部割り込みの設定 (High -> Low に落ちた瞬間に反応 = FALLING)
  attachInterrupt(digitalPinToInterrupt(PIN_IN),  isr_IN,  FALLING);
  attachInterrupt(digitalPinToInterrupt(PIN_OUT), isr_OUT, FALLING);
  attachInterrupt(digitalPinToInterrupt(PIN_RB),  isr_RB,  FALLING);
  attachInterrupt(digitalPinToInterrupt(PIN_BB),  isr_BB,  FALLING);
}

// ==========================================
// メインループ
// ==========================================
void loop() {
  // データが更新された場合のみシリアル通信でPCへ送信
  if (data_updated) {
    // データの読み取り中に割り込みが入って値が狂うのを防ぐため、一時的に割り込みを停止
    noInterrupts();
    unsigned int current_IN  = count_IN;
    unsigned int current_OUT = count_OUT;
    unsigned int current_RB  = count_RB;
    unsigned int current_BB  = count_BB;
    data_updated = false;
    interrupts(); // 割り込み再開

    // PCへデータを送信 (カンマ区切りなどで送信するとPC側で処理しやすいです)
    Serial.print("IN:");
    Serial.print(current_IN);
    Serial.print("\tOUT:");
    Serial.print(current_OUT);
    Serial.print("\tRB:");
    Serial.print(current_RB);
    Serial.print("\tBB:");
    Serial.println(current_BB);
  }
}

これが問題なく動けば、あとはIN/OUT、RB/BBの信号を受け取りSQLiteに保存するような仕組みを作り、FlaskでデータをフェッチするAPIを生やし、フロントエンドでデータを表示するような仕組みを作れば完成。適当に次のようなプロンプトでGemini Proにコードを生成させてみたが、ほぼ一発で動くものが出来た。

# 1回目
Arduino から情報を受け取って、データを保存・表示するためのPythonベースのウェブアプリを作成したいと思います。Arduinoはシリアル通信でデータを送信する前提とし、Python側ではpyserialを使ってデータを受け取ります。受け取ったデータはSQLiteに保存し、Flaskを使ってウェブアプリとして表示するような仕組みを作りたいと思います。
# 2回目
機械割、BB/RB確率、スランプグラフを実装したいと思います。現在のコードをベースとして変更案を提示してください

今のところ長いAT中にBBのカウントが若干おかしくなる問題があるが、これは機種特有の仕様かもしれないので、もう少しデータを取ってみてから対処するか考えることにする。どうせ設定は自分で入れているので、差枚が分かれば十分使える感じ。

設定5

また、パチンコのほうはまだ信号の受け取り方がわかっていないので、こちらはまだ未着手となっている。

おまけ: 台の感想

  • ダンバイン256ver
    • やはりチャージなしで256で図柄揃い、当たれば時短 or LTなしでそこそこやれるラッシュというのはシンプルで良い。
    • 左打ちはカスタムなどないので当たらない演出を見続けることになるが、釘をガン開けしているのでそこまでストレスは感じない。
    • 今のところ最初に打った時に数回転で入ったラッシュが50連くらいしたのが最高で、あとは大した当たりはない。やれるスペックな気がするが現実は厳しい。
  • マクロスデルタ
    • スロットのほうは全然打ったことがなかったので新鮮な気持ちでプレイ中。パチンコの先バレをひたすら見続けるようなゲームと思うと中々楽しめている
    • 設定6だとかなりの割合でATに入るが上乗せがショボく完走する未来が見えず、負ける気はしないが大勝もしなさそう。設定5にしてみたが今のところCZスルーを3連で引いていたりするので店じゃなくて良かった。低設定だとどれだけヤバいのか、実戦する予定の8月の邪神ちゃんスロに向けて今から戦々恐々である。
    • ただ、演出がちょっと残念で折角のマクロスなのにATに入らないとほぼワルキューレの曲を聴くことができない。しかも収録されているのが1番だけ。CZ移行前で風の歌を聴いている時間のほうが長いのでは?

45インチ ウルトラワイドモニター含むトリプルモニター環境のためデスクを買った

概要

引っ越しに伴い新たにPCデスクを購入する必要があったのだが、大分前の家よりも面積に余裕があるので折角ならばと奮発してモニターも更新。

ということでかねてから気になっていた45インチ 有機ELウルトラワイドと32インチの有機ELゲーミングモニターということで

  • Corsair XENEON FLEX 45WQHD240 ¥149,800
  • LG 32GS95UV-W ¥123,792

の2台を新たに購入した。

今まで利用していたHP X34というウルトラワイドモニターも余っている状況なので、これらを組み合わせたトリプルモニター環境を構築することに。

しかし、いずれも大きなモニターなので配置するためには奥行・幅ともに広いデスクが必要となる。普通に事務机を探すと中々望むサイズのものが見つからなかったのだが、ニトリのダイニングテーブルでちょうど良いサイズのものがあったので、これを購入することにしたというお話。

まとめ

  • 幅180×奥行90のデスクなら45インチウルトラワイド + 31.5インチを余裕をもって横に並べて配置可能
  • 45インチウルトラワイドの上にモニターを配置したい場合は、サンコーの100cmモニターポールを使うとよい

購入したデスク

ニトリのダイニングテーブル(TLEG LG-010 180 WH/LBR, 商品コード4017620)を44,990円で買った。サイズは幅180×奥行90×高さ70cmと望んでいた通りのサイズで、天板の厚みも十分にあるため安定感がある。

www.nitori-net.jp

大きさもそうだがPCデスクとして非常に嬉しい点として、天板端が4辺すべて平らでどこにでもモニターアームやクランプを取り付けられるというところが購入の決め手だった。デスクを探していると天板の端が丸まっていたり脚が天板の端に近い位置にあったりしてモニターアームが取り付けられず、この要件を満たさずに買えないものも多かった。

届いたときはデカすぎ&あまりにも食卓でPCデスクとしてはどうなんだろうと思ったが、壁につけて設置しモニターを置いてみると特に変な感じはしない。当初は左に31.5インチ、中央に45インチ、右に34インチの配置を考えていたが、さすがにウルトラワイドを2枚横に並べることはできず34インチを縦置きにせざるを得なかった。

とはいえこれはあまり使いやすくなかったので、何とかして34インチを横置きにできないかと試行錯誤。45インチの上にアームで34インチを重ねる形で配置したいと思いエルゴトロンのロングポールを買ってみたのですが、45インチの高さが60cmほどあるため、更にその上に34インチを重ねるには高さが足りなかった……。高かったのだが無駄になってしまった。

結局、サンコーの100cmモニターポールを買うことで何とか45インチの上に34インチを重ねる形で配置することができた。5000円しないくらいの安いモニターポールだが、しっかりとした作りで安定感もあり、そこそこ重さのある34インチモニターもグラつくことなく設置できている

ただ、モニターのサイズが大きいので、そのままデスクの上にキーボード・マウスを置いて作業すると視界にモニターが収まりきらない。もう少し奥行のあるデスクを買うべきだったかもと思ったが、現実的な解決策としてキーボードスライダーを買うことにした。結果的にはこれがなかなかいい感じで、アーロンチェアのひじ掛けから負担なく操作できる位置にキーボード・マウスを置くことができるようになった。

ちなみにXeneon Flexは平面‐湾曲を切り替えることのできる特殊なモニターなのだが、結局ずっと湾曲させたまま使っている。湾曲モニターは使ったことがなかったのでもしかしたら平面に戻したくなるかもと思っていたが、特にグラフィック系の作業はせずゲームとコーディングくらいしかしないので支障はなく、むしろ視界に収まる領域が増えて使いやすいような気がしている。

しかし音響・モニター・入力機器・PC本体と大体これでデスク回りが贅沢すぎるほど揃ってしまったので、いよいよ買うものが無くなりつつある。

DeepCool Assassin IVとNoctua NH-D15 G2 LBCのCPUクーラー性能比較@7950X3D

概要

2023年9月にDeepCool Assassin IVを購入し、7950X3Dと組み合わせて2年くらい利用していた。特に冷却性能的には不満はなかったが大分長いこと使ってきて飽きてきたのもあり、この度Noctua NH-D15 G2 LBCがツクモのセールで若干安く(21,980円)なっていたので購入した。

hashicco.hatenablog.com

価格帯が違いAssassin IV VCという後継機も出ているからなのか、意外とAssassin IVとNoctua NH-D15 G2 LBCを直接同条件で比較した記事が見当たらなかったので、7950X3Dでの冷却性能を比較した記事を書いておく。

まとめ

  • 1万近い価格差もあるので、さすがにNoctua NH-D15 G2 LBCの方が明確に冷却性能も静穏性も高かった7950X3Dのフルロードを常時65度程度で冷やすことができた。
  • Noctua NH-D15 G2 LBCは奥行がデカいのとメモリ側に寄っているせいで他パーツとの干渉が起きやすいかも。自分の環境だとRTX5090用のL型12V-2×6ケーブルが使えなかった
  • 140Wの7950X3Dを使っている分にはDeepCool Assassin IVでも十分冷やせるので、コスパを考えると悪くない選択肢だと思う

写真・取付

見た目的にはAssassin IVのほうがスタイリッシュ。どちらもデカいがNoctua NH-D15 G2 LBCの方がヒートシンクの厚みがある気がする

取付はどちらも似たような感じで簡単。AM5においてはデフォルトのバックプレート上にマウント用の金属プレートを取り付け、その上からクーラーを固定する方式なのでマザボを取り外したり裏側にアクセスする必要はない(Intelは別)。取り付けに必要な工具はどちらも付属しており、Noctuaはトルクスネジ、Assassin IVはプラスネジ。

実際にFractal DesignのTorrentに取り付けた写真が次のもの。付属している静穏化のためのLNA(Low-Noise Adaptor)ケーブルは使用していない。Assassin IVよりもメモリ側に寄っており外向きのクリアランスに余裕はあるが、このせいで12V-2x6のL型電源ケーブルが干渉してしまい使えなくなり、止む無くストレートタイプのケーブルに戻すことになった。

比較条件

  • CPU: AMD Ryzen 9 7950X3D(140W TDP)
  • マザーボード: MSI X670P WIFI
  • メモリ: Crucial Pro DDR5-5600 64GBx2
  • ストレージ: WD Black SN850X 4TB
  • GPU: MSI RTX 5090 Vanguard SOC
  • 電源: Asrock PG-1300G
  • ケース: Fractal Design Torrent
  • グリス: 条件をそろえるため、どちらのCPUクーラーでもArctic MX-6を使用

ソフトウェアとしてOCCTの無料版を利用し、CPU負荷を30分間かけ続けた。CPU温度とファン回転数をLibreHardwareMonitorを利用してログ取得してグラフ化した。

室温は10~15度。騒音値は騒音計をケースの全面から約20㎝ほど離れた位置の床において測定した。

ベンチマーク結果

結果はグラフの通り。CPU温度、ファン回転数(assasinは12cm+14cmファンなのでそもそも単純比較できないが)ともにNoctua NH-D15 G2 LBCの方が優れていることがわかる。

騒音計の測定値は次のようで、約4dBほどNoctua NH-D15 G2 LBCの方が静かだった。とはいえ、騒音計の読みはTorrentのケースファンの音のほうが寄与がデカい気もするので、参考程度に。

クーラー 騒音値 (dB)
DeepCool Assassin IV 56 dB
Noctua NH-D15 G2 LBC 52 dB

(2026/01/25追記) OCCTの設定をオートにしていたためかあまり負荷が十分にかけられていなさそうだったので、前回のAssassin IV記事の時と同様Cinebenchで負荷をかけたときの温度も確認した。

Cinebench 2026を利用したので前回記事とは正確には比べられないが、温度はMax73度ほど、ファン回転数もまだ余裕を残した1200rpm以下(騒音計の読みも55dBほど)で抑えられていた。ついでにスコアは7291でした。

最近CPUのTDPも高くなり水冷前提の時代になってきましたが、Noctuaから空冷で冷やし切れるソリューションが出てくるのはとてもありがたいところ(高いけど)。

今回の結果から多少余力を残しながら7950X3Dを冷やせているところから、おそらく9950Xのようなさらに強力なCPUもご家庭環境でちゃんと冷やせるように見えますので、長い付き合いになりそうです。

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

概要

仕事の部署移動で徳島から大阪に引っ越すことになった。転職はしておらず、仕事の内容としても創薬で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万のGeForce RTX 5090 32G VANGUARD SOC 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を買ってもいいのではないでしょうか

  • 3440x1440, 最高設定
RTX4090 RTX5090 ratio
score 28689 33245 1.160
Min FPS 88 92 1.045
Ave FPS 199.5 230.4 1.155
  • 3840x2160, 最高設定
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,
)