更新时间:2025-11-17 GMT+08:00
分享

进阶能力MemArts

MemArts介绍

当前ModelArts的常规训练流程为调用MoXing从OBS下载数据到本地SSD后读取本地SSD数据进行训练。然而,这一流程存在以下显著问题:

  1. 下载时间长:某region的小文件下载带宽通常在70Mbps左右,以2T数据为例,下载时间可能长达8小时,严重影响训练体验。
  2. 磁盘空间不足:华为云某region的ModelArts训练服务器搭载的SSD大小为4.7T,当数据量超过4.7T时,训练服务器将无法存储全部数据。
  3. 带宽瓶颈:多个训练节点同时下载数据时,受限于OBS带宽瓶颈,下载时间存在不确定性。
  4. 高阶特性受限:ModelArts开发了混部、弹性、容错等高阶特性,但由于数据下载时间长,训练过程中拓扑发生变化时重新下载数据的成本极高,严重影响高阶特性的使用体验。

为了解决上述问题,ModelArts提供了MemArts近计算缓存,为用户提供训练服务节点上的数据缓存能力。该方案通过将多块SSD通过网络组成一个分布式数据缓存池,用于缓存训练数据集。在缓存首次装载训练数据时,需要访问OBS将数据下载至缓存中。一旦缓存完成,后续训练数据下载或读取都直接读取MemArts缓存池来完成,从而显著提升训练效率并优化用户体验。

基础功能使用,在配置约束限制后参考使用方式即可。

如还需要其他操作,则可以参考其他环境变量配置介绍使用案例的内容介绍。

约束限制

  1. 此进阶功能是受限使用阶段,使用前需要联系技术支持,协助专属资源池安装MemArts后方可使用。
  2. 相关操作需要提前配置环境变量USE_MEMARTS=1并使用MoXing提供的数据API进行数据下载或者读取。
  3. 设置环境变量后import moxing,设置的环境变量才会生效。

使用方式

借助MemArts能加速数据读取,基础功能使用参照如下介绍。

  1. copy
    #拷贝文件到本地
    import moxing as mox 
    mox.file.copy('obs://bucket_name/obs_file.txt', '/cache/obs_file.txt')
  2. copy_parallel
    #并发拷贝目录到本地
    import moxing as mox  
    mox.file.copy_parallel('obs://bucket_name/sub_dir_0', '/cache/sub_dir_0')
  3. read
    # 读取以文本方式读取文件,返回string
    import moxing as mox  
    file_str = mox.file.read('obs://bucket_name/obs_file.txt') 
    #读取以二进制方式读取文件,返回bytes
    import moxing as mox  
    file_data = mox.file.read('obs://bucket_name/aaa.jpg',binary=True)
  4. read_meta_free
    # 用于超大规模数据读取场景,无需提前做元数据缓存
    # 读取以文本方式读取文件,返回string
    import moxing as mox  
    file_str = mox.file.read_meta_free('obs://bucket_name/obs_file.txt') 
    #读取以二进制方式读取文件,返回bytes
    import moxing as mox  
    file_data = mox.file.read_meta_free('obs://bucket_name/aaa.jpg',binary=True) 
    #读取write_memarts函数写入MemArts的文件,返回bytes
    import moxing as mox  
    file_data = mox.file.read_meta_free('obs://bucket_name/obs_file.txt',memarts_only=True)
  5. File
    #使用文件对象以文本方式读取文件
    import moxing as mox 
    with mox.file.File('obs://bucket_name/obs_file.txt', 'r') as f:  
      file_str = f.read() 
    # 使用文件对象以二进制方式读取文件
    import moxing as mox  
    with mox.file.File('obs://bucket_name/obs_file.bin', 'rb') as f:             
      file_bytes = f.read()
  6. write_memarts
    #将文件写入MemArts,文件内容需要转换为二进制,返回写入结果。成功为True,失败为False 
    import moxing as mox 
    ret = mox.file.write_memarts('obs://bucket/dir/data.bin', b'xxx', retry=3)

MemArts代理功能

安装2.3.8及以上版本MoXing后,在执行MoXing相关脚本前执行shell命令:

# stop用于故障快恢场景清理原有代理客户端残留
moxing stop_memarts_proxy 
# 后台开启8个代理客户端保证性能最优
moxing start_memarts_proxy 8

环境变量配置USE_MEMARTS=1,USE_MEMARTS_PROXY=1可以开启MemArts代理功能。无需其他改动即可使用该功能,该功能以性能略微降低的代价极大减少了MemArts进程占用的内存。

其他环境变量配置介绍

