【深度学习】分布式常见问题汇总(踩坑指南)

一、框架分布式简介

本文仅重点摘录对于OneFlow框架分布式的简介,更多分布式框架简介请移步原文获取,如需阅读请点击原文链接。

OneFlow

看过其他框架中的分布式代码示例,是不是觉得很复杂?或许你也会疑惑。

  • 为什么单机版的代码/api不能应用到多机?

  • 为什么还要手动管理数据集切分、分布式optimizer、参数更新这些脏活累活?

  • 难道没有一种框架屏蔽掉单机和分布式代码的差异,让我们愉快地写代码?

答案是:YES

不吹不黑的说一句,OneFlow确实就是这样的框架,满足你对分布式训练的所有需求:

  • 单机/分布式下,共用一套接口(是真的共用,而不是外面一套,内部却有其各自的实现)

  • 单机/分布式下,无需操心数据切分;

  • 单机/分布式下,无需操心optimizer梯度更新、参数状态同步等问题;

  • 单机/分布式下,性能最强(对GPU利用率最高),训练速度最快;

那么问题来了:

1.OneFlow为什么能做到单机/分布式如此简单?

2.OneFlow分布式这么容易用,运行效率怎么样?

1.OneFlow为什么能做到单机/分布式如此简单?

实际上,OneFlow中天然支持分布式(数据并行、模型并行、流水并行),使用OneFlow进行分布式训练完全不需要修改已有代码,也不需要安装horovod、dali、nccl、openmpi等一系列的支撑库,因为OneFlow独特的底层架构设计,使得其在单机和分布式情况下,已经达到其他框架各种优化后的上限。

oneflow对分布式的天然支持来源于其底层设计:抛弃了传统的master/worker架构,而是一种去中心化的流式架构,而这种架构带来的优势也比较明显:1.采用去中心化的流式架构,而非maste/worker 架构,最大程度优化节点网络通信效率 2.极简配置,由单一节点的训练程序转变为分布式训练程序,只需要几行配置代码

更多OneFlow底层设计、actor机制等请参考:OneFlow官方文档—分布式训练 ;OneFlow官方文档—系统设计

2.OneFlow分布式这么容易用,运行效率怎么样?

我们为了比较各大深度学习框架在单机、分布式情况下,对主流模型的训练速度,特意发起了一个性能评测项目——DLPerf,项目目前在保证软硬件一致的情况下,对各大主流框架在主流模型上做了训练性能测试(CV领域经典模型ResNet50;NLP领域Bert)。同时,我们有一帮小伙伴对cuda kernel等方面做了极致的性能优化,最终的测试结果表明,综合情况下OneFlow不仅单机单卡速度最快,单机多卡、多机多卡时也最快,加速比最高。

关于DLPerf评测的详细数据和信息,请看报告:dlperf_benchmark_test_report_v1
关于OneFlow为什么能做到最快,性能优化的绝招,请看知乎文章:OneFlow是如何做到世界最快深度学习框架的

概念

由于OneFlow独特的底层设计,其并没有为分布式任务设立单独的接口/方法。由于其天然支持分布式,所以也没有单独的概念用于描述分布式,如果必须有,那就是去中心化的Actor、以及SBP机制,更详细的概念描述,请参考: OneFlow系统设计和OneFlow概念清单

分布式示例

在对比多个框架的分布式用法后,我们发现OneFlow的分布式最简单易用,因为其设计的出发点就是追求分布式性能及易用性。所以,在OneFlow中,无论是单机单卡、单机多卡、还是多机多卡,都是一套统一的代码(无需额外的分布式接口、无需修改原有的模型训练相关代码)。

对于上层用户,使用OneFlow进行分布式进行却异常简单,实际上,在OneFlow中无需改动原有代码,只需要简单的几行配置,即可完美支持分布式训练,下面我们看一下示例。

单机

只需要在开头,加入单机需使用的GPU数即可。如:

# 单机单卡
flow.config.gpu_device_num(1)
# 单机8卡
flow.config.gpu_device_num(8)

分布式

分布式几乎和单机配置一样,无需操心多机情况下的数据切分,optimizer设置、权重同步等问题,只需额外增加3行代码用于配置多机的ip信息、通信端口号即可:

#每个节点的 gpu 使用数目
flow.config.gpu_device_num(8)
# 通信节点ip
nodes = [{"addr":"192.168.1.12"}, {"addr":"192.168.1.11"}]
flow.env.machine(nodes)
#通信端口
flow.env.ctrl_port(9988)

以下,是完整的分布式训练代码示例:

# see : http://docs.oneflow.org/basics_topics/distributed_train.html#_5
import oneflow as flow
import oneflow.typing as tp

BATCH_SIZE = 100


def mlp(data):
    initializer = flow.truncated_normal(0.1)
    reshape = flow.reshape(data, [data.shape[0], -1])
    hidden = flow.layers.dense(
        reshape,
        512,
        activation=flow.nn.relu,
        kernel_initializer=initializer,
        name="hidden",
    )
    return flow.layers.dense(
        hidden, 10, kernel_initializer=initializer, name="output-weight"
    )


def config_distributed():
    print("distributed config")
    # 每个节点的gpu使用数目
    flow.config.gpu_device_num(8)
    # 通信端口
    flow.env.ctrl_port(9988)

    # 节点配置
    nodes = [{"addr": "192.168.1.12"}, {"addr": "192.168.1.11"}]
    flow.env.machine(nodes)


@flow.global_function(type="train")
def train_job(
    images: tp.Numpy.Placeholder((BATCH_SIZE, 1, 28, 28), dtype=flow.float),
    labels: tp.Numpy.Placeholder((BATCH_SIZE,), dtype=flow.int32),
) -> tp.Numpy:
    logits = mlp(images)
    loss = flow.nn.sparse_softmax_cross_entropy_with_logits(
        labels, logits, name="softmax_loss"
    )
    lr_scheduler = flow.optimizer.PiecewiseConstantScheduler([], [0.1])
    flow.optimizer.SGD(lr_scheduler, momentum=0).minimize(loss)
    return loss


if __name__ == "__main__":
    config_distributed()
    flow.config.enable_debug_mode(True)
    check_point = flow.train.CheckPoint()
    check_point.init()
    (train_images, train_labels), (test_images, test_labels) = flow.data.load_mnist(
        BATCH_SIZE, BATCH_SIZE
    )
    for epoch in range(1):
        for i, (images, labels) in enumerate(zip(train_images, train_labels)):
            loss = train_job(images, labels)
            if i % 20 == 0:
                print(loss.mean())
  • 完整的利用ResNet50训练ImageNet的示例可参考:OneFlow官方Benchmark仓库

  • 分布式训练速度测评及结果,可以参考DLPerf:【DLPerf】OneFlow Benchmark评测


二、分布式训练常用库

通常,算法开发者使用深度学习框架开发出模型的训练/预测任务是单机版的,即只能在单机单卡、单机多卡条件下正常工作。当需要分布式训练时,我们通常需要进行如下三个层面的工作:

  • 数据层面

  • 多机通讯层面

  • 代码层面

在数据层面,我们可以使用DALI(非必须)来加速数据预处理过程;在多机通讯层面,需要安装和使用nccl、openmpi、gloo等作为底层的集合通信库;在代码层面,我们需要使用框架提供的分布式API或者使用Horovod来对单机版(单机单卡/多卡)代码进行改造,以使其支持分布式任务。

下面,我们对这些常用库进行简单的介绍和安装说明

1. DALI

DALI是NVIDIA提供的库,有较为先进的内存管理技术,可以构建基于CPU/GPU的高效数据加载pipeline,使得数据预处理速度大大提高。

通常,对于数据集规模较大(如imagenet等)的任务,或数据预处理成为瓶颈的任务,使用DALI后加速效果明显。不过在使用DALI基于GPU对图片进行解码/预处理时,通常需要占用较高的GPU显存。

安装

# CUDA 10
pip install --extra-index-url https://developer.download.nvidia.com/compute/redist nvidia-dali-cuda100
# CUDA 11
pip install --extra-index-url https://developer.download.nvidia.com/compute/redist nvidia-dali-cuda110

使用

DALI提供了多框架支持、可基于CPU/GPU构建自己的数据加载pipeline,相关学习资源和使用方式参考:

DALI Home 

Fast AI Data Preprocessing with NVIDIA DALI

DALI Developer Guide 

Getting Started 

nvidia-dali-speeding-up-pytorch

2. NCCL

