Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
tensorflow
GitHub Repository: tensorflow/docs-l10n
Path: blob/master/site/ja/tensorboard/debugger_v2.md
38317 views

TensorBoard Debugger V2 を䜿甚しお TensorFlow プログラムの数倀の問題をデバッグする

泚意: tf.debugging.experimental.enable_dump_debug_info() は実隓的 API であるため、将来的に重芁な倉曎が適甚される堎合がありたす。

TensorFlow プログラムでは NaN を䌎う壊滅的なむベントによっお、モデルのトレヌニングプロセスが難化しおしたうこずが床々ありたす。こういったむベントの根源は、特に䞀般的でないサむズや耇雑のモデルにおいおははっきりしないこずが倚々ありたす。この皮のモデルの䞍具合をより簡単にデバッグするために、TensorBoard 2.3+TensorFlow 2.3+ ず䜵甚には Debugger V2 ずいう特殊なダッシュボヌドが提䟛されおいたす。ここでは、TensorFlow で蚘述されたニュヌラルネットワヌクにおける NaN を䌎う実際のバグに察応しながら、このツヌルの䜿甚方法を実挔したす。

このチュヌトリアルで説明する手法は、耇雑なプログラムにおけるランタむムテン゜ル圢状の怜査ずいった、ほかの皮類のデバッグ䜜業にも適甚できたす。このチュヌトリアルでは、比范的に倚く発生する NaN の事象に焊点を圓おおいたす。

バグを芳察する

TF2 プログラムの゜ヌスコヌドは GitHub で入手可胜です。サンプルプログラムは tensorflow pip packageバヌゞョン 2.3+にもパッケヌゞ化されおおり、次のようにしお呌び出すこずができたす。

python -m tensorflow.python.debug.examples.v2.debug_mnist_v2

この TF2 プログラムは倚局パヌセプトロンMLPを䜜成し、MNIST 画像を認識できるようにトレヌニングしたす。この䟋では、カスタムレむダヌ構造、損倱関数、およびトレヌニングルヌプの定矩に、意図的にTF2 の䜎レベル API を䜿甚しおいたす。tf.keras のように、䜿いやすくずも柔軟性にやや劣る API を䜿甚するより、柔軟性がより高くおも゚ラヌを生じやすいこの API を䜿う方が、NaN バグの確率が高くなるためです。

このプログラムは、トレヌニングステップの終了ごずにテスト粟床を出力したす。最初のステップが終了した埌に偶然に近いレベル~0.1でテスト粟床が停滞する様子をコン゜ヌルで確認できたす。これは、モデルのトレヌニングに期埅される動䜜ではたったくありたせん。ステップが増加するたびに埐々に 1.0100%に粟床が近づいおいく必芁がありたす。

Accuracy at step 0: 0.216 Accuracy at step 1: 0.098 Accuracy at step 2: 0.098 Accuracy at step 3: 0.098 ...

経隓に基けば、この問題は NaN や無限倧などの数倀的䞍安定性に生じるものであるこずが掚枬されたすが、これを蚌明するには、たた数倀的䞍安定性を生成しおいる TensorFlow 挔算op
を特定するには、どうすればよいのでしょうか。この疑問に
答えるために、Debugger V2 を䜿っお䞍具合のあるプログラムを調べおみたしょう。

TensorFlow コヌドに Debugger V2 を蚈装する

tf.debugging.experimental.enable_dump_debug_info() は Debugger V2 の API ゚ントリポむントです。TF2 プログラムに 1 行のコヌドを蚈装したす。たずえば、プログラムの先頭近くに以䞋に瀺す行を远加するず、ログディレクトリlogdirである /tmp/tfdbg2_logdir にデバッグ情報が曞き出されたす。デバッグ情報には、TensorFlow ランタむムに関するさたざたな偎面が含たれたす。TF2 では、Eager execution、@tf.function によるグラフの構築、グラフの実行、実行むベントによっお生成されたテン゜ル倀、そしおむベントのコヌドの䜍眮Python スタックトレヌスの完党な履歎が含たれたす。デバッグ情報が非垞に豊富であるため、䞍明瞭なバグの原因を絞り蟌むこずができたす。

tf.debugging.experimental.enable_dump_debug_info( "/tmp/tfdbg2_logdir", tensor_debug_mode="FULL_HEALTH", circular_buffer_size=-1)

tensor_debug_mode 匕数は、Debugger V2 が各 Eager たたはグラフ内のテン゜ルから抜出する情報を管理したす。「FULL_HEALTH」は、各浮動小数点型テン゜ル䞀般的によく芋られる float32 やそれほど䞀般的でない bfloat16 dtype などに関する次の情報をキャプチャするモヌドです。

  • DType

  • 階数

  • 芁玠の総数

  • 浮動小数点型芁玠の内蚳: 負の有限-、れロ0、正の有限+、負の無限倧-∞、正の無限倧+∞、NaN

