MindSpore运行环境信息获取及dataset并行数报错的解决

本文主要分享一个和运行环境相关报错的解决方案,不知道大家有没有遇到过"ValueError: num_parallel_workers exceeds the boundary between 1 and XXX !"的报错。然而并不清楚变量"num_parallel_workers"的取值有何依据,为啥MindSpore/mindspore仓内model_zoo的网络脚本,别人能用,而自己却频繁报错。
其实这一切都是因为每个人的运行环境存在差异,从硬件信息到驱动包,以及第三方依赖库,都可能导致报错的产生。所以,想要随心所欲的用好MindSpore框架,做到知彼知己是必需的。下面将从了解自己的运行环境开始,详细介绍dataset并行数报错的解决过程。

一 环境信息获取

1.1 操作系统

首先,Linux系统可以使用"uname -a"和"cat /etc/os-release"来查看操作系统版本
image.png

1.2 硬件信息

1)使用"lscpu"查看cpu信息,包括处理器架构和线程数
image.png
2)使用"free -h"或"cat /proc/cpuinfo |grep "processor" |wc -l"查看内存大小
image.png
3)使用"npu-smi info"查看昇腾系列NPU型号及工作状态(需Atlas run包)
image.png
4) 使用"nvidia-smi"查看英伟达系列GPU型号、驱动版本及状态

1.3 mindspore版本

在conda环境类或者原生python环境下,使用"pip show mindspore-ascend"或"pip show mindspore-gpu"查看MindSpore版本号
image.png

1.4 run package版本

通常情况下,使用root用户安装的Ascend芯片run包都会在/usr/local/Ascend目录下,而使用非root用户进行安装的话,会在/home/HwHiAiUser/目录下。
以root用户的安装地址为例,使用"cat /usr/local/Ascend/version.info"可以查看Atlas版run包的版本号
image.png

二 dataset报错

前文提及的dataset报错如下:
我们以使用FasterRCNN网络进行推理遇到的报错为例
1.png

三 问题分析

通过查看调用栈可知,报错位置在“src/dataset.py"文件line 497的”create_fasterrcnn_dataset“ 函数的内。
下层的调用都在conda环境的python依赖库中,根据路径大致可分析出是MindSpore的接口抛出的错误。

暂且认为MindSpore的接口功能正常,分析接口调用的逻辑,将create_fasterrcnn_dataset函数的代码部分拷贝,如下:

import mindspore.dataset as de

def create_fasterrcnn_dataset(mindrecord_file, batch_size=2, repeat_num=12, device_num=1, rank_id=0,
                              is_training=True, num_parallel_workers=4):
    ds = de.MindDataset(mindrecord_file, columns_list=["image", "annotation"], num_shards=device_num, shard_id=rank_id,
                        num_parallel_workers=1, shuffle=is_training)
    decode = C.Decode()
    ds = ds.map(operations=decode, input_columns=["image"], num_parallel_workers=1)
    compose_map_func = (lambda image, annotation: preprocess_fn(image, annotation, is_training))

    ...

    if is_training:
        ...

    else:
        ds = ds.map(operations=compose_map_func,
                    input_columns=["image", "annotation"],
                    output_columns=["image", "image_shape", "box", "label", "valid_num"],
                    column_order=["image", "image_shape", "box", "label", "valid_num"],
                    num_parallel_workers=num_parallel_workers)

        ds = ds.map(operations=[normalize_op, hwc_to_chw, type_cast1], input_columns=["image"],
                    num_parallel_workers=24)
    ...

    return ds

通过阅读代码可知,该方法是在调用MindSpore框架的MindDataset接口,同时对数据进行预处理。
那么报错信息中“num_parallel_workers”的取值是与mindspore.dataset.MindDataset接口息息相关的,通过查看官网API文档可知:
image.png

该参数是用来设置MindRecord格式文件的读取器并行数的,可以理解为多线程数,这里就和上文查询到的处理器线程数有直接关系了。

五 解决办法

通过Linux命令查看当前环境的CPU硬件信息,得知处理器为4核8线程设计,故应将多线程数量限制在0-7的范围内。

# lscpu

>>>
    Architecture:          x86_64
    CPU op-mode(s):        32-bit, 64-bit
    Byte Order:            Little Endian
    CPU(s):                8
    On-line CPU(s) list:   0-7
    Thread(s) per core:    2
    Core(s) per socket:    4
    Socket(s):             1
    NUMA node(s):          1
    Vendor ID:             GenuineIntel
    CPU family:            6
    Model:                 158
    Model name:            Intel(R) Core(TM) i7-7700 CPU @ 3.60GHz
    Stepping:              9
    CPU MHz:               4200.292
    CPU max MHz:           4200.0000
    CPU min MHz:           800.0000
    BogoMIPS:              7200.00
    Virtualization:        VT-x
    L1d cache:             32K
    L1i cache:             32K
    L2 cache:              256K
    L3 cache:              8192K
    NUMA node0 CPU(s):     0-7

将“num_parallel_workers”参数的硬编码部分修改为[0,8)的区间内,重新进行模型推理计算,报错不复现并得到该网络预期的推理精度:
image.png

posted @ 2021-12-30 19:03  MS小白  阅读(110)  评论(0)    收藏  举报