使用OSS加速器提升模型訓練速度

更新時間:
Copy as MD

使用OSS加速器可以顯著提升資料集載入速度,從而提升整體的模型訓練速度。本文基於大量效能測試對比了使用和未使用OSS加速器的加速效果,說明在GPU利用率尚未達到瓶頸的情況下,資料載入效率至關重要。此外,本文以預訓練模型ResNet-18Imagenet ILSVRC資料集上進行微調的訓練任務為例,指導您如何在GPU雲端服務器中使用OSS加速器來提升模型訓練速度。

加速效果

對比標準OSS Bucket,OSS加速器展現出了顯著的效能優勢。憑藉其低延遲特性,OSS加速器在使用較少的worker數量時便能實現更高的輸送量表現。在多組實驗中,OSS加速器提升訓練效率40%~400%,大幅降低了計算資源的消耗與使用成本,為使用者提供了更高效的解決方案。

效能測試實驗結果

重要

以下效能測試結果僅供參考,實際訓練加速效果可能受到多種因素的影響,例如資料集大小、硬體設定、模型複雜性以及其他超參數設定等。

針對使用了加速器的OSS Bucket和未使用加速器的標準OSS Bucket,開展了模型訓練過程中的效能測試工作。此次測試所採用的資料集由128萬張圖片的訓練集以及5萬張圖片的驗證集構成,根據機器規格(4c15g+1*Tesla T4)設計了多組並發參數,並且分別使用標準OSS和加速器進行資料集載入完成多組實驗。具體測試結果如下所示。

batch size

worker數量

平均每epoch耗時(min)

標準OSS

加速器

64

6

63.18

34.70

4

54.96

34.68

2

146.05

34.66

32

6

82.19

37.11

4

108.33

37.13

2

137.87

37.30

16

6

68.93

41.58

4

132.97

41.69

2

206.32

41.69

方案概覽

要實現以上加速效果只需三步:

  1. 建立GPU雲端服務器:建立一個適合模型訓練工作需求的GPU雲端服務器。

  2. 建立OSS Bucket並開通OSS加速器:建立一個OSS Bucket儲存空間並開通OSS加速器,同時擷取Bucket內網網域名稱以及OSS加速器網域名稱用於後續訓練任務。

  3. 訓練模型:在完成上述準備工作後,先對未經處理資料集進行預先處理,再將其上傳至OSS。隨後,在訓練過程中使用OSS加速器把資料集載入到本地,以此開展模型的訓練工作。

操作步驟

步驟一:建立GPU雲端服務器

以下步驟旨在建立並串連一個適用於模型訓練任務的GPU雲端服務器執行個體。該執行個體的規格為ecs.gn6i-c4g1.xlarge,作業系統為Ubuntu 22.04、CUDA版本為12.4.1。需注意,自訂執行個體配置時,CUDA版本請選擇最新版本。

1. 建立GPU雲端服務器

  1. 前往執行個體建立頁

  2. 選擇自訂購買頁簽。

  3. 按需選擇付費類型、地區、網路及可用性區域、執行個體規格、鏡像等配置。完成建立。有關各配置項詳細說明,請參見配置項說明

    重要

    OSS加速器功能目前在華東1(杭州)、華東2(上海)、華北2(北京)、華北6(烏蘭察布)、華南1(深圳)以及新加坡地區開放公測。請確保您所建立的GPU雲端服務器位於上述地區之一。本文將以華東1(杭州)地區為例進行說明。

    • 本次實踐ECS執行個體所採用規格為ecs.gn6i-c4g1.xlarge,僅供參考。

      在執行個體規格選擇頁面,單擊全部規格標籤頁,在搜尋方塊中輸入規格名稱,選中GPU 計算型 gn6i,該規格配置為 4 vCPU、15 GiB 記憶體、1 * NVIDIA T4(16 GB 顯存)。

    • 選擇作業系統鏡像以Ubuntu 22.04版本為例,並勾選安裝 GPU 驅動選擇CUDA版本為CUDA 版本 12.4.1,屆時伺服器啟動時會自動安裝CUDA環境,無需額外手動設定。

      同時 Driver 版本選擇 550.90.07,CUDNN 版本選擇 9.2.0.82