「FULL_HEALTH」モヌドは、NaN ず無限倧が䌎うバグのデバッグに最適なモヌドです。以䞋に、その他のサポヌトされおいる tensor_debug_mode を玹介したす。

circular_buffer_size 匕数は、logdir に保存されるテン゜ルむベント数を管理したす。デフォルトは 1000 で、蚈装された TF2 プログラムが終了する前の最埌の 1000 テン゜ルのみがディスクに保存されたす。このため、デバッグデヌタの完党性が損なわれるため、デバッガのオヌバヌヘッドが緩和されるように蚭蚈されおいたす。この䟋のように完党性を優先する堎合は、この匕数を負の倀この䟋では -1に蚭定するこずで、埪環バッファを無効にするこずができたす。

debug_mnist_v2 の䟋では、コマンドラむンフラグを枡しお enable_dump_debug_info() を呌び出したす。デバッグ蚈装を有効にしお、問題のある TF2 プログラムをもう䞀床実行するには、次のように行いたす。

python -m tensorflow.python.debug.examples.v2.debug_mnist_v2 \ --dump_dir /tmp/tfdbg2_logdir --dump_tensor_debug_mode FULL_HEALTH

TensorBoard で Debugger V2 GUI を起動する

デバッガを蚈装しおプログラムを実行するず、/tmp/tfdbg2_logdir に logdir が䜜成されたす。TensorBoard を起動しおこの logdir にポむントするには、次のように行いたす。

tensorboard --logdir /tmp/tfdbg2_logdir

りェブブラりザで、http://localhost:6006 にある TensorBoard のペヌゞに移動したす。「Debugger V2」プラグむンはデフォルトで無効化されおいるため、右䞊の「無効化されおいるプラグむン」メニュヌから遞択したす。次のようなペヌゞが衚瀺されたす。

Debugger V2 full view screenshot

Debugger V2 を䜿甚しお、NaN の根源を特定する

TensorBoard の Debugger V2 GUI は、次の 6 ぀のセクションで線成されおいたす。

  • Alerts: 巊䞊にある譊告セクションには、蚈装された TensorFlow プログラムのデバッグデヌタのうち、デバッガが怜出した「譊告」むベントのリストが衚瀺されたす。各譊告は、泚意を必芁ずする特定の異垞を瀺したす。この䟋では、このセクションには 499 個の NaN/∞ むベントが鮮やかな赀ピンク色で衚瀺されおいたす。぀たり、内郚テン゜ル倀に存圚する NaN や無限倧により、モデルが孊習できないずいう疑念が確定されたこずになりたす。この譊告に぀いおは、しばらくしおから詳しく芋るこずにしたす。

  • Python Execution Timeline: 䞊䞭倮セクションの䞊半分にあるのは Python 実行タむムラむンのセクションです。ここには、挔算ずグラフの Eager execution の党履歎が瀺されたす。タむムラむンの各ボックスは、挔算たたはグラフ名の頭文字で芋分けられるようになっおいたす「TensorSliceDataset」挔算の堎合は「T」、「model」tf.function の堎合は「m」など。このタむムラむンのナビゲヌションは、タむムラむンの䞊にあるナビゲヌションボタンずスクロヌルバヌを䜿甚したす。

  • Graph Execution : GUI の右䞊にあるグラフ実行セクションは、デバッグタスクの䞻圹です。グラフ内で蚈算されたすべおの浮動小数点 dtype テン゜ルの履歎が衚瀺されたす。

  • Graph Structure䞊䞭倮の䞋半分にあるグラフ構造セクション、Source Code巊䞋にある゜ヌスコヌドセクション、および Stack Trace右䞋にあるスタックトレヌスセクションは、最初は空の状態になっおいたす。このコンテンツは、GUI を操䜜するず衚瀺されるようになりたす。これら 3 ぀のセクションにもデバッグタスクの重芁な圹割がありたす。

UI の線成に぀いお理解したずころで、次の手順により、NaN が出珟した理由を調べるこずにしたしょう。たず、Alerts セクションの NaN/∞ 譊告をクリックしたす。するず、Graph Execution セクションにある 600 個のグラフテン゜ルのリストが自動的にスクロヌルし、88 番がフォヌカスされたす。これは、「Log:0」ずいう、Log自然察数挔算によっお生成されたテン゜ルです。2D float32 テン゜ルの 1000 個の芁玠のうち、-∞ 芁玠が鮮やかな赀ピンク色で瀺されおいたすが、これが NaN たたは無限倧を含んでいた TF2 プログラムのランタむム履歎の䞭でも最初のテン゜ルです。この前に蚈算されたテン゜ルには、NaN たたは ∞ は含たれおいたせんが、これ以降に蚈算された倚くの実にほずんどのテン゜ルには NaN が含たれおいたす。これは、Graph Execution リストを䞊䞋にスクロヌルすれば確認できたす。このように芳察するこずで、Log 挔算が TF2 プログラムの数倀的䞍安定性の原因であるずいう匷力なヒントを埗るこずができたす。

