Help Needed with DDP Training on Multiple Nodes Unexpected Low Accuracy with ResNet50 and MoCo v3

Reem_Alharthi: <p>Hello PyTorch Community,</p>
<p>I am a beginner in distributed training using PyTorch and have been facing some issues with Distributed Data Parallel (DDP) training. Despite my efforts, I am unable to achieve the expected results and would greatly appreciate any guidance or recommendations.</p>
<p><strong>System Setup:</strong><br>
I have 7 nodes managed by a PBS script, which is used to submit jobs to the scheduler.<br>
I am using <code>torchrun</code> to execute the training on each node with the following command:</p>
<pre><code class="lang-auto">torchrun --nproc_per_node=1 --node_rank=$RANK --nnodes=$NNODES --master_addr=$MASTER --master_port=9977 --max-restarts=3 main.py
</code></pre>
<p><strong>Problem Description:</strong></p>
<p>The distributed training process is functioning correctly, and I am able to observe accelerated training. <strong>However, the accuracy results are significantly lower than expected.</strong></p>
<p><strong>ResNet50 on ImageNet:</strong></p>
<p>Training ResNet50 using the ImageNet dataset in a supervised approach.<br>
The best top-1 accuracy I can achieve is 30%.<br>
MoCo v3 on Full ImageNet:</p>
<p>Training <strong>MoCo v3</strong> using the full ImageNet dataset.<br>
After 100 epochs, the best top-1 accuracy I achieve is 40%, whereas the author reports an accuracy of 69%.</p>
<p><strong>Key Details:</strong><br>
I am using the exact parameters recommended by the authors of MoCo v3.<br>
The only difference in my setup is the use of torchrun instead of mp.spawn.</p>
<p><strong>Request for Help:</strong><br>
I have been stuck on this issue for almost two months and am unable to understand the discrepancies in the results. Here are my specific questions:</p>
<ul>
<li>
<p>Could the use of torchrun instead of mp.spawn be causing this issue? If so, how can I mitigate this?</p>
</li>
<li>
<p>Are there any common pitfalls or configuration issues in DDP that might lead to such a significant drop in accuracy?<br>
Is there any additional debugging or logging I should enable to better understand the problem?</p>
</li>
<li>
<p>Any other suggestions or recommendations that could help me align my results with the expected benchmarks?</p>
</li>
</ul>
<p>I would greatly appreciate any insights or advice from those who have experience with distributed training and similar setups. Thank you in advance for your time and assistance.</p>

agu: <p>If you are hesitant about the correctness of your distributed training setup, one thing you can do is choose a small global batch size and try to check the convergence when running that global batch size on a single GPU vs. running that global batch size on multiple GPUs with DDP.</p>
<p>For example, if you have 4 GPUs, you can choose global batch size of 4. On your single GPU, you run with batch size of 4 and record the curve. On your four GPUs with DDP, you run with local batch size of 1 and record the curve. If the curves are not matching well, then there is probably something wrong in the setup.</p>

Reem_Alharthi: <p>Hello,</p>
<p>Thanks for the reply. I did the experiment and I am unsure if the curves match very well. Here are the details and results:</p>
<p><strong>Model and Dataset:</strong></p>
<ul>
<li><strong>Model:</strong> ResNet-18</li>
<li><strong>Dataset:</strong> Custom image dataset</li>
<li><strong>Number of Classes:</strong> 30</li>
</ul>
<p><strong>Hyperparameters:</strong></p>
<ul>
<li><strong>Batch Size:</strong> 32 for DDP (4 GPUs), 128 for single GPU</li>
<li><strong>Number of Epochs:</strong> 30</li>
<li><strong>Learning Rate:</strong> 0.001<br>
<div class="lightbox-wrapper"><a class="lightbox" href="https://discuss.pytorch.org/uploads/default/original/3X/1/c/1c75ccdd314ffb476d1f34a17a6d0fe9304a2c9e.png" data-download-href="https://discuss.pytorch.org/uploads/default/1c75ccdd314ffb476d1f34a17a6d0fe9304a2c9e" title="combined_training_results"><img src="https://discuss.pytorch.org/uploads/default/optimized/3X/1/c/1c75ccdd314ffb476d1f34a17a6d0fe9304a2c9e_2_690x287.png" alt="combined_training_results" data-base62-sha1="43LKOof4jFjWpaYb4h2WjMauE2i" width="690" height="287" srcset="https://discuss.pytorch.org/uploads/default/optimized/3X/1/c/1c75ccdd314ffb476d1f34a17a6d0fe9304a2c9e_2_690x287.png, https://discuss.pytorch.org/uploads/default/optimized/3X/1/c/1c75ccdd314ffb476d1f34a17a6d0fe9304a2c9e_2_1035x430.png 1.5x, https://discuss.pytorch.org/uploads/default/optimized/3X/1/c/1c75ccdd314ffb476d1f34a17a6d0fe9304a2c9e_2_1380x574.png 2x" data-dominant-color="FBFAF9"><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">combined_training_results</span><span class="informations">2400×1000 164 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></li>
</ul>

agu: <p>What is your loss function?</p>
<p>You may need to reduce the loss across DDP workers depending on what the loss function is to make it comparable to single GPU. The validation curve seems to match reasonably.</p>

Reem_Alharthi: <p>I am using two different loss functions depending on the training scenario:</p>
<ol>
<li><strong>Supervised Training:</strong></li>
</ol>
<ul>
<li><strong>Loss Function:</strong> <code>CrossEntropyLoss</code>.</li>
<li><strong>Optimizer:</strong> The optimizer used is <code>optim.Adam</code>.</li>
</ul>
<ol start="2">
<li><strong>Contrastive Learning:</strong></li>
</ol>
<ul>
<li><strong>Loss Function:</strong> For contrastive learning, we employ the contrastive loss function implemented by the MoCo research team.</li>
<li><strong>Optimizer:</strong> the optimizer used here is <code>optim.SGD</code>.</li>
</ul>
<p>Could you clarify what you mean when you say reduce the loss across DDP workers?</p>

agu: <p>I mean to think about data parallel training mathematically. You are sharding your logical/global batch on the batch dimension, so if your forward/backward is not directly parallelizable on the batch dimension, then you may need some communication (e.g. all-reduce) to recover needed information across data parallel workers.</p>
<p>I am not familiar with the MoCo contrastive loss, but maybe you can check if this is parallelizable on batch dimension. For example, if your loss function depends on the number of negative examples in the batch, but now after data parallelism, the negative examples in the global batch are partitioned across data parallel workers, then you may need to think about what the implication is on the loss.</p>