fix(video): replace assertions with proper exceptions in video frame decoding (#3016)

Replaced assert statements with FrameTimestampError exceptions in
decode_video_frames_torchvision and decode_video_frames_torchcodec.

Assertions are unsuitable for runtime validation because they can be
silently disabled with python -O, and they produce unhelpful
AssertionError tracebacks. The codebase already defines
FrameTimestampError for this exact purpose but it was only used
in one of the three validation sites.

Also removed AssertionError from the except clause in
LeRobotDataset.__init__, which was masking video timestamp errors
by silently triggering a dataset re-download instead of surfacing
the actual problem.
This commit is contained in:
Jash Shah
2026-02-25 03:29:22 -08:00
committed by GitHub
parent f138e5948a
commit 0317a15bf1
2 changed files with 27 additions and 21 deletions
+1 -1
View File
@@ -747,7 +747,7 @@ class LeRobotDataset(torch.utils.data.Dataset):
# Check if cached dataset contains all requested episodes # Check if cached dataset contains all requested episodes
if not self._check_cached_episodes_sufficient(): if not self._check_cached_episodes_sufficient():
raise FileNotFoundError("Cached dataset doesn't contain all requested episodes") raise FileNotFoundError("Cached dataset doesn't contain all requested episodes")
except (AssertionError, FileNotFoundError, NotADirectoryError): except (FileNotFoundError, NotADirectoryError):
if is_valid_version(self.revision): if is_valid_version(self.revision):
self.revision = get_safe_version(self.repo_id, self.revision) self.revision = get_safe_version(self.repo_id, self.revision)
self.download(download_videos) self.download(download_videos)
+26 -20
View File
@@ -227,16 +227,17 @@ def decode_video_frames_torchvision(
min_, argmin_ = dist.min(1) min_, argmin_ = dist.min(1)
is_within_tol = min_ < tolerance_s is_within_tol = min_ < tolerance_s
assert is_within_tol.all(), ( if not is_within_tol.all():
f"One or several query timestamps unexpectedly violate the tolerance ({min_[~is_within_tol]} > {tolerance_s=})." raise FrameTimestampError(
"It means that the closest frame that can be loaded from the video is too far away in time." f"One or several query timestamps unexpectedly violate the tolerance ({min_[~is_within_tol]} > {tolerance_s=})."
"This might be due to synchronization issues with timestamps during data collection." " It means that the closest frame that can be loaded from the video is too far away in time."
"To be safe, we advise to ignore this item during training." " This might be due to synchronization issues with timestamps during data collection."
f"\nqueried timestamps: {query_ts}" " To be safe, we advise to ignore this item during training."
f"\nloaded timestamps: {loaded_ts}" f"\nqueried timestamps: {query_ts}"
f"\nvideo: {video_path}" f"\nloaded timestamps: {loaded_ts}"
f"\nbackend: {backend}" f"\nvideo: {video_path}"
) f"\nbackend: {backend}"
)
# get closest frames to the query timestamps # get closest frames to the query timestamps
closest_frames = torch.stack([loaded_frames[idx] for idx in argmin_]) closest_frames = torch.stack([loaded_frames[idx] for idx in argmin_])
@@ -248,7 +249,11 @@ def decode_video_frames_torchvision(
# convert to the pytorch format which is float32 in [0,1] range (and channel first) # convert to the pytorch format which is float32 in [0,1] range (and channel first)
closest_frames = closest_frames.type(torch.float32) / 255 closest_frames = closest_frames.type(torch.float32) / 255
assert len(timestamps) == len(closest_frames) if len(timestamps) != len(closest_frames):
raise FrameTimestampError(
f"Number of retrieved frames ({len(closest_frames)}) does not match "
f"number of queried timestamps ({len(timestamps)})"
)
return closest_frames return closest_frames
@@ -353,15 +358,16 @@ def decode_video_frames_torchcodec(
min_, argmin_ = dist.min(1) min_, argmin_ = dist.min(1)
is_within_tol = min_ < tolerance_s is_within_tol = min_ < tolerance_s
assert is_within_tol.all(), ( if not is_within_tol.all():
f"One or several query timestamps unexpectedly violate the tolerance ({min_[~is_within_tol]} > {tolerance_s=})." raise FrameTimestampError(
"It means that the closest frame that can be loaded from the video is too far away in time." f"One or several query timestamps unexpectedly violate the tolerance ({min_[~is_within_tol]} > {tolerance_s=})."
"This might be due to synchronization issues with timestamps during data collection." " It means that the closest frame that can be loaded from the video is too far away in time."
"To be safe, we advise to ignore this item during training." " This might be due to synchronization issues with timestamps during data collection."
f"\nqueried timestamps: {query_ts}" " To be safe, we advise to ignore this item during training."
f"\nloaded timestamps: {loaded_ts}" f"\nqueried timestamps: {query_ts}"
f"\nvideo: {video_path}" f"\nloaded timestamps: {loaded_ts}"
) f"\nvideo: {video_path}"
)
# get closest frames to the query timestamps # get closest frames to the query timestamps
closest_frames = torch.stack([loaded_frames[idx] for idx in argmin_]) closest_frames = torch.stack([loaded_frames[idx] for idx in argmin_])