Skip to content
This repository was archived by the owner on Feb 21, 2026. It is now read-only.

Consolidate open PRs: MIM inference, Hessian solver, gradient accumulation, and AMP#10

Merged
thinksyncs merged 7 commits intomainfrom
copilot/combine-all-prs
Feb 6, 2026
Merged

Consolidate open PRs: MIM inference, Hessian solver, gradient accumulation, and AMP#10
thinksyncs merged 7 commits intomainfrom
copilot/combine-all-prs

Conversation

Copy link
Contributor

Copilot AI commented Feb 6, 2026

Merges PRs #6, #7, #8, and #9 to prevent conflicts. Total delta: 18 files, +2,888 lines.

Changes

PR #6: Masked reconstruction branch (1,270 lines)

  • Adds RenderTeacher and DecoderMIM modules for geometry-aligned masked image modeling in inference
  • New loss functions: mim_reconstruction_loss() and entropy_loss() for test-time adaptation
  • RTDETRPose.forward() accepts geom_input (mask + normalized depth), feature_mask, and return_mim flag
model = RTDETRPose(enable_mim=True)
geom = create_geom_input(mask, depth_obj)
outputs = model(image, geom_input=geom, feature_mask=mask_feat, return_mim=True)
loss = mim_reconstruction_loss(outputs["mim"]["recon_feat"], outputs["mim"]["teacher_feat"])

PR #7: Hessian solver (1,319 lines)

  • Gauss-Newton with Levenberg-Marquardt damping for per-detection depth/rotation/offset refinement
  • HessianSolverConfig and refine_predictions_hessian() API
  • CLI tool: tools/refine_predictions_hessian.py

PR #8: Gradient accumulation + AMP (252 lines)

  • --gradient-accumulation-steps N scales loss by 1/N, defers optimizer step to accumulation boundaries
  • --use-amp enables torch.cuda.amp with proper gradient unscaling before clipping
  • Fixed lint error: removed unused json import in test file

PR #9: Lint documentation (50 lines)

  • Documents lint fixes needed in other PRs (already applied during merge)

Implementation notes

  • Merge strategy: patch-based application to main branch to avoid unrelated history conflicts
  • All features backward compatible with existing code (disabled by default)
  • MIM operates on P5 features (1/16 to 1/32 scale) with ~100K additional parameters
  • Hessian solver typical convergence: 3-5 iterations, ~1-2ms per detection on CPU
Original prompt

