Créer et gérer des types d’instances pour une utilisation efficace des ressources de calcul
Les types d’instances sont un concept d’Azure Machine Learning qui permet de cibler certains types de nœuds de calcul pour les charges de travail d’apprentissage et d’inférence. Par exemple, dans une machine virtuelle Azure, un type d’instance est STANDARD_D2_V3
. Cet article vous apprend à créer et à gérer des types d’instance pour vos besoins de calcul.
Dans les clusters Kubernetes, les types d’instances sont représentés dans une définition de ressource personnalisée (CRD) qui est installée avec l’extension Azure Machine Learning. Deux éléments dans l’extension Azure Machine Learning représentent les types d’instances :
- Utilisez nodeSelector pour vous permettre de spécifier le nœud sur lequel un pod doit s’exécuter. Le nœud doit avoir une étiquette correspondante.
- Dans la section ressources, vous pouvez définir les ressources de calcul (processeur, mémoire et GPU NVIDIA) du pod.
Si vous spécifiez un champ nodeSelector lors du déploiement de l’extension Azure Machine Learning, le champ nodeSelector
sera appliqué à tous les types d’instance. Cela signifie que :
- Pour chaque type d’instance que vous créez, le champ
nodeSelector
spécifié doit être un sous-ensemble du champnodeSelector
spécifié par l’extension. - Si vous utilisez un type d’instance avec
nodeSelector
, la charge de travail s’exécute sur n’importe quel nœud correspondant à la fois au champnodeSelector
spécifié par l’extension et au champnodeSelector
spécifié par le type d’instance. - Si vous utilisez un type d’instance sans un champ
nodeSelector
, la charge de travail s’exécute sur n’importe quel nœud correspondant au champnodeSelector
spécifié par l’extension.
Créer un type d’instance par défaut
Par défaut, un type d’instance defaultinstancetype
est créé lorsque vous attachez un cluster Kubernetes à un espace de travail Azure Machine Learning. Voici la définition :
resources:
requests:
cpu: "100m"
memory: "2Gi"
limits:
cpu: "2"
memory: "2Gi"
nvidia.com/gpu: null
Si vous n’appliquez pas de champ nodeSelector
, le pod peut être planifié sur n’importe quel nœud. Des ressources par défaut sont affectées aux pods de la charge de travail avec 0,1 cœur de processeur, 2 Go de mémoire et 0 GPU pour la requête. Les ressources utilisées par les pods de la charge de travail sont limitées à 2 cœurs de processeur et à 8 Go de mémoire.
Le type d’instance par défaut utilise peu de ressources. Pour garantir que toutes les charges de travail de Machine Learning s’exécutent avec les ressources appropriées (par exemple, une ressource GPU), nous vous recommandons vivement de créer des types d’instance personnalisées.
Gardez à l’esprit les points suivants concernant le type d’instance par défaut :
defaultinstancetype
n’apparaît pas en tant que ressource personnaliséeInstanceType
dans le cluster lors de l’exécution de la commandekubectl get instancetype
, mais apparaît dans tous les clients (IU, Azure CLI, SDK).defaultinstancetype
peut être remplacé par la définition d’un type d’instance personnalisé portant le même nom.
Créer un type d’instance personnalisée
Pour créer un nouveau type d’instance, créez une ressource personnalisée pour le type d’instance CRD. Par exemple :
kubectl apply -f my_instance_type.yaml
Voici le contenu de my_instance_type_list.yaml :
apiVersion: amlarc.azureml.com/v1alpha1
kind: InstanceType
metadata:
name: myinstancetypename
spec:
nodeSelector:
mylabel: mylabelvalue
resources:
limits:
cpu: "1"
nvidia.com/gpu: 1
memory: "2Gi"
requests:
cpu: "700m"
memory: "1500Mi"
Le code précédent crée un type d’instance avec le comportement étiqueté :
- Les pods sont planifiés uniquement sur les nœuds avec l’étiquette
mylabel: mylabelvalue
. - Les demandes de ressources de
700m
pour le processeur et de1500Mi
pour la mémoire sont affectées aux pods. - Des limites de ressources de
1
pour le processeur, de2Gi
pour la mémoire et de1
pour GPU NVIDIA.
La création de types d’instance personnalisés doit répondre aux paramètres et règles de définition suivants, sinon elle échoue :
Paramètre | Obligatoire ou facultatif | Description |
---|---|---|
name |
Obligatoire | Valeurs de chaîne, qui doivent être uniques dans un cluster. |
CPU request |
Requis | Valeurs de chaîne, qui ne peuvent pas être zéro ou vides. Vous pouvez spécifier le processeur en millicœurs ; par exemple, 100m . Vous pouvez également le spécifier sous forme de nombres complets. Par exemple, "1" équivaut à 1000m . |
Memory request |
Requis | Valeurs de chaîne, qui ne peuvent pas être zéro ou vides. Vous pouvez indiquer la mémoire sous forme d’un nombre entier + suffixe, par exemple 1024Mi pour 1 024 mébioctets (Mio). |
CPU limit |
Requis | Valeurs de chaîne, qui ne peuvent pas être zéro ou vides. Vous pouvez spécifier le processeur en millicœurs ; par exemple, 100m . Vous pouvez également le spécifier sous forme de nombres complets. Par exemple, "1" équivaut à 1000m . |
Memory limit |
Requis | Valeurs de chaîne, qui ne peuvent pas être zéro ou vides. Vous pouvez indiquer la mémoire sous forme d’un nombre entier + suffixe, par exemple 1024Mi pour 1024 Mio. |
GPU |
Facultatif | Valeurs entières, qui ne peuvent être spécifiées que dans la section limits . Pour plus d’informations, consultez la documentation Kubernetes. |
nodeSelector |
Facultatif | Mappage des clés de chaîne et des valeurs. |
Il est également possible de créer plusieurs types d’instances à la fois :
kubectl apply -f my_instance_type_list.yaml
Voici le contenu de my_instance_type_list.yaml :
apiVersion: amlarc.azureml.com/v1alpha1
kind: InstanceTypeList
items:
- metadata:
name: cpusmall
spec:
resources:
requests:
cpu: "100m"
memory: "100Mi"
limits:
cpu: "1"
nvidia.com/gpu: 0
memory: "1Gi"
- metadata:
name: defaultinstancetype
spec:
resources:
requests:
cpu: "1"
memory: "1Gi"
limits:
cpu: "1"
nvidia.com/gpu: 0
memory: "1Gi"
L’exemple précédent crée deux types d’instances : cpusmall
et defaultinstancetype
. Cette définition defaultinstancetype
remplace la définition defaultinstancetype
créée lorsque vous avez attaché le cluster Kubernetes à l’espace de travail Azure Machine Learning.
Si vous soumettez une charge de travail de formation ou d’inférence sans type d’instance, elle utilise defaultinstancetype
. Pour spécifier un type d’instance par défaut pour un cluster Kubernetes, créez un type d’instance avec le nom defaultinstancetype
. C’est automatiquement reconnu comme valeur par défaut.
Sélectionner un type d’instance pour envoyer un travail de formation
Pour sélectionner un type d’instance pour un travail de formation à l’aide de l’interface Azure CLI (v2), spécifiez son nom dans le cadre de la section de propriétés resources
dans le YAML du travail. Par exemple :
command: python -c "print('Hello world!')"
environment:
image: library/python:latest
compute: azureml:<Kubernetes-compute_target_name>
resources:
instance_type: <instance type name>
Dans l’exemple précédent, remplacez par <Kubernetes-compute_target_name>
le nom de votre cible de calcul Kubernetes. Remplacez <instance type name>
par le nom du type d’instance que vous souhaitez sélectionner. Si vous ne spécifiez pas une propriété instance_type
, le système utilise defaultinstancetype
pour envoyer le travail.
Sélectionner le type d’instance pour déployer un modèle
Pour sélectionner un type d’instance pour un modèle de déploiement à l’aide de l’interface Azure CLI (v2), spécifiez son nom pour la propriété instance_type
dans le YAML de déploiement. Par exemple :
name: blue
app_insights_enabled: true
endpoint_name: <endpoint name>
model:
path: ./model/sklearn_mnist_model.pkl
code_configuration:
code: ./script/
scoring_script: score.py
instance_type: <instance type name>
environment:
conda_file: file:./model/conda.yml
image: mcr.microsoft.com/azureml/openmpi3.1.2-ubuntu18.04:latest
Dans l’exemple précédent, remplacez <instance type name>
par le nom du type d’instance que vous souhaitez sélectionner. Si vous ne spécifiez pas une propriété instance_type
, le système utilise defaultinstancetype
pour déployer le modèle.
Important
Pour le modèle de déploiement MLflow, la demande de ressource nécessite au moins 2 cœurs de processeur et 4 Go de mémoire. Si ce n'est pas le cas, le déploiement échouera.
Validation de la section de ressource
Vous pouvez utiliser la section resources
pour définir la demande de ressources et limiter vos modèles de déploiement. Par exemple :
name: blue
app_insights_enabled: true
endpoint_name: <endpoint name>
model:
path: ./model/sklearn_mnist_model.pkl
code_configuration:
code: ./script/
scoring_script: score.py
environment:
conda_file: file:./model/conda.yml
image: mcr.microsoft.com/azureml/openmpi3.1.2-ubuntu18.04:latest
resources:
requests:
cpu: "0.1"
memory: "0.2Gi"
limits:
cpu: "0.2"
#nvidia.com/gpu: 0
memory: "0.5Gi"
instance_type: <instance type name>
Si vous utilisez la section resources
, une définition de ressource valide doit répondre aux règles suivantes. Une définition de ressource non valide entraîne l’échec du déploiement de modèle.
Paramètre | Obligatoire ou facultatif | Description |
---|---|---|
requests: cpu: |
Obligatoire | Valeurs de chaîne, qui ne peuvent pas être zéro ou vides. Vous pouvez spécifier le processeur en millicœurs ; par exemple, 100m . Vous pouvez également le spécifier sous forme de nombres complets. Par exemple, "1" équivaut à 1000m . |
requests: memory: |
Requis | Valeurs de chaîne, qui ne peuvent pas être zéro ou vides. Vous pouvez indiquer la mémoire sous forme d’un nombre entier + suffixe, par exemple 1024Mi pour 1024 Mio. La mémoire ne peut pas être inférieure à 1 Mo. |
limits: cpu: |
Facultatif (obligatoire uniquement lorsque vous avez besoin de GPU) |
Valeurs de chaîne, qui ne peuvent pas être zéro ou vides. Vous pouvez spécifier le processeur en millicœurs ; par exemple, 100m . Vous pouvez également le spécifier sous forme de nombres complets. Par exemple, "1" équivaut à 1000m . |
limits: memory: |
Facultatif (obligatoire uniquement lorsque vous avez besoin de GPU) |
Valeurs de chaîne, qui ne peuvent pas être zéro ou vides. Vous pouvez indiquer la mémoire sous forme d’un nombre entier + suffixe, par exemple 1024Mi pour 1 024 Mio. |
limits: nvidia.com/gpu: |
Facultatif (obligatoire uniquement lorsque vous avez besoin de GPU) |
Valeurs entières, qui ne peuvent être vides et ne peuvent être spécifiées que dans la section limits . Pour plus d’informations, consultez la documentation Kubernetes. Si vous n’avez besoin que du processeur, vous pouvez omettre toute la section limits . |
Le type d’instance est requis pour le modèle de déploiement. Si vous avez défini la sectionresources
et qu’elle sera validée par rapport au type d’instance, les règles sont les suivantes :
- Avec une définition de la section
resource
valide, les limites des ressources doivent être inférieures aux limites de type d’instance. Dans le cas contraire, le déploiement échouera. - Si vous ne définissez pas un type d’instance, le système utilise
defaultinstancetype
pour la validation avec la sectionresources
. - Si vous ne définissez pas la section
resources
, le système utilise le type d’instance pour créer le déploiement.