MXNet 分布式训练精度

MXNet distributed training accuracy

我正在使用 MXNet 在 Caltech 256 数据集上微调 Resnet 模型,示例如下:

https://mxnet.incubator.apache.org/how_to/finetune.html

我主要是为了一个 POC 来测试分布式训练(我稍后会在我的实际项目中使用)。

首先,我 运行 这个例子是在一台机器上用 2 个 GPU 进行 8 个 epoch 的。我花了大约 20 分钟,最终验证准确率为 0.809072。

然后我 运行 在 2 台机器(相同,每台有 2 个 GPU)上使用分布式设置并将训练数据分成两半(使用 num_partspart_index).

8个epoch只用了10分钟,但最终验证准确率只有0.772847(两者中最高)。即使我使用了 16 个 epoch,我也只能达到 0.797006。

所以我的问题是这正常吗?我主要想使用分布式训练来减少训练时间。但是,如果需要两倍或更多的 epoch 才能达到相同的精度,那么有什么优势呢?也许我遗漏了什么。

如果需要,我可以 post 我的代码和 运行 命令。

谢谢

编辑

一些有助于回答的更多信息:

MXNet 版本: 0.11.0

拓扑结构: 2 个工人(每个工人在单独的机器上)

代码: https://gist.github.com/reactivefuture/2a1f9dcd3b27c0fe8215b4e3d25056ce

启动命令:

python3 mxnet/tools/launch.py -n 2 -H hosts --sync-dst-dir /tmp/mxnet python3 training.py --kv-store dist_sync --gpus 0,1

因为我无法让 kv.num_workerskv.rank 工作,所以我使用了一种 hacky 方式进行分区(使用 IP 地址)。

So my question is that is it normal? I primarily want to use distributed training to reduce training time. But if it takes twice or more epochs to achieve the same accuracy, then what's the advantage?

不,这不是正常情况,分布式训练确实应该用来加快训练过程,而不是减慢它。然而,有很多方法以错误的方式做到这一点。

根据提供的数据感觉worker还是运行在单一训练('device')模式下,或者可能kv_store创建不正确。因此每个工人自己训练模型。在这种情况下,您应该在 16 个纪元接近单机 8 个纪元后看到验证结果(仅仅是因为在集群中您正在拆分数据)。在您的情况下,它是 0.797006 与 0.809072。取决于您执行了多少次实验,这些数字可能被视为相等。我会把调查重点放在集群引导的方式上。

如果您需要更深入地了解如何创建 kv_store(或这是什么)并将其用于分布式训练,请参阅 this article

总的来说为了更好的回答,以后请至少提供以下信息:

  • MXNet 的版本是多少?
  • 集群的拓扑结构是什么,信息如下:
    • 使用了多少逻辑工作者;
    • 使用了多少台服务器(它们与工人在同一台机器上)?
  • 你如何开始训练(最好使用代码)
  • 如果无法提供代码,至少要指定kv_store
  • 的类型
  • 你如何在 worker 之间划分数据

编辑

尽管开始训练的调用看起来是正确的:

python3 mxnet/tools/launch.py -n 2 -H hosts --sync-dst-dir /tmp/mxnet python3 training.py --kv-store dist_sync --gpus 0,1

training.py 本身至少有一个问题。如果你看 here,它实际上不考虑输入参数中的 kv-store 类型,只是使用 'device'。因此,所有工作人员都在尝试单独训练模型(而不是在一个集群中)。我相信修复这一行应该有所帮助。

我再次建议阅读 the article 以熟悉 MXNet 集群的工作原理。通过分析调试日志并观察没有创建 kv-store,因此集群没有训练任何东西(只有独立机器正在做某事),可以很容易地发现此类问题。