今上がっているPRを全てまとめて一つのPRにして欲しい。
for prevents conflicts


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI changed the title [WIP] Consolidate all open pull requests into one Consolidate open PRs: MIM inference, Hessian solver, gradient accumulation, and AMP Feb 6, 2026
Copilot AI requested a review from thinksyncs February 6, 2026 04:38
@thinksyncs thinksyncs marked this pull request as ready for review February 6, 2026 06:38
Copilot AI review requested due to automatic review settings February 6, 2026 06:38
@thinksyncs thinksyncs merged commit 4b11323 into main Feb 6, 2026
8 checks passed
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request consolidates four separate PRs (#6, #7, #8, #9) into a single comprehensive update that adds significant new functionality to the YOLOZU RT-DETR pose estimation system. The consolidation strategy prevents merge conflicts by applying changes in a coordinated manner.

Changes:

  • MIM Reconstruction Branch (PR #6): Adds geometry-aligned masked image modeling for test-time adaptation with ~100K additional parameters, including RenderTeacher and DecoderMIM modules
  • Hessian Solver (PR #7): Implements Gauss-Newton optimization with Levenberg-Marquardt damping for per-detection refinement of depth, rotation, and offset predictions
  • Gradient Accumulation & AMP (PR #8): Adds training enhancements with gradient accumulation support and automatic mixed precision (AMP) for efficient large-batch training
  • Lint Documentation (PR #9): Documents and fixes lint errors from other PRs (unused import removed)

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
yolozu/calibration/hessian_solver.py New Hessian-based solver for iterative regression refinement using second-order optimization
yolozu/calibration/__init__.py Exports for HessianSolverConfig and refinement functions
tools/refine_predictions_hessian.py CLI tool for batch refinement of predictions with configurable solver parameters
rtdetr_pose/rtdetr_pose/model.py Adds RenderTeacher, DecoderMIM modules and MIM branch to RTDETRPose with backward compatibility
rtdetr_pose/rtdetr_pose/losses.py New loss functions: mim_reconstruction_loss and entropy_loss for geometric consistency
rtdetr_pose/tools/train_minimal.py Gradient accumulation and AMP integration with proper gradient scaling and clipping
tests/test_hessian_solver.py Comprehensive test suite (9 tests) for Hessian solver
tests/test_mim_reconstruction.py Comprehensive test suite (10 tests) for MIM components
rtdetr_pose/tests/test_train_minimal_integration.py Integration tests for gradient accumulation and AMP
rtdetr_pose/tests/test_train_minimal_grad_accum_amp.py Unit tests for new training arguments
tools/example_mim_inference.py Example script demonstrating MIM usage with test-time adaptation
docs/hessian_solver.md Documentation for Hessian solver API and usage
docs/mim_inference.md Documentation for MIM branch usage and test-time training
train_setting.yaml Configuration examples for new gradient accumulation and AMP features
README.md Updated feature highlights with Hessian solver reference
LINT_FIXES_NEEDED.md Documents lint fixes applied during merge
SECURITY_SUMMARY.md Security assessment of all changes
IMPLEMENTATION_SUMMARY.md Detailed implementation summary for MIM feature

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +1921 to +1936
# Perform optimizer step only at accumulation boundaries
# steps is 0-indexed within each epoch, so we use (steps + 1) for the check
if (steps + 1) % accum_steps == 0:
if scaler is not None:
# Unscale gradients before clipping
if args.clip_grad_norm and float(args.clip_grad_norm) > 0:
scaler.unscale_(optim)
torch.nn.utils.clip_grad_norm_(model.parameters(), float(args.clip_grad_norm))
scaler.step(optim)
scaler.update()
optim.zero_grad(set_to_none=True)
else:
if args.clip_grad_norm and float(args.clip_grad_norm) > 0:
torch.nn.utils.clip_grad_norm_(model.parameters(), float(args.clip_grad_norm))
optim.step()
optim.zero_grad(set_to_none=True)
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The optimizer step is only performed when (steps + 1) % accum_steps == 0. However, if the epoch ends before reaching an accumulation boundary, gradients will remain accumulated without being applied. This means the last few batches of an epoch might not contribute to parameter updates if they don't reach an accumulation boundary. Consider adding logic to perform a final optimizer step at the end of each epoch if there are accumulated gradients remaining.

Copilot uses AI. Check for mistakes.
Comment on lines +1711 to +1719
# Initialize GradScaler for AMP if enabled
scaler = None
if args.use_amp:
if device.startswith("cuda"):
scaler = torch.cuda.amp.GradScaler()
print("amp_enabled=True device=cuda")
else:
print("amp_warning: --use-amp requires CUDA device; AMP disabled")

Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When gradient accumulation is used with checkpoint resumption, there's a potential issue: if training is resumed and the checkpoint had accumulated gradients, those gradients might still be present. The code doesn't explicitly zero gradients at the start of training after checkpoint loading. Consider adding optim.zero_grad(set_to_none=True) after initializing the scaler (around line 1718) to ensure a clean gradient state when starting/resuming training with gradient accumulation.

Copilot uses AI. Check for mistakes.
# With mask
loss_masked = mim_reconstruction_loss(recon_feat, teacher_feat, mask=mask)
self.assertEqual(loss_masked.shape, torch.Size([]))
self.assertTrue(loss_masked.item() >= 0.0)
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assertTrue(a >= b) cannot provide an informative message. Using assertGreaterEqual(a, b) instead will give more informative messages.

Copilot uses AI. Check for mistakes.
Comment on lines +170 to +175
self.assertTrue(loss_masked.item() >= 0.0)

# Without mask
loss_full = mim_reconstruction_loss(recon_feat, teacher_feat, mask=None)
self.assertEqual(loss_full.shape, torch.Size([]))
self.assertTrue(loss_full.item() >= 0.0)
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assertTrue(a >= b) cannot provide an informative message. Using assertGreaterEqual(a, b) instead will give more informative messages.

Suggested change
self.assertTrue(loss_masked.item() >= 0.0)
# Without mask
loss_full = mim_reconstruction_loss(recon_feat, teacher_feat, mask=None)
self.assertEqual(loss_full.shape, torch.Size([]))
self.assertTrue(loss_full.item() >= 0.0)
self.assertGreaterEqual(loss_masked.item(), 0.0)
# Without mask
loss_full = mim_reconstruction_loss(recon_feat, teacher_feat, mask=None)
self.assertEqual(loss_full.shape, torch.Size([]))
self.assertGreaterEqual(loss_full.item(), 0.0)

Copilot uses AI. Check for mistakes.
loss = entropy_loss(logits)

self.assertEqual(loss.shape, torch.Size([]))
self.assertTrue(loss.item() >= 0.0)
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assertTrue(a >= b) cannot provide an informative message. Using assertGreaterEqual(a, b) instead will give more informative messages.

Suggested change
self.assertTrue(loss.item() >= 0.0)
self.assertGreaterEqual(loss.item(), 0.0)

Copilot uses AI. Check for mistakes.
self.assertIn("loss", result)
self.assertIn("loss_mim", result)
self.assertIn("loss_entropy", result)
self.assertTrue(result["loss"].item() > 0.0)
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assertTrue(a > b) cannot provide an informative message. Using assertGreater(a, b) instead will give more informative messages.

Suggested change
self.assertTrue(result["loss"].item() > 0.0)
self.assertGreater(result["loss"].item(), 0.0)

Copilot uses AI. Check for mistakes.
r_flat = [float(x) for row in gt_rotation for x in row]
if len(r_flat) == 9:
r_gt_tensor = torch.tensor(r_flat, dtype=dtype, device=device).reshape(3, 3)
except (TypeError, ValueError):
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'except' clause does nothing but pass and there is no explanatory comment.

Suggested change
except (TypeError, ValueError):
except (TypeError, ValueError):
# If ground-truth rotation is malformed, silently skip rotation supervision.
# This keeps behavior consistent with treating missing gt_rotation as no constraint.

Copilot uses AI. Check for mistakes.
if isinstance(t_gt, (list, tuple)) and len(t_gt) >= 3:
try:
gt_depth = float(t_gt[2]) # Z component.
except (TypeError, ValueError):
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'except' clause does nothing but pass and there is no explanatory comment.

Copilot uses AI. Check for mistakes.
if isinstance(r_gt, (list, tuple)) and len(r_gt) == 3:
try:
gt_rotation = [[float(x) for x in row] for row in r_gt]
except (TypeError, ValueError):
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'except' clause does nothing but pass and there is no explanatory comment.

Copilot uses AI. Check for mistakes.
@thinksyncs thinksyncs deleted the copilot/combine-all-prs branch February 6, 2026 06:44
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants