ローダーが提供すべきものを定義する
最適化の前に出力契約を書いてください。要素数、各フィールドの型、次元、ターゲットの範囲、不完全な入力の扱いを定めます。サンプルの識別子とバッチ内での位置を区別します。変換によって形状が変わることや入力がフィルタリングされることがあります。それが許可されるかを学習プログラムが把握している必要があります。
通常のファイル、境界ケース、データセットの最後の要素を含む代表的なサンプルを取得します。Dataset と全く同じ前処理で各要素を開きます。次にそれらのアセンブルを確認します。個別のアクセスが成功しても、複数の結果をスタックできるとは限りません。テキストの場合は padding とマスクを、画像の場合はチャネル、次元、軸の順序を文書化します。
範囲を定めます。データがローカルかリモートか、デコードを含むか否か、変換が固定かランダムか。2つの設定間でそれを維持してください。見かけ上の向上は、削除された作業に起因する可能性があります。
単一プロセスに戻してエラーを読む
まず num_workers=0、shuffle=False、小さなバッチで再現します。すると読み込みはメインプロセス内で行われ、エラーのトレースは通常より読みやすくなります。DataLoader のドキュメントはデバッグのためにこの設定を推奨しています。失敗した要素の識別子をデコード前に記録しますが、その機密内容をログにコピーしないでください。
分離して進めます。生アクセス、変換、collate_fn、そして転送です。転送の前で処理が失敗するなら、CUDA の変更が最初の手がかりではありません。複数の workers の場合にのみブロックするのなら、それらのプロセスに渡されるオブジェクトとリソースを確認します。最初のイテレーションとその次を比較します。workers の起動は初回の待機を説明できますが、継続的な問題を立証するものではありません。
timeout は待機を可視化できますが、利用できないソースやブロックした worker を修復するものではありません。この遅延を無限に増やすのではなく、最後に把握できたステップを保ち、入力数を減らします。
実例: 期待される3チャンネル、異なる画像
4つの教育用レコードを考えます。最初の3つは形状 [3, 16, 16] のテンソルを与え、4番目は [1, 16, 16] です。3チャンネルを義務付ける契約では、4番目の要素はスタックの前に識別されなければなりません。このシナリオはここでは実行されておらず、選ばれた形状に基づく期待される結果を記述しています。
以下の関数は、各レコードが id、x、y フィールドを持ち、x が CPU テンソルであり、y が整数インデックスであることを前提としています。矛盾を黙って削除するのではなく拒否します。あなたのプロジェクトでは、モノクロ画像を3チャンネルに変換すべきか、インポート時に拒否すべきかを明示的に決定してください。この決定はデータの意味とモデルが期待する前処理に依存します。
修正後、4つの識別子はすべて存在し続けなければならず、組み立てられたテンソルは形状 [4, 3, 16, 16] でなければなりません。ターゲットに適したガードを追加してください。正しく次元付けされた画像でも、無効なアノテーションを持つ可能性があります。
import torch
from torch.utils.data import DataLoader
def assemble(records):
for item in records:
if tuple(item["x"].shape) != (3, 16, 16):
raise ValueError(f"予期しない形状です: {item['id']}")
return {
"ids": [item["id"] for item in records],
"x": torch.stack([item["x"] for item in records]),
"y": torch.tensor([item["y"] for item in records],
dtype=torch.long),
}
# dataset は、ここで説明したレコードを生成するあなたの Dataset です。
# マルチプロセススクリプトでは、main ガードの下で loader を作成してください。
if __name__ == "__main__":
loader = DataLoader(dataset, batch_size=4, num_workers=0,
shuffle=False, collate_fn=assemble)
iterator = iter(loader)
batch = next(iterator)データを変えずに workers を再導入する
batch、順序、変換を維持したまま、ゼロから少数の worker へと進めましょう。まず 1 エポック全体をテストし、続いて 2 回目をテストします。一部のエラーは、イテレータの再起動時やリソースが消費された後にのみ現れるからです。並列性を高めることが役立つのは、前処理の作業が実際に並行して進められる場合だけです。
起動方式はシステムと Python のバージョンによって異なります。spawn を使う場合は、プログラムのエントリを if __name__ == '__main__' で保護し、Dataset、collate_fn、worker 関数をローカルのラムダではなくモジュールレベルで定義してください。プロセスのドキュメントでは、継承されたロックやスレッドがデッドロックを引き起こす理由も説明されています。ライブラリが要求する場合は、プロセスごとに固有のアクセス初期化を行ってください。
IterableDataset の場合、識別子を使って workers 間の分割を検証します。複数のワーカーがそれぞれ同じストリーム全体を消費してはなりません。バッチの数だけで判断せず、重複や欠落した要素も確認してください。
明確な単位で待ち時間とスループットを測る
2つの補完的な観測を使用してください。ローダー単体の実行では、定義された区間中に準備されたサンプルを数えます。統合された実行では、モデルがそのデータを消費する際に何が起こるかを調べます。前者は準備を切り分けるのに役立ちますが、自動的にトレーニングのスループットを表すものではありません。
プロトコルでは、実際に配信されたサンプル数を数え、経過した秒数で割ります。起動時に除外した分、データのキャッシュ、変換、繰り返し回数を明記してください。最良の値だけを選ぶのではなく、各回の値をそのまま保持します。以下の表は記録用のシートであり、性能の数値はあらかじめ埋められていません。
形状が変化する場合、1秒あたりのサンプル数は負荷の変化を覆い隠す可能性があります。デコードされたピクセル数や実際に準備されたトークン数など、関連する単位を加えつつ、サンプル数も保持してください。完全なループ内での待ち時間を特定するには、次のバッチの読み取りを計算とは別に名付けてください。
表をスクロールしてすべての列を表示してください。| 設定 | 確認する項目 | 観測された所要時間 | 期待される結論 |
|---|---|---|---|
| workers=0 | 識別子、形状、ターゲット | 秒単位で測定するもの | 正しい基準 |
| 少数の workers | 同じ入力集合 | 秒単位で測定するもの | 実際の利得または追加コスト |
| 同じ設定、第二の時代 | 欠落も重複もなし | 秒単位で測定するもの | 起動とキャッシュの影響 |
メモリ、先読み、転送を別々に扱う
ワーカーと待機中のバッチはホストメモリを消費します。VRAMだけが重要だと結論づける前に、試用中はこれを監視してください。より深いプリロードは待機を移動させる一方で占有率を高めることがありますが、1秒あたりの結果が増えることを保証するものではありません。まず疑わしい変数を減らし、同じ範囲で比較してください。
pin_memory と非ブロッキング転送は、アクセラレータへのデータの受け渡しに関係します。PyTorch の最適化レシピでは、これらはハードウェアと負荷に応じて検討すべきレバーとして紹介されています。デコードの誤りを修正するものではありません。まず workers 内で CPU 上のデータを扱い、その後、計算を駆動するプロセスで転送を整理してください。利点と実際のオーバーラップは、想定ではなく観測する必要があります。
persistent_workers を使用する場合は、エポック間で保持されるリソースと状態に注意してください。単一のバッチで良好な設定が得られても、ファイルのクローズやデータソースの再読み込みを検証するには不十分です。
データが正しいままである場合にのみ設定を採用する
期待される結果は、選択した枠組みの中で、予定されたすべての入力をサイレントエラーなしで受け取るループです。最適化の前後で識別子とターゲットを比較してください。最後の不完全なバッチを除外する場合は drop_last を説明してください。変換がランダムな場合は、そのポリシーに反するピクセルの一致を要求するのではなく、ポリシー自体を確認してください。
測定された要件を満たす最もシンプルな設定を維持してください。ストレージ、デコード、またはモデルがすでに制限を課している場合、ワーカー数を増やしても改善しないことがあります。サーバーの CPU、RAM、ストレージのリソースは、その GPU の名前から推測することはできません。Kernodeck 環境を準備する際は、これらの要件を別途明示してください。