Initialize 2 (or multiple) models at the same time

mrT: <p>I have some questions with pytorch that I can’t find an answer to for days.  so any help is appreciated</p>
<ol>
<li>
<p>In example, i have a simple pytorch model, loaded on GPU. What happens when multiple threads call the model at the same time? <strong>why doesn’t the speed increase compared to the case of single thread ?</strong> What is the order of execution on gpu when there are multiple thread/process ?<br>
<div class="lightbox-wrapper"><a class="lightbox" href="https://discuss.pytorch.org/uploads/default/original/3X/e/b/ebbe2b794e4fcf8d03deb19fffcf71912dfeaf4d.png" data-download-href="https://discuss.pytorch.org/uploads/default/ebbe2b794e4fcf8d03deb19fffcf71912dfeaf4d" title="image"><img src="https://discuss.pytorch.org/uploads/default/optimized/3X/e/b/ebbe2b794e4fcf8d03deb19fffcf71912dfeaf4d_2_383x375.png" alt="image" data-base62-sha1="xDtDPPmOmG9u6SgyvEiPFv9Zcrb" width="383" height="375" srcset="https://discuss.pytorch.org/uploads/default/optimized/3X/e/b/ebbe2b794e4fcf8d03deb19fffcf71912dfeaf4d_2_383x375.png, https://discuss.pytorch.org/uploads/default/optimized/3X/e/b/ebbe2b794e4fcf8d03deb19fffcf71912dfeaf4d_2_574x562.png 1.5x, https://discuss.pytorch.org/uploads/default/original/3X/e/b/ebbe2b794e4fcf8d03deb19fffcf71912dfeaf4d.png 2x" data-dominant-color="2D2F29"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">image</span><span class="informations">611×597 56.3 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div><br>
case 1: forward time: ~0.05s, gpu utils: ~25%<br>
case 2: 5 thread calling the model: forward time: ~0.25s, gpu utils ~25%</p>
</li>
<li>
<p>As I noticed that multithreading does not increase the speed nor gpu ultis of the model, i try to create another instance of model to run multiple instance of models at the same time. but on gpu memory it seems the model is not reinitialized same as cpu case.</p>
</li>
</ol>
<blockquote>
<p>import torchvision</p>
<h4>case 1: init multiple models on cpu</h4>
<p>model1 = torchvision.models.resnet18(pretrained=True)<br>
model2 = torchvision.models.resnet18(pretrained=True)</p>
<h4>case 2: init multiple models on gpu</h4>
<p>model1 = torchvision.models.resnet18(pretrained=True).to(‘cuda:0’)<br>
model2 = torchvision.models.resnet18(pretrained=True).to(‘cuda:0’)</p>
</blockquote>
<p>case 1: memory (RAM) usage of two model is doubled vs single model.<br>
case2: GPU memory usage of two model is same as single model.<br>
So what is different when model is init on gpu, Why gpu memory usage is not increasing ?<br>
How to initialize multiple instances of model on gpu to run them at same time to increase gpu ultilization ?</p>

ptrblck: <ol>
<li>
<p>The order of execution is defined by the kernel scheduling from multiple streams. Since you are launching all kernels in the same stream, no parallel execution will be performed. Even if you are using separate CUDA streams, your device would need to have free compute resources to be able to execute kernels in parallel.</p>
</li>
<li>
<p>The GPU memory does increase in the second example:</p>
</li>
</ol>
<pre><code class="lang-python">print(torch.cuda.memory_allocated())
# 0
model1 = torchvision.models.resnet18(pretrained=True).to('cuda:0')
print(torch.cuda.memory_allocated())
# 46861312
model2 = torchvision.models.resnet18(pretrained=True).to('cuda:0')
print(torch.cuda.memory_allocated())
# 93722624
</code></pre>

mrT: <p>thanks you for your helpful reply! I understand a little more now. There are some questions I would like to ask you in more depth</p>
<ol>
<li>So the stream is decided by the program or what factors ?  According to what I read in docs, the stream is decided by torch.devices, each GPU (hardware level ?) has a default stream. But when i run 2 same python programs on single GPU, gpu is correctly in double usage (25 → 50%). if so, is it that 2 different programs will use 2 different “default streams” of a hardware gpu ?</li>
<li>yes that true, thanks you. i checked back, and gpu alloc for the model is only 46mb, but first initialization eat 800mb vram that i guessed because of cuda context, so i do not notice the memory increase</li>
<li>Can i ask you one more question: So when i want to do parallel execution to maximize the gpu utils, is it better to use one model instance and multiple cuda stream, or multiple instances (take more VRAM) with multiple cuda stream ?<br>
and can you give me an example to be able to run multiple excecution on gpu concurrently with cuda streams (with simple models as above)<br>
Thank you again!</li>
</ol>

ptrblck: <p><a href="https://github.com/pytorch/pytorch/issues/59692#issuecomment-859173905">Here</a> is a simple example, but note that you cannot expect to execute different workloads in parallel just by using different Streams.<br>
If the operations on a single stream already saturate the GPU and its compute resources you won’t be able to launch any more work.</p>