Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
20250515_SeedEverythingな人を救いたい
Search
yuyagi
May 19, 2025
Technology
0
35
20250515_SeedEverythingな人を救いたい
内部の勉強会で使った、Pytorchのseedに関する備忘スライドです
RNGに関してミスしやすいポイントをまとめています
yuyagi
May 19, 2025
Tweet
Share
Other Decks in Technology
See All in Technology
[CV勉強会@関東 ICCV2025 読み会] World4Drive: End-to-End Autonomous Driving via Intention-aware Physical Latent World Model (Zheng+, ICCV 2025)
abemii
0
250
学術的根拠から読み解くNotebookLMの音声活用法
shukob
0
360
JJUG CCC 2025 Fall バッチ性能!!劇的ビフォーアフター
hayashiyuu1
1
410
IaC を使いたくないけどポリシー管理をどうにかしたい
kazzpapa3
1
150
AWS Media Services 最新サービスアップデート 2025
eijikominami
0
100
生成AIシステムとAIエージェントに関する性能や安全性の評価
shibuiwilliam
0
120
クラウドネイティブ時代の 開発プロセス再設計 〜速さと品質を両立するには〜
moritamasami
0
110
AI駆動開発を実現するためのアーキテクチャと取り組み
baseballyama
15
12k
スタートアップの事業成長を支えるアーキテクチャとエンジニアリング
doragt
1
7.1k
不確実性に備える ABEMA の信頼性設計とオブザーバビリティ基盤
nagapad
4
6.9k
膨大なデータをどうさばく? Java × MQで作るPub/Subアーキテクチャ
zenta
0
120
現地速報!Microsoft Ignite 2025 M365 Copilotアップデートレポート
kasada
2
1.6k
Featured
See All Featured
Faster Mobile Websites
deanohume
310
31k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
55
3.1k
What's in a price? How to price your products and services
michaelherold
246
12k
Build The Right Thing And Hit Your Dates
maggiecrowley
38
2.9k
Become a Pro
speakerdeck
PRO
29
5.6k
YesSQL, Process and Tooling at Scale
rocio
174
15k
We Have a Design System, Now What?
morganepeng
54
7.9k
Building a Modern Day E-commerce SEO Strategy
aleyda
45
8.1k
Making the Leap to Tech Lead
cromwellryan
135
9.6k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
15k
Typedesign – Prime Four
hannesfritz
42
2.9k
Leading Effective Engineering Teams in the AI Era
addyosmani
8
1.1k
Transcript
Seed Everythingな人を救いたい Yuyagi
自己紹介 ◆ データサイエンティスト 新規事業/データ活用系プロジェクトを担当 YuYagi ◆ Kagle Master - 信号処理系のコンペ参加が多め(画像、音響、センサ等)
(気分転換に未知のジャンルもやってみたい)
こんなことありませんか? • 疑似乱数Seedを指定して訓練をしているのに、↓みたいなことをうっかりやらかす • JupyterでEDAしながら学習してたら、前の実験が再現できなくなってしまった • 訓練途中のEpochから再開してみたら、全エポック学習したときと結果が違う しーどえぶりしんぐしたのに・・・ ↓DS界隈で流通している便利なやつ ※要出典
(何も考えずに使えるくらい) 本発表内容: やらかしがちなミス(1例)を題材に原因の説明、ほか意外と知らないPytorchの仕様について説明
目次 • 疑似乱数とは? • よくあるミスとその原因 → Epochの途中から再開すると結果が変わってしまう、という例を題材に原因を説明 ・さらなる注意ポイント → DataLoaderのWorker数を増やすと、Workerごとに別のシードが設定される?!
疑似乱数とは 簡単に言うと、 「見かけはランダムだけど、中身は決まった計算で作られる数列」 疑似乱数(Pseudo Random Number)とは、アルゴリズムによって生成された乱数 モデルの初期化 学習データの準備 / 前処理
モデルの学習 モデルの評価 テストデータへの予測 ◆ 機械学習・深層学習での使われ方 ※重み初期化、データのシャッフル・分割、データ拡張、ドロップアウトなど 第46回 市村学術賞 功績賞 -01:一様疑似乱数発生法の高機能化 決まった計算で 生成するので、 実際には一様乱数にならない。 メルセンヌツイスタによる一様乱数
疑似乱数の仕組み ① 疑似乱数生成器は、シード(seed)と呼ばれる初期状態からスタートする ② 生成器は内部状態(state)を持ち、乱数の出力を持ち、その状態を更新 ② 同じシードから開始すれば常に同じ乱数列が再現される 種(seed) 内部状態 疑似乱数列
疑似乱数生成器(RNG) ① 内部状態の初期化 ② 乱数生成 ③ 内部状態の更新 参考:【初学者向け】暗号基本技術まとめ その1 実験の再現性確保のためには、 シードを固定する必要がある
疑似乱数の仕組み 種(seed) 内部状態 疑似乱数列 疑似乱数生成器(RNG) ① 内部状態の初期化 ② 乱数生成 しかし、コードの実行順序や、
マルチプロセス等の処理で、 想定外の挙動が発生することがよくある ③ 内部状態の更新 ① 疑似乱数生成器は、シード(seed)と呼ばれる初期状態からスタートする ② 生成器は内部状態(state)を持ち、乱数の出力を持ち、その状態を更新 ② 同じシードから開始すれば常に同じ乱数列が再現される 参考:【初学者向け】暗号基本技術まとめ その1
よくあるミスの例:途中Epochから再開したら結果が違う • 学習途中の重みやオプティマイザの状態を保存、再読み込みしたのに、全エポック通し で学習した場合と結果が異なる モデルの初期化 学習データの準備 / 前処理 モデルの学習 モデルの評価
テストデータへの予測 このタイミングでseedを固定 コードの実行開始 20エポック中、10エポックで学習を中断 (weight、optimizer等は保存) その後、重みを読み込んで、 残り10エポックで学習 ↓ 20エポックを一気に学習した場合と 結果が異なる!
原因:乱数生成器の内部状態 • Seed固定の関数は呼び出せているが、乱数生成器の内部状態が再現できていない モデルの初期化 学習データの準備 / 前処理 モデルの学習 モデルの評価 テストデータへの予測
◆ 例1:途中Epochから再開したい場合 種(seed) 内部状態 疑似乱数列 疑似乱数生成器(RNG) ② 乱数生成 ③ 内部状態の更新 学習コードの流れ ① 内部状態の初期化 モデルの初期化、データ拡張など、 学習が進むにつれてRNGの状態が変化 → 初期状態のRNGから再開すると、全体の結果が変わってしまう
ポイントと対処方法:内部状態について ✓Python、Numpy、pytorchライブラリはそれぞれのアルゴリズムで疑似乱数を計算 ✓ライブラリごとに別のRNGをつかっているため、それぞれが内部状態を持つ ✓内部状態は取得・読み込みすることができる → 途中Epochから再開する場合は、これらの内部状態も保存して読み込むとよい Numpy Python Pytorch Seed
固定 メソッド Random.seed(seed) np.random.seed(seed) torch.manual_ seed(seed) RNGの 取得 読み込み random.getstate() random.setstate(state) numpy.random.get_state() numpy.random.set_state(state) torch.get_rng_st ate() torch.set_rng_st ate(state) 採用 アルゴ リズム メルセンヌツイスタ PCG64(numpy 1.17+) メルセンヌ ツイスタ torch.cuda.man ual_seed(seed) torch.cuda.get_rng _state_all() torch.cuda.set_rng _state_all(state) Philox CPU GPU
さらなる注意ポイント:乱数シードの有効範囲 • シードの固定はメインプロセスでのみされていて、別プロセスには自動では適用されない → 学習中にマルチプロセスな処理を行う場合は注意が必要 ※学習コードの中では、データを取り出す際に、マルチプロセスな処理を行うことが多い ◆ よくある現象: Pytorch DataLoaderのWorkerを増減したら、結果が変化
・並列でデータを取り出すために、num_worker > 0に設定する場合、 処理がマルチプロセスになるので注意が必要 . num_workers>0の時、 データの取り出し専用の別のプロセスが立ち上がる この時、Pytorch側でseed固定してくれるような実装だが、 仕様が少しわかりづらい・・・(次頁) モデルの初期化 学習データの準備 / 前処理 モデルの学習 モデルの評価 テストデータへの予測
Pytorch DataLoaderのデフォルト挙動(エポック開始時) メインプロセスのtorch(CPU)のRNGで乱数を生成し、その乱数にworker_idを足した値で、 サブプロセスの各seedを設定(サブプロセスごとにseedが違う、かつ毎エポックの開始時に動作) Worker 0 メインプロセス(訓練スクリプト) サブプロセス(DataLoader) Seed (Python)
RNG (Numpy) RNG (torch CPU) RNG (Python) RNG (Numpy) RNG (torch CPU) 乱数生成 base_seed + worker_id seedを設定 _generate_state (seedの桁数調整) Worker 1 RNG (Python) RNG (Numpy) RNG (torch CPU) base_seed + worker_id seedを設定 _generate_state (seedの桁数調整) Worker 2 RNG (Python) RNG (Numpy) RNG (torch CPU) base_seed + worker_id seedを設定 _generate_state (seedの桁数調整) ※最新(2.6.0)のソースコードでは、 サブプロセスのnumpyのseedも設定してくれる!(下記228行目以降) https://github.com/pytorch/pytorch/blob/main/torch/utils/data/_utils/worker.py 新しいプロセスが作られた (≒エポック開始時) のtorchのRNGの内部状態で、 base_seedを生成する
なぜサブプロセスごとに、異なるseedを使っているのか? • Workerごとの乱数生成器だと、まったく同じ乱数が生成されるため → 具体的な例としては、同じエポック内で、同じデータ変換が何度も実行される CourseDropOut CourseDropOut
(余談)内部状態を自分で設定する方法 • DataLoaderのworker_init_fn引数に関数を与え、各プロセス実行時のseedを固定することも できる 【Pytorch】DataLoaderの乱数を固定する方法(備忘録)
結局どうするべきか? [単一プロセス(worker=0)] ✓一気通貫で全エポック訓練する場合は、基本的にseed_everythingだけやればOK ※ ただし、乱数生成器の状態が同じになるように気を付ける ✓エポックの途中から訓練する場合は、訓練途中の各ライブラリのRNGを読み込めばOK [マルチプロセスの場合(worker>0)] ✓一気通貫で全エポック訓練する場合は、こちらもseed_everythingだけやればOK ※ workerの設定によっては結果も若干変わるので注意
(疑問) 途中Epochから再開したかったら、サブプロセスのseed全部読み込む必要があるのでは・・・? →基本的にはメインプロセスのRNGだけ読み込めばOK (・・・のはず)
(参考)学習途中から再開する場合(マルチプロセス) 途中Epochから再開したかったら、サブプロセスのseed全部読み込む必要があるのでは・・・? →基本的にはメインプロセスのRNGだけ読み込めばOK (・・・のはず) Worker 0 メインプロセス(訓練スクリプト) サブプロセス(DataLoader) Seed (Python)
RNG (Numpy) RNG (torch CPU) RNG (Python) RNG (Numpy) RNG (torch CPU) 乱数生成 base_seed + worker_id seedを設定 _generate_state (seedの桁数調整) Worker 0 RNG (Python) RNG (Numpy) RNG (torch CPU) base_seed + worker_id seedを設定 _generate_state (seedの桁数調整) Worker 0 RNG (Python) RNG (Numpy) RNG (torch CPU) base_seed + worker_id seedを設定 _generate_state (seedの桁数調整) Torchの乱数生成器が生成 した乱数が、サブプロセスの base_seedになる → 赤枠内さえ再現できればOK!
終わりに 読んでいただいてありがとうございました! 実験で試したことを実行できるノートブックです↓ https://github.com/yu-yagi/random_seed_experment