torchmetrics: MeanAveragePrecision is slow
🐛 Bug
It’s extremely slow to compute the mean-average-precision since torchmetrics > 0.6.0.
To Reproduce
I noticed that my training times have almost doubled since I upgraded torchmetrics from 0.6.0, because validation using the MAP / MeanAveragePrecision metric is so much slower. During validation steps I call update()
, and in the end of a validation epoch I call compute()
on the MeanAveragePrecision
object.
I calculated the time that spent inside compute()
with different torchmetrics versions:
- torchmetrics 0.6.0: 12 s
- torchmetrics 0.6.1: didn’t work for some reason
- torchmetrics 0.6.2: 9.5 min
- torchmetrics 0.7.0: 9.4 min
- torchmetrics 0.7.1: 1.9 min
- torchmetrics 0.7.2: 2.0 min
- torchmetrics 0.7.3: 1.9 min
- torchmetrics 0.8.0: 4.5 min
- torchmetrics 0.8.1: 4.6 min
- torchmetrics 0.8.2: 4.6 min
It seems that after 0.6.0 the time to run compute()
has increased from 10 seconds to 9.5 minutes. In 0.7.1 it was improved and took 2 minutes. Then in 0.8.0 things got worse again and it took 4.5 minutes to run compute()
. This is more than 20x slower than with 0.6.0 and for example when training 100 epochs adds another 7 hours to the training time.
Environment
- TorchMetrics version (and how you installed TM, e.g.
conda
,pip
, build from source): 0.6.0 through 0.8.2, installed using pip - Python & PyTorch Version (e.g., 1.0): Python 3.8.11, PyTorch 1.10.0
- Any other relevant information such as OS (e.g., Linux): Linux
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 8
- Comments: 33 (17 by maintainers)
Hi there,
I just fixed it. 😃 PR coming your way.
Here’s some kind of a benchmark script:
My results:
@DataAndi, I was having the same problem with the 0.8.2 until I found this thread, then I downgraded to 0.6.0 as I am only using the mAP from torchmetrics. I hope the calculation from 0.6.0 is fine because it is much faster.
Does anyone else have very long compute times for metric.compute() ( Mean Average Precision). I have for version: 0.11.0 == 420s 011.1 == 394s 0.11.2 == 382s 011.3 == 371s 0.11.4 == 396s Used the above mentioned script to evaluate the computation time. Or is there maybe a way to compute it faster with cuda or something?
@stancld Hmm. The data’s not public. I wonder if you could debug it using random boxes, like in the speed test. I modified it to make the task a little bit easier and to make sure that the results are deterministic:
With torchmetrics 0.10.0 I get:
map: 0.1534 map_50: 0.5260 map_75: 0.0336 map_small: 0.1534 mar_1: 0.0449 mar_10: 0.3039 mar_100: 0.5445 mar_small: 0.5445
With the code from your PR I get
map: 0.2222 map_50: 0.7135 map_75: 0.0594 map_small: 0.2222 mar_1: 0.0449 mar_10: 0.4453 mar_100: 2.2028 mar_small: 2.2028
Some recall values are also > 1.
@24hours I think the way to go here would be to first try and clean up the code before we decide to dispatch to C++
@tkupek yeah, I am more and more moving in that direction. I would actually reintroduce
pycocotools
as an required dependency to MAP because we are seeing multiple issues that indicates that something is wrong with our implementation:As the primary maintainer of TM, I do not have the expertise in MAP required to solve these issues and the metric is therefore unmaintainable at the moment. And relying on contributors from experts does not seem to be the solution (because you have other things to do). I would therefore much rather accept defeat and revert back to something, where all details about the calculation is dealt with by
pycocotools
and I only need to worry about the user interface.One consequence that this will have, is that since v0.6 we have introduced the
iou_type
argument. Is it possible to convert the input when usingiou_type="segm"
toiou_type="bbox"
such that we in both cases can rely onpycocotools
to do the calculation? Else I would propose that weBBoxMeanAveragePrecision
that corresponds toiou_type="bbox"
SegmMeanAveragePrecision
that corresponds to `iou_type=“segm”Pinging @Borda, @justusschock, @senarvi, @wilderrodrigues for opinions.
@SkafteNicki How about this solution from your first response? Maybe we can make an optional
pycocotools
backend available so users can manually switch without downgrading to0.6.0
?The implementation in this repo is quite fast if you want to look into it. https://github.com/MathGaron/mean_average_precision
@heitorrapela @ckyrkou I am very happy about your interest, and we are trying to improve, but this is quite challenging, so any help would be very welcome… see some ongoing PRs: #1389 #1330
@ckyrkou yes, they just changed the path and name definition. You should use as follow:
I have just installed 0.6.0 to try it out. When I import from torchmetrics.detection.mean_ap import MeanAveragePrecision
I get an error that mean_ap does not exist. I guess things changed between versions. Any idea how this used to be used?