Use o componente Python Script no Machine Learning Designer para instalar pacotes de dependências e executar funções Python personalizadas.
Localizar o componente
O componente Python Script está na pasta UserDefinedScript da lista de componentes do Machine Learning Designer.
Pré-requisitos
Permissões do DLC concedidas. Cloud service dependencies and authorizations: DLC.
O componente Python Script usa recursos computacionais do DLC. Associe os recursos computacionais do DLC ao seu workspace. Gerencie workspaces.
-
O componente Python Script armazena código no OSS. Crie um bucket do OSS. Crie um bucket.
ImportanteO bucket do OSS deve estar na mesma região do Machine Learning Designer e do DLC.
O usuário RAM deve ter a função Algorithm Development no workspace. Gerencie membros do workspace. Para usar o MaxCompute como fonte de dados, conceda também a função MaxCompute Developer.
Configure o componente
-
Portas de entrada
O componente Python Script tem quatro portas de entrada. Conecte-as a dados de um caminho do OSS ou de uma tabela do MaxCompute.
-
Entrada de caminho do OSS
A entrada de um caminho do OSS proveniente de um componente upstream é montada no nó onde o script executa. O sistema passa o caminho do arquivo montado como argumento. Por exemplo,
--input1 /ml/input/data/input1especifica o caminho da primeira porta de entrada. Leia os arquivos montados em/ml/input/data/input1como arquivos locais no script. -
Entrada de tabela do MaxCompute
As entradas de tabelas do MaxCompute não são montadas. O sistema passa as informações da tabela como um argumento URI. Por exemplo,
python main.py --input1 odps://some-project-name/tables/tableindica a tabela do MaxCompute da primeira porta de entrada. Use a funçãoparse_odps_urldo modelo de código para analisar metadados como ProjectName, TableName e Partition. Usage examples.
-
-
Portas de saída
O componente Python Script tem quatro portas de saída. A OSS Output Port 1 e a OSS Output Port 2 direcionam dados para caminhos do OSS. A Table Output Port 1 e a Table Output Port 2 enviam dados para tabelas do MaxCompute.
-
Saída de caminho do OSS
O caminho do OSS definido em Job output path, na aba Code Config, é montado em
/ml/output/. A OSS Output Port 1 e a OSS Output Port 2 correspondem, respectivamente, a/ml/output/output1e/ml/output/output2. Grave arquivos nesses diretórios no script para passá-los aos componentes downstream. -
Saída de tabela do MaxCompute
Se o workspace tiver um projeto do MaxCompute, o sistema fornecerá um URI de tabela temporária ao script. Exemplo:
python main.py --output3 odps://<some-project-name>/tables/<output-table-name>. Use o PyODPS para criar essa tabela e gravar dados nela e, em seguida, passe-a para os componentes downstream pelas conexões.
-
-
Parâmetros
Code Config
Parameter
Description
Job output path
Caminho do OSS para a saída do job.
-
O diretório do OSS configurado é montado em
/ml/output/no contêiner do job. Os dados gravados em/ml/output/persistem no diretório correspondente do OSS. -
As portas de saída OSS Output-1 e OSS Output-2 correspondem aos subcaminhos
output1eoutput2em/ml/output/. Quando uma porta de saída do OSS se conecta a um componente downstream, este recebe os dados do subcaminho correspondente.
Code source
(Escolha uma opção)
Literal code
-
Python code: Caminho do OSS onde o código é salvo. O código escrito no editor é armazenado neste local. O nome padrão do arquivo é
main.py.ImportanteAntes de clicar em Save pela primeira vez, verifique se o caminho do OSS especificado não contém um arquivo com o mesmo nome. Caso contrário, o arquivo existente será sobrescrito.
-
Editor de código Python: O editor fornece um código de exemplo por padrão. Usage examples. Escreva seu código diretamente no editor.
Especifique a configuração do Git
-
Git repository address: Endereço do repositório Git.
-
Code branch: Branch do código. O valor padrão é master.
-
Code commit: ID do commit. Tem prioridade sobre a branch. Se especificado, a configuração da branch é ignorada.
-
Git username: Obrigatório para acessar um repositório privado.
-
Git access token: Necessário para acessar um repositório de código privado. Appendix: Obtain a GitHub account token.
Escolha a source do código
-
Escolha repositórios de source de código: Selecione uma configuração de código criada anteriormente. Code configurations.
-
Code branch: Branch do código. O valor padrão é master.
-
Code commit: ID do commit. Tem prioridade sobre a branch. Se especificado, a configuração da branch é ignorada.
Escolha o caminho do OSS
No campo OSS Code Path, selecione o caminho onde o código foi carregado.
Command
Comando a ser executado, como
python main.py.NotaO sistema gera o comando de execução automaticamente com base no nome do script e nas conexões das portas. Não é necessária configuração manual.
Advanced option
-
Third-party dependencies: Especifique bibliotecas de terceiros no formato
requirements.txtdo Python. O sistema instala essas bibliotecas antes da execução do nó.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 -
Ative o monitoramento do contêiner: Exibe uma caixa de texto para configurar parâmetros de monitoramento de tolerância a falhas.
Execute Config
Parameter
Description
Select Resource Group
Selecione um grupo de recursos público do DLC:
-
Para grupos de recursos públicos, configure o InstanceType. Escolha uma instância CPU ou GPU. Padrão:
ecs.c6.large.
Por padrão, o sistema usa o grupo de recursos cloud-native padrão do DLC no workspace atual.
VPC Settings
Selecione uma Virtual Private Cloud (VPC) existente.
Security Group
Selecione um grupo de segurança existente.
Advanced option
Ao selecionar esta opção, configure os seguintes parâmetros:
-
Instance count: Quantidade de instâncias. O valor padrão é 1.
-
Job image URI: URI da imagem do job. A imagem padrão usa XGBoost 1.6.0. Altere a imagem se precisar de um framework de deep learning.
-
Job type: Modifique apenas se o seu código for implementado para execução distribuída. Valores suportados:
-
XGBoost/LightGBM Job
-
TensorFlow Job
-
PyTorch Job
-
MPI Job
-
-
Exemplos de uso
Código de exemplo padrão
O componente Python Script fornece o seguinte código de exemplo por padrão.
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)
Descrição das funções comuns:
-
init_odps(): Inicializa uma instância ODPS para leitura de dados de tabelas do MaxCompute. Forneça seu AccessKeyId e AccessKeySecret. Obtain an AccessKey pair. parse_odps_url(table_uri): Analisa o URI da tabela do MaxCompute de entrada e retorna o nome do projeto, o nome da tabela e a partição. O formato detable_uriéodps://${your_projectname}/tables/${table_name}/${pt_1}/${pt_2}/. Por exemplo,odps://test/tables/iris/pa=1/pb=1, ondepa=1/pb=1representa uma partição multinível.parse_args(): Analisa os argumentos passados ao script. Os dados de entrada e saída são transmitidos ao script executado como argumentos.
Exemplo 1: Encadeamento com outros componentes
Este exemplo modifica o modelo de previsão de doenças cardíacas para demonstrar como usar o componente Python Script com outros componentes do Machine Learning Designer. Configuração do pipeline:
Crie um pipeline a partir do modelo de previsão de doenças cardíacas e abra-o. Heart disease prediction.
-
Arraste o componente Python Script para o canvas, renomeie-o para
SMOTEe configure o código abaixo.ImportanteA biblioteca
imblearnnão faz parte da imagem padrão. Adicioneimblearnno campo Third-party dependencies, na aba Code Config. A instalação da biblioteca ocorre automaticamente antes da execução do nó.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()Substitua <Your_AccessKeyId> e <Your_AccessKeySecret> pelos seus próprios valores. Obtain an AccessKey pair.
Conecte o componente SMOTE downstream do componente Split. O SMOTE faz oversampling nos dados de treinamento para equilibrar a distribuição das classes, criando amostras sintéticas para a classe minoritária.
Direcione os novos dados gerados pelo componente SMOTE para o componente Logistic Regression for Binary Classification para treinamento.
-
Conecte o modelo treinado aos mesmos dados de previsão e componentes de avaliação usados no ramo esquerdo para comparação lado a lado. Após a execução do componente, clique em no ícone de visualização (
) para visualizar os resultados da avaliação.Os resultados da avaliação indicam que a Binary Classification Evaluation sem oversampling atingiu um ROC AUC de
0.924, com matriz de confusão verdadeiro-0/predito-0: 43, verdadeiro-0/predito-1: 6, verdadeiro-1/predito-0: 9 e verdadeiro-1/predito-1: 33. A Binary Classification Evaluation-2, com oversampling via SMOTE, obteve um ROC AUC de0.917, com matriz de confusão verdadeiro-0/predito-0: 41, verdadeiro-0/predito-1: 8, verdadeiro-1/predito-0: 9 e verdadeiro-1/predito-1: 33.O oversampling adicional não melhorou significativamente o desempenho do modelo, o que indica que a distribuição original das amostras e o modelo já eram eficazes.
Exemplo 2: Orquestração de jobs do DLC
Conecte vários componentes Python Script no Machine Learning Designer para orquestrar um pipeline de jobs do DLC. O exemplo a seguir inicia quatro jobs do DLC organizados em um DAG para controlar a ordem de execução.
Se o código do job do DLC não ler dados de nós upstream nem enviar dados para nós downstream, as conexões representarão apenas dependências de agendamento e ordem de execução.
A topologia do DAG do fluxo de trabalho é: DLC Job 1→DLC Job 2→DLC Job 3, DLC Job 1→DLC Job 4, DLC Job 2→DLC Job 4. Na aba Code Config de cada nó de job do DLC, configure:
OSS Authorization: Autorize o acesso ao OSS.
Job output path: Especifique o local de saída.
Code path: Por exemplo,
oss://xxx/python/.Code: Edite o arquivo de código Python. Por exemplo, o DLC Job 4 corresponde a
main4.pycom o conteúdoimport time; print("DLC task4"); time.sleep(5).
Implante o pipeline no DataWorks para execução agendada. Use DataWorks to schedule Machine Learning Designer pipelines for offline execution.
Exemplo 3: Passagem de variáveis globais
-
Configure as variáveis globais.
Na página do pipeline do Machine Learning Designer, clique em uma área em branco do canvas e defina as variáveis na aba Global Variables, no painel à direita.
Por exemplo, adicione a variável
arg1com o valortest1e a variávelarg2com o valor1234. Referencie as variáveis usando${variable_name}. Os nomes das variáveis devem ter entre 1 e 20 caracteres e começar com uma letra. Se for usar variáveis globais para agendamento offline, configure os mesmos nomes de variáveis na configuração de agendamento offline. -
Passe as variáveis globais ao componente Python Script de uma das duas formas abaixo.
Clique em no nó do componente Python Script. Na aba Code Config, marque Advanced option e configure as variáveis globais como parâmetros de entrada no campo Command. Por exemplo, insira
python main.py --arg1 ${arg1} --arg2 ${arg2}para passar as variáveis globais ao script por argumentos de linha de comando.-
Modifique o código Python para analisar os argumentos com
argparse.O código abaixo usa as variáveis globais configuradas na etapa 1 como exemplo. Atualize o código conforme suas variáveis globais reais. Substitua o código existente na área de edição de código na aba 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)