Utilisez le composant Script Python dans Machine Learning Designer pour installer les packages de dépendance et exécuter des fonctions Python personnalisées.
Localiser le composant
Le composant Python Script se trouve dans le dossier UserDefinedScript de la liste des composants de Machine Learning Designer.
Prérequis
Accordez les autorisations DLC. Dépendances et autorisations des services cloud : DLC.
Le composant Script Python s'exécute sur les ressources de calcul DLC. Associez les ressources de calcul DLC à votre espace de travail. Gérer les espaces de travail.
-
Le composant Script Python stocke le code dans OSS. Créez un bucket OSS. Créer un bucket.
ImportantLe bucket OSS doit se trouver dans la même région que Machine Learning Designer et DLC.
L'utilisateur RAM doit disposer du rôle Algorithm Development dans l'espace de travail. Gérer les membres de l'espace de travail. Pour utiliser MaxCompute comme source de données, attribuez également le rôle MaxCompute Developer.
Configurer le composant
-
Ports d'entrée
Le composant Script Python dispose de quatre ports d'entrée. Connectez-les aux données provenant d'un chemin OSS ou d'une table MaxCompute.
-
Entrée de chemin OSS
L'entrée depuis le chemin OSS d'un composant en amont est montée sur le nœud où le script s'exécute. Le système transmet le chemin du fichier monté en tant qu'argument. Par exemple,
--input1 /ml/input/data/input1spécifie le chemin pour le premier port d'entrée. Lisez les fichiers montés depuis/ml/input/data/input1comme des fichiers locaux dans votre script. -
Entrée de table MaxCompute
Les entrées de table MaxCompute ne sont pas montées. Le système transmet les informations de la table sous forme d'argument URI. Par exemple,
python main.py --input1 odps://some-project-name/tables/tableindique la table MaxCompute pour le premier port d'entrée. Utilisez la fonctionparse_odps_urldu modèle de code pour analyser les métadonnées telles que ProjectName, TableName et Partition. Exemples d'utilisation.
-
-
Ports de sortie
Le composant Script Python dispose de quatre ports de sortie. OSS Output Port 1 et OSS Output Port 2 envoient les résultats vers des chemins OSS. Table Output Port 1 et Table Output Port 2 envoient les résultats vers des tables MaxCompute.
-
Sortie de chemin OSS
Le chemin OSS configuré pour Job output path dans l'onglet Code Config est monté sur
/ml/output/. OSS Output Port 1 et OSS Output Port 2 correspondent respectivement à/ml/output/output1et/ml/output/output2. Écrivez les fichiers dans ces répertoires dans votre script pour les transmettre aux composants en aval. -
Sortie de table MaxCompute
Si l'espace de travail dispose d'un projet MaxCompute, le système transmet un URI de table temporaire au script, par exemple :
python main.py --output3 odps://<some-project-name>/tables/<output-table-name>. Utilisez PyODPS pour créer cette table et y écrire les données, puis transmettez-la aux composants en aval via les connexions.
-
-
Paramètres
Code Config
Paramètre
Description
Job output path
Chemin OSS pour la sortie du job.
-
Le répertoire OSS configuré est monté sur
/ml/output/dans le conteneur du job. Les données écrites dans/ml/output/sont persistées dans le répertoire OSS correspondant. -
Les ports de sortie OSS Output-1 et OSS Output-2 correspondent aux sous-chemins
output1etoutput2sous/ml/output/. Lorsqu'un port de sortie OSS est connecté à un composant en aval, ce dernier reçoit les données du sous-chemin correspondant.
Source du code
(Choisissez une option)
Literal code
-
Python code : Chemin OSS où le code est enregistré. Le code saisi dans l'éditeur est enregistré à cet emplacement. Le nom de fichier par défaut est
main.py.ImportantAvant de cliquer sur Save pour la première fois, assurez-vous que le chemin OSS spécifié ne contient pas de fichier portant le même nom. Sinon, le fichier existant sera écrasé.
-
Éditeur de code Python : L'éditeur fournit un exemple de code par défaut. Exemples d'utilisation. Saisissez votre code directement dans l'éditeur.
Specify Git configuration
-
Git repository address : Adresse du dépôt Git.
-
Code branch : Branche du code. La valeur par défaut est master.
-
Code commit : ID du commit. Cette option est prioritaire sur la branche. Si elle est spécifiée, le paramètre de branche est ignoré.
-
Git username : Requis si vous devez accéder à un dépôt privé.
-
Git access token : Requis pour accéder à un dépôt de code privé. Annexe : Obtenir un jeton de compte GitHub.
Select code source
-
Select code source repositories : Sélectionnez une configuration de code créée. Configurations de code.
-
Code branch : Branche du code. La valeur par défaut est master.
-
Code commit : ID du commit. Cette option est prioritaire sur la branche. Si elle est spécifiée, le paramètre de branche est ignoré.
Select OSS path
Dans le champ OSS Code Path, sélectionnez le chemin où le code a été téléchargé.
Command
Commande à exécuter, telle que
python main.py.RemarqueLe système génère la commande d'exécution en fonction du nom du script et des connexions de port. Aucune configuration manuelle n'est requise.
Advanced option
-
Third-party dependencies : Spécifiez les bibliothèques tierces au format Python
requirements.txt. Le système installe ces bibliothèques avant l'exécution du nœud.cycler==0.10.0 # via matplotlib kiwisolver==1.2.0 # via matplotlib matplotlib==3.2.1 numpy==1.18.5 pandas==1.0.4 pyparsing==2.4.7 # via matplotlib python-dateutil==2.8.1 # via matplotlib, pandas pytz==2020.1 # via pandas scipy==1.4.1 # via seaborn -
Enable container monitoring : Affiche une zone de texte de configuration pour les paramètres de surveillance de la tolérance aux pannes.
Run Config
Paramètre
Description
Select Resource Group
Sélectionnez un groupe de ressources DLC :
-
Pour un groupe de ressources public, configurez InstanceType. Sélectionnez une instance CPU ou GPU. Valeur par défaut :
ecs.c6.large.
Par défaut, le groupe de ressources cloud-native DLC par défaut de l'espace de travail actuel est utilisé.
VPC Settings
Sélectionnez un Virtual Private Cloud (VPC) existant.
Security Group
Sélectionnez un groupe de sécurité existant.
Advanced option
Si vous sélectionnez cette option, configurez les paramètres suivants :
-
Instance count : Nombre d'instances. La valeur par défaut est 1.
-
Job image URI : URI de l'image du job. L'image par défaut utilise XGBoost 1.6.0. Modifiez l'image si vous avez besoin d'un framework de deep learning.
-
Job type : Modifiez ce paramètre uniquement si votre code est conçu pour une exécution distribuée. Valeurs prises en charge :
-
XGBoost/LightGBM Job
-
TensorFlow Job
-
PyTorch Job
-
MPI Job
-
-
Exemples d'utilisation
Exemple de code par défaut
Le composant Script Python fournit l'exemple de code suivant par défaut.
import os
import argparse
import json
"""
Sample code for the Python Script component
"""
# Default MaxCompute execution environment in the current workspace, which includes the MaxCompute project name and endpoint.
# This environment is injected only when a MaxCompute project exists in the current workspace.
# Example: {"endpoint": "http://service.cn.maxcompute.aliyun-inc.com/api", "odpsProject": "lq_test_mc_project"}.
ENV_JOB_MAX_COMPUTE_EXECUTION = "JOB_MAX_COMPUTE_EXECUTION"
def init_odps():
from odps import ODPS
# Information about the default MaxCompute project in the current workspace.
mc_execution = json.loads(os.environ[ENV_JOB_MAX_COMPUTE_EXECUTION])
o = ODPS(
access_id="<YourAccessKeyId>",
secret_access_key="<YourAccessKeySecret>",
# Select the endpoint based on the region where your project is located, for example: http://service.cn-shanghai.maxcompute.aliyun-inc.com/api.
endpoint=mc_execution["endpoint"],
project=mc_execution["odpsProject"],
)
return o
def parse_odps_url(table_uri):
from urllib import parse
parsed = parse.urlparse(table_uri)
project_name = parsed.hostname
r = parsed.path.split("/", 2)
table_name = r[2]
if len(r) > 3:
partition = r[3]
else:
partition = None
return project_name, table_name, partition
def parse_args():
parser = argparse.ArgumentParser(description="PythonV2 component script example.")
parser.add_argument("--input1", type=str, default=None, help="Component input port 1.")
parser.add_argument("--input2", type=str, default=None, help="Component input port 2.")
parser.add_argument("--input3", type=str, default=None, help="Component input port 3.")
parser.add_argument("--input4", type=str, default=None, help="Component input port 4.")
parser.add_argument("--output1", type=str, default=None, help="Output OSS port 1.")
parser.add_argument("--output2", type=str, default=None, help="Output OSS port 2.")
parser.add_argument("--output3", type=str, default=None, help="Output MaxComputeTable 1.")
parser.add_argument("--output4", type=str, default=None, help="Output MaxComputeTable 2.")
args, _ = parser.parse_known_args()
return args
def write_table_example(args):
# Example: Execute an SQL statement to copy data from a public table provided by PAI to the temporary table specified for Table Output Port 1 (--output3).
output_table_uri = args.output3
o = init_odps()
project_name, table_name, partition = parse_odps_url(output_table_uri)
o.run_sql(f"create table {project_name}.{table_name} as select * from pai_online_project.heart_disease_prediction;")
def write_output1(args):
# Example: Write data results to the mounted OSS path (subdirectory for OSS Output Port 1), and results can be passed to downstream components through connections.
output_path = args.output1
os.makedirs(output_path, exist_ok=True)
p = os.path.join(output_path, "result.text")
with open(p, "w") as f:
f.write("TestAccuracy=0.88")
if __name__ == "__main__":
args = parse_args()
print("Input1={}".format(args.input1))
print("Output1={}".format(args.output1))
# write_table_example(args)
# write_output1(args)
Description des fonctions courantes :
-
init_odps(): Initialise une instance ODPS pour lire les données de la table MaxCompute. Indiquez vos AccessKeyId et AccessKeySecret. Obtenir une paire de clés AccessKey. parse_odps_url(table_uri): Analyse l'URI de la table MaxCompute en entrée et renvoie le nom du projet, le nom de la table et la partition. Le format detable_uriestodps://${your_projectname}/tables/${table_name}/${pt_1}/${pt_2}/, par exemple,odps://test/tables/iris/pa=1/pb=1, oùpa=1/pb=1représente une partition multiniveau.parse_args(): Analyse les arguments transmis au script. Les données d'entrée et de sortie sont transmises au script exécuté sous forme d'arguments.
Exemple 1 : Chaînage avec d'autres composants
Cet exemple modifie le modèle de prédiction des maladies cardiaques pour illustrer l'utilisation du composant Script Python avec d'autres composants de Machine Learning Designer. Configuration du pipeline :
Créez un pipeline à partir du modèle de prédiction des maladies cardiaques et ouvrez-le. Prédiction des maladies cardiaques.
-
Faites glisser le composant Script Python vers le canevas, renommez-le
SMOTEet configurez le code suivant.ImportantLa bibliothèque
imblearnn'est pas incluse dans l'image par défaut. Ajoutezimblearndans le champ Third-party dependencies de l'onglet Code Config. La bibliothèque sera installée automatiquement avant l'exécution du nœud.import argparse import json import os from odps.df import DataFrame from imblearn.over_sampling import SMOTE from urllib import parse from odps import ODPS ENV_JOB_MAX_COMPUTE_EXECUTION = "JOB_MAX_COMPUTE_EXECUTION" def init_odps(): # Information about the default MaxCompute project in the current workspace. mc_execution = json.loads(os.environ[ENV_JOB_MAX_COMPUTE_EXECUTION]) o = ODPS( access_id="<Your_AccessKeyId>", secret_access_key="<Your_AccessKeySecret>", # Select the endpoint based on the region where your project is located, for example: http://service.cn-shanghai.maxcompute.aliyun-inc.com/api. endpoint=mc_execution["endpoint"], project=mc_execution["odpsProject"], ) return o def get_max_compute_table(table_uri, odps): parsed = parse.urlparse(table_uri) project_name = parsed.hostname table_name = parsed.path.split('/')[2] table = odps.get_table(project_name + "." + table_name) return table def run(): parser = argparse.ArgumentParser(description='PythonV2 component script example.') parser.add_argument( '--input1', type=str, default=None, help='Component input port 1.' ) parser.add_argument( '--output3', type=str, default=None, help='Component input port 1.' ) args, _ = parser.parse_known_args() print('Input1={}'.format(args.input1)) print('output3={}'.format(args.output3)) o = init_odps() imbalanced_table = get_max_compute_table(args.input1, o) df = DataFrame(imbalanced_table).to_pandas() sm = SMOTE(random_state=2) X_train_res, y_train_res = sm.fit_resample(df, df['ifhealth'].ravel()) new_table = o.create_table(get_max_compute_table(args.output3, o).name, imbalanced_table.schema, if_not_exists=True) with new_table.open_writer() as writer: writer.write(X_train_res.values.tolist()) if __name__ == '__main__': run()Remplacez <Your_AccessKeyId> et <Your_AccessKeySecret> par vos propres valeurs. Obtenir une paire de clés AccessKey.
Connectez le composant SMOTE en aval du composant Split. SMOTE effectue un suréchantillonnage des données d'entraînement pour équilibrer la distribution des classes en créant des échantillons synthétiques pour la classe minoritaire.
Connectez les nouvelles données du composant SMOTE au composant Logistic Regression for Binary Classification pour l'entraînement.
-
Connectez le modèle entraîné aux mêmes composants de prédiction et d'évaluation des données que la branche de gauche pour une comparaison côte à côte. Une fois le composant exécuté, cliquez sur l'icône de visualisation (
) pour afficher les résultats de l'évaluation.Les résultats de l'évaluation du modèle indiquent que l'Binary Classification Evaluation sans suréchantillonnage présente une ROC AUC de
0.924, avec une matrice de confusion de vrai-0/prédit-0 : 43, vrai-0/prédit-1 : 6, vrai-1/prédit-0 : 9, vrai-1/prédit-1 : 33. L'Binary Classification Evaluation-2 avec suréchantillonnage SMOTE affiche une ROC AUC de0.917, avec une matrice de confusion de vrai-0/prédit-0 : 41, vrai-0/prédit-1 : 8, vrai-1/prédit-0 : 9, vrai-1/prédit-1 : 33.Le suréchantillonnage supplémentaire n'améliore pas significativement les performances du modèle, ce qui indique que la distribution d'échantillons d'origine et le modèle étaient déjà efficaces.
Exemple 2 : Orchestrer des jobs DLC
Connectez plusieurs composants Script Python dans Machine Learning Designer pour orchestrer un pipeline de jobs DLC. L'exemple suivant démarre quatre jobs DLC organisés en DAG pour contrôler l'ordre d'exécution.
Si le code du job DLC ne lit pas les données des nœuds en amont ni ne transmet de données aux nœuds en aval, les connexions représentent uniquement les dépendances de planification et l'ordre d'exécution.
La topologie DAG du workflow est : DLC Job 1→DLC Job 2→DLC Job 3, DLC Job 1→DLC Job 4, DLC Job 2→DLC Job 4. Dans l'onglet Code Config de chaque nœud de job DLC, configurez :
OSS Authorization : Autorisez l'accès à OSS.
Job output path : Spécifiez l'emplacement de sortie.
Code path : Par exemple,
oss://xxx/python/.Code : Modifiez le fichier de code Python. Par exemple, le DLC Job 4 correspond à
main4.pyavec le contenuimport time; print("DLC task4"); time.sleep(5).
Déployez le pipeline dans DataWorks pour une exécution planifiée. Utiliser DataWorks pour planifier l'exécution hors ligne des pipelines Machine Learning Designer.
Exemple 3 : Transmettre des variables globales
-
Configurez les variables globales.
Sur la page du pipeline Machine Learning Designer, cliquez sur une zone vide du canevas et configurez les variables dans l'onglet Global Variables du volet droit.
Par exemple, ajoutez la variable
arg1avec la valeurtest1, et la variablearg2avec la valeur1234. Référencez les variables en utilisant${variable_name}. Les noms de variables doivent comporter entre 1 et 20 caractères et commencer par une lettre. Si vous utilisez des variables globales pour la planification hors ligne, configurez les mêmes noms de variables dans la configuration de planification hors ligne. -
Transmettez les variables globales au composant Script Python de l'une des deux manières suivantes.
Cliquez sur le nœud du composant Script Python. Dans l'onglet Code Config, sélectionnez Advanced option et configurez les variables globales en tant que paramètres entrants dans le champ Command. Par exemple, saisissez
python main.py --arg1 ${arg1} --arg2 ${arg2}pour transmettre les variables globales au script via des arguments de ligne de commande.-
Modifiez le code Python pour analyser les arguments à l'aide de
argparse.Le code suivant utilise les variables globales configurées à l'étape 1 comme exemple. Mettez à jour le code en fonction de vos variables globales réelles. Remplacez le code dans la zone d'édition de code de l'onglet Code Config.
import os import argparse import json """ Sample code for the Python Script component """ ENV_JOB_MAX_COMPUTE_EXECUTION = "JOB_MAX_COMPUTE_EXECUTION" def init_odps(): from odps import ODPS mc_execution = json.loads(os.environ[ENV_JOB_MAX_COMPUTE_EXECUTION]) o = ODPS( access_id="<YourAccessKeyId>", secret_access_key="<YourAccessKeySecret>", endpoint=mc_execution["endpoint"], project=mc_execution["odpsProject"], ) return o def parse_odps_url(table_uri): from urllib import parse parsed = parse.urlparse(table_uri) project_name = parsed.hostname r = parsed.path.split("/", 2) table_name = r[2] if len(r) > 3: partition = r[3] else: partition = None return project_name, table_name, partition def parse_args(): parser = argparse.ArgumentParser(description="PythonV2 component script example.") parser.add_argument("--input1", type=str, default=None, help="Component input port 1.") parser.add_argument("--input2", type=str, default=None, help="Component input port 2.") parser.add_argument("--input3", type=str, default=None, help="Component input port 3.") parser.add_argument("--input4", type=str, default=None, help="Component input port 4.") parser.add_argument("--output1", type=str, default=None, help="Output OSS port 1.") parser.add_argument("--output2", type=str, default=None, help="Output OSS port 2.") parser.add_argument("--output3", type=str, default=None, help="Output MaxComputeTable 1.") parser.add_argument("--output4", type=str, default=None, help="Output MaxComputeTable 2.") # Add code based on the configured global variables. parser.add_argument("--arg1", type=str, default=None, help="Argument 1.") parser.add_argument("--arg2", type=int, default=None, help="Argument 2.") args, _ = parser.parse_known_args() return args def write_table_example(args): output_table_uri = args.output3 o = init_odps() project_name, table_name, partition = parse_odps_url(output_table_uri) o.run_sql(f"create table {project_name}.{table_name} as select * from pai_online_project.heart_disease_prediction;") def write_output1(args): output_path = args.output1 os.makedirs(output_path, exist_ok=True) p = os.path.join(output_path, "result.text") with open(p, "w") as f: f.write("TestAccuracy=0.88") if __name__ == "__main__": args = parse_args() print("Input1={}".format(args.input1)) print("Output1={}".format(args.output1)) # Add code based on the configured global variables. print("Argument1={}".format(args.arg1)) print("Argument2={}".format(args.arg2)) # write_table_example(args) # write_output1(args)