MemArts使用到的MoXing API相关的环境变量如下,需要注意的是设置环境变量后import moxing,设置的环境变量才会生效。

  • USE_MEMARTS

    该环境变量用于设置是否使用MemArts,默认不开启,设置为1后开启。

  • MOX_COPY_PARALLEL_THREADS

    该环境变量用于设置copy_parallel函数的线程数,默认值为16,使用16进程并发进行该函数涉及到的列举和拷贝操作。

  • MOX_FILE_CHUNK_SIZE

    该环境变量用于设置read、read_meta_free、copy、copy_parallel、write_memarts函数的分片大小,单位为Bytes。默认为1MB,通常无需修改。moxing会将所需文件切成MOX_FILE_CHUNK_SIZE设置的大小后基于MemArts或OBS获取对应段的数据。

  • MOX_OBS_CLIENT_LOG

    该环境变量用于设置obs python sdk日志是否打印,默认设置为1开启. 开启后OBS相关日志会打印到/home/ma-user/modelarts/log/obs_log下。

  • MOX_AUTO_READ_META_FREE

    该环境变量用于设置是否默认使用read_meta_free函数进行读操作,默认不开启,设置为1后开启。开启后当用户调用read函数时实际使用read_meta_free函数进行读操作。

  • MOX_MEMARTS_LARGE_FILE_ACC

    该环境变量用于设置copy、copy_parallel并从memarts下载数据时启用大文件加速模式,默认不开启,设置为1后开启。开启后基于环境变量MOX_FILE_PARTIAL_MAXIMUM_SIZE(单位为bytes)判断文件是否属于大文件,该值默认为5GB。当下载文件大于等于环境变量MOX_FILE_PARTIAL_MAXIMUM_SIZE时,基于环境变量MOX_FILE_LARGE_FILE_TASK_NUM得到的并发数来开启多进程下载,该并发数默认为8。建议在代理服务模式下使用。

  • MOX_OBS_TO_MOUNT_PATH

    该环境变量用于开启sfsturbo等挂载服务兼容功能,默认不开启,值为字符串,其中每个映射由=分隔,多个映射由;分隔,映射的前后分别为obs地址与本地地址。开启后用户调用read, read_meta_free, exists函数和File对象时可以直接使用obs路径读取本地挂载目录中的数据。例如用户在训练任务中使用sfsturbo将obs://test/a 目录挂载到本地c目录中,将obs://test/b 目录挂载到本地/cache/b目录中。那么可以设置环境变量MOX_OBS_TO_MOUNT_PATH为"obs://test/a=/cache/a;obs://test/b=/cache/b"。后续使用read, read_meta_free, exists函数时涉及obs://test/a或obs://test/b目录的数据会直接从sfsturbo挂载目录中读取。

  • USE_MEMARTS_PROXY

    该环境变量用于设置是否使用memarts客户端代理功能, 当环境中已经存在代理客户端或环境变量设置为1后开启。客户端代理功能相关使用方法参考memarts代理功能。

  • USE_METADATA_CACHE

    该环境变量用于开启本地元数据缓存,默认不开启,设置为1后开启。开启后使用copy,copy_parallel,read函数读取数据所需要的元数据信息将从本地读取,若本地不存在则从OBS读取后保存在本地,用于提升元数据读取性能。

使用案例

对于用户可能使用到的第三方库功能,可采用如下代码代替使用。

json.load(file_path)可用如下代码代替使用:

json.loads(mox.file.read(file_path, binary=False))

np.load(file_path)可用如下代码代替使用:

np.load(io.BytesIO(moxing.file.read_meta_free(file_path,binary=True)))

np.fromfile(file_path, dtype=dtype)可用如下代码代替使用:

np.frombuffer(mox.file.read(file_path,binary=True), dtype=dtype)

torch.load(file_path)可用如下代码代替使用:

with io.BytesIO(mox.file.read(file_path,binary=True)) as f:
                pth = torch.load(f)

ndarray = scipy.sparse.load_npz(file_path)可用如下代码代替使用:

with io.BytesIO(mox.file.read(file_path,binary=True)) as f:
                ndarray = scipy.sparse.load_npz(f)

with open(file_path, 'rb') as f:pickle.load(f)可用如下代码代替使用:

with io.BytesIO(mox.file.read(file_path,binary=True)) as f:
                data = pickle.load(f)

Image.open(file_path)可用如下代码代替使用:

Image.open(io.BytesIO(moxing.file.read_meta_free(file_path,binary=True)))

cv2.imread(file_path, imread_type)可用如下代码代替使用:

cv2.imdecode(np.frombuffer(mox.file.read_meta_free(file_path,binary=True), np.uint8), imread_type)

在API改造较为困难的情况下,可以使用moxing.file.copy将数据复制到本地,然后通过本地API进行读取和删除操作。在大多数情况下,这种方法不会遇到性能问题。代码示例如下:

_, ext = os.path.splitext(file_path)
with tempfile.NamedTemporaryFile(suffix=ext, dir='/cache', delete=False) as fp:
  moxing.file.copy(file_path, fp.name)
  data = np.load(fp.name)

相关文档