Я пытаюсь реализовать алгоритм квантования АдаРаунд, и мне нужно тренировать свои слои один за другим.
Я использую набор данных с 1024 с размером пакета 32, и мне нужно выполнить итерацию по набору данных примерно 312 эпох (или 10 000 итераций по пакетному набору данных), я заметил, что данные копируются с хоста на устройство каждую итерацию и что данные не кэшируются на графическом процессоре (несмотря на повторное использование одних и тех же данных) - графический процессор простаивает 30–40% процентов времени
Процент бездействия графического процессора
Данные по-прежнему копируются с хоста на устройство в расширенных итерациях:
Чанк memcpyH2D за одну итерацию
я пытался использовать
tf.data.experimental.prefetch_to_device
tf.data.experimental.copy_to_device
но когда я перебираю данные после prefetch_to_device или copy_to_device, тензоры сохраняются на графическом процессоре, но если я использую повтор для просмотра набора данных, тензоры сохраняются на ЦП
Я пытался использовать model.fit без dataset.repeat, но с несколькими эпохами, но получаю похожее поведение.
Я также пытался использовать model.fit с тензорами, которые хранятся на графическом процессоре, но подгонка модели преобразует его в набор данных, который возвращает данные обратно в процессор.
Фрагмент кода для воссоздания проблемы:
input_shape = (56, 56, 64)
output_shape = (54, 54, 64)
conv = tf.keras.layers.Conv2D(64, (3, 3))
mock_input = tf.keras.layers.Input(input_shape)
mock_output = conv(mock_input)
train_model = tf.keras.Model(inputs=mock_input, outputs=mock_output)
input_data = np.random.rand(1024, *input_shape)
output_data = np.random.rand(1024, *output_shape)
input_dataet = tf.data.Dataset.from_tensor_slices(input_data)
output_dataset = tf.data.Dataset.from_tensor_slices(output_data)
train_model.compile(
optimizer='adam',
loss='mse'
)
train_data = tf.data.Dataset.zip((input_dataet, output_dataset))
batched_train_data = train_data.batch(32).cache()
fetched_train_data = batched_train_data.prefetch(tf.data.AUTOTUNE).repeat()
with tf.profiler.experimental.Profile('logs'):
train_model.fit(fetched_train_data, steps_per_epoch=1024, epochs=1)
Есть ли способ применить операцию dataset.repeat к графическому процессору?

Подробный ответ
У nvidia есть пакет с именем Nvidia ДАЛИ, этот пакет предлагает эффективную оболочку для набора данных tensorflow (и многое другое, но это важная функция, которую я использовал здесь), мне пришлось установить 2 пакета — nvidia-dali-cuda110, nvidia-dali-tf- plugin-cuda110 (подробное руководство по установке можно найти здесь)
Класс, который я использовал, называется DALIНабор данных, чтобы правильно его наполнить, мне сначала пришлось инициализировать объект трубопровода.
одна итерация при использовании правильно инициализированного DALIDataset
Фрагмент кода:
from nvidia.dali.plugin.tf import DALIDataset
from nvidia.dali import pipeline_def, fn
def prep_dataset_dali(dir1, dir2, batch_size):
@pipeline_def(batch_size=batch_size, num_threads=3, device_id=0)
def pipe(path1, path2):
data1 = fn.readers.numpy(device='cpu', file_root=path1, file_filter='*.npy')
data2 = fn.readers.numpy(device='cpu', file_root=path2, file_filter='*.npy')
return data1.gpu(), data2.gpu()
my_pipe = pipe(dir1, dir2)
my_pipe.build()
return DALIDataset(my_pipe, output_dtypes=(tf.float32, tf.float32), output_shapes=((None, 56, 56, 64), (None, 56, 56, 64)))
Примечание:
внешний конвейер не работает с DALIDataset, но может работать с Класс DALIDatasetWithInputs из экспериментального раздела