全部產品
Search
文件中心

Platform For AI:OSS使用

更新時間:Aug 12, 2026

PAI的DLC和DSW支援通過ossfs 2.0或JindoFuse掛載OSS到容器路徑,也支援通過OSS Connector for AI/ML或OSS SDK直接讀取OSS資料。按是否使用PyTorch、是否需要POSIX語義等情境選擇合適方式。

背景資訊

AI開發常把來源資料存到OSS,再下載到訓練環境。這會帶來以下問題:

  • 資料集下載時間長,GPU空等。

  • 每次訓練任務都需要重複下載資料。

  • 隨機採樣要求每個訓練節點都下載完整資料集。

參考下表選擇合適的OSS讀取方式:

OSS資料讀取方法

描述

適用情境

JindoFuse

通過JindoFuse將OSS資料集掛載到容器路徑,直接讀寫資料。

  • 希望像訪問本機資料一樣讀取OSS,或資料集較小、可用JindoFuse本機快取加速。

  • 使用的架構不是PyTorch。

  • 需要向OSS寫入資料。

ossfs 2.0

ossfs 2.0是一款高效能掛載訪問OSS的用戶端,順序讀寫能力強,充分發揮OSS高頻寬優勢。

ossfs 2.0適用於對儲存訪問效能要求較高的情境,比如AI訓練、推理、巨量資料處理、自動駕駛等新型計算密集型負載。這類工作負載主要涉及順序和隨機讀取、順序(僅支援追加)寫入操作,並且無需依賴完整的 POSIX 語義。

OSS Connector for AI/ML

PAI整合了OSS Connector for AI/ML,可在PyTorch代碼中直接流式讀取OSS檔案。優勢如下:

  • 流式載入:無需提前下載資料,節省GPU等待時間和成本。

  • 介面友好:與PyTorch Dataset用法一致,簡單易用,封裝優於OSS SDK,便於自訂。

  • 高效讀取:相比OSS SDK,資料讀取效能更優,載入更快。

該方式無需掛載OSS。如果您用PyTorch訓練,需要讀取海量(百萬層級)小檔案且對輸送量要求較高,可使用OSS Connector for AI/ML加速讀取。

OSS SDK

使用OSS2流式訪問OSS資料。OSS2靈活高效,可縮短請求時間,提升訓練效率。

如果您只需臨時、非掛載地訪問OSS,或按商務邏輯決定是否訪問OSS,可使用OSS Python SDK或API。

重要

通過JindoFuse和ossfs 2.0掛載OSS時,可指定訪問OSS的RAM角色,獲得更精細的許可權管控。同時支援在工作空間通用配置中開啟OSS掛載必選RAM角色。開啟後:

  • DSW/DLC/EAS等功能建立OSS掛載時必須選擇RAM角色,不允許使用預設RAM角色;

  • 建立進階型/邏輯型資料集且涉及OSS掛載時,也會強制校正RAM角色;

  • DSW建立執行個體、DLC建立任務、EAS建立服務時,RAM角色不允許選擇PAI預設角色。

JindoFuse

DLC和DSW支援使用JindoFuse將OSS資料集或路徑掛載到容器,訓練時直接讀寫OSS資料。

掛載方式

在DLC中掛載OSS

建立分布式訓練(DLC)任務時,可掛載OSS資料。掛載後,訓練代碼可以像訪問本地檔案一樣讀取OSS資料。支援以下兩種掛載類型,具體配置請參見建立訓練任務。

在数据集和直接挂载地區,單擊展開進階配置查看更多掛載選項,通過是否唯讀開關控制掛載模式。

掛載類型

描述

数据集

選擇对象存储OSS類型的資料集,並配置挂载路径。公用資料集僅支援唯讀掛載。

直接挂载

直接掛載OSS Bucket儲存路徑。

使用已開啟本機快取的靈駿智算資源配額時,可開啟使用緩衝開關。

在DSW中掛載OSS

建立DSW執行個體時,可掛載OSS資料。掛載後,開發環境可以像訪問本地檔案一樣讀取OSS資料。支援以下兩種掛載類型,具體配置請參見建立DSW執行個體。

兩種掛載類型均提供展開進階配置選項。儲存路徑掛載支援OSS、通用型NAS、極速型NAS、CPFS和智算CPFS。

掛載類型

描述

数据集挂载

選擇对象存储OSS類型的資料集,並配置挂载路径。公用資料集僅支援唯讀掛載。

存储路径挂载

直接掛載OSS Bucket儲存路徑。

預設配置限制

當高级配置參數為空白時使用預設配置,限制如下:

  • 為加速讀取,掛載OSS時會緩衝中繼資料(目錄與檔案清單)。

    分布式任務中,多個節點同時建立同一目錄時,中繼資料快取會讓每個節點都嘗試建立。最終只有一個節點成功,其餘報錯。

  • 預設使用OSS的Multipart API建立檔案,寫入過程中OSS上看不到該對象,寫入完成後才能查看。

  • 不支援同時讀寫同一檔案。

  • 不支援隨機寫入檔案。

常見JindoFuse配置

您也可以按情境在進階配置中自訂JindoFuse參數。

