動かざることバグの如し

近づきたいよ 君の理想に

per_device_train_batch_sizeとgradient_accumulation_stepsの違い

機械学習モデルのトレーニングにおけるバッチサイズと勾配蓄積について

per_device_train_batch_sizeとは

per_device_train_batch_sizeとは、GPUで一度に処理するデータのサンプル数を指定するパラメータである。 例えば、per_device_train_batch_size=8と設定するとモデルは8個のサンプルを同時に処理する。

がVRAMが足りない

バッチサイズは大きいほど学習効率は高くなる。 じゃあデカけりゃいいのかっていうとそうでもなくて、GPUメモリ使用量が増えてしまうので限界がある。 この問題を解決するのがgradient_accumulation_steps

VRAMが足りない状況で無理にバッチサイズを大きくすると、OutOfMemoryエラーが発生して学習が停止してしまう。 そこでgradient_accumulation_stepsを使って、擬似的にバッチサイズを大きくすることで、少ないVRAMでも効率的に学習を進めることができる。

勾配蓄積の仕組み

勾配蓄積は、大きなバッチサイズを小さな単位に分割して処理する手法。 例えば

設定例

  • per_device_train_batch_size=4, gradient_accumulation_steps=16
    • →実効バッチサイズ: 64
  • per_device_train_batch_size=1, gradient_accumulation_steps=64
    • →実効バッチサイズ: 64

例えば、実効バッチサイズを64にしたいとする。 per_device_train_batch_size=4、gradient_accumulation_steps=16と設定した場合、 モデルはまず4つのサンプルを処理して勾配を計算する。 しかし、この時点では勾配の更新は行われず、代わりに蓄積される。 このプロセスを16回繰り返し、合計64個のサンプル分の勾配が蓄積された後、パラメータが更新される。

per_device_train_batch_size=1、gradient_accumulation_steps=64の場合も同様だ。 一度に処理するサンプル数は1つだが、64回分の勾配が蓄積された後にパラメータが更新されるので、実効バッチサイズは64になる。

最適な設定方法

  1. GPUメモリの限界までper_device_train_batch_sizeを設定する
  2. 必要な実効バッチサイズに達するようにgradient_accumulation_stepsを調整する

  • OK: per_device_train_batch_size=4, gradient_accumulation_steps=16
  • NG: per_device_train_batch_size=1, gradient_accumulation_steps=64

勾配蓄積のデメリットとして、トレーニング速度が低下する。per_device_train_batch_sizeで事足りるならそっちに割り振るべき

まとめ

per_device_train_batch_sizeとgradient_accumulation_stepsは、GPUメモリ使用量と学習効率のバランスをとるための重要なパラメータだ。 GPUメモリが限られている場合は、勾配蓄積を使って実質的なバッチサイズを大きくすることで、学習時間を短縮し、モデルの精度を向上させることができる。

いつの間にかdstatが開発終了していた件

いつの間にかdstatが開発終了し、doolが後継になっていたのでそのまとめメモ

dstatとは

dstat コマンドは、Linuxシステムのリソース使用状況をリアルタイムに監視するための強力なツール。 CPU、メモリ、ディスクI/O、ネットワークなど、様々なシステムリソースの統計情報を、画面上に分かりやすく確認できる。

dstat-real/dstat: Versatile resource statistics tool (the real one, not the Red Hat clone)

  • 豊富なプラグインによる柔軟な拡張性
  • 多彩なメトリクスをリアルタイムに監視できる
  • 軽量で低負荷

dstat開発終了の経緯

  1. dstatは2004年からDag Wieers氏によって開発がされていた
  2. 2016年以降コミットがなく、プロジェクトが放置されていた
  3. 完全に開発停止って訳ではなかった模様
  4. 2018年、Red Hatはdstatを死んだものとみなして独自のdstatバージョンの開発を開始
  5. 当時のdstatはPython3のサポートがなかった
  6. Red HatがFedra Projectにおいて自社で開発するPerformance Co-Pilot(PCP)に、dstatを改変して取り込んだ(pcp-dstat)
  7. Red Hatは新しいツール「pcp-dstat」を開発し、/usr/bin/dstatのシンボリックリンクとして配置
  8. dstatの作者はこれを既存ツールの知名度にただ乗りした乗っ取りとみなし嫌悪感を表明、嫌気がさしたことを理由としてdstatの開発終了を宣言した

問題点

  • 元の開発者との事前相談なしに置き換えを決定
  • 同じ「dstat」という名前を使用し、オリジナルのdstatをユーザーがインストールできなくなった
  • PCPの依存関係が必要となり、軽量という元々の設計思想から外れた