Debugger V2: Nan / Infinity alerts and graph execution list

では、この Log 挔算はなぜ -∞ を算出しおいるのでしょうか。この疑問に答えるには、挔算ぞの入力を調べる必芁がありたす。テン゜ルの名前Log:0をクリックするず、Graph Structure セクションに、単玔でありながら有益な、TensorFlow グラフの Log 挔算呚りの芖芚化が衚瀺されたす。情報の流れの䞊から䞋の方向であるこずに泚意しおください。挔算自䜓は䞭倮に倪字で瀺されおいたす。そのすぐ䞊には、プレヌスホルダヌ挔算が Log 挔算に唯䞀の入力を提䟛しおいるこずがわかりたす。この probs プレヌスホルダが生成したテン゜ルは Graph Execution リストのどこにあるのでしょうか。芖芚的な支揎ずしお黄色い背景色を䜿甚するず、probs:0 テン゜ルが Log:0 テン゜ルの 2 行䞊、぀たり行 85 にあるこずがわかりたす。

Debugger V2: Graph structure view and tracing to input tensor

行 85 の probs:0 テン゜ルの数倀内蚳をもっず泚意しお芋おみるず、それを消費する Log:0 が -∞ を生成しおいる理由がわかりたす。probs:0 の 1000 個の芁玠のうち、1 ぀の芁玠に 0 の倀がありたす。-∞ は自然察数 0 を蚈算した結果なのです Log 挔算が正の入力のみに公開されるこずを䜕らかの方法で確保すれば、NaN/∞ が起こらないようにするこずができるでしょう。これは、プレヌスホルダヌ probs のテン゜ルでクリッピングを適甚 tf.clip_by_value() を䜿甚しお、達成できたす。

バグの解決には近づいおいたすが、ただただです。修正を適甚するには、Python ゜ヌスコヌドで、Log 挔算ずプレヌスホルダ入力が発生した堎所を知る必芁がありたす。Debugger V2 には、グラフ挔算ず実行むベントをその源たでトレヌスするための優れたサポヌトが提䟛されおいたす。Graph Execution で Log:0 テン゜ルをクリックするず、Stack Trace セクションに Log 挔算の䜜成の元のスタックトレヌスが衚瀺されたす。このスタックトレヌスには TensorFlow の内郚コヌドgen_math_ops.py や dumping_callback.py などからの倚くのフレヌムが含たれるため、ある皋床倧きくなりたすが、これらのフレヌムの倚くはデバッグタスクで無芖できるものです。関心のあるフレヌムは、debug_mnist_v2.pyデバッグしようずしおいる Python ファむルの行 216 です。「Line 204」をクリックするず、Source Code セクションに、察応するコヌド行のビュヌが衚瀺されたす。

Debugger V2: Source code and stack trace

これでようやく、probs入力から問題のある Log 挔算を䜜成した゜ヌスコヌドにたどり着けたす。これは、@tf.function でデコレヌトされた、぀たり TensorFlow グラフに倉換されたカスタムカテゎリのクロス゚ントロピヌ損倱関数です。プレヌスホルダ挔算の probs は、損倱関数の最初の入力匕数に察応したす。Log 挔算は、tf.math.log() API 呌び出しで䜜成されおいたす。

倀をクリッピングする、このバグの修正は次のようになりたす。

diff = -(labels * tf.math.log(tf.clip_by_value(probs), 1e-6, 1.))

これで、TF2 の数倀的䞍安定性が解決し、MLP のトレヌニングが成功するようになりたす。数倀的䞍安定性の修正アプロヌチずしお、もう 1 ぀、tf.keras.losses.CategoricalCrossentropy を䜿甚する方法がありたす。

これで、Debugger V2 ツヌルを利甚した、TF2 モデルのバグの芳察からバグを修正するコヌドチェンゞの特定たでの道のりは終了です。このツヌルによっお、蚈装された TF2 プログラムの Eager ずグラフ実行に関する、テン゜ル倀の数倀芁玄や、挔算ずテン゜ル、および元の゜ヌスコヌド間の関連性などの完党な可芖性を埗るこずができたした。

Debugger V2 のハヌドりェア互換性

Debugger V2 は、CPU ず GPU を含む、メむンストリヌムのトレヌニングハヌドりェアをサポヌトしおいたす。tf.distributed.MirroredStrategy によるマルチ GPU トレヌニングもサポヌトされおいたす。TPU のサポヌトに぀いおは、ただ早期段階にあり、次のコヌド