以下僅提供部分情境建議,未覆蓋所有最優效能設定。更多配置請參見JindoFuse使用指南。
  • 快速讀寫:允許使用者讀寫,讀取速度快,但並發讀寫可能會出現資料不一致的問題,適合掛載訓練資料和模型,不適合作為工作目錄。

    {
      "fs.oss.download.thread.concurrency": "cpu核心數2倍",
      "fs.oss.upload.thread.concurrency": "cpu核心數2倍",
      "fs.jindo.args": "-oattr_timeout=3 -oentry_timeout=0 -onegative_timeout=0 -oauto_cache -ono_symlink"
    }
    
  • 增量讀寫:在增量寫入時能夠保證資料一致性,覆蓋原有資料會有一致性問題。讀取速度略慢,適合儲存訓練的模型權重檔案。

    {
      "fs.oss.upload.thread.concurrency": "cpu核心數2倍",
      "fs.jindo.args": "-oattr_timeout=3 -oentry_timeout=0 -onegative_timeout=0 -oauto_cache -ono_symlink"
    }
    
  • 讀寫一致:在並發讀寫中能保持資料一致性,適用於對資料一致性要求高,可以容忍讀取速度慢的情境,適合儲存代碼專案。

    {
      "fs.jindo.args": "-oattr_timeout=0 -oentry_timeout=0 -onegative_timeout=0 -oauto_cache -ono_symlink"
    }
    
  • 唯讀:僅允許讀取,不允許寫入,適合掛載公用資料集。

    {
      "fs.oss.download.thread.concurrency": "cpu核心數2倍",
      "fs.jindo.args": "-oro -oattr_timeout=7200 -oentry_timeout=7200 -onegative_timeout=7200 -okernel_cache -ono_symlink"
    }

常見配置如下:

  • 選擇JindoFuse版本:

    {
      "fs.jindo.fuse.pod.image.tag": "6.7.0"
    }
  • 關閉中繼資料快取:分布式任務中多個節點同時向同一目錄寫檔案時,緩衝可能導致部分節點寫入失敗。在JindoFuse命令列參數中增加-oattr_timeout=0-oentry_timeout=0-onegative_timeout=0可避免該問題。

    {
      "fs.jindo.args": "-oattr_timeout=0-oentry_timeout=0-onegative_timeout=0"
    }
  • 調整上傳/下載線程數:配置以下參數調整並發。

    {
      "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"
    }
  • 使用AppendObject方式掛載OSS檔案:本地建立的檔案會調用OSS AppendObject介面。產生的Object大小不得超過5 GB,更多限制請參見AppendObject。樣本配置如下。

    {
      "fs.jindo.args": "-oattr_timeout=0 -oentry_timeout=0 -onegative_timeout=0",
      "fs.oss.append.enable": "true",
      "fs.oss.flush.interval.millisecond": "1000",
      "fs.oss.read.readahead.buffer.size": "4194304",
      "fs.oss.write.buffer.size": "262144"
    }
  • 掛載OSS-HDFS:開通OSS-HDFS請參見什麼是OSS-HDFS服務。分布式訓練情境建議增加以下參數。

    {
      "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"
    }
  • 配置記憶體資源:通過fs.jindo.fuse.pod.mem.limit參數調整記憶體上限,樣本如下。

    {
      "fs.jindo.fuse.pod.mem.limit": "10Gi"
    }

使用Python SDK修改資料集的JindoFuse參數