勝手にパッケージ書き換えるのはひどいなあ Red Hat仕草というかなんというか。

で、Ubuntu 24.04のdstatコマンド確認したら確かにRed Hatの文字があった。

#!/usr/bin/env pmpython
#
# Copyright (C) 2018-2022 Red Hat.
# Copyright (C) 2004-2016 Dag Wieers <dag@wieers.com>
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version.

けどインストールパッケージ名はdstatだったよなぁと思って確認したらpcpにすり替わっていたw

apt install dstat
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています... 完了
状態情報を読み取っています... 完了
注意、'dstat' の代わりに 'pcp' を選択します
pcp はすでに最新バージョン (6.2.0-1.1build4) です。

その後

別の人がdstatの開発を受け継ぐ意思を表明し、dstat作者の承諾を得た。これはdoolという名前で受け継がれた。

scottchiefbaker/dool: Python3 compatible fork of dstat

doolのインストール

aptでは2024年10月24日現在提供されていないのでgitから直接インストール

curl https://cdn.jsdelivr.net/gh/scottchiefbaker/dool@master/dool | sudo tee /usr/local/bin/dool
sudo chmod +x /usr/local/bin/dool

オリジナルのdstatよりもデフォルト見やすくなってた

picture 0

参考リンク

nvtopでMacOSのGPU使用率をモニタリングする

環境

やりたいこと

生成AI使うならGPUの利用状況は常にチェック必須である。 ただ、MacOSだと標準でツール入ってないから自分でなんとかしなきゃいけない。そこでnvtopコマンドの出番だ。

Linuxならnvitopの方が使い勝手がよかったりするんだが、 MacOSに対応しているGPUモニタリングツールは有名なものだとnvtopのみ。

nvtopで確認できること

  • GPUリアルタイムの使用率、履歴
  • GPUメモリ使用率(CPUと共有だが)
  • メモリ使用率の多いプロセスの確認

インストール

事前に brew install cmake が必要

git clone https://github.com/Syllo/nvtop.git
mkdir -p nvtop/build && cd nvtop/build
cmake .. -DNVIDIA_SUPPORT=OFF -DAMDGPU_SUPPORT=OFF -DINTEL_SUPPORT=OFF -DAPPLE_SUPPORT=ON
make

sudo make install

cmakeのオプションについて

-DNVIDIA_SUPPORT=OFF -DAMDGPU_SUPPORT=OFF -DINTEL_SUPPORT=OFF -DAPPLE_SUPPORT=ONはcmakeのオプションで、 MacApple Siliconでnvtopを使うために必須の設定。 他のオプションはNVIDIAAMDIntelGPUサポートを無効にする設定。Macで使うならApple Silicon以外はありえないから、こう設定しとけばOK。

実行

nvtop を実行するだけ 終了する際は「Ctrl+c」または「q」だけでも可

picture 0

Rubyで複数文字列置換を一発で終わらせる

環境

  • Ruby3

やりたいこと

gsub何回も重ねるのは非効率なので一括置換したい

コード

gsubdict = {
  "ストロベリー" => "strawberry",
  "パイナップル" => "pineapple"
}

original_text = "ストロベリーパフェとパイナップルジュース"
# gsub と Regexp.union を使用して文字列を置換
result = original_text.gsub(Regexp.union(gsubdict.keys), gsubdict)

puts result

注意点

渡すハッシュのキーは文字列でないといけない。シンボルは不可、つまり

gsubdict = {
  "ストロベリー": "strawberry",
  "パイナップル": "pineapple"
}

は動作しない。

Railsで期間内の月数をカウントする方法

環境

やりたいこと

Railsで期間を与えてその中に含まれる月の数を数えたい。

コード

def count_months(start_date, end_date)
  (start_date.beginning_of_month..end_date.end_of_month).map { |d| [d.year, d.month] }.uniq.count
end

# 使用例
start_date = Date.new(2024, 1, 15)
end_date = Date.new(2024, 3, 5)
months = count_months(start_date, end_date)
# => 3

count_months メソッドでは、まず開始日と終了日をそれぞれ月の最初と最後に変換している。 map { |d| [d.year, d.month] } で日付の範囲を [年, 月] の配列に変換し、 uniq で重複する月を削除している。 最後に count メソッドで、ユニークな月の数をカウントしている。 この例では、開始日が2024年1月15日で、終了日が2024年3月5日なので、含まれる月は1月、2月、3月の3ヶ月となる。