From c1767994408395bc5dd7a4fb029f6653b83a20d3 Mon Sep 17 00:00:00 2001 From: devdeepr Date: Thu, 7 May 2026 20:39:21 +0000 Subject: [PATCH 1/2] perf(dex-hand): run retargeting optimizer under torch.no_grad MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DexHandRetargeter._compute_hand wrapped the per-frame call to ``self._dex_hand.retarget(...)`` in ``torch.enable_grad()`` and ``torch.inference_mode(False)`` — every step paid for autograd bookkeeping the dex_retargeting QP solver does not consume. Switch to ``torch.no_grad()`` so forward ops in the optimizer skip grad tracking entirely. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/retargeters/dex_hand_retargeter.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/retargeters/dex_hand_retargeter.py b/src/retargeters/dex_hand_retargeter.py index b056de146..41297bfb6 100644 --- a/src/retargeters/dex_hand_retargeter.py +++ b/src/retargeters/dex_hand_retargeter.py @@ -412,10 +412,14 @@ def _compute_hand(self, poses: Dict[str, np.ndarray]) -> np.ndarray: ref_value = target_pos[task_indices, :] - target_pos[origin_indices, :] # 4. Run optimizer + # ``dex_retargeting`` solves a QP-style optimization that does not + # require autograd; running under ``torch.no_grad()`` avoids the + # per-step grad-tracking overhead the previous ``enable_grad`` / + # ``inference_mode(False)`` context was incurring on every frame. try: import torch # type: ignore - with torch.enable_grad(), torch.inference_mode(False): + with torch.no_grad(): return self._dex_hand.retarget(ref_value) # type: ignore except Exception as e: logger.error(f"Error in retargeting: {e}") From 8b399e13160d21052574832f73b7537dadf37d53 Mon Sep 17 00:00:00 2001 From: devdeepr Date: Thu, 7 May 2026 21:09:44 +0000 Subject: [PATCH 2/2] review(dex-hand): preserve inference_mode(False) escape Copilot review on #478 flagged that switching the per-frame context from ``torch.enable_grad(), torch.inference_mode(False)`` to ``torch.no_grad()`` alone drops the explicit opt-out from any outer ``torch.inference_mode()``. Some in-place / view ops in dex_retargeting can error under inference mode, so a caller wrapping the session in ``torch.inference_mode()`` would now break. Combine both: ``torch.inference_mode(False), torch.no_grad()`` keeps the escape from inference mode (preserving prior behaviour) while still skipping autograd bookkeeping (the actual perf win). Co-Authored-By: Claude Opus 4.7 (1M context) --- src/retargeters/dex_hand_retargeter.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/retargeters/dex_hand_retargeter.py b/src/retargeters/dex_hand_retargeter.py index 41297bfb6..ad4d38db4 100644 --- a/src/retargeters/dex_hand_retargeter.py +++ b/src/retargeters/dex_hand_retargeter.py @@ -413,13 +413,15 @@ def _compute_hand(self, poses: Dict[str, np.ndarray]) -> np.ndarray: # 4. Run optimizer # ``dex_retargeting`` solves a QP-style optimization that does not - # require autograd; running under ``torch.no_grad()`` avoids the - # per-step grad-tracking overhead the previous ``enable_grad`` / - # ``inference_mode(False)`` context was incurring on every frame. + # require autograd. ``torch.no_grad()`` avoids the per-step + # grad-tracking overhead the previous ``enable_grad`` context paid for. + # ``torch.inference_mode(False)`` is preserved so callers running + # inside an outer ``torch.inference_mode()`` (where some in-place / + # view ops can error) still see the optimizer execute in normal mode. try: import torch # type: ignore - with torch.no_grad(): + with torch.inference_mode(False), torch.no_grad(): return self._dex_hand.retarget(ref_value) # type: ignore except Exception as e: logger.error(f"Error in retargeting: {e}")