您還可以通過Python SDK修改JindoFuse參數。

  1. 完成以下準備工作。

    1. 安裝工作空間SDK。

      !pip install alibabacloud-aiworkspace20210204
    2. 配置環境變數。環境變數用於SDK身份認證,避免在代碼中寫入程式碼密鑰。具體步驟,請參見安裝Credentials工具和在Linux、macOS和Windows系統配置環境變數。

  2. 修改JindoFuse參數。

    快速讀寫

    import json
    from alibabacloud_tea_openapi.models import Config
    from alibabacloud_credentials.client import Client as CredClient
    from alibabacloud_aiworkspace20210204.client import Client as AIWorkspaceClient
    from alibabacloud_aiworkspace20210204.models import UpdateDatasetRequest
    
    
    def change_config():
        # 使用DLC任務所在地區。例如華東1(杭州)配置為cn-hangzhou。
        region_id = 'cn-hangzhou'
        # AccessKey擁有所有API存取權限,建議使用RAM使用者。
        # 請勿將AccessKey ID和AccessKey Secret儲存到工程代碼中,避免泄露。
        # 本樣本通過Credentials SDK從環境變數讀取AccessKey。請提前安裝Credentials工具並配置環境變數。
        cred = CredClient()
        dataset_id = '** 資料集的ID **'
    
        workspace_client = AIWorkspaceClient(
            config=Config(
                credential=cred,
                region_id=region_id,
                endpoint="aiworkspace.{}.aliyuncs.com".format(region_id),
            )
        )
        # 1、擷取資料集內容
        get_dataset_resp = workspace_client.get_dataset(dataset_id)
        options = json.loads(get_dataset_resp.body.options)
        # 建議值設定為CPU核心數的2倍
        options['fs.oss.download.thread.concurrency'] = 32
        options['fs.oss.upload.thread.concurrency'] = 32
        options['fs.jindo.args'] = '-oattr_timeout=3 -oentry_timeout=0 -onegative_timeout=0 -oauto_cache -ono_symlink'
    
        update_request = UpdateDatasetRequest(
            options=json.dumps(options)
        )
        # 2、更新options
        workspace_client.update_dataset(dataset_id, update_request)
        print('new options is: {}'.format(update_request.options))
    
    
    change_config()

    增量讀寫

    import json
    from alibabacloud_tea_openapi.models import Config
    from alibabacloud_credentials.client import Client as CredClient
    from alibabacloud_aiworkspace20210204.client import Client as AIWorkspaceClient
    from alibabacloud_aiworkspace20210204.models import UpdateDatasetRequest
    
    
    def change_config():
        # 使用DLC任務所在地區。例如華東1(杭州)配置為cn-hangzhou。
        region_id = 'cn-hangzhou'
        # AccessKey擁有所有API存取權限,建議使用RAM使用者。
        # 請勿將AccessKey ID和AccessKey Secret儲存到工程代碼中,避免泄露。
        # 本樣本通過Credentials SDK從環境變數讀取AccessKey。請提前安裝Credentials工具並配置環境變數。
        cred = CredClient()
        dataset_id = '** 資料集的ID **'
    
        workspace_client = AIWorkspaceClient(
            config=Config(
                credential=cred,
                region_id=region_id,
                endpoint="aiworkspace.{}.aliyuncs.com".format(region_id),
            )
        )
        # 1、擷取資料集內容
        get_dataset_resp = workspace_client.get_dataset(dataset_id)
        options = json.loads(get_dataset_resp.body.options)
        # 建議值設定為CPU核心數的2倍
        options['fs.oss.upload.thread.concurrency'] = 32
        options['fs.jindo.args'] = '-oattr_timeout=3 -oentry_timeout=0 -onegative_timeout=0 -oauto_cache -ono_symlink'
    
        update_request = UpdateDatasetRequest(
            options=json.dumps(options)
        )
        # 2、更新options
        workspace_client.update_dataset(dataset_id, update_request)
        print('new options is: {}'.format(update_request.options))
    
    
    change_config()

    讀寫一致

    import json
    from alibabacloud_tea_openapi.models import Config
    from alibabacloud_credentials.client import Client as CredClient
    from alibabacloud_aiworkspace20210204.client import Client as AIWorkspaceClient
    from alibabacloud_aiworkspace20210204.models import UpdateDatasetRequest
    
    
    def change_config():
        # 使用DLC任務所在地區。例如華東1(杭州)配置為cn-hangzhou。
        region_id = 'cn-hangzhou'
        # AccessKey擁有所有API存取權限,建議使用RAM使用者。
        # 請勿將AccessKey ID和AccessKey Secret儲存到工程代碼中,避免泄露。
        # 本樣本通過Credentials SDK從環境變數讀取AccessKey。請提前安裝Credentials工具並配置環境變數。
        cred = CredClient()
        dataset_id = '** 資料集的ID **'
    
        workspace_client = AIWorkspaceClient(
            config=Config(
                credential=cred,
                region_id=region_id,
                endpoint="aiworkspace.{}.aliyuncs.com".format(region_id),
            )
        )
        # 1、擷取資料集內容
        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 -oauto_cache -ono_symlink'
    
        update_request = UpdateDatasetRequest(
            options=json.dumps(options)
        )
        # 2、更新options
        workspace_client.update_dataset(dataset_id, update_request)
        print('new options is: {}'.format(update_request.options))
    
    
    change_config()

    唯讀

    import json
    from alibabacloud_tea_openapi.models import Config
    from alibabacloud_credentials.client import Client as CredClient
    from alibabacloud_aiworkspace20210204.client import Client as AIWorkspaceClient
    from alibabacloud_aiworkspace20210204.models import UpdateDatasetRequest
    
    
    def change_config():
        # 使用DLC任務所在地區。例如華東1(杭州)配置為cn-hangzhou。
        region_id = 'cn-hangzhou'
        # AccessKey擁有所有API存取權限,建議使用RAM使用者。
        # 請勿將AccessKey ID和AccessKey Secret儲存到工程代碼中,避免泄露。
        # 本樣本通過Credentials SDK從環境變數讀取AccessKey。請提前安裝Credentials工具並配置環境變數。
        cred = CredClient()
        dataset_id = '** 資料集的ID **'
    
        workspace_client = AIWorkspaceClient(
            config=Config(
                credential=cred,
                region_id=region_id,
                endpoint="aiworkspace.{}.aliyuncs.com".format(region_id),
            )
        )
        # 1、擷取資料集內容
        get_dataset_resp = workspace_client.get_dataset(dataset_id)
        options = json.loads(get_dataset_resp.body.options)
        # 建議值設定為CPU核心數的2倍
        options['fs.oss.download.thread.concurrency'] = 32
        options['fs.jindo.args'] = '-oro -oattr_timeout=7200 -oentry_timeout=7200 -onegative_timeout=7200 -okernel_cache -ono_symlink'
    
        update_request = UpdateDatasetRequest(
            options=json.dumps(options)
        )
        # 2、更新options
        workspace_client.update_dataset(dataset_id, update_request)
        print('new options is: {}'.format(update_request.options))
    
    
    change_config()

    選擇JindoFuse版本

    範例程式碼如下:

    import json
    from alibabacloud_tea_openapi.models import Config
    from alibabacloud_credentials.client import Client as CredClient
    from alibabacloud_aiworkspace20210204.client import Client as AIWorkspaceClient
    from alibabacloud_aiworkspace20210204.models import UpdateDatasetRequest
    
    
    def change_version():
        # 使用DLC任務所在地區。例如華東1(杭州)配置為cn-hangzhou。
        region_id = 'cn-hangzhou'
        # AccessKey擁有所有API存取權限,建議使用RAM使用者。
        # 請勿將AccessKey ID和AccessKey Secret儲存到工程代碼中,避免泄露。
        # 本樣本通過Credentials SDK從環境變數讀取AccessKey。請提前安裝Credentials工具並配置環境變數。
        cred = CredClient()
        dataset_id = '** 資料集的ID **'
    
        workspace_client = AIWorkspaceClient(
            config=Config(
                credential=cred,
                region_id=region_id,
                endpoint="aiworkspace.{}.aliyuncs.com".format(region_id),
            )
        )
        # 1、擷取資料集內容
        get_dataset_resp = workspace_client.get_dataset(dataset_id)
        options = json.loads(get_dataset_resp.body.options)
        # 配置JindoFuse版本,可選6.4.4、6.7.0、6.6.0。release note見:https://aliyun.github.io/alibabacloud-jindodata/releases/
        options['fs.jindo.fuse.pod.image.tag'] = "6.7.0"
    
        update_request = UpdateDatasetRequest(
            options=json.dumps(options)
        )
        # 2、更新options
        workspace_client.update_dataset(dataset_id, update_request)
        print('new options is: {}'.format(update_request.options))
    change_version()

    關閉中繼資料快取

    分布式任務中多個節點同時向同一目錄寫檔案時,Cache可能導致部分節點寫入失敗。在fuse命令列參數中增加-oattr_timeout=0-oentry_timeout=0-onegative_timeout=0可解決該問題。範例程式碼如下。

    import json
    from alibabacloud_tea_openapi.models import Config
    from alibabacloud_credentials.client import Client as CredClient
    from alibabacloud_aiworkspace20210204.client import Client as AIWorkspaceClient
    from alibabacloud_aiworkspace20210204.models import UpdateDatasetRequest
    
    
    def turnOffMetaCache():
        region_id = 'cn-hangzhou'
        # AccessKey擁有所有API存取權限,建議使用RAM使用者。
        # 請勿將AccessKey ID和AccessKey Secret儲存到工程代碼中,避免泄露。
        # 本樣本通過Credentials SDK從環境變數讀取AccessKey。請提前安裝Credentials工具並配置環境變數。
        cred = CredClient()
        dataset_id = '** 資料集的ID **'
        workspace_client = AIWorkspaceClient(
          config=Config(
                credential=cred,
                region_id=region_id,
                endpoint="aiworkspace.{}.aliyuncs.com".format(region_id),
          )
        )
        # 1、擷取資料集內容
        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、更新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

    範例程式碼如下:

    import json
    from alibabacloud_tea_openapi.models import Config
    from alibabacloud_credentials.client import Client as CredClient
    from alibabacloud_aiworkspace20210204.client import Client as AIWorkspaceClient
    from alibabacloud_aiworkspace20210204.models import UpdateDatasetRequest
    
    
    def adjustThreadNum():
        # 使用DLC任務所在地區。例如華東1(杭州)配置為cn-hangzhou。
        region_id = 'cn-hangzhou'
        # AccessKey擁有所有API存取權限,建議使用RAM使用者。
        # 請勿將AccessKey ID和AccessKey Secret儲存到工程代碼中,避免泄露。
        # 本樣本通過Credentials SDK從環境變數讀取AccessKey。請提前安裝Credentials工具並配置環境變數。
        cred = CredClient()
        dataset_id = '** 資料集的ID **'
    
        workspace_client = AIWorkspaceClient(
            config=Config(
                credential=cred,
                region_id=region_id,
                endpoint="aiworkspace.{}.aliyuncs.com".format(region_id),
            )
        )
        # 1、擷取資料集內容
        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、更新options
        workspace_client.update_dataset(dataset_id, update_request)
        print('new options is: {}'.format(update_request.options))
     
     
    adjustThreadNum()
    

    使用AppendObject方式掛載OSS檔案

    本地建立的檔案會調用OSS AppendObject介面。產生的Object大小不得超過5 GB,更多限制請參見AppendObject。範例程式碼如下:

    import json
    from alibabacloud_tea_openapi.models import Config
    from alibabacloud_credentials.client import Client as CredClient
    from alibabacloud_aiworkspace20210204.client import Client as AIWorkspaceClient
    from alibabacloud_aiworkspace20210204.models import UpdateDatasetRequest
    
    
    def useAppendObject():
        # 使用DLC任務所在地區。例如華東1(杭州)配置為cn-hangzhou。
        region_id = 'cn-hangzhou'
        # AccessKey擁有所有API存取權限,建議使用RAM使用者。
        # 請勿將AccessKey ID和AccessKey Secret儲存到工程代碼中,避免泄露。
        # 本樣本通過Credentials SDK從環境變數讀取AccessKey。請提前安裝Credentials工具並配置環境變數。
        cred = CredClient()
        dataset_id = '** 資料集的ID **'
    
        workspace_client = AIWorkspaceClient(
            config=Config(
                credential=cred,
                region_id=region_id,
                endpoint="aiworkspace.{}.aliyuncs.com".format(region_id),
            )
        )
        # 1、擷取資料集內容
        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、更新options
        workspace_client.update_dataset(dataset_id, update_request)
        print('new options is: {}'.format(update_request.options))
    
    
    useAppendObject()

    掛載OSS-HDFS

    開通OSS-HDFS請參見什麼是OSS-HDFS服務。使用OSS-HDFS Endpoint建立資料集的範例程式碼如下:

    import json
    from alibabacloud_tea_openapi.models import Config
    from alibabacloud_credentials.client import Client as CredClient
    from alibabacloud_aiworkspace20210204.client import Client as AIWorkspaceClient
    from alibabacloud_aiworkspace20210204.models import CreateDatasetRequest
    
    
    def createOssHdfsDataset():
        # 使用DLC任務所在地區。例如華東1(杭州)配置為cn-hangzhou。
        region_id = 'cn-hangzhou'
        # AccessKey擁有所有API存取權限,建議使用RAM使用者。
        # 請勿將AccessKey ID和AccessKey Secret儲存到工程代碼中,避免泄露。
        # 本樣本通過Credentials SDK從環境變數讀取AccessKey。請提前安裝Credentials工具並配置環境變數。
        cred = CredClient()
        workspace_id = '** DLC任務所在工作空間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=Config(
                credential=cred,
                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()
    
    

    配置記憶體資源

    通過fs.jindo.fuse.pod.mem.limit參數調整記憶體資源,範例程式碼如下:

    import json
    from alibabacloud_tea_openapi.models import Config
    from alibabacloud_credentials.client import Client as CredClient
    from alibabacloud_aiworkspace20210204.client import Client as AIWorkspaceClient
    from alibabacloud_aiworkspace20210204.models import UpdateDatasetRequest
    
    
    def adjustResource():
        # 使用DLC任務所在地區。例如華東1(杭州)配置為cn-hangzhou。
        region_id = 'cn-hangzhou'
        # AccessKey擁有所有API存取權限,建議使用RAM使用者。
        # 請勿將AccessKey ID和AccessKey Secret儲存到工程代碼中,避免泄露。
        # 本樣本通過Credentials SDK從環境變數讀取AccessKey。請提前安裝Credentials工具並配置環境變數。
        cred = CredClient()
        dataset_id = '** 資料集的ID **'
    
        workspace_client = AIWorkspaceClient(
            config=Config(
                credential=cred,
                region_id=region_id,
                endpoint="aiworkspace.{}.aliyuncs.com".format(region_id),
            )
        )
        # 1、擷取資料集內容
        get_dataset_resp = workspace_client.get_dataset(dataset_id)
        options = json.loads(get_dataset_resp.body.options)
        # 要配置的記憶體資源。
        options['fs.jindo.fuse.pod.mem.limit'] = "10Gi"
    
        update_request = UpdateDatasetRequest(
            options=json.dumps(options)
        )
        # 2、更新options
        workspace_client.update_dataset(dataset_id, update_request)
        print('new options is: {}'.format(update_request.options))
    
    
    adjustResource()
    