2. 串連GPU雲端服務器

  1. Elastic Compute Service控制台執行個體列表頁面,根據地區、執行個體ID找到建立好的ECS執行個體,單擊操作列下的遠端連線

  2. 遠程連接對話方塊中,單擊通過Workbench遠端連線對應的立即登錄

  3. 登入執行個體對話方塊中,選擇認證方式為您建立GPU雲端服務執行個體時所選擇的登入憑證方式,例如SSH密鑰認證,填寫使用者名稱,輸入或上傳建立金鑰組時下載的私密金鑰檔案,單擊登入,即可登入ECS執行個體。

    說明

    私密金鑰檔案在建立金鑰組時自動下載到本地,請您關注瀏覽器的下載記錄,尋找.pem格式的私密金鑰檔案。

  4. 顯示如下頁面後,說明您已成功登入ECS執行個體且CUDA驅動已開始自動安裝,只需等待安裝完成即可。

    Welcome to Alibaba Cloud Elastic Compute Service !
    Last login: Fri Dec 13 14:15:04 2024 from 100.104.86.0
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100    20  100    20    0     0    645      0 --:--:-- --:--:-- --:--:--   645
    CHECKING AUTO INSTALL, DRIVER VERSION=550.90.07 CUDA_VERSION=12.4.1 CUDNN VERSION=9.2.0.82 , INSTALL RDMA=FALSE, INSTALL eRDMA=FALSE, PLEASE WAIT ......
    The script automatically downloads and installs a NVIDIA GPU driver and CUDA, CUDNN library. if you choose install RDMA or ERDMA, RDMA or ERDMA software will install.
    if you choose install perseus, perseus environment will install as well.
    1. The installation takes 15 to 20 minutes, depending on the intranet bandwidth and the quantity of vCPU cores of the instance. Please do not operate the GPU or install any GPU-related software until the GPU driver is installed successfully.
    2. After the GPU is installed successfully, the instance will restarts automatically.
    CUDA-12.4.1 downloading, it takes 3 minutes or more. Remaining installation time 14 - 19 minutes!

步驟二:建立OSS Bucket並開通OSS加速器

以下步驟旨在與目標GPU雲端服務器同一地區下,建立一個用於儲存資料集的Bucket並開啟該BucketOSS加速器空間,以提高資料集的訪問速度。需注意,雲端服務器和Bucket處於同一地區且通過內網網域名稱訪問不會產生任何流量費用。

  1. 建立Bucket並擷取內網網域名稱

    重要

    OSS加速器功能目前在華東1(杭州)、華東2(上海)、華北2(北京)、華北6(烏蘭察布)、華南1(深圳)以及新加坡地區開放公測。請確保您建立的Bucket位於上述地區之一,並且與目標GPU雲端服務器處於同一地區。本文將以華東1(杭州)地區為例進行說明。

    1. 進入Object Storage Service控制台的Bucket列表頁面,單擊建立 Bucket

    2. 建立 Bucket面板,依據面板所給出的提示資訊來完成Bucket的建立工作。

    3. 在目標Bucket概覽頁面,訪問連接埠地區,複製ECS 的 VPC 網絡訪問(內網)Endpoint留作備用,以便在後續訓練時上傳資料集和checkpoint到目標Bucket。

  2. 開通OSS加速器並擷取加速器網域名稱

    1. 進入Object Storage Service控制台的Bucket列表頁面,選擇目標Bucket後在左側導覽列,選擇Bucket 配置 > OSS 加速器進入OSS 加速器頁面。

    2. 單擊建立OSS加速器,在建立OSS加速器面板設定加速器容量,本次實驗以配置500 GB為例。單擊下一步

    3. 選擇指定路徑加速,並配置加速路徑為資料集所在目錄後單擊確定,然後根據頁面指引完成加速器的建立。

      加速路徑填寫 dataset/,並勾選同步預熱。開啟同步預熱後,用戶端通過加速器網域名稱寫入的資料會同時寫入 OSS Bucket 和 OSS 加速器,再次讀取時可獲得更低延遲。

    4. OSS加速器介面複製加速器網域名稱留作備用,以便在後續訓練時用於從目標Bucket下載資料集。

步驟三:訓練模型

以下步驟旨在GPU雲端服務器上,完成模型訓練環境的配置、資料集的上傳,以及使用OSS加速器網域名稱來加速模型訓練。

