cudnn:CUDNN_SOFTMAX_FAST 在 CUDNN_SOFTMAX_ACCURATE 工作正常时输出 NaN

cudnn: CUDNN_SOFTMAX_FAST ouputing NaN when CUDNN_SOFTMAX_ACCURATE workings fine

当使用设置 CUDNN_SOFTMAX_FAST 而不是 CUDNN_SOFTMAX_ACCURATE 时,为 cudnnSoftmaxForward 使用某些浮点值集会产生 NaN 输出。有谁知道为什么会这样?这是库中的错误吗?

cudnnHandle_t lib;
cudnnCreate(&lib);
int count = 10;
size_t size = count * sizeof(float);

float examples[] = {
    95.094505f,
    -600.288879f,
    85.621284f,
    72.220154f,
    70.099487f,
    43.734470f,
    69.538422f,
    69.705490f,
    20.752966f,
    81.020088f
};

float* cexamples;
cudaMalloc(&cexamples, size);
cudaMemcpy(cexamples, examples, size, cudaMemcpyKind::cudaMemcpyHostToDevice);

cudnnTensorDescriptor_t tExamples;
cudnnCreateTensorDescriptor(&tExamples);
cudnnSetTensor4dDescriptor(tExamples, cudnnTensorFormat_t::CUDNN_TENSOR_NCHW, cudnnDataType_t::CUDNN_DATA_FLOAT, 1, count, 1, 1);

float one = 1;
float zero = 0;

cudnnSoftmaxForward(lib, cudnnSoftmaxAlgorithm_t::CUDNN_SOFTMAX_FAST, cudnnSoftmaxMode_t::CUDNN_SOFTMAX_MODE_INSTANCE, &one, tExamples, cexamples, &zero, tExamples, cexamples);

cudaMemcpy(examples, cexamples, size, cudaMemcpyKind::cudaMemcpyDeviceToHost);
for (size_t i = 0; i < count; i++)
{
    printf("\n");
    printf("%f  ", examples[i]);
}

以下是使用 CUDNN_SOFTMAX_FAST 的结果:

以下是使用 CUDNN_SOFTMAX_ACCURATE 的结果:

我猜你的问题是由溢出引起的,即你(过程中的某个地方)的值变得太大而不能成为 float

CUDNN_SOFTMAX_FAST 只是 运行 而不检查是否发生溢出。另一方面,CUDNN_SOFTMAX_ACCURATE 避免了它(使用减法)。

CUDNN returns NaN 溢出(注意 'standart' C 可能不会这样)

我的建议:

  • 使用较小的值(为什么不使用 normalization?)
  • 尝试使用更大的类型(看起来很幼稚但也许没问题)
  • 只需设置CUDNN_SOFTMAX_ACCURATE

希望对您有所帮助

pltrdy