ossfs 2.0

掛載OSS資料來源時,在進階配置中設定{"mountType":"ossfs"},即可使用ossfs掛載。

掛載方式

在DLC中掛載OSS

建立分布式訓練(DLC)任務時,可掛載OSS資料。掛載後,訓練代碼可以像訪問本地檔案一樣讀取OSS資料。支援以下兩種掛載類型,具體配置請參見建立訓練任務。

掛載類型

描述

数据集

選擇对象存储OSS類型的資料集,並配置挂载路径。公用資料集僅支援唯讀掛載。

直接挂载

直接掛載OSS Bucket儲存路徑。

使用已開啟本機快取的靈駿智算資源配額時,可開啟使用緩衝開關。

在DSW中掛載OSS

建立DSW執行個體時,可掛載OSS資料。掛載後,開發環境可以像訪問本地檔案一樣讀取OSS資料。支援以下兩種掛載類型,具體配置請參見建立DSW執行個體。

掛載類型

描述

数据集挂载

選擇对象存储OSS類型的資料集,並配置挂载路径。公用資料集僅支援唯讀掛載。

存储路径挂载

直接掛載OSS Bucket儲存路徑。

常見ossfs配置

在進階配置中,通過fs.ossfs.args設定進階參數,多個參數之間使用半形逗號,分隔。進階參數說明請參見ossfs 2.0。常見情境樣本如下:

  • 任務過程中資料來源不變:如果讀取過程中檔案不會被修改,可配置較大的緩衝時間,減少中繼資料請求次數。例如讀取一批已有舊檔案,處理後產生新檔案。

    {
        "mountType":"ossfs",
        "fs.ossfs.args": "-oattr_timeout=7200" 
    }
  • 快速讀寫:使用較小的中繼資料快取時間,平衡緩衝效率與資料及時性。

    {
        "mountType":"ossfs",
        "fs.ossfs.args": "-oattr_timeout=3, -onegative_timeout=0"
    }
  • 分布式任務讀寫一致:ossfs預設會緩衝中繼資料。通過以下配置實現多節點同步視圖。

    {   
        "mountType":"ossfs",
        "fs.ossfs.args": "-onegative_timeout=0, -oclose_to_open"
    }
  • DLC/DSW情境中同時開啟過多檔案導致OOM:DLC或DSW情境中任務並發量較高,可能同時開啟大量檔案導致OOM(記憶體不足)。通過以下配置緩解記憶體壓力。

    {
        "mountType":"ossfs",
        "fs.ossfs.args": "-oreaddirplus=false, -oinode_cache_eviction_threshold=300000"
    }
  • 寫入大檔案失敗:-oupload_buffer_size用於設定分區上傳緩衝區大小(Bytes)。該參數決定可寫入檔案的最大大小,計算方式為upload_buffer_size * 10000。

    ossfs 2.0預設分區大小為8 MiB,最大支援寫入78.125 GiB的檔案。超過該限制時寫入會失敗。可配置-oupload_buffer_size增加分區大小,從而提升可寫入檔案大小上限。例如將Part大小設為32 MiB(33554432位元組),可支援最大312.5 GiB的檔案。-upload_buffer_size越大,消耗記憶體越多,可配置-total_mem_limit控制記憶體使用量,詳情請參見掛載選項說明

    {
        "mountType":"ossfs",
        "fs.ossfs.args": "-oupload_buffer_size=33554432"
    }
    