NCCL是英伟达基于NCIDIA-GPU的一套开源的集合通信库,如其官网描述:NVIDIA集合通信库(NCCL)实现了针对NVIDIA GPU性能优化的多GPU和多节点集合通信原语。NCCL提供了诸如all-gather, all-reduce, broadcast, reduce, reduce-scatter等实现,这些实现优化后可以通过PCIe和NVLink等高速互联,从而实现高带宽和低延迟。因为NCCL则是NVIDIA基于自身硬件定制的,能做到更有针对性且更方便优化,故在英伟达硬件上,NCCL的效果往往比其它的通信库更好。

在大多数情况下,NCCL作为底层的集合通信库为分布式深度学习框架提供了多机通讯能力、我们只要安装即可,在分布式深度学习相关的任务或代码中通常感知不到其存在。除深度学习框架以外、Horovod通常也依赖nccl作为底层的集合通信库。

更多关于NCCL和集合通信相关的介绍,请参考上一篇文章:【深度学习】— 分布式训练常用技术简介

安装

需要从NVIDIA-NCCL官网下载并安装和操作系统、CUDA版本适配的NCCL。如Ubuntu16.04、CUDA10.2版本可以通过如下命令安装NCCL:

sudo dpkg -i nccl-repo-ubuntu1604-2.7.3-ga-cuda10.2_1-1_amd64.deb
sudo apt update
sudo apt install libnccl2=2.7.3-1+cuda10.2 libnccl-dev=2.7.3-1+cuda10.2

使用

通常,我们在深度学习任务中无需手动使用NCCL。但是,可以通过设定相应变量来查看/更改NCCL的设定,如打印NCCL相关的日志信息:

export NCCL_DEBUG=INFO
export NCCL_DEBUG=WARN

指定NCCL使用enp开头类型的网卡进行通信:

export NCCL_SOCKET_IFNAME=enp

更多NCCL相关的环境变量设置,请参考:

  • NCCL官方文档——故障排除

  • NCCL官方文档——环境变量

3. Horovod

在文章的前半部分也说过:

我们需要使用框架提供的分布式API或者使用Horovod来对单机版(单机单卡/多卡)代码进行改造,以使其支持分布式任务。

刚刚在上面提到的各个框架,他们都提供了原生的接口解决分布式环境下的通信问题。在上一篇文章中我们也介绍了,各个框架底层采用的通信库几乎都是NCCL、Open MPI 等少数几种。但是各个框架对于通信的利用水平可能层次不齐,某些情况下,因为框架自身的设计和代码实现的问题,使得底层集合通信库(如nccl)的能力无法充分发挥。

Horovod作为第三方库,就是想为各个分布式框架解决此问题,因为其易用和高效,可以说,Horovod已经是最流行的用于支持分布式深度学习任务的开源项目。其支持多种深度学习框架如:pytorch,tensorflow,mxnet等,其底层机器间通讯依赖nccl、mpi、gloo等集合通信库,所以安装前通常需要先安装好nccl、openmpi,且至少安装了一种深度学习框架,譬如mxnet。

安装

通常,安装horovod需要经过如下步骤:

  • 1.安装NCCL

  • 2.安装 nv_peer_memory以提供GPUDirect RDMA支持

  • 3.安装Open MPI或者其他MPI实现

  • 4.安装horovod

详细的安装说明参考Horovod官方项目 Readme,下面假设各种依赖已经安装完成,可以通过下面命令安装支持MXNet的horovod:

HOROVOD_WITH_MXNET=1  HOROVOD_GPU_OPERATIONS=NCCL HOROVOD_GPU_ALLREDUCE=NCCL HOROVOD_GPU_BROADCAST=NCCL

使用

上面MXNet的分布式示例中,我们简单介绍了horovod分布式训练的一些概念,下面,我们以pytorch为例,介绍一下使用horovod将单机代码改造为分布式代码时更通用的一些步骤:

3.1 初始化horovod

通过hvd.init()来初始化horovod主进程。

import torch
import horovod.torch as hvd

# Initialize Horovod
hvd.init()

3.2 将horovod进程和gpu绑定

通常,一个gpu绑定到1个horovod进程,此进程称为一个worker。

# Pin GPU to be used to process local rank (one GPU per process)
torch.cuda.set_device(hvd.local_rank())

3.3 切分数据集

在同步数据并行的分布式训练时,需要感觉gpu数量对数据集进行切分。

# Define dataset...
train_dataset = ...

