warp-debug-gradients について
Warp の自動微分を使う開発者向けの勾配デバッグスキルです。有限差分による検証で原因を特定し、修正後も再確認します。
主な機能
- 01失敗する処理の再現と縮小
- 02自動微分と有限差分の比較
- 03テープ中の配列上書きの追跡
- 04パイプライン内の勾配差異の特定
- 05出荷対象プログラムでの修正検証
活用シーン
- 01Warp の学習停滞や発散の調査
- 02NaN、ゼロ、偏った勾配の診断
- 03gradcheck 失敗後の勾配確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ nvidia/ skills --skill warp-debug-gradientsインストール後、Claude Code で/warp-debug-gradientsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
BENCHMARK.mdevals/EVAL.mdevals-full.jsonevals.jsonevals/files/checkpoint_control.pycontact.pydac.pydeblur.pyemitters.pygain_train.pyheightfit.pyhuber_fit.pylattice.pylens_calibrate.pyevals/files/compound/objective.pyphysics.pystate.pytrain.pyevals/files/compreassign/model.pytrain.pyevals/files/dynloop/model.pytrain.pyevals/files/funcgradassign/model.pytrain.pyevals/files/inplacemul/model.pytrain.pyevals/files/missingzero/model.pytrain.pyevals/files/nangrad/model.pytrain.py詳細
Warp での勾配のデバッグ
Warp の勾配バグは、ほとんどの場合、数学のバグではありません。順方向シミュレーションはまったく問題なく見える一方で、逆方向パスでは上書きされた値が気付かれないまま読み取られたり、配列がスキップされたり、随伴変数が二重に加算されたりします。ユーザーは、実際の原因がテーピングパターンを2行修正するだけなのに、物理パラメーターや損失関数、アセットの調整に何日も費やしがちです。直感ではなく、証拠をもとにその修正を見つけてください。
最も重要な原則は、仮説を立てる前に測定することです。縮小した再現ケースを実行し、自動微分と有限差分を比較するのは簡単です。勾配の誤り方(その特徴)を調べれば、コードを読むだけの場合よりはるかに速く仮説の範囲を絞り込めます。コードを読んだだけで修正案を出し始めないでください。微分可能性のバグについて、もっともらしく見える診断が実際には間違っていることはよくあり、検証せずに行った「修正」がたまたま数値を変えてしまうと、全員の時間を無駄にします。
このスキルを使用する場面
Warp カーネルを通じて学習、最適化、キャリブレーション、またはフィッティングを行うものはすべて、wp.Tape の勾配を使用します。そのため、ユーザーが勾配という言葉を使わなくても、そのようなワークフローに問題があれば、まず勾配を疑ってください。ユーザーが実際に報告する症状を基準にしてください。学習が発散する、NaN が発生する、または何も起こらない、損失が停滞する、あるいは想定より高い値で頭打ちになる、フィッティングが誤った値や偏った値に収束する、または参照実装より悪い、パイプラインが小規模では動作するが本番規模では失敗する、または QA の再確認で失敗する、といった場合です。勾配の爆発、NaN/inf、ゼロ、または微妙な誤り、wp.autograd.gradcheck の失敗、wp.Tape/逆方向処理の問題が疑われる場合や、勾配を信頼できるかユーザーが尋ねた場合にも、このスキルを使用してください。
順方向処理のみを行う Warp の作業(カーネル作成、レンダリング、パフォーマンス調整)、Warp のビルドやインストールの問題、Warp を使わない他のフレームワークの自動微分に関する質問、または勾配がすでに検証済みである逆方向パスのパフォーマンスのみを対象とする作業では、このスキルを使用しないでください。
基本となる情報源は Warp 独自のドキュメントです。該当する領域の診断を行う前に、関連するセクションを参照してください(オンラインでは
https://nvidia.github.io/warp/stable/、Warp のソースコードをチェックアウトしている場合は同じ内容が
docs/user_guide/ にあります。pip のインストールには含まれません)。
- 「Differentiability」ガイド。特に「Array Overwrites」、「Debugging Gradients」、「Array Overwrite Tracking」、「Limitations and Workarounds」 (インプレース演算、コンポーネントの代入、動的ループ)。
- FAQ の「Differentiation and Interoperability」セクション。テープが保持する状態と保持しない状態、およびチェックポイントについて。
前提条件
このスキルを実行するには、以下のすべてが必要です。1つでも欠けている場合は、その場しのぎで対応せず、ユーザーに伝えてください。
- ユーザーのスクリプト(または忠実な再現ケース)をワークスペース内で利用でき、実行および変更できること。診断では繰り返し実行し、修正を適用するために編集します。
- このスキルに
references/内のファイル(quick-checks.md、verification.md、custom-gradients.md、case-studies.md)が付属しており、それらを参照する手順で確認できること。
手順
-
まずユーザーの Warp バージョンを確認します(
wp.__version__、または初期化時に Warp が出力するバナー)。Warp 1.17 では、複数の検証動作が変更されています。コピー時の随伴変数の累積、上書き警告を出す呼び出し箇所、読み取りフラグの有効期間、gradcheckのrestore_inputsです。参照資料では、それぞれにバージョンに関する注意事項を記載しています。Warp 1.17 より前には、それ以降のバージョンで修正された一連のバグが存在します(quick-checks §1 のバージョンに関する注意事項)。一部のツールには回避策が必要です。 -
再現して縮小します。 ユーザーのスクリプトを実行し、規模を小さくします。 粒子や要素の数を減らし、タイムステップ数やオプティマイザーの反復回数を減らし、 シミュレーションが対応していれば CPU デバイスを使います。何度も実行するため、 数秒で動く再現ケースが必要です。構造(カーネルの数、テープ記録のパターン、 バッファーの再利用)はそのまま維持してください。バグが潜んでいるのはそこです。 物理現象の規模を小さくするのは問題ありませんが、データフローの構造を変えてはいけません。
スクリプトを実行できない場合(依存関係の不足、コードの破損など)は、阻害要因を 成果物として報告し、そこで終了してください。一度も実行していないプログラムの検証に 進んではいけません。
-
計測して正解を確立します(詳細とテンプレートは
references/verification.mdを参照してください)。- モジュールの読み込み前に
wp.config.verify_autograd_array_access = Trueを設定し、 アクティブなテープの下で再実行します。警告をすべて記録してください。これにより、 最もよくあるバグの種類(読み取り後の上書き)を、ほとんど手間をかけずに検出できます。 検出できないケースも把握しておいてください。テープが必要であり、Warp の構造体内に 保存された配列は検出できず、カーネルキャッシュが無効になります(カーネルの再構築が 発生しますが、ネイティブライブラリの再構築ではなく、JIT モジュールの再コンパイルのみです)。 トラッカーに問題がなくても勾配が間違っている場合は、結果を信頼する前に、Warp の 構造体内に保持された配列がインプレースで変更されていないかを必ず確認してください (クイックチェック §1 と「制限事項」を参照)。 - エンドツーエンドの有限差分チェックを 1 回実行します。順伝播全体(シミュレーションの
ステップと損失)を Python 呼び出し可能オブジェクトでラップし、実際の最適化入力を使って
wp.autograd.gradcheckに渡します。これにより、自動微分の勾配と中心差分を比較します。 評価のたびに配列入力が復元されるため(Warp 1.17 以降)、インプレース変更を行う順伝播も 初期状態から検証されます。それ以前の Warp では、references/verification.mdの手動ハーネスを 使用してください。比較対象は、ユーザーが実際に最適化する全期間にわたる目的関数と、 オプティマイザーが実際に受け取る勾配です。より短いウィンドウを使ってはいけません (references/verification.mdを参照)。これにより、勾配が本当に間違っていることを確認できます (勾配についてのユーザーの認識が誤っていることもあるため、「勾配は正しい」という結果も 正直に報告してください)。また、誤差の特徴も明らかになります。references/verification.mdのテンプレートでは、eps/許容誤差の選択と、確率的な順伝播に 必要なシードの固定方法が規定されています。浮動小数点誤差やサンプリングノイズを見て、 合否を目測で判断してはいけません。正解を確立する際に逆伝播でメモリ不足になった場合は、 続行する前に、下記の「エッジケース:メモリ不足」のチェックポイント手法を適用してください。
- モジュールの読み込み前に
-
特徴を以下の表と照合し、仮説の優先順位を付けます。
-
既知パターンのチェックリスト(
references/quick-checks.md)に照らして コードを確認します。これはすぐにできます。特徴によって、妥当な原因と単なる懸念点を 見分けながら、同じ確認の中で実施してください。 -
まだ曖昧な場合は原因を絞り込みます。 パイプラインを二分探索し、K ステップで 打ち切って、有限差分と自動微分が最初に食い違う箇所を見つけます。
wp.autograd.gradcheck_tapeを実行し、記録された各起動を個別にテストします。 gradcheck_tape はカーネルを個別に検証するため、カーネル間の上書きは構造上検出できません。 したがって、カーネル単位の検証に合格してもエンドツーエンドの勾配が間違っている場合は、 カーネルではなくテープ記録のパターンを疑ってください。また、enable_backward=Falseを指定して コンパイルされたカーネルは警告なしにスキップされます(「制限事項」を参照)。 パイプライン内のカーネルがこれを設定している場合、検証に合格しても何も確認できていません。 そのカーネルは別途検証してください。 -
最小限の修正を行い、その後、失敗を特定したのとまったく同じ FD ハーネスで再検証する。前後の FD 比較を伴わない勾配の修正は修正ではありません。出荷するまさにそのプログラムを検証してください — 現状のままの修正済みファイルを、すべての行を含めて — 診断スクリプト内でそれを再実装したものは決して検証しないでください。再構築されたパイプラインは、無関係だとあなたが信じていたものを黙って捨て去り、その信念が誤っている場合には、検証は通過するのに、出荷されたコードは壊れたままになります。機械的には、ハーネスは修正済みモジュールをインポートする(または修正済みファイルを実行する)とともに、それを呼び出さなければならない — 出荷するプログラムの外部に置いてよいコードは、FD ドライバー自体だけです。また、上書きトラッカーを再実行して、警告が消えたことを確認してください。「最小限」はコードの差分に当てはまるのであって、診断に当てはまるのではありません。根本原因が構造的な場合(例: 偶発的な勾配の切り捨て、クイックチェック §8)、最小の正しい修正は再構築です — 表面の症状を黙らせるだけのより小さな変更で代用しないでください。
-
ユーザーの最初の不満に対してループを閉じる。ユーザーの実際のワークフロー(ユーザーのスクリプト、ユーザーが出力するメトリクス)を再実行してください。ユーザーが報告した症状が解消されたときに、この作業は完了です — 「爆発」していた最適化は今や、単に NaN を避けるだけでなく、目的関数を改善していることを実証できるはずです。勾配が完全なホライズンで正しいと検証されても、なお学習が失敗する場合、それは新たなシグネチャテーブルのエントリであり、勝利ではありません。診断を続けてください(または、検証済みの勾配と、残っている勾配以外の原因、例えば学習率を報告してください)。
失敗の兆候
| 兆候 | 主な仮説 |
|---|---|
| 勾配が完全にゼロ | チェーン内のどこかで requires_grad=True が設定されていない(wp.zeros の既定値は False であり、zeros_like/clone はソースから引き継ぎます);モジュールまたはカーネルのレベルで enable_backward=False が設定されている;損失配列がテープにつながっていない;tape.zero() の実行後に勾配を読み取っている;チェーン内に区分定数演算(round/floor/sign/キャスト/しきい値処理)がある——この場合、ゼロは 正しい 結果であり、修正にはバグ探しではなく、直通推定器のような代理勾配が必要です(クイックチェック §9c);Warp < 1.17 では、ソースにほかの下流の読み取り処理がある場合に、テープに記録されたコピー/クローンが原因となることがあります(references/quick-checks.md のバージョンに関する注意を参照) |
| オプティマイザーの反復ごとに勾配が際限なく増大する | 反復の間に tape.zero()/tape.reset() がない;フレーム間でテープ内の上書きを引き継ぐ状態オブジェクトのエイリアシング(事例研究 1) |
| 正確な小さな倍率(2x、Nx)だけずれる | 二重加算:重複したカーネル起動がテープに記録されている——ただし、Warp 1.13 以降では、ストアの随伴処理は最初の使用時に出力勾配を消費するため、書き換えられた配列に retain_grad=True が設定されている場合(クイックチェック §7)か、Warp のバージョンが古い場合を除き、単なる重複起動は影響しません。同じ処理を二度テープ記録する、重複したテープスコープ。さらに、逆伝播のシードが明示された目的関数に一致していない場合もあります——要素ごとの損失の随伴に ones をシードすると、合計に対して逆伝播するため、平均目的関数の勾配のちょうど N× になります |
| NaN または inf | 逆伝播中に非微分可能な点が評価されている(wp.sqrt(0)、wp.length(0)、wp.normalize(0)、除算)——カスタム勾配(references/custom-gradients.md)が必要です。より望ましいのは、安定した形に書き換えることです;wp.where の選択されない分岐でオーバーフローが評価されている(分岐ではなく選択です——クイックチェック §9b);動的ループ内のローカル変数が再実行時に再計算されない(inf が生成されることが記録されています) |
| 微妙に誤っており、ステップ数/反復回数が増えるほど悪化することが多い | 読み取り後の書き込みによる上書き:すでに読み取られた配列への wp.copy、1 つのテープ内での ping-pong バッファー、2 つの「異なる」状態をエイリアスさせる Python の再束縛(事例研究);インプレースの *=//=;ベクトル/行列の成分の再代入;動的ループの中間値;Warp < 1.17 では、ソースの最後の消費処理ではない、記録済みのコピー/クローン(references/quick-checks.md のバージョンに関する注意を参照) |
| ウィンドウごとの FD は一致するが、全ホライズンの FD は一致しない;または、勾配を「検証済み」にもかかわらずオプティマイザーが停滞するか、損失が悪化する | 意図しない勾配の切り捨て:各ステップでテープを作成し、その中で逆伝播を行って状態をテープ間で引き継ぐループは、報告しているものとは異なる目的関数を最適化します(クイックチェック §8 を参照)。構造的な修正は、total_steps + 1 個の異なる状態バッファーを使い、ホライズン全体を 1 つのテープで処理することです。ソルバー空間での類似例:収束が不十分な反復解法をテープ内で行うと、FD と自動微分は誤ったプログラムに対して一致します。テープの外で収束させ、テープ内の反復ではウォームスタートしてください(クイックチェック §8) |
| 疎でデータ依存の一部でのみ、参照実装または実行ごとに勾配が異なる;順伝播の出力は浮動小数点精度で一致する | 非滑らかな点で順伝播の選択が一意に定まらない(クイックチェック §9):どちらの答えも有効な劣勾配である可能性があり、折れ点では FD による判定はできません。破損を調べる前に、不一致の要素で離散的な選択が異なっているか確認してください |
| 全ホライズンで FD と自動微分は一致するが、最適化に失敗する | 勾配のバグではありません。そう明記してください。学習率、損失地形、物理の安定性を確認し、勾配が正しいことを検証した結果として報告してください |
例
代表的なセッションを最初から最後まで紹介します。あるユーザーが「布のシミュレーションをしばらく学習させると、その後、損失が徐々に上がってしまいます。学習率を調整しても改善しません」と報告します。勾配には言及していませんが、このワークフローが Warp カーネルを通じて最適化するため、勾配の問題だと推測します。
- スクリプトは、反復ごとに 512 個の粒子を 200 ステップ実行しています。粒子数を 16、ステップ数を 10 に減らし、CPU で実行すると、再現ケースは約 2 秒で実行され、同じ上昇傾向が確認できます。
- テープの下で
wp.config.verify_autograd_array_access = Trueを設定すると、次の出力が表示されます。array ... was read from kernel integrate and is now being written to by kernel integrate— 読み取り後の書き込みによる上書きです。 - 縮小した再現ケースでエンドツーエンドの
wp.autograd.gradcheckを実行すると、有限差分に対する最大相対誤差は 0.4 です。勾配が誤っていることが確認でき、「わずかに誤っていて、ステップ数が増えるほど悪化する」という特徴とも一致します。 - この特徴とクイックチェック §1 から、1 つのテープ内でのバッファー再利用が原因と考えられます。シミュレーションは
state_a → state_b → state_aと 2 つのバッファーを交互に使うため、逆伝播時に上書きされた状態が読み取られます。 - 最小限の修正として、テープに記録される異なる状態バッファーを
num_steps + 1個割り当てます(物理演算は変更せず、データフローのみを変更します)。 - 再検証では、同じ gradcheck ハーネスが合格し(最大相対誤差は 3e-4)、上書き警告もなくなり、ユーザーの本番規模の学習実行でも損失が単調に減少します。
報告には、根本原因(テープ内でのバッファー再利用)、証拠の連鎖(警告と修正前後の FD の数値)、2 行の差分、Differentiability ガイドの「Array Overwrites」セクションへのリンクを含めます。
報告
根本原因と証拠の連鎖を最初に示します。失敗を裏付けた FD と自動微分の数値、原因の特定に使った警告または切り分け手順、最小限の差分、修正後の FD の数値です。このパターンを説明するドキュメントのセクション名を挙げ、ユーザーが標準的な説明を読めるようにします。問題なく確認できたパターン(例:上書きトラッカーで何も検出されなかった)があれば、それも伝えてください。除外できた原因をユーザーに示せます。
ユーザーが勾配を信頼できるかどうかだけを尋ねている場合は、検証と報告までで止めます。修正を求められた場合に修正を適用します。
証拠を保全します。診断スクリプト(FD ハーネス、縮小した再現ケース)は削除せず、ワークスペースに残して報告に記載してください。これらは証拠の連鎖のうち再現可能な部分であり、ユーザーやレビュー担当者が修正の根拠となった検証を正確に再実行できるようにします。自分が作成していないファイルは決して削除しないでください。
制限事項
検証ツールには見落としがあります。いずれか 1 つのツールで問題が検出されなかったとしても、問題がないとは限りません(詳細は references/verification.md を参照してください)。
- 上書きトラッカーを使うにはテープが有効である必要があり、Warp 構造体の内部に格納された配列は確認できません。また、有効にするとカーネルキャッシュは無効になります。
wp.autograd.gradcheckは構造体入力を受け付けません。基底となる配列を使う呼び出し可能オブジェクトで順伝播をラップしてください。Warp < 1.17 では、評価の間に変更された配列入力を復元しないため、手動ハーネスを使用してください。wp.autograd.gradcheck_tapeは記録された各カーネル起動を個別に検証するため、カーネル間の上書きバグは構造上検出できず、enable_backward=Falseでコンパイルされたカーネルは警告なくスキップされます。*=//=の微分不可警告は、wp.LOG_DEBUGの下でコード生成時にのみ出力されます。そのため、通常の実行で警告が見当たらなくても何の根拠にもなりません。- Warp には勾配チェックポイント機能が組み込まれていません。長い時間範囲でのメモリ負荷には、以下のアプリケーションレベルのパターンが必要です。
- 非滑らかな点(同値、折れ曲がり、argmin による選択)では、有限差分を使って妥当な劣勾配同士の優劣を判定できません。そのため、そこでの FD と自動微分の不一致が、必ずしもバグを意味するわけではありません(クイックチェック §9)。
エッジケース:メモリ不足
逆伝播でメモリの割り当てに失敗する場合(長時間のシミュレーションでは、中間状態がすべてテープ上に保持されます)、勾配チェックポイントを使って解決します。状態を定期的に保存し、逆伝播中に各状態の間のセグメントを再実行します。Warpには組み込みのユーティリティがないため、アプリケーション側で実装します。参考パターンとしてwarp/examples/optim/example_fluid_checkpoint.pyを使用し、FAQの「微分と相互運用性」セクションも参照してください。
参照ファイル
references/quick-checks.md— ドキュメントへの参照と、各パターンを見落としやすくする注意点をまとめた、既知のバグパターンのチェックリストです。references/verification.md— ツールの詳細:上書きトラッカーのセットアップと見落としやすい点、エンドツーエンドのFDハーネステンプレート、wp.autogradのgradcheck/jacobianの使い方と注意点、テープの可視化、二分探索。references/custom-gradients.md—@wp.func_grad、@wp.func_replay、@wp.func_native:必要な場面と誤った使い方について説明します。references/case-studies.md— 実際のデバッグ事例を2件(状態のエイリアシング、微分可能なコピーの上書き)取り上げ、表面上の症状がいかに微妙であるかを示します。チェックリストで問題が見つからない場合は、こちらを読んでください。ここでいう「微妙」の意味をつかめます。