OSS Connector for AI/ML

使用OSS Connector for AI/ML加速模型訓練是阿里雲OSS團隊為AI/ML情境設計的用戶端庫,在大規模PyTorch訓練中提供便捷的資料載入,縮短資料轉送時間,加速模型訓練。PAI整合了OSS Connector for AI/ML,可在PyTorch代碼中流式讀取OSS檔案。

使用限制

  • 官方鏡像:僅當DLC任務或DSW執行個體選擇PyTorch 2.0及以上版本的鏡像時,可用OSS Connector for AI/ML模組。

  • 自訂鏡像:僅支援PyTorch 2.0及以上版本。滿足版本要求後,運行以下命令安裝OSS Connector for AI/ML模組。

    pip install -i http://yum.tbsite.net/aliyun-pypi/simple/ --extra-index-url http://yum.tbsite.net/pypi/simple/ --trusted-host=yum.tbsite.net osstorchconnector
  • Python版本:僅支援Python 3.8~3.12。

準備工作

  1. 配置credential檔案。

    通過以下任一方式配置credential:

    • 參考配置DLC RAM角色,為DLC任務配置免密訪問OSS的credential。DLC任務會擷取STS臨時訪問憑證,安全訪問OSS或其他雲資源,無需在代碼中配置認證資訊,降低密鑰泄露風險。

    • 在代碼專案中配置credential檔案管理認證資訊。配置樣本如下:

      說明

      明文配置AK存在安全風險,建議在DLC執行個體內通過角色自動設定credential,詳情請參見配置DLC RAM角色。

      使用OSS Connector for AI/ML介面時,指定credential檔案路徑後自動擷取認證資訊,完成OSS資料請求認證。

      {
        "AccessKeyId": "<Access-key-id>",
        "AccessKeySecret": "<Access-key-secret>",
        "SecurityToken": "<Security-Token>",
        "Expiration": "2024-08-20T00:00:00Z"
      }

      具體配置項說明如下:

      配置項

      是否必填

      說明

      樣本值

      AccessKeyId

      是

      阿里雲帳號或RAM使用者的AccessKey ID和AccessKey Secret。

      說明

      使用STS臨時訪問憑證訪問OSS時,請設定為臨時訪問憑證的AccessKey ID和AccessKey Secret。

      NTS****

      AccessKeySecret

      是

      7NR2****

      SecurityToken

      否

      臨時存取權杖。使用STS臨時訪問憑證訪問OSS時,需要設定。

      STS.6MC2****

      Expiration

      否

      鑒權資訊到期時間,Expiration為空白表示永不到期,到期後OSS Connector會重新讀取鑒權資訊。

      2024-08-20T00:00:00Z

  2. 配置config.json檔案,樣本如下:

    在代碼專案中配置config.json檔案,管理並發數、預取參數和日誌路徑等。使用OSS Connector for AI/ML介面時,指定config.json檔案路徑後,系統會自動讀取並發數和預取值,並將OSS資料請求日誌輸出到指定檔案。

    {
        "logLevel": 1,
        "logPath": "/var/log/oss-connector/connector.log",
        "auditPath": "/var/log/oss-connector/audit.log",
        "datasetConfig": {
            "prefetchConcurrency": 24,
            "prefetchWorker": 2
        },
        "checkpointConfig": {
            "prefetchConcurrency": 24,
            "prefetchWorker": 4,
            "uploadConcurrency": 64
        }
    }

    配置項說明如下:

    配置項

    是否必填

    說明

    樣本值

    logLevel

    是

    日誌記錄層級。預設為INFO。取值如下:

    • 0:表示Debug。

    • 1:表示INFO。

    • 2:表示WARN。

    • 3:表示ERROR。

    1

    logPath

    是

    connector日誌路徑。預設路徑為/var/log/oss-connector/connector.log。

    /var/log/oss-connector/connector.log

    auditPath

    是

    connector IO審計日誌,記錄延遲大於100毫秒的讀寫請求。預設路徑為/var/log/oss-connector/audit.log。

    /var/log/oss-connector/audit.log

    DatasetConfig

    prefetchConcurrency

    是

    使用Dataset從OSS預取資料時的並發數,預設為24。

    24

    prefetchWorker

    是

    使用Dataset從OSS預取時可用的vCPU數,預設為4。

    2

    checkpointConfig

    prefetchConcurrency

    是

    使用checkpoint read從OSS預取資料時的並發數,預設為24。

    24

    prefetchWorker

    是

    使用checkpoint read從OSS預取時可用的vCPU數,預設為4。

    4

    uploadConcurrency

    是

    使用checkpoint write上傳資料時的並發數,預設為64。

    64