# Partition dataset among workers using DistributedSampler
train_sampler = torch.utils.data.distributed.DistributedSampler(
    train_dataset, num_replicas=hvd.size(), rank=hvd.rank())

train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=..., sampler=train_sampler)

3.4 构建分布式optimizer

将原有的optimizer通过hvd.DistributedOptimizer进行包装、以使得新的optimizer可以在分布式环境下应用梯度更新。

# Build model...
model = ...
model.cuda()

optimizer = optim.SGD(model.parameters())

# Add Horovod Distributed Optimizer
optimizer = hvd.DistributedOptimizer(optimizer, named_parameters=model.named_parameters())

3.5 广播模型参数

多机上的模型权重,通常通过_allreduce_、_allgather _等方式在root_rank=0的主节点所在机器上汇合,汇合后需要将主节点上的模型权重信息广播至各台机器,以同步模型。

# Broadcast parameters from rank 0 to all other processes.
hvd.broadcast_parameters(model.state_dict(), root_rank=0)

更完整的使用说明,请参考horovod官方文档

三、踩坑指南

读了前文总结,相信你已经具备了进行分布式训练的能力,在刚参与 DLPerf 时,我也是这样想的,直到多次跪倒在实际训练中。分布式训练本身也是各复杂工程,遇到的问题不难,但是可能因为第一次遇见而耽误进度很久。为了避免大家重蹈我的覆辙,特总结了一些经验教训,欢迎参考和补充。

  1. 精确到commit

  2. 使用具体到版本的库/依赖

  3. 多机问题

  4. 查看GPU拓扑

接下来将对以上问题进行粗浅的回答和总结,权当抛砖引玉,欢迎大家关注和交流!本篇文章重点梳理深度学习分布式训练领域常用的一些技术及概念。如有疏漏和不足之处,还请多指点。

1. 精确到commit

通常,github上的代码和框架版本是脱节的,用最新版的框架往往运行之前的github项目代码时会各种报错;反之亦然。原因很简单:首先,各个框架存在不同版本;其次,项目代码也在不断维护和更新。

我们需要复现一个项目,首先需要熟读项目的readme,然后精确地匹配到对应的commit,保证代码版本和框架版本相匹配,才能将由于代码/框架版本不匹配导致各种问题的概率降至最低。

2. 使用具体到版本的库/依赖

在安装python依赖库时,有时官方没有提供requirement.txt,这时可能运行时会各种报错(缺少各种库和依赖);当你发现官方提供了requirement.txt时,通常直接pip install -r requirement.txt即可,少数情况下还是会有各种坑,譬如requirement.txt没有指定库的具体版本,但是pip install时往往安装的是最新版的库,而最新版方法/api有更新,所以项目跑起来,还是会各种报错...这时,最坏的可能是:手动一个版本一个版本的试,直到安装上版本相匹配的库为止~

3. 多机问题

多机情况下常见的问题主要有:

  • horovod/mpi多机运行失败

  • docker环境下ssh连通问题

  • 多机没连通/长时间卡住没反应

  • 多机下速度提升不明显,加速比低的问题

下面,我们将总结一下遇到这些问题的常见原因,以及归纳一下通常的解决方式。

3.1 horovod/mpi多机运行失败

通常,通过horovod/mpi运行分布式深度学习任务前,需要提前在节点之间配置ssh免密登录,保证用于通信的端口可以互相连通。如:

# export PORT=10001
horovodrun -np ${gpu_num} \
-H ${node_ip} -p ${PORT} \
--start-timeout 600 \
python3  train.py ${CMD} 2>&1 | tee ${log_file}

# 或者:
mpirun --allow-run-as-root -oversubscribe -np ${gpu_num} -H ${node_ip} \
     -bind-to none -map-by slot \
     -x LD_LIBRARY_PATH -x PATH \
     -mca pml ob1 -mca btl ^openib \
     -mca plm_rsh_args "-p ${PORT}  -q -o StrictHostKeyChecking=no" \
     -mca btl_tcp_if_include ib0 \
 python3  train.py ${CMD} 2>&1 | tee ${log_file}

(可左右滑动查看)

需要保证节点间ssh可以通过默认22端口或者指定端口如:10001互相连通。如:ssh vs002ssh vs002 -p 10001

3.2 docker容器连通问题

