<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>未完成 on Ganko Space</title><link>https://ganko.asia/tags/%E6%9C%AA%E5%AE%8C%E6%88%90/</link><description>Recent content in 未完成 on Ganko Space</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Thu, 24 Jul 2025 00:00:00 +0000</lastBuildDate><atom:link href="https://ganko.asia/tags/%E6%9C%AA%E5%AE%8C%E6%88%90/index.xml" rel="self" type="application/rss+xml"/><item><title>并行训练实践</title><link>https://ganko.asia/posts/%E5%B9%B6%E8%A1%8C%E8%AE%AD%E7%BB%83%E5%AE%9E%E8%B7%B5/</link><pubDate>Thu, 24 Jul 2025 00:00:00 +0000</pubDate><guid>https://ganko.asia/posts/%E5%B9%B6%E8%A1%8C%E8%AE%AD%E7%BB%83%E5%AE%9E%E8%B7%B5/</guid><description>&lt;h2 id="accelerate">Accelerate&lt;/h2>
&lt;p>Accelerate 是 Hugging Face 开发的深度学习多卡并行训练库，构建在 &lt;code>torch_xla&lt;/code> 和 &lt;code>torch.distributed&lt;/code> 之上。它提供了一个简单的 API，将与多 GPU、TPU、混合精度训练相关的样板代码抽离了出来，让用户可以在不同设备上轻松地进行分布式训练和混合精度训练，而无需重复编写大量样板代码。&lt;/p>
&lt;p>另外，Accelerate 还提供了很多性能优化的功能，使得大规模训练和推理变得简单、高效且适应性强。&lt;/p>
&lt;p>在学习如何使用 Accelerate 之前，首先回顾一下并行训练的其他方法。&lt;/p>
&lt;hr>
&lt;h2 id="dataparallel-dp">DataParallel (DP)&lt;/h2>
&lt;p>DP 是最常见的并行训练方式，通过将数据拆分（split）到各个 workers 中（每个 worker 拥有完整模型）进行并行计算，以解决 Batch Size 过大的问题。因为求导以及加和都是线性的，所以数据并行在数学上是等价的。&lt;/p>
&lt;p>&lt;code>DataParallel&lt;/code> 是 PyTorch 中最容易实现的并行方案，只需要增加一行代码：&lt;code>model = nn.DataParallel(model)&lt;/code>。&lt;/p>
&lt;h3 id="代码示例">代码示例&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-python" data-lang="python">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> torch
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> torch.nn &lt;span style="color:#66d9ef">as&lt;/span> nn
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">from&lt;/span> torch.utils.data &lt;span style="color:#f92672">import&lt;/span> DataLoader, Dataset
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 数据集的长度为 100，batch size 为 32&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 模型是一个简单的 fc 层，输入长度是 5，输出是 2&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>input_size, output_size &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#ae81ff">5&lt;/span>, &lt;span style="color:#ae81ff">2&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>batch_size, data_size &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#ae81ff">32&lt;/span>, &lt;span style="color:#ae81ff">100&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>model &lt;span style="color:#f92672">=&lt;/span> Model(input_size, output_size)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">if&lt;/span> torch&lt;span style="color:#f92672">.&lt;/span>cuda&lt;span style="color:#f92672">.&lt;/span>device_count() &lt;span style="color:#f92672">&amp;gt;&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> print(&lt;span style="color:#e6db74">f&lt;/span>&lt;span style="color:#e6db74">&amp;#34;Detected &lt;/span>&lt;span style="color:#e6db74">{&lt;/span>torch&lt;span style="color:#f92672">.&lt;/span>cuda&lt;span style="color:#f92672">.&lt;/span>device_count()&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74"> GPUs!&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> model &lt;span style="color:#f92672">=&lt;/span> nn&lt;span style="color:#f92672">.&lt;/span>DataParallel(model)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>device &lt;span style="color:#f92672">=&lt;/span> torch&lt;span style="color:#f92672">.&lt;/span>device(&lt;span style="color:#e6db74">&amp;#34;cuda:0&amp;#34;&lt;/span> &lt;span style="color:#66d9ef">if&lt;/span> torch&lt;span style="color:#f92672">.&lt;/span>cuda&lt;span style="color:#f92672">.&lt;/span>is_available() &lt;span style="color:#66d9ef">else&lt;/span> &lt;span style="color:#e6db74">&amp;#34;cpu&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>model&lt;span style="color:#f92672">.&lt;/span>to(device)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>rand_loader &lt;span style="color:#f92672">=&lt;/span> DataLoader(
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> dataset&lt;span style="color:#f92672">=&lt;/span>RandomDataset(input_size, data_size),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> batch_size&lt;span style="color:#f92672">=&lt;/span>batch_size,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> shuffle&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#66d9ef">True&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">for&lt;/span> data &lt;span style="color:#f92672">in&lt;/span> rand_loader:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> input &lt;span style="color:#f92672">=&lt;/span> data&lt;span style="color:#f92672">.&lt;/span>to(device)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> output &lt;span style="color:#f92672">=&lt;/span> model(input)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>在上述代码中，&lt;code>batch_size=32&lt;/code>。由于使用了 &lt;code>DataParallel&lt;/code>，在有 2 个 GPU 时，一个 batch 被划分成了 2 份，即 &lt;code>tensor.split(16)&lt;/code>，分别送往两个 GPU。&lt;/p></description></item></channel></rss>