使用方式

OSS Connector for AI/ML提供OssMapDataset和OssIterableDataset兩種資料集提供者,分別擴充Dataset和IterableDataset。OssIterableDataset有預取最佳化,訓練效率更高。OssMapDataset的讀取順序由DataLoader決定,支援shuffle。建議如下:

  • 如果記憶體較小或資料量較大,只需順序讀取且對平行處理要求不高,建議使用OssIterableDataset。

  • 如果記憶體充足、資料量較小,且需要隨機操作和平行處理,建議使用OssMapDataset。

OSS Connector for AI/ML還提供OssCheckpoint介面,支援模型載入和儲存。當前OssCheckpoint功能僅限通用資源環境使用。

下面介紹這三種介面的使用方式:

OssMapDataset

支援以下三種資料集訪問模式:

  • 根據OSS路徑首碼訪問檔案夾

    只需指定檔案夾名稱,無需配置索引檔案。如果OSS檔案夾結構如下,可採用該方式訪問資料集:

    dataset_folder/
        ├── class1/
        │   ├── image1.JPEG
        │   └── ...
        ├── class2/
        │   ├── image2.JPEG
        │   └── ...

    使用時指定OSS路徑首碼,並自訂檔案流解析方式。以下是解析和轉換圖片檔案的方法:

    def read_and_transform(data):
        normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406],
                                         std=[0.229, 0.224, 0.225])
        transform = transforms.Compose([
            transforms.RandomResizedCrop(224),
            transforms.RandomHorizontalFlip(),
            transforms.ToTensor(),
            normalize,
        ])
    
        try:
            img = accimage.Image((data.read()))
            val = transform(img)
            label = data.label # 檔案名稱
        except Exception as e:
            print("read failed", e)
            return None, 0
        return val, label
    dataset = OssMapDataset.from_prefix("{oss_data_folder_uri}", endpoint="{oss_endpoint}", transform=read_and_transform, cred_path=cred_path, config_path=config_path)
  • 根據manifest_file擷取檔案

    支援訪問多個OSS Bucket,管理更靈活。如果OSS檔案夾結構如下,且存在管理檔案名稱與Label對應關係的manifest_file,可採用該方式訪問資料集。

    dataset_folder/
        ├── class1/
        │   ├── image1.JPEG
        │   └── ...
        ├── class2/
        │   ├── image2.JPEG
        │   └── ...
        └── .manifest

    其中manifest_file格式如下:

    {'data': {'source': 'oss://examplebucket.oss-cn-wulanchabu.aliyuncs.com/dataset_folder/class1/image1.JPEG'}}
    {'data': {'source': ''}}

    使用時自訂manifest_file的解析方式,樣本如下:

    def transform_oss_path(input_path):
        pattern = r'oss://(.*?)\.(.*?)/(.*)'
        match = re.match(pattern, input_path)
        if match:
            return f'oss://{match.group(1)}/{match.group(3)}'
        else:
            return input_path
    
    
    def manifest_parser(reader: io.IOBase) -> Iterable[Tuple[str, str, int]]:
        lines = reader.read().decode("utf-8").strip().split("\n")
        data_list = []
        for i, line in enumerate(lines):
            data = json.loads(line)
            yield transform_oss_path(data["data"]["source"]), ""
    dataset = OssMapDataset.from_manifest_file("{manifest_file_path}", manifest_parser, "", endpoint=endpoint, transform=read_and_trans, cred_path=cred_path, config_path=config_path)
  • 根據OSS_URI列表的方式擷取檔案

    只需指定OSS URI,無需配置索引檔案即可訪問OSS檔案。樣本如下:

    uris =["oss://examplebucket.oss-cn-wulanchabu.aliyuncs.com/dataset_folder/class1/image1.JPEG", "oss://examplebucket.oss-cn-wulanchabu.aliyuncs.com/dataset_folder/class2/image2.JPEG"]
    dataset = OssMapDataset.from_objects(uris, endpoint=endpoint, transform=read_and_trans, cred_path=cred_path, config_path=config_path)

