Почему сохранение модели MultiLayerNetwork происходит очень медленно при использовании ParallelWrapper с несколькими графическими процессорами - PullRequest
0 голосов
/ 25 апреля 2019

Я работаю в среде, состоящей из: Windows 10, Eclipse, cuda.version = 10.0 и bytedecoPresets.version = 10.0-7.3-1.4.3

Использование LocalFileModelSaver для сохранения MultiLayerNetwork очень медленное, когда сеть обучается с использованием ParallelWrapper и нескольких графических процессоров. При использовании EarlyStoppingTrainer с одним графическим процессором время, необходимое для сохранения модели, соответствует ожидаемому. Я что-то настроил неправильно или это ошибка в DL4J?

Я использовал отладчик для пошагового просмотра кода DL4J при сохранении модели. В случае использования нескольких графических процессоров и параллельной оболочки генерируется следующая трассировка стека:

Thread [main] (Приостановлено (точка останова на строке 69 в cudaEvent_t))
Строка cudaEvent_t.synchronize (): 69
GridFlowController (SynchronousFlowController) .waitTillFinished (AllocationPoint) строка: 134
GridFlowController.waitTillFinished (AllocationPoint) строка: 63
Строка GridFlowController.synchronizeToHost (AllocationPoint): 47
CudaZeroHandler.synchronizeThreadDevice (Long, Integer, AllocationPoint) строка: 1304
Строка AtomicAllocator.synchronizeHostData (DataBuffer): 370
CudaFloatDataBuffer (BaseCudaDataBuffer) .getFloat (длинная) строка: 1131
CudaFloatDataBuffer (BaseDataBuffer) .write (DataOutputStream) строка: 1562
CudaFloatDataBuffer (BaseCudaDataBuffer) .write (DataOutputStream) строка: 801
Nd4j.write (INDArray, DataOutputStream) строка: 2464
Строка ModelSerializer.writeModel (Model, OutputStream, логическое, DataNormalization): 156
Строка ModelSerializer.writeModel (Model, OutputStream, логическое значение): 119
LenetNetworkTrainer.trainNetwork (булево) строка: 251 Строка ImageClassificationTrainer.run (): 88
Строка ImageClassificationTrainer.main (String []): 217

Похоже, что cudaEvent_t.synchronize () вызывается каждый раз, когда извлекается значение с плавающей запятой при записи CudaFloatDataBuffer (я считаю, что это является источником проблемы).

Эквивалентная трассировка стека при использовании одного графического процессора и EarlyStoppingTrainer:

Тема [основная] (приостановлено)
GridFlowController (SynchronousFlowController) .synchronizeToHost (AllocationPoint) строка: 97
Строка GridFlowController.synchronizeToHost (AllocationPoint): 50
CudaZeroHandler.synchronizeThreadDevice (Long, Integer, AllocationPoint) строка: 1304
Строка AtomicAllocator.synchronizeHostData (DataBuffer): 370
CudaFloatDataBuffer (BaseCudaDataBuffer) .getFloat (длинная) строка: 1131
CudaFloatDataBuffer (BaseDataBuffer) .write (DataOutputStream) строка: 1562
CudaFloatDataBuffer (BaseCudaDataBuffer) .write (DataOutputStream) строка: 801
Nd4j.write (INDArray, DataOutputStream) строка: 2464
Строка ModelSerializer.writeModel (Model, OutputStream, логическое, DataNormalization): 156
Строка ModelSerializer.writeModel (Model, OutputStream, логическое значение): 119
Строка ModelSerializer.writeModel (Model, String, boolean): 106
Строка LocalFileModelSaver.save (MultiLayerNetwork, String): 99
Строка LocalFileModelSaver.saveBestModel (MultiLayerNetwork, double): 77
LocalFileModelSaver.saveBestModel (модель, двойная) строка: 42
EarlyStoppingTrainer (BaseEarlyStoppingTrainer) .fit () строка: 223
LenetNetworkTrainer.trainNetwork (булево) строка: 228 Строка ImageClassificationTrainer.run (): 88
Строка ImageClassificationTrainer.main (String []): 217

cudaEvent_t.synchronize () вызывается не для каждой записываемой переменной.

        network = new MultiLayerNetwork(getConfiguration(
            trainingIterator.getLabels().size(), this.builder.getRandomSeed(),
            this.builder.getImageWidth(), this.builder.getImageHeight(),
            this.builder.getImageChannels(), this.builder.getEpochs(),
            iterators.getLeft().getRight(), this.builder.getBatchSize(),
            this.builder.getLearningRateInitialValue(),
            this.builder.getLearningRateDecayExponent()));
        network.init();

        ParallelWrapper wrapper = new ParallelWrapper.Builder<>(network)
            .prefetchBuffer(8).workers(2).averagingFrequency(3)
            .reportScoreAfterAveraging(true).build();
        LocalFileModelSaver localFileModelSaver = new LocalFileModelSaver(
            this.builder.getTrainingPath().getAbsolutePath());
       DataSetLossCalculator dataSetLossCalculator = new dataSetLossCalculator(testingIterator, true);

        for (int i = 0; i < this.builder.getEpochs(); i++) {
          wrapper.fit(trainingIterator);
        }

        //
        // This takes about 25 minutes to save the model
        //
        localFileModelSaver.saveLatestModel(network, 0.0);

Я ожидаю, что модель будет сохранена на диск примерно через 15-30 секунд. Я что-то упустил?

...