Cannot utilize fully all GPUs during network training
Mostrar comentarios más antiguos
It’s the performance and use of the resources installed on the Computer (Amazon Cloud EC2 instance in our case).
I am using a p3.8xlarge instance in EC2 on awamzon web server – basically it means I am using 4 GPUs V100,
I am training a neural network.
using:
mdl(i).Net = trainNetwork(trainData(:, :, :, 1: itStep: end), trainLabels(1: itStep: end, :), layers, options);
in options I define 'multi-gpu'
I also defined 'parallel' and tried to play with number of workers but all I see is just more processes waiting in the GPU queue on nvidia-smi.
For some reason I see that all GPU are working (see GPU.png) but for limited amount of time (very high usage for 3 seconds and then drops to 0% for 10 seconds at least.
I looked at the htop information(htop.jpg), I see that not all threads of the CPU are in use so that is the bottleneck (I think?)
I have a xeon processor on this instance with 32 cores (16 physical, 32 logical)
When I try to utilize all threads through local profile (profile local pool.png) it seems like it still doesn’t respond .
I get more workers because of it (CPU ?), but the GPUs still doesn't seem to improve
Tried to increase batch size - but at some point the GPU is out of memory, so that's not the problem.
How do i utilize all cores of the CPU to transfer data to the GPUs?
I read somewhere that you can also load the data to the pool itself? will that help?
I use the https://ngc.nvidia.com/catalog/containers/partners:matlab/tagsmatlab container for matlab:r2019a
I scanned these already:
Would appreciate your help.
Tomer
9 comentarios
Joss Knight
el 31 de Dic. de 2019
Editada: Joss Knight
el 31 de Dic. de 2019
It's hard to know where to start here; to be sure we'd need complete reproduction steps with code and data, and for that process I suggest you contact Technical Support.
Without further knowledge of what is going on, I can only advise getting a profile report to see what your MATLAB workers think they are spending their time doing.
Start your pool independently. I'm assuming you are running on some kind of virtual desktop.
parpool('local', gpuDeviceCount);
Then start the mpiprofiler.
spmd
mpiprofile on
end
Now run your training code. Then afterwards generate the profile report.
spmd
mpiprofile viewer
end
You should be able to use this report to generate a pdf. See the help for mpiprofile for more info. mpiprofile was generally intended for use in pmode but it can be used successfully in spmd in this way.
Analyzing the report you should be able to see where the bottleneck is. Typically in cases like this you'll find that either
- Your network is too small and there isn't enough work for the GPU to do, so the time is dominated in other activity such as loading and preprocessing input data, plotting, or sending data between workers.
- Your input data is taking a long time to load. It may be that trainData is huge and is being stored in virtual memory, so indexing into it is taking a huge amount of time. Very large data shouldn't be stored in memory, it should be stored in files and accessed using a Datastore.
- Some hardware issue means you're not actually using all the GPUs.
The fact that you are creating multiple networks and storing them in an array is a concern. It either means you are storing a lot of data in memory, or your network is very small (which means it is unlikely to benefit from parallel training). It would be good to see more of the code in which your call to trainNetwork is embedded.
Tomer Nahshon
el 7 de En. de 2020
Joss Knight
el 16 de En. de 2020
It's just impossible for me to be too certain without seeing your code, and if I speculate too much I could just end up confusing you more. It sounds like you're saying that you have multiple gigabytes of data stored in a matlab variable X that you are passing to trainNetwork? And we're guessing that maybe whos X is so enormous that you're ending up in the machine's swap space, which means you're using the disk, but in a way managed by the operating system rather than MATLAB. And, frankly, it's just not designed for this kind of thing, and never behaves well with MATLAB. But you haven't yet profiled your MATLAB as I advised so we don't have any actual direct evidence that the bottleneck is the point where trainNetwork tries to load a batch of data.
Is this true? Where did X come from? Was it created somehow from data that was originally on disk? So can we get you to store the data somewhere easily accessible by your Amazon instance, such as Amazon S3? And then use a datastore to load batches of data directly off the disk?
Anyway, as I say, this is just so much speculation.
Tomer Nahshon
el 23 de En. de 2020
Editada: Tomer Nahshon
el 23 de En. de 2020
Joss Knight
el 25 de En. de 2020
File Datastore is partitionable but Combined Datastore isn't in R2019b. Does the DispatchInBackground training option work for your example? If not we may be talking about using a Custom datastore so you can do the file loading and transform on a parallel pool.
Tomer Nahshon
el 26 de En. de 2020
Editada: Tomer Nahshon
el 26 de En. de 2020
Joss Knight
el 26 de En. de 2020
You need to follow this documentation on writing custom datastores. This will allow you to create a datastore which manually combines your two datastores, and implement the partition method to divide them. You will, of course, need to partition them ensuring that the data and targets are partitioned in the same way - this is what CombinedDatastore can't do for you.
Once you've done this you ought to get DispatchInBackground, parallel training, and both together. It sounds like DispatchInBackground on its own is what you are after, you need to do a bunch of data preparation and you can use a pool to do that in the background for you. It just depends on being able to divide up the data so that each worker has a different piece of the data.
Tomer Nahshon
el 29 de En. de 2020
Editada: Tomer Nahshon
el 29 de En. de 2020
Joss Knight
el 29 de En. de 2020
Editada: Joss Knight
el 2 de Feb. de 2020
That will work or just implement an ordinary datastore with the Partitionable mixin, which is the currently advised approach. All you have to do is implement read() to read the data and the targets that go with it, and return a cell array containing both.
"For networks with a single input, the table or cell array returned by the datastore has two columns that specify the network inputs and expected responses, respectively.
For networks with multiple inputs, the datastore must be a combined or transformed datastore that returns a cell array with (numInputs+1) columns containing the predictors and the responses, where numInputs is the number of network inputs and numResponses is the number of responses. For i less than or equal to numInputs, the ith element of the cell array corresponds to the input layers.InputNames(i), where layers is the layer graph defining the network architecture. The last column of the cell array corresponds to the responses."
Respuesta aceptada
Más respuestas (0)
Categorías
Más información sobre Parallel Computing Fundamentals en Centro de ayuda y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!