#deep-learning #pytorch #profiler
Вопрос:
Я пытаюсь профилировать свою модель с помощью профилировщика pytorch. Я использовал приведенный ниже код для профилирования
with profile(activities=[ProfilerActivity.CPU, ProfilerActivity.CUDA], record_shapes=True) as prof:
with record_function("model_inference"):
output_batch = self.model(input_batch)
print(prof.key_averages().table(sort_by="cpu_time_total", row_limit=10))
Выходные данные профилировщика выглядят следующим образом
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Name Self CPU % Self CPU CPU total % CPU total CPU time avg Self CUDA Self CUDA % CUDA total CUDA time avg # of Calls
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
model_inference 3.17% 83.011ms 63.97% 1.675s 1.675s 0.000us 0.00% 373.844ms 373.844ms 1
aten::copy_ 0.24% 6.333ms 39.93% 1.046s 1.504ms 28.758ms 7.69% 29.035ms 41.777us 695
cudaHostAlloc 36.02% 943.053ms 36.02% 943.053ms 30.421ms 0.000us 0.00% 0.000us 0.000us 31
cudaLaunchKernel 35.93% 940.773ms 35.93% 940.773ms 86.619us 0.000us 0.00% 0.000us 0.000us 10861
aten::repeat 0.04% 979.000us 33.77% 884.170ms 30.489ms 0.000us 0.00% 204.000us 7.034us 29
aten::conv2d 0.06% 1.481ms 8.71% 228.183ms 695.680us 0.000us 0.00% 145.688ms 444.171us 328
aten::convolution 0.05% 1.391ms 8.66% 226.702ms 691.165us 0.000us 0.00% 145.688ms 444.171us 328
aten::_convolution 0.10% 2.742ms 8.61% 225.311ms 686.924us 0.000us 0.00% 145.688ms 444.171us 328
aten::cudnn_convolution 0.53% 13.803ms 8.33% 218.051ms 664.790us 137.822ms 36.87% 137.822ms 420.189us 328
cudaFree 7.46% 195.373ms 7.46% 195.373ms 48.843ms 0.000us 0.00% 0.000us 0.000us 4
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Self CPU time total: 2.618s
Self CUDA time total: 373.844ms
Я замечаю, что большую часть времени (самостоятельный процессор) занимает cudaHostAlloc
И. cudaLaunchKernel
Что это cudaHostAlloc
за «и cudaLaunchKernel
«? Можно ли сократить это время? Если да, то как? Существуют ли какие-либо стандартные операции, которые я пропускаю, что приводит к столь высокому расходу времени?
PS: Я новичок в профилировании как таковом. Пожалуйста, дайте мне знать, если потребуется какая-либо другая информация.
Ответ №1:
Я не эксперт, но я думаю, что cudaLaunchKernel вызывается при каждой операции, выполняемой с помощью cuda. Поэтому я думаю, что вы не можете оптимизировать его.
Если вы построите подробную трассировку https://pytorch.org/tutorials/recipes/recipes/profiler_recipe.html#using-tracing-functionality, вы видите, что он вызывается каждый раз, когда вы выполняете операцию cuda, как здесь, для линейного слоя.
Одно замечание о выводе вашего профилировщика: aten::copy_
cudaHostAlloc
cudaLaunchKernel
и aten::repeat
все это занимает примерно 40% общего времени процессора. Я думаю, что это может быть связано с ProfilerActivity.CUDA
этой операцией записи CUDA, но это также добавляет много процессорного времени для вашей первой профилированной операции CUDA. В моем случае простая torch.ones(1000, device="cuda")
операция заняла целую секунду процессорного времени, потому что это была первая операция cuda.
Это может быть проблемой в вашем случае, попробуйте удалить ProfilerActivity.CUDA
, а может aten::copy_
cudaHostAlloc
cudaLaunchKernel
быть, и aten::repeat
будет иметь гораздо меньшее процессорное время и исчезнет из таблицы.