Les produits PAI, tels que Deep Learning Containers (DLC) et Data Science Workshop (DSW), vous permettent de monter une source de données depuis Object Storage Service (OSS) vers un chemin spécifique dans un conteneur à l'aide d'ossfs 2.0 ou de JindoFuse d'Alibaba Cloud E-MapReduce. Vous pouvez également lire les données OSS en utilisant le connecteur OSS Connector for AI/ML ou le kit SDK OSS. Choisissez la méthode d'accès aux données la mieux adaptée à votre cas d'utilisation.
Contexte
Dans le développement de l'IA, les données sources sont souvent stockées dans OSS et téléchargées vers un environnement d'entraînement pour le développement et l'entraînement des modèles. Cependant, cette pratique courante présente plusieurs défis :
Les temps de téléchargement prolongés des jeux de données peuvent laisser les GPU inactifs.
Les données doivent être téléchargées à plusieurs reprises pour chaque tâche d'entraînement.
L'échantillonnage aléatoire des données nécessite le téléchargement de l'intégralité du jeu de données sur chaque nœud d'entraînement.
Pour résoudre ces problèmes, envisagez les méthodes suivantes pour lire les données OSS :
|
Méthode d'accès |
Description |
Cas d'utilisation |
|
Monte un jeu de données OSS vers un chemin spécifié dans un conteneur à l'aide du composant JindoFuse, permettant la lecture et l'écriture directes des données. |
|
|
|
ossfs 2.0 est un client offrant un accès monté haute performance à OSS. Il excelle dans les opérations de lecture et d'écriture séquentielles, vous permettant de tirer pleinement parti de la bande passante élevée d'OSS. |
ossfs 2.0 convient aux scénarios nécessitant un accès au stockage haute performance, tels que l'entraînement IA, l'inférence, le traitement du Big Data, la conduite autonome et autres charges de travail intensives en calcul. Ces charges de travail impliquent principalement des lectures séquentielles et aléatoires, des écritures séquentielles (ajout uniquement) et ne nécessitent pas la sémantique POSIX complète. |
|
|
PAI intègre le connecteur OSS Connector for AI/ML pour diffuser des fichiers depuis OSS directement dans le code PyTorch, simplifiant et accélérant l'accès aux données. Ses principaux avantages incluent :
|
Utilisez ce connecteur pour un accès non monté afin d'accélérer la lecture des jeux de données pour l'entraînement PyTorch, en particulier lors de la lecture de millions de petits fichiers ou lorsque le débit est élevé. |
|
|
Diffuse les données depuis OSS à l'aide du kit SDK OSS. Il offre une solution flexible et efficace, réduisant considérablement les temps de requête de données et améliorant l'efficacité de l'entraînement. |
Utilisez le kit SDK Python OSS ou l'API Python OSS pour un accès temporaire et non monté aux données OSS, ou lorsque la logique de votre application détermine quand accéder à OSS. |
Lorsque vous utilisez JindoFuse ou ossfs 2.0 pour monter OSS, vous pouvez spécifier un rôle RAM pour l'accès à OSS afin d'obtenir un contrôle des autorisations plus granulaire. Vous pouvez également activer l'option OSS Mount Requires RAM Role dans la configuration générale d'un espace de travail. Une fois cette option activée :
Lors de la création de montages OSS dans des fonctionnalités telles que DSW, DLC et EAS, vous devez sélectionner un rôle RAM. Le rôle RAM par défaut n'est pas autorisé.
Lors de la création d'un jeu de données avancé ou logique impliquant un montage OSS, le rôle RAM est également appliqué en fonction de cette configuration.
Lors de la création d'une instance DSW, d'une tâche DLC ou d'un service EAS, vous ne pouvez pas sélectionner le rôle PAI par défaut comme rôle RAM.
JindoFuse
DLC et DSW vous permettent d'utiliser le composant JindoFuse pour monter un jeu de données OSS ou un chemin OSS vers un chemin spécifié dans un conteneur. Cela vous permet de lire et d'écrire directement les données stockées dans OSS pendant le processus d'entraînement.
Méthodes de montage
DLC
Lors de la création d'une tâche d'entraînement distribué (DLC), vous pouvez monter des données OSS. Les deux types de montage suivants sont pris en charge. Pour des instructions de configuration détaillées, consultez Créer une tâche d'entraînement.
Dans les sections Datasets et Directly Mount, cliquez sur Expand Advanced Configuration pour afficher plus d'options de montage et utilisez le commutateur Read-Only pour contrôler le mode de montage.
|
Type de montage |
Description |
|
Datasets |
Sélectionnez un jeu de données de type OSS et configurez le Mount Path. Pour les jeux de données publics, seul le mode lecture seule est pris en charge. |
|
Directly Mount |
Montez directement un chemin de bucket OSS. Si vous utilisez un quota de ressource de calcul intelligent Lingjun avec la mise en cache locale activée, activez le commutateur Use Cache pour activer la mise en cache. |
DSW
Lors de la création d'une instance DSW, vous pouvez monter des données OSS. Les deux types de montage suivants sont pris en charge. Pour des instructions de configuration détaillées, consultez Créer une instance DSW.
Les deux types de montage offrent l'option Expand Advanced Configuration. Les types de stockage pris en charge par Storage Path Mounting incluent OSS, General-purpose NAS, Extreme NAS, CPFS et Intelligent Computing CPFS.
|
Type de montage |
Description |
|
Dataset Mounting |
Sélectionnez un jeu de données de type OSS et configurez le Mount Path. Lors de l'utilisation d'un jeu de données public, seul le mode lecture seule est pris en charge. |
|
Storage Path Mounting |
Montez directement un chemin de bucket OSS. |
Limitations de la configuration par défaut
Si vous laissez vides les paramètres Advanced Configurations, la configuration par défaut est appliquée. La configuration par défaut présente les limitations suivantes :
-
Pour accélérer la lecture des fichiers OSS, les métadonnées (répertoires et listes de fichiers) sont mises en cache lors du montage d'OSS.
Lors d'un entraînement distribué, si plusieurs nœuds tentent de créer le même répertoire, le cache de métadonnées peut amener chaque nœud à tenter la création. Un seul nœud réussira, tandis que les autres signaleront une erreur.
Par défaut, l'API OSS MultiPart est utilisée pour créer des fichiers. L'objet devient visible dans OSS uniquement après la fin des opérations d'écriture.
Les opérations de lecture et d'écriture simultanées sur le même fichier ne sont pas prises en charge.
Les opérations d'écriture aléatoire sur les fichiers ne sont pas prises en charge.
Configurations courantes de JindoFuse
Vous pouvez également personnaliser les paramètres JindoFuse dans la configuration avancée en fonction de votre cas d'utilisation.
Cette rubrique fournit des suggestions de configuration JindoFuse pour certains scénarios courants. Ces paramètres peuvent ne pas offrir des performances optimales pour toutes les charges de travail. Pour des options de configuration plus flexibles, consultez le Guide d'utilisation de JindoFuse .
-
Quick Read/write : garantit des lectures et écritures rapides. Cependant, des incohérences de données peuvent survenir lors de lectures ou d'écritures simultanées. Vous pouvez monter les données d'entraînement et les modèles sur le chemin de montage de ce mode. Nous vous recommandons de ne pas utiliser le chemin de montage de ce mode comme répertoire de travail.
{ "fs.oss.download.thread.concurrency": "Twice the number of CPU cores", "fs.oss.upload.thread.concurrency": "Twice the number of CPU cores", "fs.jindo.args": "-oattr_timeout=3 -oentry_timeout=0 -onegative_timeout=0 -oauto_cache -ono_symlink" } -
Incremental Read/Write : garantit la cohérence des données lors de l'écriture incrémentielle. Si les données d'origine sont écrasées, des incohérences de données peuvent survenir. La vitesse de lecture est légèrement plus lente. Vous pouvez utiliser ce mode pour enregistrer les fichiers de poids de modèle pour les données d'entraînement.
{ "fs.oss.upload.thread.concurrency": "Twice the number of CPU cores", "fs.jindo.args": "-oattr_timeout=3 -oentry_timeout=0 -onegative_timeout=0 -oauto_cache -ono_symlink" } -
Consistent Read/write : garantit la cohérence des données lors de lectures ou d'écritures simultanées et convient aux scénarios nécessitant une forte cohérence des données sans besoin de lectures rapides. Vous pouvez utiliser ce mode pour enregistrer le code de vos projets.
{ "fs.jindo.args": "-oattr_timeout=0 -oentry_timeout=0 -onegative_timeout=0 -oauto_cache -ono_symlink" } -
Read-only : autorise uniquement la lecture. Vous pouvez utiliser ce mode pour monter des jeux de données publics.
{ "fs.oss.download.thread.concurrency": "Twice the number of CPU cores", "fs.jindo.args": "-oro -oattr_timeout=7200 -oentry_timeout=7200 -onegative_timeout=7200 -okernel_cache -ono_symlink" }
Les autres opérations de configuration courantes incluent :
-
Sélectionner une version différente de JindoFuse :
{ "fs.jindo.fuse.pod.image.tag": "6.7.0" } -
Désactiver le cache de métadonnées : Lors de l'exécution d'un entraînement distribué où plusieurs nœuds tentent d'écrire simultanément dans le même répertoire, le cache peut provoquer l'échec des opérations d'écriture sur certains nœuds. Pour résoudre ce problème, ajoutez l'argument
-oattr_timeout=0 -oentry_timeout=0 -onegative_timeout=0à la ligne de commande JindoFuse.{ "fs.jindo.args": "-oattr_timeout=0 -oentry_timeout=0 -onegative_timeout=0" } -
Ajuster le nombre de threads de chargement/téléchargement : Ajustez le nombre de threads à l'aide des paramètres suivants.
{ "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" } -
Utiliser AppendObject pour les écritures : Tous les fichiers créés localement sur le montage sont créés en tant qu'objets dans OSS en appelant l'API
AppendObject. La taille d'un objet créé à l'aide d'AppendObject ne peut pas dépasser 5 Go. Pour plus de limites d'utilisation, consultez AppendObject. Voici un exemple de configuration :{ "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" } -
Monter OSS-HDFS : Pour savoir comment activer OSS-HDFS, consultez Qu'est-ce que le service OSS-HDFS ? Dans les scénarios d'entraînement distribué, nous vous recommandons d'ajouter les paramètres suivants :
{ "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" } -
Configurer les ressources mémoire : Vous pouvez définir le paramètre
fs.jindo.fuse.pod.mem.limitpour ajuster la limite de mémoire. Le code suivant fournit un exemple :{ "fs.jindo.fuse.pod.mem.limit": "10Gi" }
ossfs 2.0
Pour monter une source de données OSS à l'aide d'ossfs, définissez {"mountType":"ossfs"} dans Advanced Configuration.
Méthodes de montage
Montage d'OSS dans DLC
Lors de la création d'une tâche DLC, vous pouvez monter des données OSS. DLC prend en charge les deux types de montage suivants. Pour plus de détails sur la configuration, consultez Créer une tâche d'entraînement.
|
Type de montage |
Description |
|
Datasets |
Sélectionnez un jeu de données OSS et configurez le Mount Path. Les jeux de données publics ne sont accessibles qu'en lecture seule. |
|
Directly Mount |
Montez directement un chemin de stockage de bucket OSS. Si vous utilisez un quota de ressources Lingjun avec mise en cache locale activée, vous pouvez activer l'option Use Cache. |
Montage d'OSS dans DSW
Lors de la création d'une instance DSW, vous pouvez monter des données OSS. DSW prend en charge les deux types de montage suivants. Pour plus de détails sur la configuration, consultez Créer une instance DSW.
|
Type de montage |
Description |
|
Dataset Mounting |
Sélectionnez un jeu de données OSS et configurez le Mount Path. Les jeux de données publics ne sont accessibles qu'en lecture seule. |
|
Storage Path Mounting |
Montez directement un chemin de stockage de bucket OSS. |
Configurations ossfs courantes
Dans Advanced Configuration, vous pouvez définir des paramètres avancés à l'aide de fs.ossfs.args. Séparez plusieurs paramètres par une virgule (,). Pour plus d'informations sur ces paramètres avancés, consultez ossfs 2.0. Les exemples suivants illustrent plusieurs cas d'utilisation courants :
-
Source de données statique pendant la tâche : pour les fichiers qui ne sont pas modifiés pendant l'exécution de la tâche, configurez un délai d'expiration de cache long afin de réduire les requêtes de métadonnées. Ce scénario est typique lors de la lecture d'un lot de fichiers existants et de la génération d'un nouvel ensemble de fichiers après traitement.
{ "mountType":"ossfs", "fs.ossfs.args": "-oattr_timeout=7200" } -
Lecture/écriture rapide : utilisez un délai d'expiration de cache de métadonnées plus court pour équilibrer l'efficacité du cache et l'actualité des données.
{ "mountType":"ossfs", "fs.ossfs.args": "-oattr_timeout=3, -onegative_timeout=0" } -
Cohérence en lecture/écriture pour les tâches distribuées : par défaut, ossfs met à jour les données des fichiers en fonction du cache de métadonnées. Utilisez la configuration suivante pour garantir une vue cohérente sur plusieurs nœuds.
{ "mountType":"ossfs", "fs.ossfs.args": "-onegative_timeout=0, -oclose_to_open" } -
Erreur de mémoire insuffisante (OOM) due à un trop grand nombre de fichiers ouverts dans DLC ou DSW : une forte concurrence des tâches dans DLC et DSW peut entraîner l'ouverture simultanée de nombreux fichiers, provoquant potentiellement des erreurs OOM. La configuration suivante permet de réduire la pression sur la mémoire.
{ "mountType":"ossfs", "fs.ossfs.args": "-oreaddirplus=false, -oinode_cache_eviction_threshold=300000" } -
Échec de l'écriture de fichiers volumineux :
-oupload_buffer_sizedéfinit la taille du tampon (en octets) pour les téléchargements multiparties. Ce paramètre détermine la taille maximale du fichier pouvant être écrit, calculée comme suit : upload_buffer_size * 10 000.Par défaut, ossfs 2.0 utilise une taille de partie de 8 MiB, ce qui limite la taille maximale du fichier écrivable à 78,125 GiB. Si vous tentez d'écrire un fichier dépassant cette limite, l'opération échoue. Pour augmenter la taille de fichier maximale prise en charge, configurez l'option
-oupload_buffer_sizeafin d'augmenter la taille des parties. Par exemple, une taille de partie de 32 MiB (33 554 432 octets) permet de prendre en charge des fichiers jusqu'à 312,5 GiB. Notez qu'une valeur-upload_buffer_sizeplus élevée consomme davantage de mémoire. Vous pouvez contrôler l'utilisation de la mémoire en configurant-total_mem_limit. Pour plus d'informations, consultez Options de montage.{ "mountType":"ossfs", "fs.ossfs.args": "-oupload_buffer_size=33554432" }
OSS Connector for AI/ML
Le connecteur OSS Connector for AI/ML est une bibliothèque cliente développée par l'équipe Alibaba Cloud OSS pour les charges de travail d'intelligence artificielle et d'apprentissage automatique. Elle simplifie le chargement des données pour l'entraînement PyTorch à grande échelle, réduit le temps et la complexité des transferts de données, et accélère l'entraînement des modèles en éliminant les goulots d'étranglement liés au chargement des données. Afin de simplifier l'accès aux données, la plateforme PAI a intégré OSS Connector for AI/ML, ce qui vous permet de diffuser des données directement depuis OSS dans votre code PyTorch pour un chargement efficace.
Limites
Images officielles : OSS Connector for AI/ML est disponible uniquement dans les tâches DLC et les instances DSW utilisant une image officielle de PyTorch 2.0 ou version ultérieure.
-
Images personnalisées : Seules les versions PyTorch 2.0 ou ultérieures sont prises en charge. Pour les images personnalisées utilisant une version compatible, installez OSS Connector for AI/ML en exécutant la commande suivante :
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 Version Python : Seules les versions Python 3.8 à 3.12 sont prises en charge.
Prérequis
-
Configurez un fichier d'identifiants.
Vous pouvez configurer les identifiants de l'une des manières suivantes :
Configurez l'accès sans mot de passe à OSS pour votre tâche DLC. Pour plus d'informations, consultez Configurer un rôle RAM DLC. Avec cette méthode, la tâche DLC obtient un identifiant temporaire auprès de STS pour accéder de manière sécurisée à OSS et aux autres ressources cloud, éliminant ainsi le besoin d'informations d'authentification explicites et réduisant le risque de fuite de clés d'accès.
-
Configurez un fichier d'identifiants dans votre projet de code pour gérer les informations d'authentification. Le code suivant fournit un exemple de configuration :
RemarqueLe stockage des informations de clé d'accès en texte clair présente un risque de sécurité. Nous vous recommandons d'utiliser un rôle RAM pour configurer automatiquement les identifiants au sein d'une instance DLC. Pour plus d'informations, consultez Configurer un rôle RAM DLC.
Lorsque vous utilisez OSS Connector for AI/ML, vous pouvez spécifier le chemin d'accès au fichier d'identifiants afin de récupérer automatiquement les informations d'authentification nécessaires à la signature des demandes de données OSS.
{ "AccessKeyId": "<Access-key-id>", "AccessKeySecret": "<Access-key-secret>", "SecurityToken": "<Security-Token>", "Expiration": "2024-08-20T00:00:00Z" }Le tableau suivant décrit les champs.
Paramètre
Obligatoire
Description
Exemple
AccessKeyId
Oui
L'ID de clé d'accès et la clé d'accès secrète d'un compte Alibaba Cloud ou d'un utilisateur RAM.
RemarqueLorsque vous utilisez un identifiant temporaire de STS pour accéder à OSS, définissez ces paramètres sur l'ID de clé d'accès temporaire et la clé d'accès secrète temporaire.
NTS****
AccessKeySecret
Oui
7NR2****
SecurityToken
Non
Le jeton de sécurité de STS. Ce paramètre est requis uniquement lorsque vous utilisez un identifiant temporaire de STS pour accéder à OSS.
STS.6MC2****
Expiration
Non
La date d'expiration de l'identifiant. Si ce champ est vide, l'identifiant n'expire pas. OSS Connector for AI/ML relit le fichier d'identifiants lorsque l'identifiant expire.
2024-08-20T00:00:00Z
-
Configurez un fichier
config.json. Le code suivant fournit un exemple de configuration :Ce fichier sert à gérer les paramètres de votre projet, tels que les niveaux de simultanéité, les paramètres de préchargement et les emplacements des fichiers journaux. Lorsque vous utilisez OSS Connector for AI/ML, spécifiez le chemin d'accès à ce fichier
config.json. Le connecteur applique alors automatiquement vos paramètres configurés et écrit les journaux relatifs aux demandes de données OSS dans le fichier journal spécifié.{ "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 } }Le tableau suivant décrit les champs.
Paramètre
Obligatoire
Description
Exemple
logLevel
Oui
Le niveau de journalisation. La valeur par défaut est 1 (INFO). Valeurs valides :
-
0 : DEBUG
-
1 : INFO
-
2 : WARN
-
3 : ERROR
1
logPath
Oui
Le chemin d'accès au journal du connecteur. Le chemin par défaut est
/var/log/oss-connector/connector.log./var/log/oss-connector/connector.log
auditPath
Oui
Le journal d'audit pour les enregistrements d'E/S du connecteur consigne les demandes de lecture et d'écriture dont la latence est supérieure à 100 millisecondes. Le chemin par défaut est
/var/log/oss-connector/audit.log./var/log/oss-connector/audit.log
DatasetConfig
prefetchConcurrency
Oui
Le nombre de tâches simultanées pour le préchargement des données depuis OSS lors de l'utilisation d'un jeu de données. La valeur par défaut est 24.
24
prefetchWorker
Oui
Le nombre de vCPU disponibles pour le préchargement des données depuis OSS lors de l'utilisation d'un jeu de données. La valeur par défaut est 2.
2
checkpointConfig
prefetchConcurrency
Oui
Le nombre de tâches simultanées pour le préchargement des données depuis OSS lors de la lecture d'un point de contrôle. La valeur par défaut est 24.
24
prefetchWorker
Oui
Le nombre de vCPU disponibles pour le préchargement des données depuis OSS lors de la lecture d'un point de contrôle. La valeur par défaut est 4.
4
uploadConcurrency
Oui
Le nombre de tâches simultanées pour le téléchargement des données lors de l'écriture d'un point de contrôle. La valeur par défaut est 64.
64
-
Utilisation
Le connecteur OSS pour l'IA/ML met à disposition deux interfaces d'accès aux jeux de données, OssMapDataset et OssIterableDataset, qui étendent respectivement les interfaces Dataset et IterableDataset de PyTorch. L'interface OssIterableDataset est optimisée grâce au préchargement (prefetching) pour améliorer l'efficacité de l'entraînement. L'ordre de lecture des données avec OssMapDataset est déterminé par le DataLoader et prend en charge les opérations de mélange (shuffle). Choisissez l'interface d'accès aux données adaptée à votre scénario en suivant ces recommandations :
Si la mémoire disponible est limitée, que le jeu de données est volumineux et que seules des lectures séquentielles avec un faible niveau de parallélisme sont nécessaires, utilisez
OssIterableDataset.Si la mémoire est suffisante, que le jeu de données est de taille réduite et que vous avez besoin d'un accès aléatoire ainsi que d'un traitement parallèle, utilisez
OssMapDataset.
Le connecteur OSS pour l'IA/ML propose également l'interface OssCheckpoint pour le chargement et l'enregistrement des modèles. À ce jour, la fonctionnalité OssCheckpoint n'est disponible que dans les environnements disposant de ressources de calcul polyvalentes.
Les sections suivantes détaillent l'utilisation de ces trois interfaces.
OssMapDataset
Trois méthodes d'accès aux jeux de données sont prises en charge :
-
Accès à un dossier via un préfixe de chemin OSS
Il suffit de spécifier le nom du dossier sans avoir à configurer de fichier d'index, ce qui simplifie la maintenance et la montée en charge. Privilégiez cette méthode si votre dossier OSS présente la structure suivante :
dataset_folder/ ├── class1/ │ ├── image1.JPEG │ └── ... ├── class2/ │ ├── image2.JPEG │ └── ...Lorsque vous utilisez cette méthode, vous devez indiquer un préfixe de chemin OSS et définir une méthode personnalisée pour analyser le flux de fichiers. L'exemple ci-dessous illustle l'analyse et la transformation des fichiers image :
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 # File name 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) -
Accès aux fichiers depuis un fichier manifeste
Cette méthode permet d'accéder aux données stockées dans plusieurs buckets OSS, offrant ainsi une gestion des données plus flexible. Utilisez-la si votre dossier OSS est structuré comme ci-dessous et si vous disposez d'un fichier manifeste associant les noms de fichiers à leurs libellés.
dataset_folder/ ├── class1/ │ ├── image1.JPEG │ └── ... ├── class2/ │ ├── image2.JPEG │ └── ... └── .manifestLe fichier manifeste respecte le format suivant :
{'data': {'source': 'oss://examplebucket.oss-cn-wulanchabu.aliyuncs.com/dataset_folder/class1/image1.JPEG'}} {'data': {'source': ''}}Avec cette approche, il est nécessaire de définir une méthode personnalisée pour analyser le fichier manifeste. Voici un exemple de code :
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) -
Accès aux fichiers depuis une liste d'URI OSS
Vous pouvez accéder aux fichiers OSS en spécifiant leurs URI sans avoir besoin de configurer de fichier d'index. L'exemple de code suivant montre comment procéder :
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
L'interface OssIterableDataset prend en charge les mêmes trois méthodes d'accès aux jeux de données que OssMapDataset. Les exemples suivants montrent comment utiliser chacune de ces méthodes :
-
Accès à un dossier via un préfixe de chemin OSS
dataset = OssIterableDataset.from_prefix("{oss_data_folder_uri}", endpoint="{oss_endpoint}", transform=read_and_transform, cred_path=cred_path, config_path=config_path) -
Accès aux fichiers depuis un fichier manifeste
dataset = OssIterableDataset.from_manifest_file("{manifest_file_path}", manifest_parser, "", endpoint=endpoint, transform=read_and_trans, cred_path=cred_path, config_path=config_path) -
Accès aux fichiers depuis une liste d'URI OSS
dataset = OssIterableDataset.from_objects(uris, endpoint=endpoint, transform=read_and_trans, cred_path=cred_path, config_path=config_path)
OssCheckpoint
Actuellement, la fonctionnalité OssCheckpoint n'est disponible que dans les environnements disposant de ressources de calcul polyvalentes. L'interface OssCheckpoint permet d'accéder aux fichiers de modèle dans OSS et de les y enregistrer. Le code suivant illustre son utilisation :
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)
Exemple de code
L'exemple de code complet ci-dessous montre comment utiliser le connecteur OSS pour l'IA/ML afin d'accéder aux données stockées dans OSS :
from osstorchconnector import OssMapDataset, OssCheckpoint
import torchvision.transforms as transforms
import accimage
import torchvision.models as models
import torch
# The default credential path after you configure a RAM role for a DLC job or DSW instance.
cred_path = "/mnt/.alibabacloud/credentials"
config_path = "config.json"
checkpoint = OssCheckpoint(endpoint="{oss_endpoint}", cred_path=cred_path, config_path=config_path)
model = models.__dict__["resnet18"]()
epochs = 100 # Specify the number of epochs.
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)
Points clés de cet exemple :
Créez un jeu de données avec
OssMapDatasetdirectement à partir de l'URI OSS fournie, en suivant le modèle standardDataLoaderde PyTorch.Utilisez ce jeu de données pour créer un
DataLoaderPyTorch standard, puis exécutez une boucle d'entraînement classique pour traiter chaque lot, entraîner le modèle et enregistrer les points de contrôle.Cela permet un chargement à la demande, supprimant ainsi la nécessité de monter le jeu de données dans l'environnement du conteneur ou de le télécharger préalablement sur le stockage local.
SDK OSS
SDK Python OSS
Utilisez le SDK Python OSS pour lire et écrire des données dans OSS :
Installez le SDK Python OSS. Pour plus d'informations, consultez la rubrique Installation (Python SDK V1).
Configurez les identifiants d'accès pour le SDK Python OSS. Pour plus d'informations, consultez la rubrique Configure access credentials (Python SDK V1).
-
Lisez et écrivez des données dans OSS.
# -*- coding: utf-8 -*- import oss2 from oss2.credentials import EnvironmentVariableCredentialsProvider # Configure access credentials using the RAM user access key from environment variables. auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider()) bucket = oss2.Bucket(auth, '<Endpoint>', '<your_bucket_name>') # Read a complete file. result = bucket.get_object('<your_file_path/your_file>') print(result.read()) # Read data by range. result = bucket.get_object('<your_file_path/your_file>', byte_range=(0, 99)) # Write data to OSS. bucket.put_object('<your_file_path/your_file>', '<your_object_content>') # Append data to an appendable file. 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>')Modifiez les paramètres suivants selon vos besoins :
Paramètre
Description
<Endpoint>
Endpoint de la région de votre bucket. Par exemple, pour la région Chine (Hangzhou), définissez l'endpoint sur https://oss-cn-hangzhou.aliyuncs.com. Pour savoir comment obtenir un endpoint, consultez la rubrique Regions and endpoints.
<your_bucket_name>
Nom de votre bucket.
<your_file_path/your_file>
Chemin du fichier à lire ou à écrire. Indiquez le chemin complet de l'objet, sans inclure le nom du bucket. Exemple :
testfolder/exampleobject.txt.<your_object_content>
Contenu à écrire ou à ajouter. Adaptez selon vos besoins.
API Python OSS
Vous pouvez utiliser l'API Python OSS pour stocker facilement vos données d'entraînement et vos modèles dans OSS. Avant de commencer, assurez-vous d'avoir installé le SDK Python OSS et configuré vos identifiants d'accès. Pour plus d'informations, consultez les rubriques Installation (Python SDK V1) et Configure access credentials (Python SDK V1).
-
Chargement des données d'entraînement
Stockez vos données dans un bucket OSS, les chemins d'accès aux données et les libellés correspondants étant inscrits dans un fichier d'index situé dans le même bucket. En créant un Dataset personnalisé, vous pouvez utiliser l'API
DataLoaderde PyTorch pour lire les données en parallèle via plusieurs processus. Voici un exemple de code.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 # Obtain access credentials from environment variables. Before you run this code sample, # make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are set. 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)Ce tableau décrit les principaux paramètres.
Paramètre
Description
endpoint
Endpoint de la région de votre bucket. Par exemple, pour la région Chine (Hangzhou), définissez l'endpoint sur https://oss-cn-hangzhou.aliyuncs.com. Pour savoir comment obtenir un endpoint, consultez la rubrique Regions and endpoints.
bucket
Nom de votre bucket.
index_file
Chemin du fichier d'index.
RemarqueDans l'exemple, le fichier d'index utilise une virgule (,) pour séparer chaque échantillon et deux-points (:) pour séparer le chemin de l'échantillon du libellé.
-
Enregistrement ou chargement des modèles
Utilisez l'API Python OSS pour enregistrer ou charger des modèles PyTorch. Pour plus d'informations sur l'enregistrement et le chargement des modèles dans PyTorch, consultez la documentation PyTorch. Les exemples de code suivants illustrent ces opérations :
-
Enregistrement d'un modèle
from io import BytesIO import torch import oss2 from oss2.credentials import EnvironmentVariableCredentialsProvider auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider()) # bucket_name 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())Où :
endpoint correspond à l'endpoint de la région de votre bucket. Par exemple, pour la région Chine (Hangzhou), définissez l'endpoint sur https://oss-cn-hangzhou.aliyuncs.com.
<your_bucket_name> représente le nom du bucket OSS, sans le préfixe oss://.
<your_model_path> indique le chemin du modèle. Adaptez selon vos besoins.
-
Chargement d'un modèle
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))Où :
endpoint correspond à l'endpoint de la région de votre bucket. Par exemple, pour la région Chine (Hangzhou), définissez l'endpoint sur https://oss-cn-hangzhou.aliyuncs.com.
<your_bucket_name> représente le nom du bucket OSS, sans le préfixe oss://.
<your_model_path> indique le chemin du modèle. Adaptez selon vos besoins.
-