如果是在docker容器中进行多机训练,需要保证docker容器间可以通过指定端口互相ssh免密登录。(如:在10.11.0.2节点的docker容器内可以通过ssh root@10.11.0.3 -p 10001可以直接登录10.11.0.3节点的docker容器)

而在docker容器启动时,有两种网络方式:

  • docker的host模式

  • docker的bridge模式

docker的host模式

host模式,需要通过docker run时添加参数 --net=host 指定,该模式下表示容器和物理机共用端口(没有隔离),需要修改容器内ssh服务的通信端口号(vim /etc/ssh/sshd_config),用于docker容器多机通讯,具体方式见:README—SSH配置

docker的bridge模式

即docker的默认模式。该模式下,容器内部和物理机的端口是隔离的,可以通过docker run时增加参数如:-p 9000:9000进行端口映射,表明物理机9000端口映射到容器内9000端口,docker容器多机时即可指定9000端口进行通信。

两种方式都可以,只要保证docker容器间能通过指定端口互相ssh免密登录即可。

3.3 多机没连通/长时间卡住没反应

  • 通信库没有正确安装

  • 存在虚拟网卡,nccl需指定网卡类型

  • 通信端口被占用

通信库没有正确安装

通常是没有正确地安装多机依赖的通信库(openmpi、nccl)所导致。譬如paddle、tensorflow2.x等框架依赖nccl,则需要在每个机器节点上安装版本一致的nccl,多机训练时,可以通过export NCCL_DEBUG=INFO来查看nccl的日志输出。

openmpi安装

官网:点此进入openmpi官网

wget https://download.open-mpi.org/release/open-mpi/v4.0/openmpi-4.0.0.tar.gz
gunzip -c openmpi-4.0.0.tar.gz | tar xf -
cd openmpi-4.0.0
sudo ./configure --prefix=/usr/local/openmpi --with-cuda=/usr/local/cuda-10.2 --enable-orterun-prefix-by-default
sudo make && make install

make时,若报错numa相关的.so找不到:

sudo apt-get install libnuma-dev

添加到环境变量

vim ~/.bashrc
export PATH=$PATH:/usr/local/openmpi/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/openmpi/lib
source ~/.bashrc

horovod安装

官网:点此进入horovod官网

HOROVOD_GPU_OPERATIONS=NCCL python -m pip install --no-cache-dir horovod

存在虚拟网卡,nccl需指定网卡类型 有时,nccl已经正常安装,且节点间可以正常ssh免密登录,且都能互相ping通,不过还是遭遇多机训练长时间卡住的问题,可能是虚拟网卡的问题,当存在虚拟网卡时,如果不指定nccl变量,则多机通信时可能会走虚拟网卡,而导致多机不通的问题。如下图:

NCCL WARN Connect to fe80::a480:7fff:fecf:1ed9%13<45166> failed : Network is unreachable表明多机下遭遇了网络不能连通的问题。具体地,是经过网卡:fe80::a480:7fff:fecf...通信时不能连通。

我们排查时,通过在发送端ping一个较大的数据包(如ping -s 10240 10.11.0.4),接收端通过bwm-ng命令查看每个网卡的流量波动情况(找出ping相应ip时,各个网卡的流量情况),发现可以正常连通,且流量走的是enp类型的网卡。

通过ifconfig查看当前节点中的所有网卡类型:

可以发现有很多enp开头的网卡,也有很多veth开头的虚拟网卡,而nccl日志输出中的:fe80::a480:7fff:fecf:1ed9是veth虚拟网卡。

通过查看nccl官网文档发现,我们可以通过指定nccl变量来设定nccl通信使用的网卡类型:

export NCCL_SOCKET_IFNAME=enp

3.4 加速比低

  • IB驱动安装

如果服务器之间支持IB(InfiniBand)网络,则可以安装IB驱动,使得多机情况下各个节点间的通信速率明显提升,从而加速框架在多机环境下的训练,提升加速比。可以从NVIDIA官网下载适合操作系统及相应版本的IB驱动包,然后进入源码包路径,并安装:

cd MLNX_OFED_LINUX-4.9-0.1.7.0-ubuntu18.04-x86_64 && ./mlnxofedinstall --user-space-only --without-fw-update --all --force

完成后,可以通过ibstat命令检查驱动是否安装成功。更详细的IB驱动安装,请参考:mellanox官方文档

  • horovod/mpi参数设置

