nn.Conv2d PyTorch с половинной точностью (fp16) работает медленнее, чем fp32

#python #pytorch

Вопрос:

Я обнаружил, что одна операция свертки 2D с float16 выполняется медленнее, чем с float32.

Я работаю с Gtx 1660 Ti с torch.1.8.0 cu111 и cuda-11.1 (также пробовал с torch.1.9.0 )

Dtype вход=1,выход=64 вход=1,выход=128 вход=64,выход=128
Fp16 3532 ит/с 632 ит/с 599ит/с
Fp32 2160 ит/с 1311 ит/с 925ит/с

Я измеряю скорость свертки с помощью следующего кода.

 inputfp16 = torch.arange(0,ch_in*64*64).reshape(1, ch_in, 64, 64).type(torch.float16).to('cuda:0')
inputfp32 = torch.arange(0,ch_in*64*64).reshape(1, ch_in, 64, 64).type(torch.float32).to('cuda:0')

conv2d_16 = nn.Conv2d(ch_in,ch_out, 3, 1, 1).eval().to('cuda:0').half()
conv2d_32 = nn.Conv2d(ch_in,ch_out, 3, 1, 1).eval().to('cuda:0')


for i in tqdm(range(0, 50)):
    out = conv2d_16(inputfp16)
    out.cpu()

for i in tqdm(range(0, 50)):
    out = conv2d_32(inputfp32)
    out.cpu()
 

Было бы здорово, если бы вы дали мне знать, была ли у вас такая же проблема, а еще лучше, если вы сможете предложить решение.

Комментарии:

1. Как вы точно измеряете использование времени? Одна вещь, которая приходит на ум, заключается в том, что вам, как правило, приходится звонить torch.cuda.synchronize() перед записью времени окончания, чтобы получить надежную оценку использования времени

Ответ №1:

Ну, проблема заключается в том, что тензорные вычисления смешанной/половинной точности ускоряются с помощью тензорных ядер.

Теоретически (и практически) тензорные ядра предназначены для обработки матричных вычислений с более низкой точностью, где, например, вы добавляете в накопитель произведение умножения fp32 на 2 вычисления матрицы fp16.

Пока GTX 1660 TI не поставляется с тензорными ядрами, мы можем сделать вывод, что CUDA не сможет использовать ускорение со смешанной/половинной точностью на этом графическом процессоре.