tf.reduce_sum на GPU терпит неудачу в сочетании с заполнителем в качестве формы ввода

UPDATE: Исправлено в Tensorflow 1.14.0 (возможно, раньше, не проверял)

UPDATE: По-прежнему происходит в Tensorflow 1.7.0

UPDATE: Я написал записную книжку, которая воспроизводит эту ошибку на оборудовании Google gpu: https://drive.google.com/file/d/13V87kSTyyFVMM7NoJNk9QTsCYS7FRbyz/view?usp=sharing

UPDATE: После ошибочного обвинения в первом пересмотре этого вопроса tf.gather я теперь сузил его до tf.reduce_sum в сочетании с заполнителем в форме:

tf.reduce_sum создает нули (только на графическом процессоре) для больших тензоров, форма которых зависит от заполнителя.

Выполнение следующего кода при подаче большого целого числа в заполнитель batch_size (> 700000 в моем случае):

import tensorflow as tf
import numpy as np

graph = tf.Graph()
with graph.as_default():
    batch_size = tf.placeholder(tf.int32,shape=[])
    ones_with_placeholder = tf.ones([batch_size,256,4])
    sum_out = tf.reduce_sum(ones_with_placeholder,axis=2)
    min_sum_out = tf.reduce_min(sum_out)

sess = tf.Session(graph=graph)

sum_result,min_sum_result = sess.run([sum_out,min_sum_out],feed_dict={batch_size: 1000000})
print("Min value in sum_out processed on host with numpy:", np.min(sum_result))
print("Min value in sum_out tensor processed in graph with tf:", min_sum_result)

Отображается следующий неверный результат:

Min value in sum_out processed on host with numpy: 0.0
Min value in sum_out tensor processed in graph with tf: 0.0

Я ожидал, что применение reduce_sum к оси 2 должно повсеместно привести к 4.0!

Запуск этого точного кода на процессоре приводит к правильным результатам. Кроме того, выполнение этого с фиксированной формой для tf.ones приводит к правильным результатам как на CPU, так и на GPU:

ones_with_fixed_shape = tf.ones([1000000,256,4])
sum_out = tf.reduce_sum(ones_with_fixed_shape,axis=2)

В чем проблема с заполнителем на GPU?

Ответ 1

Основная проблема заключается в том, что существует компромисс скорости и точности. Несмотря на то, что ваш пример кажется тривиальным: весь тензор, инициализированный 1, содержит 1,024B записей. Обратите внимание, что int32 может представлять целые числа в диапазоне [-2, 147,483,648 до 2,147,483,647] без потери точности:

Поэтому мы ожидаем увидеть некоторую ошибку, если будем накапливать все записи и выполнять вычисления. Это также объясняет, почему меньшие матрицы не проявляют проблемы (меньший размер партии).