open-mmlab / mmdetection

OpenMMLab Detection Toolbox and Benchmark
https://mmdetection.readthedocs.io
Apache License 2.0
29.61k stars 9.47k forks source link

[Feature] A very simple but effective trick for deterministic issue in detection. #9831

Open GeoffreyChen777 opened 1 year ago

GeoffreyChen777 commented 1 year ago

What's the feature?

Deterministic issue in detection models.

We all know that it's hard to reproduce identical results for two runs in detection even we use the same radom seed and set deterministic = True.

Recently, a issue in detectron2 mentioned that it is mainly caused by using atomicAdd in the backward pass. And ROIAlign is the key module.

https://github.com/facebookresearch/detectron2/issues/4723

And he/she mentioned a very simple trick solution for this issue.

He/She tried this and found fully deterministic (losses values, and evaluation results on COCO) upto tens of thousands of steps (using same code as in https://github.com/facebookresearch/detectron2/issues/4260) for:

I also tried this trick in mmdet by:

changing

https://github.com/open-mmlab/mmdetection/blob/92d03df639a099c7263805a859923e2f0815e381/mmdet/models/roi_heads/roi_extractors/single_level_roi_extractor.py#L95

to

return self.roi_layers[0](feats[0].half().double(), rois.half().double()).to(rois.dtype)

I also found that it can solve the deterministic issue in mmdet. The loss and mAP is exactly identical after I use this trick, and it doesn't affect the mAP (at least in my project).

I think it would be good to implement this trick in mmdet with a configuarable param to turn on/off it. We can do this in the roi extractor module, or in the ROIAlign layer of mmcv.

Any other context?

No response

hhaAndroid commented 1 year ago

This is a very interesting trick.

GeoffreyChen777 commented 1 year ago

Yes, and very easy to implement.

I just tried it in my own project (a model based on Faster RCNN).

I didn't test every model in mmdet with this trick yet. If you are going to implement and release this in mmdet, please test it first. (I don't have enough GPU to do that 😥)