OssIterableDataset

OssIterableDataset也支援三種訪問方式,與OssMapDataset相同。用法如下:

  • 根據OSS路徑首碼訪問檔案夾

    dataset = OssIterableDataset.from_prefix("{oss_data_folder_uri}", endpoint="{oss_endpoint}", transform=read_and_transform, cred_path=cred_path, config_path=config_path)
  • 根據manifest_file擷取檔案

    dataset = OssIterableDataset.from_manifest_file("{manifest_file_path}", manifest_parser, "", endpoint=endpoint, transform=read_and_trans, cred_path=cred_path, config_path=config_path)
  • 根據OSS_URI列表的方式擷取檔案

    dataset = OssIterableDataset.from_objects(uris, endpoint=endpoint, transform=read_and_trans, cred_path=cred_path, config_path=config_path)

OssCheckpoint

OssCheckpoint功能僅支援通用計算資源環境。OSS Connector for AI/ML支援通過OssCheckpoint讀取和儲存OSS模型檔案。用法如下:

checkpoint = OssCheckpoint(endpoint="{oss_endpoint}", cred_path=cred_path, config_path=config_path)

checkpoint_read_uri = "{checkpoint_path}"
checkpoint_write_uri = "{checkpoint_path}"
with checkpoint.reader(checkpoint_read_uri) as reader:
    state_dict = torch.load(reader)
    model.load_state_dict(state_dict)
with checkpoint.writer(checkpoint_write_uri) as writer:
    torch.save(model.state_dict(), writer)

程式碼範例

以下是OSS Connector for AI/ML的範例程式碼,可直接用於訪問OSS資料:

from osstorchconnector import OssMapDataset, OssCheckpoint
import torchvision.transforms as transforms
import accimage
import torchvision.models as models
import torch

cred_path = "/mnt/.alibabacloud/credentials"  # 為DLC任務和DSW執行個體配置角色後credential的預設路徑。
config_path = "config.json"
checkpoint = OssCheckpoint(endpoint="{oss_endpoint}", cred_path=cred_path, config_path=config_path)
model = models.__dict__["resnet18"]()

epochs = 100  # 指定epoch
checkpoint_read_uri = "{checkpoint_path}"
checkpoint_write_uri = "{checkpoint_path}"
with checkpoint.reader(checkpoint_read_uri) as reader:
    state_dict = torch.load(reader)
    model.load_state_dict(state_dict)


def read_and_transform(data):
    normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406],
                                     std=[0.229, 0.224, 0.225])
    transform = transforms.Compose([
        transforms.RandomResizedCrop(224),
        transforms.RandomHorizontalFlip(),
        transforms.ToTensor(),
        normalize,
    ])

    try:
        img = accimage.Image((data.read()))
        value = transform(img)
    except Exception as e:
        print("read failed", e)
        return None, 0
    return value, 0
dataset = OssMapDataset.from_prefix("{oss_data_folder_uri}", endpoint="{oss_endpoint}", transform=read_and_transform, cred_path=cred_path, config_path=config_path)
data_loader = torch.utils.data.DataLoader(
    dataset, batch_size="{batch_size}",num_workers="{num_workers"}, pin_memory=True)

for epoch in range(args.epochs):
    for step, (images, target) in enumerate(data_loader):
        # batch processing
        # model training
    # save model
    with checkpoint.writer(checkpoint_write_uri) as writer:
        torch.save(model.state_dict(), writer)