說明
  • 完整代碼工程,請參見demo.tar.gz

  • 以下所有操作步驟均需要以root許可權執行,請在開始訓練前將系統切換至root使用者。

  1. 配置訓練環境

    1. 準備conda環境並配置依賴項。

      1. 執行以下命令,下載並安裝conda。

        curl -L https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -o /tmp/miniconda.sh && bash /tmp/miniconda.sh -b -p /opt/conda/ && rm /tmp/miniconda.sh && /opt/conda/bin/conda clean -tipy && export PATH=/opt/conda/bin:$PATH  && conda init bash && source ~/.bashrc && conda update conda 
      2. 執行vim environment.yaml命令,建立並開啟名為environment.yamlconda環境檔案,添加以下配置後儲存。

        name: py312
        channels:
          - defaults
          - conda-forge
          - pytorch
        dependencies:
          - python=3.12
          - pytorch>=2.5.0
          - torchvision 
          - torchaudio 
          - transformers 
          - torchdata
          - oss2
      3. 執行以下命令,基於conda環境檔案建立名為py312conda環境。

        conda env create -f environment.yaml
      4. 執行conda activate py312命令,啟用名為py312conda環境。即已成功啟用。

        重要

        後續的操作步驟,請在已啟用的conda環境中繼續進行。

    2. 配置環境變數。

      執行以下命令,配置上傳資料集時所需的訪問憑證。請注意,命令中的<ACCESS_KEY_ID><ACCESS_KEY_SECRET>請分別替換為RAM使用者的AccessKey ID、AccessKeySecret。有關如何建立AccessKey IDAccessKeySecret請參見建立AccessKey

      export OSS_ACCESS_KEY_ID=<ACCESS_KEY_ID>
      export OSS_ACCESS_KEY_SECRET=<ACCESS_KEY_SECRET>
    3. 配置OSS Connector。

      1. 執行以下命令,安裝OSS Connector。

        pip install osstorchconnector
      2. 執行以下命令,建立訪問憑證設定檔。

        mkdir -p /root/.alibabacloud && touch /root/.alibabacloud/credentials
      3. 執行vim /root/.alibabacloud/credentials命令,開啟設定檔添加如下配置並儲存。有關OSS Connector更多配置,請參見配置OSS Connector for AI/ML

        使用AccessKey IDAccessKey Secret作為訪問憑證的配置樣本,樣本中的<AccessKeyId><AccessKeySecret>請分別替換為RAM使用者的AccessKey ID、AccessKeySecret。如何建立AccessKey IDAccessKeySecret請參見建立AccessKey

        {
          "AccessKeyId": "LTAI************************",
          "AccessKeySecret": "At32************************"
        }
      4. 執行以下命令,設定credentials檔案唯讀許可權,以保障AK、SK密鑰安全。

        chmod 400 /root/.alibabacloud/credentials
      5. 執行以下命令,建立OSS Connector設定檔。

        mkdir -p /etc/oss-connector/ && touch /etc/oss-connector/config.json
      6. 執行vim /etc/oss-connector/config.json命令,開啟設定檔添加如下配置並儲存。正常情況下使用此預設配置即可。

        {
            "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
            }
        }
                        
  2. 準備資料

    1. 上傳訓練資料集和驗證資料集到目標Bucket。

      1. 執行以下命令下載訓練資料集和驗證資料集至雲端服務器。需注意,此資料集並非真實實驗情境所採用資料集,僅作測試用途。

        wget https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241216/jsnenr/n04487081.tar
        wget https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241218/dxrciv/n10148035.tar
        wget https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241216/senwji/val.tar
      2. 執行以下命令解壓下載好的資料集,並在當前路徑下建立dataset目錄將資料集放入其中。

        tar -zxvf n10148035.tar && tar -zxvf n04487081.tar && tar -zxvf val.tar
        mkdir dataset && mkdir ./dataset/train && mkdir ./dataset/val
        mv n04487081 ./dataset/train/ && mv n10148035 ./dataset/train/ && mv IL*.JPEG ./dataset/val/
      3. 執行python3 upload_dataset.py命令運行此指令碼,將解壓好的資料集上傳至指定的Bucket中。

        # upload_dataset.py
        from torchvision import transforms
        from PIL import Image
        import oss2
        import os
        from oss2.credentials import EnvironmentVariableCredentialsProvider
        # # 以杭州地區內網網域名稱為例
        OSS_ENDPOINT = "oss-cn-hangzhou-internal.aliyuncs.com"    #OSS內網訪問網域名稱 
        OSS_BUCKET_NAME = "<YourBucketName>"    #目標Bucket名稱 
        BUCKET_REGION = "cn-hangzhou"    #目標Bucket地區 
        # OSS_URI_BASE: 自訂OSS bucket中的儲存首碼
        OSS_URI_BASE = "dataset/imagenet/ILSVRC/Data"
        def to_tensor(img_path):
            IMG_DIM_224 = 224
            compose = transforms.Compose([
                    transforms.RandomResizedCrop(IMG_DIM_224),
                    transforms.RandomHorizontalFlip(),
                    transforms.ToTensor(),
                    transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
                ])
            img = Image.open(img_path).convert('RGB')
            img_tensor = compose(img)
            numpy_data = img_tensor.numpy()
            binary_data = numpy_data.tobytes()
            return binary_data
        def list_dir(directory):
            for root, _, files in os.walk(directory):
                rel_root = os.path.relpath(root, start=directory)
                for file in files:
                    rel_filepath = os.path.join(rel_root, file) if rel_root != '.' else file
                    yield rel_filepath
        IMG_DIR_BASE = "./dataset" 
        """
            IMG_DIR_BASE是本地存放圖片的路徑,絕對路徑或相對路徑都可以
            該路徑下結構應該和實際資料集結構一致,具體結構如下
            {IMG_DIR_BASE}/
                train/
                    n10148035/
                        n10148035_10034.JPEG
                        n10148035_10217.JPEG
                        ... 
                    n11879895/
                        n11879895_10016.JPEG
                        n11879895_10019.JPEG
                        ...
                    ...
                val/
                    ILSVRC2012_val_00000001.JPEG
                    ILSVRC2012_val_00000002.JPEG
                    ...
        """
        bucket_api = oss2.Bucket(oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider()), OSS_ENDPOINT, OSS_BUCKET_NAME, region=BUCKET_REGION)
        for phase in [ "val", "train"]:
            IMG_DIR = "%s/%s" % (IMG_DIR_BASE, phase)
            for _, img_relative_path in enumerate(list_dir(IMG_DIR)):
                img_bin_name = img_relative_path.replace(".JPEG", ".pt")
                object_key = "%s/%s/%s" % (OSS_URI_BASE, phase, img_bin_name)
                bucket_api.put_object(object_key, to_tensor("%s/%s" % (IMG_DIR,img_relative_path)))
    2. 下載映像資料集標籤檔案,用於構建資料集的分類映射關係。

      wget https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241220/izpskr/imagenet_class_index.json
      wget https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241220/lfilrp/ILSVRC2012_val_labels.json
  3. 訓練流程

    1. 構建用於處理ImageNet資料集的工具模組。該模組主要通過OSS加速器網域名稱,從OSS加速器空間下載資料集並構建dataloader。

      oss_dataloader.py

      # oss_dataloader.py
      import json
      import numpy as np
      from torch.utils.data import DataLoader
      import torch
      class ImageCls():
          def __init__(self):
              self.__syn_to_class = {}
              self.__syn_to_label = {}
              with open("imagenet_class_index.json", "rb") as f:
                  cls_list = json.load(f)
                  for cls, v in cls_list.items():
                      syn = v[0]
                      label = v[1]
                      self.__syn_to_class[syn] = int(cls)
                      self.__syn_to_label[int(cls)] = label
          def __len__(self):
              return len(self.__syn_to_label)
          def __getitem__(self, syn):
              cls = self.__syn_to_class[syn]
              return cls
      class ImageValSet():
          def __init__(self):
              self.__val_to_syn = {}
              with open("ILSVRC2012_val_labels.json", "rb") as f:
                  val_syn_list = json.load(f)
                  for val, syn in val_syn_list.items():
                      self.__val_to_syn[val] = syn
          def __getitem__(self, val):
              return self.__val_to_syn[val]
      imageCls = ImageCls()
      imageValSet = ImageValSet()
      IMG_DIM_224 = 224
      OSS_URI_BASE = "oss://<YourBucketName>/dataset/imagenet/ILSVRC/Data"
      # OSS加速器網域名稱, 用來下載資料集  請替換為目標OSS加速器空間網域名稱 
      ENDPOINT = "cn-hangzhou-j-internal.oss-data-acc.aliyuncs.com" 
      def obj_to_tensor(object):
          data = object.read()
          numpy_array_from_binary = np.frombuffer(data, dtype=np.float32).reshape([3, IMG_DIM_224, IMG_DIM_224])
          return torch.from_numpy(numpy_array_from_binary)
      def train_tensor_transform(object):
          tensor_from_binary = obj_to_tensor(object)
          key = object.key
          syn = key.split('/')[-2]
          return tensor_from_binary, imageCls[syn]
      def val_tensor_transform(object):
          tensor_from_binary = obj_to_tensor(object)
          key = object.key
          image_name = key.split('/')[-1].split('.')[0] + ".JPEG"
          return tensor_from_binary, imageCls[imageValSet[image_name]]
      def make_oss_dataloader(dataset, batch_size, num_worker, shuffle):
          image_datasets = {
              'train': dataset.from_prefix(OSS_URI_BASE + "/train/", endpoint=ENDPOINT, transform=train_tensor_transform),
              'val': dataset.from_prefix(OSS_URI_BASE + "/val/", endpoint=ENDPOINT, transform=val_tensor_transform),
          }
          dataloaders = {
              'train': DataLoader(image_datasets['train'], batch_size=batch_size, shuffle=shuffle, num_workers=num_worker),
              'val': DataLoader(image_datasets['val'], batch_size=batch_size, shuffle=shuffle, num_workers=num_worker)
          }
          return dataloaders
    2. 構建預訓練ResNet18模型初始化工具模組。

      pre_trained_model.py

      # pre_trained_model.py
      from torchvision import models
      import torch.nn as nn
      import torch
      def make_resnet_model(cls_count=1000):
          device = torch.device("cuda:0")
          model = models.resnet18(pretrained=True)
          num_ftrs = model.fc.in_features
          model.fc = nn.Linear(num_ftrs, cls_count)
          model = model.to(device)
          if torch.cuda.device_count() > 1:
              model = nn.DataParallel(model)
          return model, device
    3. 構建用於訓練ResNet模型的工具模組。該模組通過給定的模型(model)、資料載入器(dataloaders),以及訓練輪數(epoch_num)開展模型訓練工作。

      resnet_train.py

      # resnet_train.py
      from osstorchconnector import OssCheckpoint
      import torch.optim as optim
      import torch
      import torch.nn as nn
      OSS_CHECKPOINT_URI = "oss://<YourBucketName>/checkpoints/resnet18.pt"
      # OSS內網網域名稱 
      ENDPOINT = "oss-cn-hangzhou-internal.aliyuncs.com" 
      def train(model, dataloaders, device, epoch_num):
          optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)
          exp_lr_scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=7, gamma=0.1)
          criterion = nn.CrossEntropyLoss()
          best_acc = 0.0
          for epoch in range(epoch_num):
              for phase in ['train', 'val']:
                  if phase == 'train':
                      model.train()
                  else:
                      model.eval()
                  running_loss = 0.0
                  running_corrects = 0
                  # 遍曆資料
                  dataset_size = 0
                  for (inputs, labels) in dataloaders[phase]:
                      inputs = inputs.to(device)
                      labels = labels.to(device)
                      with torch.set_grad_enabled(phase == 'train'):
                          outputs = model(inputs)
                          _, preds = torch.max(outputs, 1)
                          loss = criterion(outputs, labels)
                          # 僅在訓練階段反向傳播和最佳化
                          if phase == 'train':
                              optimizer.zero_grad()
                              loss.backward()
                              optimizer.step()
                      # 統計
                      running_loss += loss.item() * inputs.size(0)
                      running_corrects += torch.sum(preds == labels.data)
                      dataset_size += inputs.size(0)
                  if phase == 'train':
                      exp_lr_scheduler.step()
                  epoch_loss = running_loss / dataset_size
                  epoch_acc = running_corrects / dataset_size
                  print(f'[Epoch {epoch}/{epoch_num - 1}][{phase}] {dataset_size} imgs {epoch_acc}')
                  if phase == 'val' and epoch_acc > best_acc:
                      best_acc = epoch_acc
                      # checkpoint上傳到OSS
                      checkpoint = OssCheckpoint(endpoint=ENDPOINT)
                      with checkpoint.writer(OSS_CHECKPOINT_URI) as checkpoint_writer:
                          torch.save(model.state_dict(), checkpoint_writer)
    4. 構建用於整合模型訓練流程的主指令檔。該檔案整合以上多個工具模組開啟模型訓練。

      main.py

      # main.py
      from oss_dataloader import make_oss_dataloader
      from pre_trained_model import make_resnet_model
      from osstorchconnector import OssMapDataset
      from resnet_train import train
      # 訓練基本參數
      NUM_EPOCHS = 30 # epoch number
      BATCH_SIZE = 64 # batch size
      NUM_WORKER = 4 # dataloader worker number
      # 使用預訓練的resnet18模型
      model, device = make_resnet_model()
      # 使用OssMapDataset資料集構造Dataloader
      dataloaders = make_oss_dataloader(OssMapDataset, BATCH_SIZE, NUM_WORKER, True)
      # 調用訓練主流程
      train(model, dataloaders, device, NUM_EPOCHS)
    5. 執行python3 main.py命令來開始模型訓練,如下所示,已成功啟動訓練流程。

      (py312) root@xxx :~# python3 main.py
      /opt/conda/envs/py312/lib/python3.12/site-packages/torchvision/models/_utils.py:208: UserWarning: The parameter 'pretrained' is deprecated since 0.13 and may be removed in the future, please use 'weights' instead.
        warnings.warn()
      /opt/conda/envs/py312/lib/python3.12/site-packages/torchvision/models/_utils.py:223: UserWarning: Arguments other than a weight enum or `None` for 'weights' are deprecated since 0.13 and may be removed in the future. The current behavior is equivalent to passing `weights=ResNet18_Weights.IMAGENET1K_V1`. You can also use `weights=ResNet18_Weights.DEFAULT` to get the most up-to-date weights.
        warnings.warn(msg)
      Downloading: "https://download.pytorch.org/models/resnet18-f37072fd.pth" to /root/.cache/torch/hub/checkpoints/resnet18-f37072fd.pth
      100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████| 44.7M/44.7M [00:10<00:00, 4.40MB/s]
      2024/12/20 13:36:34.853415| INFO |th=00000000000000000|dataset.cpp:222|new_oss_dataset:new oss dataset, uuid: 92251a5f-7f00-45b5-aaba-b8894ab15b0d id: 0, total: 1, pid: 20655, endpoint: cn-hangzhou-internal.oss-data-acc.aliyuncs.com
      2024/12/20 13:36:34.853437| INFO |th=00000000000000000|dataset.cpp:230|new_oss_dataset:[cred_path=/root/.alibabacloud/credentials][config_path=/etc/oss-connector/config.json]
      2024/12/20 13:36:34.853518| INFO |th=00000000000000000|dataset.cpp:255|new_oss_dataset:set log level: 1
      2024/12/20 13:36:34.853591| INFO |th=00000000000000000|dataset.cpp:262|new_oss_dataset:set log path: /var/log/oss-connector/connector_log_0
      /root/oss_dataloader.py:51: UserWarning: The given NumPy array is not writable, and PyTorch does not support non-writable tensors. This means writing to this tensor will result in undefined behavior. You may want to copy the array to protect its data or make it writable before converting it to a tensor. This type of warning will be suppressed for the rest of this program. (Triggered internally at /home/conda/feedstock_root/build_artifacts/libtorch_1733624414920/work/torch/csrc/utils/tensor_numpy.cpp:206.)
        return torch.from_numpy(numpy_array_from_binary)
      /root/oss_dataloader.py:51: UserWarning: The given NumPy array is not writable, and PyTorch does not support non-writable tensors. This means writing to this tensor will result in undefined behavior. You may want to copy the array to protect its data or make it writable before converting it to a tensor. This type of warning will be suppressed for the rest of this program. (Triggered internally at /home/conda/feedstock_root/build_artifacts/libtorch_1733624414920/work/torch/csrc/utils/tensor_numpy.cpp:206.)
        return torch.from_numpy(numpy_array_from_binary)
      /root/oss_dataloader.py:51: UserWarning: The given NumPy array is not writable, and PyTorch does not support non-writable tensors. This means writing to this tensor will result in undefined behavior. You may want to copy the array to protect its data or make it writable before converting it to a tensor. This type of warning will be suppressed for the rest of this program. (Triggered internally at /home/conda/feedstock_root/build_artifacts/libtorch_1733624414920/work/torch/csrc/utils/tensor_numpy.cpp:206.)
        return torch.from_numpy(numpy_array_from_binary)
  4. 結果驗證

    進入Bucket列表選擇目標Bucket,單擊文件管理 > 檔案清單後查看checkpoints目錄下的resnet18.pt檔案。訓練結束後checkpoint檔案已成功上傳至OSS。