「jax.checkpoint」(「jax.remat」とも呼ばれる)を介して実装されたJaxのグラデーションチェックポイントは、自動分化の前方パス中に保存される中間値を制御することにより、メモリ使用量を管理するのに役立ちます。デフォルトでは、JAXはすべての中間値(残差)を保存して、後方パス中にそれらを再利用するため、特にメモリアクセスが高価なハードウェアアクセラレータで高いメモリコストにつながる可能性があります[1] [3]。
勾配チェックポイントメカニズム:
1。報復戦略:すべての中間体を保存する代わりに、「Jax.Checkpoint」は、後方パス中に一部の中間体を再計算(修復)することを可能にします。このアプローチはメモリの使用量を削減しますが、計算時間を増加させます[1] [3]。
2。メモリの削減:チェックポイントは、バックプロパゲーション中のメモリの必要性を完全に排除しませんが(勾配は中間値にメモリが必要になるため)、特定の中間体の保存を回避することでピークメモリの使用量を削減できます[8]。ただし、実際のメモリの節約は、計算グラフ内でチェックポイントの適用方法によって異なります。
3.メモリの断片化の削減:「Jax.CheckPoint」は、メモリの断片化に直接対処するのではなく、主にピークメモリの使用量を減らすことをターゲットにしていますが、チェックポイントの効率的な使用はメモリの割り当てパターンを管理するのに役立ちます。中間体が保存および再計算されたときに制御することにより、メモリ全体のフットプリントを削減し、頻繁な割り当てと取引の必要性を最小限に抑えることにより、間接的に断片化を軽減できます[7]。
要約すると、Jaxの勾配チェックポイントは主に中間体を修復することによりピークメモリの使用量を削減することを目的としていますが、メモリ配分パターンを最適化することにより断片化を軽減するのに役立つより良いメモリ管理の実践に間接的に貢献できます。ただし、メモリの断片化の直接的な削減は、バッチング操作やメモリ使用量の監視などの他の戦略を通じてより効果的に達成されます[7]。
引用:[1] https://docs.jax.dev/en/latest/gradient-checkpointing.html
[2] https://discuss.pytorch.org/t/gradient-checkpointing-and-its-effect-on-memory-and-runtime/198437
[3] https://docs.jax.dev/en/latest/_autosummary/jax.checkpoint.html
[4] https://github.com/google/jax/discussions/20252
[5] https://jax.readthedocs.io/en/latest/gpu_memory_allocation.html
[6] https://discuss.pytorch.org/t/gradient-checkpointing-does-not-reduce-memory-usage/71421
[7] https://app.studyraid.com/en/read/11969/381958/memory-management-best-practics
[8] https://github.com/google/jax/issues/19822