Repository: huggingface/transformers
Pull request: [SAM3] Fix MPS race condition in add_point_inputs

# What does this PR do?

For Apple Sillicon this PR enables SAM2 and SAM3 inference on MPS device.

## Problem
SAM2/SAM3 video inference produces "no object" masks on MPS (all values = -1024), while CPU inference was correct.

## Root Cause
`non_blocking=True` in `add_point_inputs` causes a race condition: the CPU source tensor gets garbage collected before the async copy to MPS completes, corrupting `point_coords` and `point_labels`.

## Fix
Change `non_blocking=True` to `non_blocking=False` in `add_point_inputs`.

For my tests MPS inference is **1.78x faster** on and now produces identical masks to CPU.

Why change is made in SAM2 code: because the sam3 code is generated with [utils/modular_model_converter.py](utils/modular_model_converter.py) and change in sam2 code is propagated there.


Changed files:
filename: src/transformers/models/edgetam_video/modeling_edgetam_video.py
patch: @@ -1001,7 +1001,7 @@ def add_point_inputs(self, obj_idx: int, frame_idx: int, inputs: dict):
         device_inputs = {}
         for key, value in inputs.items():
             if isinstance(value, torch.Tensor):
-                device_inputs[key] = value.to(self.inference_device, non_blocking=True)
+                device_inputs[key] = value.to(self.inference_device, non_blocking=False)
             else:
                 device_inputs[key] = value
         self.point_inputs_per_obj[obj_idx][frame_idx] = device_inputs

filename: src/transformers/models/sam2_video/modeling_sam2_video.py
patch: @@ -209,7 +209,7 @@ def add_point_inputs(self, obj_idx: int, frame_idx: int, inputs: dict):
         device_inputs = {}
         for key, value in inputs.items():
             if isinstance(value, torch.Tensor):
-                device_inputs[key] = value.to(self.inference_device, non_blocking=True)
+                device_inputs[key] = value.to(self.inference_device, non_blocking=False)
             else:
                 device_inputs[key] = value
         self.point_inputs_per_obj[obj_idx][frame_idx] = device_inputs

filename: src/transformers/models/sam2_video/modular_sam2_video.py
patch: @@ -478,7 +478,7 @@ def add_point_inputs(self, obj_idx: int, frame_idx: int, inputs: dict):
         device_inputs = {}
         for key, value in inputs.items():
             if isinstance(value, torch.Tensor):
-                device_inputs[key] = value.to(self.inference_device, non_blocking=True)
+                device_inputs[key] = value.to(self.inference_device, non_blocking=False)
             else:
                 device_inputs[key] = value
         self.point_inputs_per_obj[obj_idx][frame_idx] = device_inputs

filename: src/transformers/models/sam3_tracker_video/modeling_sam3_tracker_video.py
patch: @@ -213,7 +213,7 @@ def add_point_inputs(self, obj_idx: int, frame_idx: int, inputs: dict):
         device_inputs = {}
         for key, value in inputs.items():
             if isinstance(value, torch.Tensor):
-                device_inputs[key] = value.to(self.inference_device, non_blocking=True)
+                device_inputs[key] = value.to(self.inference_device, non_blocking=False)
             else:
                 device_inputs[key] = value
         self.point_inputs_per_obj[obj_idx][frame_idx] = device_inputs