Accelerate documentation
トラブルシューティング
トラブルシューティング
このガイドでは、Accelerate を使用している際に遭遇する可能性のある問題に対する解決策をいくつか紹介します。Accelerate は継続的に進化しているアクティブなライブラリであり、ユースケースや分散学習のセットアップも多岐にわたるため、すべてのエラーを網羅しているわけではありません。ここで説明されている解決策が特定のエラーに役立たない場合は、ヘルプを依頼するセクションを確認し、どこでどのようにヘルプを得られるかをご覧ください。
ログ出力
ログ出力は、エラーの発生箇所を特定するのに役立ちます。複数プロセスによる分散環境ではログ出力が課題になりがちですが、Accelerate は logging() ユーティリティを提供しており、ログの同期を保証します。
問題をトラブルシューティングするには、標準のPython logging モジュールの代わりにlogging()を使用します。log_levelパラメータで詳細レベル(INFO、DEBUG、WARNING、ERROR、CRITICAL)を設定し、次に次のいずれかを実行します。
log_levelをACCELERATE_LOG_LEVEL環境変数としてエクスポートします。log_levelを直接get_loggerに渡します。
例えば、log_level="INFO"を設定するには:
from accelerate.logging import get_logger
logger = get_logger(__name__, log_level="DEBUG")デフォルトでは、ログはメインプロセスでのみ呼び出されます。すべてのプロセスで呼び出すには、main_process_only=Falseを渡します。
すべてのプロセスで、かつ順序通りにログを呼び出す場合は、in_order=Trueも渡します。
from accelerate.logging import get_logger
logger = get_logger(__name__, log_level="DEBUG")
# log all processes
logger.debug("thing_to_log", main_process_only=False)
# log all processes in order
logger.debug("thing_to_log", main_process_only=False, in_order=True)コードのハングとタイムアウトエラー
コードがハングする原因は多岐にわたります。ここでは、コードのハングを引き起こす可能性のある最も一般的な問題の解決方法について見ていきましょう。
テンソルの形状が一致しません
テンソルの形状が一致しないことは、分散環境でコードが長時間ハングする原因となる一般的な問題です。
分散環境でスクリプトを実行する際、Accelerator.gather() や Accelerator.reduce() などの関数を使用して、デバイス間でテンソルを取得し、それらに対して集約的な操作を実行する必要があります。これらの関数(およびその他の関数)は、torch.distributed に依存して gather 操作を実行しますが、この操作には、すべてのプロセス間でテンソルが完全に同じ形状であることが必要です。テンソルの形状が一致しない場合、コードがハングし、最終的にタイムアウト例外が発生します。
Accelerateのオペレーションデバッグモードを使用すると、この問題を即座に検出できます。accelerate configの設定時にこのモードを有効にすることを推奨しますが、CLIから、環境変数として、またはconfig.yamlファイルを直接編集することでも有効にできます。
accelerate launch --debug {my_script.py} --arg1 --arg2環境変数としてデバッグモードを有効にする場合、accelerate launchを呼び出す必要はありません。
ACCELERATE_DEBUG_MODE="1" torchrun {my_script.py} --arg1 --arg2config.yaml ファイルに debug: true を追加してください。
compute_environment: LOCAL_MACHINE
debug: trueデバッグモードを有効にすると、テンソルの形状の不一致の問題を示すトレースバックが表示されるはずです。
Traceback (most recent call last):
File "/home/zach_mueller_huggingface_co/test.py", line 18, in <module>
main()
File "/home/zach_mueller_huggingface_co/test.py", line 15, in main
broadcast_tensor = broadcast(tensor)
File "/home/zach_mueller_huggingface_co/accelerate/src/accelerate/utils/operations.py", line 303, in wrapper
accelerate.utils.operations.DistributedOperationException:
Cannot apply desired operation due to shape mismatches. All shapes across devices must be valid.
Operation: `accelerate.utils.operations.broadcast`
Input shapes:
- Process 0: [1, 5]
- Process 1: [1, 2, 5]早期停止
分散学習における早期停止について、各プロセスが特定の停止条件(例:検証損失)を持っている場合、すべてのプロセス間で同期されていない可能性があります。その結果、プロセス 0 で break が実行されてもプロセス 1 では実行されず、タイムアウトが発生するまでコードが無限にハングする原因になります。
早期停止の条件分岐がある場合は、set_triggerおよびcheck_triggerメソッドを使用して、すべてのプロセスが正しく終了することを確認してください。
# Assume `should_do_breakpoint` is a custom-defined function that returns a conditional,
# and that conditional might be true only on process 1
if should_do_breakpoint(loss):
accelerator.set_trigger()
# Later in the training script when we need to check for the breakpoint
if accelerator.check_trigger():
breakLinuxの古いカーネルバージョン
Linuxでカーネルバージョンが< 5.5の場合、プロセスがハングする問題が報告されています。この問題を回避するには、システムを新しいカーネルバージョンにアップグレードしてください。
MPI
MPI を使用した分散 CPU トレーニングジョブがハングしている場合は、ノード間でパスワードなし SSH(鍵認証)が設定されていることを確認してください。つまり、ホストファイルに列挙されているすべてのノードについて、パスワードの入力プロンプトなしで、あるノードから別のノードに SSH 接続できる必要があります。
次に、健全性チェックとしてmpirunコマンドの実行を試してください。例えば、以下のコマンドを実行すると、各ノードのホスト名が出力されるはずです。
mpirun -f hostfile -n {number of nodes} -ppn 1 hostnameメモリ不足
One of the most frustrating errors when it comes to running training scripts is hitting “Out-of-Memory” on devices like CUDA, XPU or CPU. The entire script needs to be restarted and any progress is lost.
この問題を解決するために、Accelerate は toma を基盤とする find_executable_batch_size() ユーティリティを提供しています。 このユーティリティは、OOM(メモリ不足)により失敗したコードを再試行し、バッチサイズを自動的に低下させます。各 OOM 条件に対して、アルゴリズムはバッチサイズを半分にしてコードを再試行し、成功するまで繰り返します。
find_executable_batch_size()を使用するには、find_executable_batch_sizeを含む内部関数を定義し、その内部でデータローダーを構築するように、トレーニング関数を再構成してください。最低限、これにより追加されるのは4行のコードだけです。
内部関数はバッチサイズを最初の引数として受け取る必要がありますが、呼び出し時にはそれを渡しません。ラッパーがこれを処理します。Acceleratorに渡されるデバイスメモリを消費するオブジェクト(モデル、オプティマイザーなど)も、内部関数の中で必ず宣言する必要があります。
def training_function(args):
accelerator = Accelerator()
+ @find_executable_batch_size(starting_batch_size=args.batch_size)
+ def inner_training_loop(batch_size):
+ nonlocal accelerator # Ensure they can be used in our context
+ accelerator.free_memory() # Free all lingering references
model = get_model()
model.to(accelerator.device)
optimizer = get_optimizer()
train_dataloader, eval_dataloader = get_dataloaders(accelerator, batch_size)
lr_scheduler = get_scheduler(
optimizer,
num_training_steps=len(train_dataloader)*num_epochs
)
model, optimizer, train_dataloader, eval_dataloader, lr_scheduler = accelerator.prepare(
model, optimizer, train_dataloader, eval_dataloader, lr_scheduler
)
train(model, optimizer, train_dataloader, lr_scheduler)
validate(model, eval_dataloader)
+ inner_training_loop()デバイス構成間で再現性のない結果
デバイス構成を変更してモデルの性能に違いが見られる場合、構成を切り替える際にスクリプトを更新し忘れている可能性が高いです。同じスクリプトで同じバッチサイズを使用している場合でも、TPU、マルチGPU、シングルGPUでは結果が異なります。
例えば、バッチサイズ16で単一GPUで学習していた場合、デュアルGPU構成に移行する際は、同じ実効バッチサイズを維持するためにバッチサイズを8に変更する必要があります。これは、Accelerateで学習を行う場合、dataloaderに渡すバッチサイズはGPUあたりのバッチサイズとなるためです。
セットアップ間で結果を再現できるようにするためには、同じシードを使用し、バッチサイズを適切に調整し、学習率のスケーリングを検討してください。
バッチサイズの詳細とクイックリファレンスについては、異なるデバイス構成間のパフォーマンス比較ガイドを参照してください。
異なるGPUでのパフォーマンスの問題
マルチGPU構成が異なるGPUで構成されている場合、パフォーマンスの問題が発生する可能性があります:
- GPU間のGPUメモリに不均衡が生じている可能性があります。この場合、メモリ容量が小さいGPUが、GPUにロードできるバッチサイズまたはモデルサイズを制限します。
- 異なる性能プロファイルを持つGPUを使用している場合、他のGPUがそのワークロードの完了を待たなければならないため、使用しているGPUの中で最も遅いGPUによって性能が左右されます。
同じセットアップ内で大きく異なるGPUを使用すると、パフォーマンスのボトルネックが発生する可能性があります。
ヘルプを依頼する
ここで紹介した解決策やアドバイスが問題の解決に役立たなかった場合は、いつでもコミュニティやAccelerateチームに連絡してサポートを受けることができます。
Accelerate カテゴリに質問を投稿して、Hugging Face フォーラムでヘルプを求めましょう。セットアップに関する関連するコンテキストと再現可能なコードを含み、説明的な投稿を書くことで、問題が解決される可能性を最大限に高めてください!
Discordに質問を投稿し、チームやコミュニティのサポートを受けてください。
AccelerateのGitHubリポジトリで、ライブラリに関連するバグを発見したと思われる場合は、Issueを作成してください。バグに関する背景情報と、分散環境の詳細を含めてください。これにより、問題の原因をより正確に特定し、修正方法を検討しやすくなります。