上述代碼的關鍵實現說明如下:

  • OssMapDataset直接基於給定的OSS URI,構建與PyTorch DataLoader用法一致的dataset。

  • 用該dataset構建標準DataLoader,並迴圈DataLoader執行訓練流程,如處理當前batch、模型訓練與儲存等。

  • 該過程無需將資料集掛載到容器,也無需預先將資料存到本地,資料按需載入。

OSS SDK

OSS Python SDK

您可直接使用OSS Python SDK讀寫OSS資料,操作步驟如下:

  1. 安裝OSS Python SDK。詳情請參見安裝(Python SDK V1)。

  2. 為OSS Python SDK配置訪問憑證。憑證用於驗證您對OSS的存取權限,詳情請參見配置訪問憑證(Python SDK V1)。

  3. 讀寫OSS資料。

    # -*- coding: utf-8 -*-
    import oss2
    from oss2.credentials import EnvironmentVariableCredentialsProvider
    
    # 使用環境變數中的RAM使用者存取金鑰配置訪問憑證
    auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())
    bucket = oss2.Bucket(auth, '<Endpoint>', '<your_bucket_name>')
    # 讀取完整檔案。
    result = bucket.get_object('<your_file_path/your_file>')
    print(result.read())
    # 按Range讀取資料。
    result = bucket.get_object('<your_file_path/your_file>', byte_range=(0, 99))
    # 寫資料到OSS。
    bucket.put_object('<your_file_path/your_file>', '<your_object_content>')
    # 對Appendable類型檔案追加資料。
    result = bucket.append_object('<your_file_path/your_file>', 0, '<your_object_content>')
    result = bucket.append_object('<your_file_path/your_file>', result.next_position, '<your_object_content>')
    

    請按實際修改以下配置項:

    配置項

    描述

    <Endpoint>

    填寫Bucket所在地區的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。擷取Endpoint更多資訊,請參見地區和Endpoint。

    <your_bucket_name>

    填寫儲存空間名稱。

    <your_file_path/your_file>

    待讀寫的檔案路徑。填寫Object完整路徑,不包含Bucket名稱,例如testfolder/exampleobject.txt。

    <your_object_content>

    待Append的內容,按實際情況修改。

OSS Python API

使用OSS Python API可方便儲存訓練資料和模型。開始前確保已安裝OSS Python SDK並正確設定訪問憑證,詳情請參見安裝(Python SDK V1)和配置訪問憑證(Python SDK V1)。

  • 載入訓練資料

    您可將資料存放在一個OSS Bucket中,將資料路徑與對應Label存入同一OSS Bucket的索引檔案。通過自訂Dataset,在PyTorch中用DataLoaderAPI多進程並行讀取資料,可提升訓練效率,樣本如下。

    import io
    import oss2
    from oss2.credentials import EnvironmentVariableCredentialsProvider
    import PIL
    import torch
    
    class OSSDataset(torch.utils.data.dataset.Dataset):
        def __init__(self, endpoint, bucket, auth, index_file):
            self._bucket = oss2.Bucket(auth, endpoint, bucket)
            self._indices = self._bucket.get_object(index_file).read().split(',')
    
        def __len__(self):
            return len(self._indices)
    
        def __getitem__(self, index):
            img_path, label = self._indices(index).strip().split(':')
            img_str = self._bucket.get_object(img_path)
            img_buf = io.BytesIO()
            img_buf.write(img_str.read())
            img_buf.seek(0)
            img = Image.open(img_buf).convert('RGB')
            img_buf.close()
            return img, label
    
    
    # 從環境變數擷取訪問憑證。運行本代碼前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
    auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())
    dataset = OSSDataset(endpoint, bucket, auth, index_file)
    data_loader = torch.utils.data.DataLoader(
        dataset,
        batch_size=batch_size,
        num_workers=num_loaders,
        pin_memory=True)
    

    關鍵配置說明如下:

    關鍵配置

    描述

    endpoint

    填寫Bucket所在地區的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。擷取Endpoint更多資訊,請參見地區和Endpoint。

    bucket

    填寫Bucket名稱。

    index_file

    索引檔案的路徑。

    說明

    樣本中索引檔案格式為每條樣本用英文逗號(,)分隔,樣本路徑與Label之間用英文冒號(:)分隔。

  • Save或Load模型

    您可使用OSS Python API儲存或載入PyTorch模型(PyTorch儲存/載入模型詳情請參見PyTorch),樣本如下:

    • Save模型

      from io import BytesIO
      import torch
      import oss2
      from oss2.credentials import EnvironmentVariableCredentialsProvider
      
      auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())
      # Bucket名稱
      bucket_name = "<your_bucket_name>"
      bucket = oss2.Bucket(auth, endpoint, bucket_name)
      buffer = BytesIO()
      torch.save(model.state_dict(), buffer)
      bucket.put_object("<your_model_path>", buffer.getvalue())
      

      其中

      • endpoint為Bucket所在地區的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。

      • <your_bucket_name>為OSS Bucket名稱,且開頭不帶oss://。

      • <your_model_path>為模型路徑,按實際情況修改。

    • Load模型

      from io import BytesIO
      import torch
      import oss2
      from oss2.credentials import EnvironmentVariableCredentialsProvider
      
      auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())
      bucket_name = "<your_bucket_name>"
      bucket = oss2.Bucket(auth, endpoint, bucket_name)
      buffer = BytesIO(bucket.get_object("<your_model_path>").read())
      model.load_state_dict(torch.load(buffer))

      其中

      • endpoint為Bucket所在地區的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。

      • <your_bucket_name>為OSS Bucket名稱,且開頭不帶oss://。

      • <your_model_path>為模型路徑,按實際情況修改。