OssIterableDataset は、OSS からオブジェクトを逐次的にストリーミング読み込みます。そのため、メモリが制限されている場合や、データセット全体をロードできないほど大規模な場合のトレーニングジョブに最適です。マップ形式のデータセットとは異なり、ランダムアクセスやワーカー間での並列シャッフリングには対応していません。
前提条件
開始する前に、以下の準備が完了していることを確認してください。
OSS Connector for AI/ML がインストール済みであること。詳細については、「OSS Connector for AI/ML のインストール」をご参照ください。
OSS Connector for AI/ML が構成済みであること。詳細については、「OSS Connector for AI/ML の構成」をご参照ください。
構築方法の選択
OssIterableDataset には、3 種類のファクトリメソッドが提供されています。ご使用のデータレイアウトに合ったものを選択してください。
| メソッド | 推奨用途 | 使用タイミング |
|---|---|---|
from_prefix | 共通のパスプレフィックス配下にあるオブジェクト | パス名が一貫した命名パターンに従っている場合 |
from_objects | 既知の、ばらばらに配置されたオブジェクトの一覧 | パスが明示的であるものの、バケット内に散在している場合 |
from_manifest_file | 非常に大規模なデータセット(数千万件のオブジェクト) | バケットでデータインデックスが有効化されており、データセットを頻繁にロードする場合。リスト API 呼び出しを繰り返さずに済むため、遅延と関連コストを削減できます |
データセットの構築
URI プレフィックスを用いたデータセットの構築
すべてのトレーニング用オブジェクトが OSS 内で共通のパスプレフィックスを共有している場合は、from_prefix を使用します。
from osstorchconnector import OssIterableDataset
ENDPOINT = "http://oss-cn-beijing-internal.aliyuncs.com"
CONFIG_PATH = "/etc/oss-connector/config.json"
CRED_PATH = "/root/.alibabacloud/credentials"
OSS_URI = "oss://ai-testset/EnglistImg/Img/BadImag/Bmp/Sample001/"
# URI プレフィックスからデータセットを構築します。プレフィックス配下のすべてのオブジェクトが含まれます。
iterable_dataset = OssIterableDataset.from_prefix(
OSS_URI,
endpoint=ENDPOINT,
cred_path=CRED_PATH,
config_path=CONFIG_PATH
)
# データセットを反復処理します。各アイテムは、key、size、read() メソッドを持つ DataObject です。
for item in iterable_dataset:
print(item.key) # オブジェクトキー(バケット内のパス)
print(item.size) # オブジェクトサイズ(バイト単位)
content = item.read()
print(len(content))URI 一覧からのデータセットの構築
特定のオブジェクト URI の一覧(異なるパスに散在していても可)が既知の場合は、from_objects を使用します。
from osstorchconnector import OssIterableDataset
ENDPOINT = "http://oss-cn-beijing-internal.aliyuncs.com"
CONFIG_PATH = "/etc/oss-connector/config.json"
CRED_PATH = "/root/.alibabacloud/credentials"
# uris は、1 つ以上の OSS URI を含む文字列イテレーターです。
uris = [
"oss://ai-testset/EnglistImg/Img/BadImag/Bmp/Sample001/img001-00001.png",
"oss://ai-testset/EnglistImg/Img/BadImag/Bmp/Sample001/img001-00002.png",
"oss://ai-testset/EnglistImg/Img/BadImag/Bmp/Sample001/img001-00003.png"
]
# URI 一覧からデータセットを構築します。
iterable_dataset = OssIterableDataset.from_objects(
uris,
endpoint=ENDPOINT,
cred_path=CRED_PATH,
config_path=CONFIG_PATH
)
# データセットを反復処理します。各アイテムは、key、size、read() メソッドを持つ DataObject です。
for item in iterable_dataset:
print(item.key)
print(item.size)
content = item.read()
print(len(content))マニフェストファイルからのデータセットの構築
データインデックスが有効化された大規模なデータセットでは、from_manifest_file を使用します。この方法では、実行時にリスト API を呼び出す代わりに、事前に作成されたマニフェストファイルからオブジェクト一覧を読み込むため、遅延と関連コストを削減できます。
ステップ 1:マニフェストファイルの作成
touch manifest_file を実行し、以下のいずれかのフォーマットで内容を記述してください。
オブジェクト名のみ:
Img/BadImag/Bmp/Sample001/img001-00001.png
Img/BadImag/Bmp/Sample001/img001-00002.png
Img/BadImag/Bmp/Sample001/img001-00003.pngオブジェクト名とラベルを含む:
Img/BadImag/Bmp/Sample001/img001-00001.png label1
Img/BadImag/Bmp/Sample001/img001-00002.png label2
Img/BadImag/Bmp/Sample001/img001-00003.png label3ステップ 2:データセットの構築
以下の例では、マニフェストファイル用の組み込みパーサである imagenet_manifest_parser を使用します。manifest_file_path には、ローカルパスと OSS URI の両方がサポートされています。
import io
from typing import Iterable, Tuple, Union
from osstorchconnector import OssIterableDataset
from osstorchconnector import imagenet_manifest_parser
ENDPOINT = "http://oss-cn-beijing-internal.aliyuncs.com"
CONFIG_PATH = "/etc/oss-connector/config.json"
CRED_PATH = "/root/.alibabacloud/credentials"
OSS_BASE_URI = "oss://ai-testset/EnglistImg/"
# オプション 1:ローカルパスからマニフェストファイルを読み込む。
# manifest_file_path: マニフェストファイルのローカルパス
# manifest_parser: 各行を (oss_uri, label) タプルに解析する関数
# oss_base_uri: マニフェスト内の相対パスに付加され、完全な OSS URI を形成するベース URI
MANIFEST_FILE_LOCAL = "/path/to/manifest_file.txt"
iterable_dataset = OssIterableDataset.from_manifest_file(
manifest_file_path=MANIFEST_FILE_LOCAL,
manifest_parser=imagenet_manifest_parser,
oss_base_uri=OSS_BASE_URI,
endpoint=ENDPOINT,
cred_path=CRED_PATH,
config_path=CONFIG_PATH
)
for item in iterable_dataset:
print(item.key)
print(item.size)
print(item.label)
content = item.read()
print(len(content))
# オプション 2:OSS URI からマニフェストファイルを読み込む。
MANIFEST_FILE_URI = "oss://manifest_fileai-testset/EnglistImg/manifest_file"
iterable_dataset = OssIterableDataset.from_manifest_file(
manifest_file_path=MANIFEST_FILE_URI,
manifest_parser=imagenet_manifest_parser,
oss_base_uri=OSS_BASE_URI,
endpoint=ENDPOINT,
cred_path=CRED_PATH,
config_path=CONFIG_PATH
)PyTorch DataLoader の作成
データセットを torch.utils.data.DataLoader に渡すことで、トレーニングループ内で利用できます。
import torch
from osstorchconnector import OssIterableDataset
ENDPOINT = "http://oss-cn-beijing-internal.aliyuncs.com"
CONFIG_PATH = "/etc/oss-connector/config.json"
CRED_PATH = "/root/.alibabacloud/credentials"
OSS_URI = "oss://ai-testset/EnglistImg/Img/BadImag/Bmp/Sample001/"
def transform(obj):
data = obj.read()
return obj.key, obj.label
iterable_dataset = OssIterableDataset.from_prefix(
OSS_URI,
endpoint=ENDPOINT,
transform=transform,
cred_path=CRED_PATH,
config_path=CONFIG_PATH
)
# 反復可能データセットを基盤とする DataLoader を作成します。
loader = torch.utils.data.DataLoader(
iterable_dataset,
batch_size=256,
num_workers=32,
prefetch_factor=2
)
# トレーニングループ内で loader を使用します。
for batch in loader:
# トレーニング操作を実行します。
...パラメーター
以下の表に、OssIterableDataset のすべてのパラメーターを示します。**共通**とマークされたパラメーターは、3 つのファクトリメソッドすべてで使用可能です。
共通パラメーター
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
endpoint | string | はい | バケットへのアクセスに使用する OSS エンドポイントです。詳細については、「リージョンとエンドポイント」をご参照ください。 |
cred_path | string | はい | 認証情報ファイルのパスです。デフォルト値:/root/.alibabacloud/credentials。詳細については、「アクセス認証情報の構成」をご参照ください。 |
config_path | string | はい | OSS Connector for AI/ML 構成ファイルのパスです。デフォルト値:/etc/oss-connector/config.json。詳細については、「OSS Connector for AI/ML の構成」をご参照ください。 |
transform | object | いいえ | DataObject が返される前に適用されるコール可能な関数です。指定しない場合、デフォルトの identity 関数が使用され、obj.copy() が返されます。 |
transform 関数から DataObject を直接返さないでください。イテレーターが失敗する可能性があります。代わりに、obj.copy() を使用してコピーを返すか、必要なデータ(たとえば、生のバイト列またはテンソル)を抽出してください。
メソッド固有のパラメーター
| パラメーター | メソッド | 型 | 必須 | 説明 |
|---|---|---|---|---|
oss_uri | from_prefix | string | はい | オブジェクトを選択するために使用する OSS URI プレフィックスです。oss:// で始める必要があります。 |
object_uris | from_objects | string | はい | 特定のオブジェクトを識別する 1 つ以上の OSS URI です。oss:// で始める必要があります。 |
manifest_file_path | from_manifest_file | string | はい | マニフェストファイルのパスです。ローカルファイルパスまたは oss:// で始まる OSS URI を指定できます。 |
manifest_parser | from_manifest_file | Callable Object | はい | マニフェストファイルを解析し、(oss_uri, label) タプルのイテレーターを返す関数です。組み込みの imagenet_manifest_parser を使用するか、カスタム実装を提供してください。詳細については、「manifest_parser」をご参照ください。 |
oss_base_uri | from_manifest_file | string | はい | マニフェスト内の相対パスに付加され、完全な OSS URI を形成するベース OSS URI です。マニフェストにすでに完全な URI が記載されている場合は、"" を指定してください。 |
組み込みメソッド
transform
データセットを反復処理する際、各 DataObject は返される前に transform 関数を経由します。
デフォルトメソッド
transform が指定されていない場合、以下の ID 関数が使用されます。
# デフォルトの transform:DataObject のコピーを返します。
def identity(obj: DataObject) -> DataObject:
if obj is not None:
return obj.copy()
else:
return Noneカスタムメソッド
前処理(たとえば、イメージのデコードおよび画素値の正規化)を適用するには、カスタム関数を渡します。
import sys
import io
import torchvision.transforms as transforms
from PIL import Image
from osstorchconnector import OssIterableDataset
ENDPOINT = "http://oss-cn-beijing-internal.aliyuncs.com"
CONFIG_PATH = "/etc/oss-connector/config.json"
CRED_PATH = "/root/.alibabacloud/credentials"
OSS_URI = "oss://ai-testset/EnglistImg/Img/BadImag/Bmp/Sample001/"
# イメージ前処理パイプラインを定義します。
trans = transforms.Compose([
transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])
# カスタム transform:イメージをデコードし、前処理を適用します。
# DataObject 自体ではなく、(tensor, label) タプルを返します。
def transform(obj):
try:
img = Image.open(io.BytesIO(obj.read())).convert('RGB')
val = trans(img)
except Exception as e:
raise e
return val, obj.label
iterable_dataset = OssIterableDataset.from_prefix(
OSS_URI,
endpoint=ENDPOINT,
transform=transform,
cred_path=CRED_PATH,
config_path=CONFIG_PATH
)manifest_parser
manifest_parser はマニフェストファイルを解析し、(oss_uri, label) タプルのイテレーターを返します。このイテレーターは from_manifest_file によって消費されます。
組み込みパーサをインポートします。
from osstorchconnector import imagenet_manifest_parser組み込み実装では、タブ区切りの各行が読み込まれます。2 つ以上のフィールドを持つ行は (key, label) を生成し、1 つのフィールドを持つ行は (key, '') を生成します。
def imagenet_manifest_parser(reader: io.IOBase) -> Iterable[Tuple[str, str]]:
lines = reader.read().decode("utf-8").strip().split("\n")
for i, line in enumerate(lines):
try:
items = line.strip().split('\t')
if len(items) >= 2:
key = items[0]
label = items[1]
yield (key, label)
elif len(items) == 1:
key = items[0]
yield (key, '')
else:
raise ValueError("format error")
except ValueError as e:
logging.error(f"Error: {e} for line {i}: {line}")異なるマニフェストフォーマットをサポートするには、同じシグネチャ(オープン済みのファイルライクオブジェクトを受け取り、(oss_uri, label) タプルのイテラブルを返す)を持つ関数を実装してください。
次のステップ
各データセットアイテムで利用可能なプロパティおよび I/O メソッドの詳細については、「OSS Connector for AI/ML のデータ型」をご参照ください。
コンテナ化されたトレーニング環境で OSS Connector for AI/ML を使用するには、「OSS Connector for AI/ML 環境を含む Docker イメージの構築」をご参照ください。