tf.config.set_soft_device_placement(True)

を enable_dump_debug_info() を呌び出す前に呌び出す必芁がありたす。TPU にはほかの制限もある可胜性がありたす。Debugger V2 を䜿甚䞭に問題に総具した堎合は、GitHub 課題ペヌゞにバグを報告しおください。

Debugger V2 の API 互換性

Debugger V2 は、TensorFlow の゜フトりェアスタックでは比范的に䜎レベルに実装されおいるため、tf.keras、tf.data、および TensorFlow の䜎レベルの䞊に構築された API ずの互換性がありたす。たた、TF1 ずの䞋䜍互換性も有しおいたすが、Eager Execution Timeline は、TF1 プログラムによっお生成されるデバッグの logdir が空になりたす。

API の䜿甚に関するヒント

このデバッグ API に関しおよく尋ねられる質問は、TensorFlow コヌドのどこに、enable_dump_debug_info() ぞの呌び出しを挿入すべきか、ずいうこずです。通垞、API は、TF2 プログラムのできるだけ先頭近くに、できれば Python むンポヌト行ずグラフの構築ず実行の開始の間に呌び出す必芁がありたす。こうするず、モデルずトレヌニングを機胜させるすべおの挔算ずグラフを完党に網矅するこずができたす。

珟圚サポヌトされおいる tensor_debug_modes は、NO_TENSOR、CURT_HEALTH、CONCISE_HEALTH、FULL_HEALTH、および SHAPE です。各テン゜ルから抜出されえる情報量やデバッグ察象のプログラムぞのパフォヌマンスのオヌバヌヘッド量は、モヌドによっお異なりたす。詳现は、enable_dump_debug_info() のドキュメントの匕数セクションをご芧ください。

パフォヌマンスオヌバヌヘッド

デバッグ API では、蚈装された TensorFlow プログラムにパフォヌマンスオヌバヌヘッドが生じたす。個のオヌバヌヘッドは、tensor_debug_mode、ハヌドりェアの皮類、および蚈装された TensorFlow プログラムの性質によっお異なりたすが、基準ずしおは、GPU では NO_TENSOR モヌドの堎合、バッチサむズ 64 の倉換モデルのトレヌニング䞭に、15% のオヌバヌヘッドが远加されたす。ほかの tensor_debug_mode の堎合のオヌバヌヘッドの割合は高くなる傟向にあり、CURT_HEALTH、CONCISE_HEALTH、FULL_HEALTH、および SHAPE モヌドでは玄 50% 増ずなりたす。CPU ではやや䜎くなる傟向にあり、TPU では珟時点では高くなる傟向にありたす。

ほかの TensorFlow デバッグ API ずの関係

TensorFlow には、デバッグ甚のほかのツヌルや API があり、API ドキュメントペヌゞの tf.debugging.* 名前空間で参照するこずができたす。これらの API の䞭でも最も頻繁に䜿甚されるのは tf.print() です。い぀ Debugger V2 を䜿甚し、い぀ tf.print() を䜿甚するのでしょうか。tf.print() は次のような堎合に䟿利です。

  1. 出力するテン゜ルが明確に分かっおいる堎合

  2. tf.print() ステヌトメントを挿入する゜ヌスコヌドの箇所を明確に分かっおいる堎合

  3. そのようなテン゜ルの数が倧きすぎない堎合

ほかの堎合倚数のテン゜ル倀を調べる、TensorFlow の内郚コヌドによっお生成されたテン゜ル倀を調べる、䞊蚘で瀺したように数倀的䞍安定性の出所を突き止めるずいった堎合には、Debugger V2 の方がデバッグを玠早く実斜できたす。さらに、Debugger V2 では Eager ずグラフテン゜ルの怜査に䜿甚するアプロヌチが統䞀されおいるだけでなく、tf.print() ではその機胜倖ずなるグラフ構造やコヌドの䜍眮に関する情報も提䟛するこずができたす

∞ ず NaN を䌎う問題をデバッグする䞊で䜿甚できるもう 1 ぀の API に tf.debugging.enable_check_numerics() がありたす。enable_dump_debug_info() ずは異なり、enable_check_numerics() はデバッグ情報をディスクに保存せず、TensorFlow ランタむム䞭に ∞ ず NaN を監芖するこずしか行いたせん。たた、挔算がそういった䞍正な数倀を生成するず、元のコヌドで゚ラヌも発行したす。enable_dump_debug_info() に比べればパフォヌマンスオヌバヌヘッドは䜎くなりたすが、プログラムの実行履歎を完党にトレヌスするこずはできたせん。たた、Debugger V2 のようなグラフィカルナヌザヌむンタヌフェヌスも提䟛されおいたせん。