通常使用horovod只需要设定较少的参数,典型的参数:-np表示总共使用的gpu数量;-H表示所有机器节点及各个节点上使用的gpu数量。例如,一个集群包含4台机器(server1~4),每台机器上有4块gpu,则典型的horovod运行命令如下:

horovodrun -np 16 -H server1:4,server2:4,server3:4,server4:4 python train.py

更多命令和使用方法,参考Horovod官方仓库。

使用mpi运行分布式任务时(如openmpi),通常可以控制的参数更多、粒度更细,如:

mpirun -oversubscribe -np ${gpu_num} -H ${nodes} \
    -bind-to none -map-by numa \
    -x NCCL_DEBUG=INFO -x LD_LIBRARY_PATH -x PATH \
    -mca pml ob1 -mca btl ^openib \
    -mca plm_rsh_args "-p 22 -q -o StrictHostKeyChecking=no" \
    -mca btl_tcp_if_include ib0 \
python3 ${WORKSPACE}/run_pretraining.py

更多参数及使用说明,参考openmpi官网。

  • 没有使用dali

有时,不使用dali时数据加载/预处理会成为瓶颈,即gpu总是很快完成训练,“空闲”在那里等待cpu对数据进行加载/预处理,此时使用dali可以明显加速此过程。

  • 数据读取线程数设置不合理

通常,在深度学习任务中,框架提供了参数如--num_thread来设定数据加载/处理的线程数,线程数的设定影响了数据加载/处理的速度,进而影响了训练的速度。程数过低时,数据加载/预处理会成为瓶颈,训练速度收到影响变的很慢;线程数过高时,线程间同步/切换的开销过大,同样会影响训练速度;故通常需要根据经验值合理设定数据加载线程数。

4.查看GPU拓扑

在分布式深度学习任务中,除了深度学习框架、集合通信库、代码层面的等软件层面,硬件层面的如cpu、gpu显存、内存容量、网卡速率、gpu拓扑等对训练速度也是很有影响。譬如,我们可以通过nvidia-smi topo -m命令查看某机器上的gpu拓扑:

可以看出,此台机器包含8块GPU(GPU0~7),mlx5_0是Mellanox ConnectX-4 PCIe网卡设备(10/25/40/50千兆以太网适配器,另外该公司是IBA芯片的主要厂商)。图的上半部分表示GPU间的连接方式,如gpu1和gpu0通过NV1互联,gpu4和gpu1通过SYS互联;图的下半部分为连接方式的具体说明**,如NV表示通过nvlink互联,PIX通过至多一个PCIe网桥互联。

在图的下半部分,理论上GPU间的连接速度从上到下依次加快,最底层的NV表示通过nvlink互联,速度最快;最上层SYS表示通过pcie以及穿过NUMA节点间的SMP互联(即走了PCie又走了QPI总线),速度最慢。

  • NV表示通过NVIDIA-nvlink互联,速度最快;

  • PIX表示GPU间至多通过一个PCIe网桥连接;

  • PHB表示通过PCIe和PCIe主网桥连接(通常PCIe 主网桥是存在于cpu之中,所以PHB可以理解为通过PCIe和cpu相连);

  • NODE表示通过PCIe以及NUMA节点内PCIe主网桥之间的互连(通常NUMA节点内,包含多个cpu节点,每个cpu节点都包含一个PCIe主网桥,所以NODE可以理解为在一个NUMA节点内,通过PCIe和多个CPU相连);

  • SYS表示通过PCIe以及NUMA节点之间的SMP互连(例如,QPI/UPI),这个可以理解为通过PCIe,且跨过多个NUMA节点及其内部的SMP(多个cpu节点)进行互联。

  • X表示gpu节点自身;

关于NUMA,SMP等服务器结构的简单介绍可参考:服务器体系(SMP, NUMA, MPP)与共享存储器架构(UMA和NUMA)

最后,再强烈安利一下DLPerf项目,该项目在相同软硬件条件下,对各个框架在单机单卡、单机多卡、多机多卡条件下进行了模型训练的性能测试。测试覆盖了CV、NLP领域经典模型,保证了模型对齐、参数对齐、相同数据集(以各自框架要求的为准),测试结果精准反应了各个框架在模型训练任务中的速度(吞吐率)、以及多机条件下的表现(加速比)。欢迎围观和分享交流!

撰文:赵露阳

2020/11/13

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值