直接使用
请打开如何在DLC训练任务中挂载OSS,并点击右上角 “ 在DSW中打开” 。
概览
PAI-DLC(Deep Learning Containers)是基于阿里巴巴容器服务ACK(Alibaba Cloud Container Service for Kubernetes)的深度学习训练平台,为您提供灵活、稳定、易用和极致性能的深度学习训练环境。 DLC支持挂载NAS、OSS到容器中,方便在训练中直接读写。
本文将介绍如何在DLC训练任务中挂载OSS数据集。
前提条件
- 开通PAI-DLC,并完成授权。
- 开通OSS。
- 创建AI工作空间。
在PAI控制台 -->> 资源管理 -->> 全部云产品依赖 页面,可以查看开通状态。
步骤一:创建OSS数据集
选择并进入一个工作空间,选择数据集:
点击创建数据集
- 点击 AI资源管理 -- 数据集;
- 点击 创建数据集;
- 创建方式选择 “从阿里云存储”;
- 指定 数据集的名称:之后在DLC、DSW中引用时会显示数据集的名字
- 选择OSS存储
- 属性选择:文件夹
- 选择需要挂载的OSS Bucket与文件路径
查看数据集详情
- 查看数据集ID:使用DLC命令行工具 或者 SDK提供训练任务时,需要使用数据集ID来此数据集
- Uri:格式是
oss://[OSS-Bucket].[OSS-Endpoint]/[OSS-Path]
- Mount Path: 是DLC节点中挂载的本地路径
步骤二:创建DLC训练任务
在训练任务中引用刚刚创建的数据集,然后在节点中可以通过读写MountPath指定的路径 来访问OSS。
高级配置
当前DLC底层使用JindoFuse来挂载的OSS。JindoFuse的挂载OSS时,有很多参数可以调整,默认的参数配置并不适合所有的场景。DLC的默认配置,有如下限制:
- 为了快速读取OSS文件,挂载OSS时会有元数据(目录与文件列表)的Cache;
- 如果分布式任务中有多个节点需要创建同一个目录并检查目录是否存在的行为,因为元数据的Cache会导致,每个节点都会创建目录,但只有一个节点创建成功,其它节点会报错。
- 默认使用OSS的 MultiPart API来创建文件,所以在写文件的过程中,在OSS上看不到这个对象;当所有写操作完成时,才能在OSS页面上查看。
- 不支持文件的边写边读的操作。
- 不支持文件的随机写操作。
当前PAI的控制台页面,不支持配置JindoFuse底层的参数,需要使用SDK来修改,下面提供一些修改示例,以供参考。
环境准备:安装工作空间的SDK
!pip install alibabacloud-aiworkspace20210204
主要的应用场景:
- 分布式作业中多个节点需要向同一目录写文件,如果有Cache,会导致有些节点找不以这个目录
需要修改fuse的命令行参数,增加: -oattr_timeout=0-oentry_timeout=0-onegative_timeout=0
import json from alibabacloud_tea_openapi.models import Config from alibabacloud_aiworkspace20210204.client import Client as AIWorkspaceClient from alibabacloud_aiworkspace20210204.models import UpdateDatasetRequest def turnOffMetaCache(): region_id = 'cn-hangzhou' access_key_id = '** 你的 AccessKeyId **' access_key_secret = '** 你的 AccessKeySecret **' dataset_id = '** 数据集的 ID **' workspace_client = AIWorkspaceClient( Config(access_key_id=access_key_id, access_key_secret=access_key_secret, region_id=region_id, endpoint='aiworkspace.{}.aliyuncs.com'.format(region_id))) # 1. get the content of dataset get_dataset_resp = workspace_client.get_dataset(dataset_id) options = json.loads(get_dataset_resp.body.options) options['fs.jindo.args'] = '-oattr_timeout=0 -oentry_timeout=0 -onegative_timeout=0' update_request = UpdateDatasetRequest( options=json.dumps(options) ) # 2. update options workspace_client.update_dataset(dataset_id, update_request) print('new options is: {}'.format(update_request.options)) turnOffMetaCache()
调整上传(下载)数据的线程数目
fs.oss.upload.thread.concurrency:32
fs.oss.download.thread.concurrency:32
fs.oss.read.readahead.buffer.count:64
fs.oss.read.readahead.buffer.size:4194304
具体可以参考文档:JindoSDK 高级参数配置
import json from alibabacloud_tea_openapi.models import Config from alibabacloud_aiworkspace20210204.client import Client as AIWorkspaceClient from alibabacloud_aiworkspace20210204.models import UpdateDatasetRequest def adjustThreadNum(): region_id = 'cn-hangzhou' access_key_id = '** 你的 AccessKeyId **' access_key_secret = '** 你的 AccessKeySecret **' dataset_id = '** 数据集的 ID **' workspace_client = AIWorkspaceClient( Config(access_key_id=access_key_id, access_key_secret=access_key_secret, region_id=region_id, endpoint='aiworkspace.{}.aliyuncs.com'.format(region_id))) # 1. get the content of dataset get_dataset_resp = workspace_client.get_dataset(dataset_id) options = json.loads(get_dataset_resp.body.options) options['fs.oss.upload.thread.concurrency'] = 32 options['fs.oss.download.thread.concurrency'] = 32 options['fs.oss.read.readahead.buffer.count'] = 32 update_request = UpdateDatasetRequest( options=json.dumps(options) ) # 2. update options workspace_client.update_dataset(dataset_id, update_request) print('new options is: {}'.format(update_request.options)) adjustThreadNum()
如何使用AppendObject方式挂载OSS文件
所有在本地创建的文件,都会使用OSS的AppendObject接口来创建Object。AppendObject本身有一些限制可以参考文档。最重要是限制是:通过AppendObject方式最后生成的Object大小不得超过5 GB。
import json from alibabacloud_tea_openapi.models import Config from alibabacloud_aiworkspace20210204.client import Client as AIWorkspaceClient from alibabacloud_aiworkspace20210204.models import UpdateDatasetRequest def useAppendObject(): region_id = 'cn-hangzhou' access_key_id = '** 你的 AccessKeyId **' access_key_secret = '** 你的 AccessKeySecret **' dataset_id = '** 数据集的 ID **' workspace_client = AIWorkspaceClient( Config(access_key_id=access_key_id, access_key_secret=access_key_secret, region_id=region_id, endpoint='aiworkspace.{}.aliyuncs.com'.format(region_id))) # 1. get the content of dataset get_dataset_resp = workspace_client.get_dataset(dataset_id) options = json.loads(get_dataset_resp.body.options) options['fs.jindo.args'] = '-oattr_timeout=0 -oentry_timeout=0 -onegative_timeout=0' options['fs.oss.append.enable'] = "true" options['fs.oss.flush.interval.millisecond'] = "1000" options['fs.oss.read.buffer.size'] = "262144" options['fs.oss.write.buffer.size'] = "262144" update_request = UpdateDatasetRequest( options=json.dumps(options) ) # 2. update options workspace_client.update_dataset(dataset_id, update_request) print('new options is: {}'.format(update_request.options)) useAppendObject()
如何挂载OSS-HDFS
如何开通OSS-HDFS,可以参考文档。 需要使用OSS-HDFS的Endpoint来创建数据集,具体示例代码如下:
import json from alibabacloud_tea_openapi.models import Config from alibabacloud_aiworkspace20210204.client import Client as AIWorkspaceClient from alibabacloud_aiworkspace20210204.models import CreateDatasetRequest def createOssHdfsDataset(): region_id = 'cn-hangzhou' access_key_id = '** 你的 AccessKeyId **' access_key_secret = '** 你的 AccessKeySecret **' workspace_id = '** 工作空间ID **' oss_bucket = '** OSS-Bucket **' # 使用 OSS-HDFS 的 Endpoint oss_endpoint = f'{region_id}.oss-dls.aliyuncs.com' # 需要挂载的 OSS-HDFS 路径 oss_path = '/' # 本地挂载路径 mount_path = '/mnt/data/' workspace_client = AIWorkspaceClient( Config(access_key_id=access_key_id, access_key_secret=access_key_secret, region_id=region_id, endpoint='aiworkspace.{}.aliyuncs.com'.format(region_id))) response = workspace_client.create_dataset(CreateDatasetRequest( workspace_id=workspace_id, name="** 数据集的名字 **", data_type='COMMON', data_source_type='OSS', property='DIRECTORY', uri=f'oss://{oss_bucket}.{oss_endpoint}{oss_path}', accessibility='PRIVATE', source_type='USER', options=json.dumps({ 'mountPath': mount_path, # 分布式训练的场景下建议增加以下参数: 'fs.jindo.args': '-oattr_timeout=0 -oentry_timeout=0 -onegative_timeout=0 -ono_symlink -ono_xattr -ono_flock -odirect_io', 'fs.oss.flush.interval.millisecond': "10000", 'fs.oss.randomwrite.sync.interval.millisecond': "10000", }) )) print(f'datasetId: {response.body.dataset_id}') createOssHdfsDataset()