Přizpůsobení skriptu jazyka R pro spuštění v produkčním prostředí
Tento článek vysvětluje, jak použít existující skript jazyka R a provést příslušné změny pro jeho spuštění jako úlohu ve službě Azure Machine Learning.
Většinu změn popsaných v tomto článku budete muset provést na maximum( pokud ne všechny).
Odebrání interakce uživatele
Skript jazyka R musí být navržený tak, aby běžel bezobslužně a bude proveden příkazem Rscript
v rámci kontejneru. Ujistěte se, že ze skriptu odeberete všechny interaktivní vstupy nebo výstupy.
Přidání analýzy
Pokud váš skript vyžaduje libovolný typ vstupního parametru (většina skriptů), předejte vstupy do skriptu prostřednictvím Rscript
volání.
Rscript <name-of-r-script>.R
--data_file ${{inputs.<name-of-yaml-input-1>}}
--brand ${{inputs.<name-of-yaml-input-2>}}
Ve skriptu jazyka R parsujte vstupy a proveďte správné převody typů. Doporučujeme použít optparse
balíček.
Následující fragment kódu ukazuje, jak:
- inicializovat analyzátor
- přidání všech vstupů jako možností
- parsování vstupů s příslušnými datovými typy
Můžete také přidat výchozí hodnoty, které jsou užitečné pro testování. Doporučujeme přidat --output
parametr s výchozí hodnotou ./outputs
, aby byl uložen jakýkoli výstup skriptu.
library(optparse)
parser <- OptionParser()
parser <- add_option(
parser,
"--output",
type = "character",
action = "store",
default = "./outputs"
)
parser <- add_option(
parser,
"--data_file",
type = "character",
action = "store",
default = "data/myfile.csv"
)
parser <- add_option(
parser,
"--brand",
type = "double",
action = "store",
default = 1
)
args <- parse_args(parser)
args
je pojmenovaný seznam. Některé z těchto parametrů můžete použít později ve skriptu.
Zdroj pomocného azureml_utils.R
skriptu
Je nutné vytvořit pomocný skript s názvem azureml_utils.R
skript ve stejném pracovním adresáři skriptu jazyka R, který se spustí. Pomocný skript se vyžaduje, aby spuštěný skript R mohl komunikovat se serverem MLflow. Pomocný skript poskytuje metodu pro průběžné načítání ověřovacího tokenu, protože se token rychle mění ve spuštěné úloze. Pomocný skript také umožňuje používat funkce protokolování poskytované v rozhraní API jazyka R MLflow k protokolování modelů, parametrů, značek a obecných artefaktů.
Vytvořte soubor s
azureml_utils.R
tímto kódem:# Azure ML utility to enable usage of the MLFlow R API for tracking with Azure Machine Learning (Azure ML). This utility does the following:: # 1. Understands Azure ML MLflow tracking url by extending OSS MLflow R client. # 2. Manages Azure ML Token refresh for remote runs (runs that execute in Azure Machine Learning). It uses tcktk2 R libraray to schedule token refresh. # Token refresh interval can be controlled by setting the environment variable MLFLOW_AML_TOKEN_REFRESH_INTERVAL and defaults to 30 seconds. library(mlflow) library(httr) library(later) library(tcltk2) new_mlflow_client.mlflow_azureml <- function(tracking_uri) { host <- paste("https", tracking_uri$path, sep = "://") get_host_creds <- function () { mlflow:::new_mlflow_host_creds( host = host, token = Sys.getenv("MLFLOW_TRACKING_TOKEN"), username = Sys.getenv("MLFLOW_TRACKING_USERNAME", NA), password = Sys.getenv("MLFLOW_TRACKING_PASSWORD", NA), insecure = Sys.getenv("MLFLOW_TRACKING_INSECURE", NA) ) } cli_env <- function() { creds <- get_host_creds() res <- list( MLFLOW_TRACKING_USERNAME = creds$username, MLFLOW_TRACKING_PASSWORD = creds$password, MLFLOW_TRACKING_TOKEN = creds$token, MLFLOW_TRACKING_INSECURE = creds$insecure ) res[!is.na(res)] } mlflow:::new_mlflow_client_impl(get_host_creds, cli_env, class = "mlflow_azureml_client") } get_auth_header <- function() { headers <- list() auth_token <- Sys.getenv("MLFLOW_TRACKING_TOKEN") auth_header <- paste("Bearer", auth_token, sep = " ") headers$Authorization <- auth_header headers } get_token <- function(host, exp_id, run_id) { req_headers <- do.call(httr::add_headers, get_auth_header()) token_host <- gsub("mlflow/v1.0","history/v1.0", host) token_host <- gsub("azureml://","https://", token_host) api_url <- paste0(token_host, "/experimentids/", exp_id, "/runs/", run_id, "/token") GET( api_url, timeout(getOption("mlflow.rest.timeout", 30)), req_headers) } fetch_token_from_aml <- function() { message("Refreshing token") tracking_uri <- Sys.getenv("MLFLOW_TRACKING_URI") exp_id <- Sys.getenv("MLFLOW_EXPERIMENT_ID") run_id <- Sys.getenv("MLFLOW_RUN_ID") sleep_for <- 1 time_left <- 30 response <- get_token(tracking_uri, exp_id, run_id) while (response$status_code == 429 && time_left > 0) { time_left <- time_left - sleep_for warning(paste("Request returned with status code 429 (Rate limit exceeded). Retrying after ", sleep_for, " seconds. Will continue to retry 429s for up to ", time_left, " second.", sep = "")) Sys.sleep(sleep_for) sleep_for <- min(time_left, sleep_for * 2) response <- get_token(tracking_uri, exp_id) } if (response$status_code != 200){ error_response = paste("Error fetching token will try again after sometime: ", str(response), sep = " ") warning(error_response) } if (response$status_code == 200){ text <- content(response, "text", encoding = "UTF-8") json_resp <-jsonlite::fromJSON(text, simplifyVector = FALSE) json_resp$token Sys.setenv(MLFLOW_TRACKING_TOKEN = json_resp$token) message("Refreshing token done") } } clean_tracking_uri <- function() { tracking_uri <- httr::parse_url(Sys.getenv("MLFLOW_TRACKING_URI")) tracking_uri$query = "" tracking_uri <-httr::build_url(tracking_uri) Sys.setenv(MLFLOW_TRACKING_URI = tracking_uri) } clean_tracking_uri() tcltk2::tclTaskSchedule(as.integer(Sys.getenv("MLFLOW_TOKEN_REFRESH_INTERVAL_SECONDS", 30))*1000, fetch_token_from_aml(), id = "fetch_token_from_aml", redo = TRUE) # Set MLFlow related env vars Sys.setenv(MLFLOW_BIN = system("which mlflow", intern = TRUE)) Sys.setenv(MLFLOW_PYTHON_BIN = system("which python", intern = TRUE))
Spusťte skript jazyka R následujícím řádkem:
source("azureml_utils.R")
Čtení datových souborů jako místních souborů
Když spustíte skript jazyka R jako úlohu, Azure Machine Learning převezme data zadaná v odeslání úlohy a připojí je ke spuštěném kontejneru. Proto budete moct číst datové soubory, jako by se jednalo o místní soubory ve spuštěném kontejneru.
- Ujistěte se, že jsou zdrojová data zaregistrovaná jako datový prostředek.
- Předání datového assetu podle názvu v parametrech odeslání úlohy
- Čtení souborů obvyklým způsobem čtení místního souboru
Definujte vstupní parametr, jak je znázorněno v části parametrů. Pomocí parametru data-file
, zadejte celou cestu, abyste mohli použít read_csv(args$data_file)
ke čtení datového assetu.
Ukládání artefaktů úloh (obrázky, data atd.)
Důležité
Tato část se nevztahuje na modely. Pokyny k ukládání a protokolování pro konkrétní model najdete v následujících dvou částech.
Můžete ukládat libovolné výstupy skriptu, jako jsou datové soubory, obrázky, serializované objekty R atd., které jsou generovány skriptem R ve službě Azure Machine Learning. Vytvořte ./outputs
adresář pro uložení všech vygenerovaných artefaktů (obrázky, modely, data atd.) Všechny soubory uložené ./outputs
do spuštění se automaticky zahrnou do spuštění a nahrají se do experimentu na konci spuštění. Vzhledem k tomu, že jste do oddílu vstupních parametrů přidali výchozí hodnotu parametru--output
, zahrňte do skriptu jazyka R následující fragment kódu, který vytvoří output
adresář.
if (!dir.exists(args$output)) {
dir.create(args$output)
}
Po vytvoření adresáře uložte artefakty do daného adresáře. Příklad:
# create and save a plot
library(ggplot2)
myplot <- ggplot(...)
ggsave(myplot,
filename = file.path(args$output,"forecast-plot.png"))
# save an rds serialized object
saveRDS(myobject, file = file.path(args$output,"myobject.rds"))
crate
vaše modely s balíčkem carrier
Dokumentace k rozhraní API R MLflow určuje, že vaše modely R musí být variantou crate
modelu.
- Pokud skript R trénuje model a vytváříte objekt modelu, budete ho muset
crate
později nasadit pomocí služby Azure Machine Learning. - Při použití
crate
funkce použijte explicitní obory názvů při volání jakékoli funkce balíčku, kterou potřebujete.
Řekněme, že máte objekt modelu timeseries, který se nazývá my_ts_model
vytvořený s balíčkem fable
. Pokud chcete, aby byl tento model při nasazení volatelný, vytvořte crate
místo, kde předáte objekt modelu a horizont prognózy v počtu období:
library(carrier)
crated_model <- crate(function(x)
{
fabletools::forecast(!!my_ts_model, h = x)
})
Objekt crated_model
je objekt, který zapíšete.
Modely protokolů, parametry, značky nebo jiné artefakty s využitím rozhraní API MLflow jazyka R
Kromě ukládání všech vygenerovaných artefaktů můžete také protokolovat modely, značky a parametry pro každé spuštění. K tomu použijte rozhraní API R MLflow.
Při protokolování modelu zaznamenáte jmenovitý model , který jste vytvořili, jak je popsáno v předchozí části.
Poznámka:
Při protokolování modelu se také uloží a přidá do artefaktů spuštění. Model není nutné explicitně ukládat, pokud jste ho nezapíšete.
Protokolování modelu a/nebo parametru:
- Spuštění spuštění pomocí
mlflow_start_run()
- Protokolovat artefakty pomocí
mlflow_log_model
,mlflow_log_param
nebomlflow_log_batch
- Ukončete spuštění s
mlflow_end_run()
. Přeskočte toto volání, protože aktuálně způsobuje chybu.
Pokud chcete například objekt protokolovat crated_model
tak, jak byl vytvořen v předchozí části, zahrnuli byste do skriptu jazyka R následující kód:
Tip
Tato hodnota se používá models
jako hodnota pro artifact_path
protokolování modelu, což je osvědčený postup (i když ho můžete pojmenovat jinak.)
mlflow_start_run()
mlflow_log_model(
model = crated_model, # the crate model object
artifact_path = "models" # a path to save the model object to
)
mlflow_log_param(<key-name>, <value>)
# mlflow_end_run() - causes an error, do not include mlflow_end_run()
Struktura skriptů a příklad
Tyto fragmenty kódu použijte jako vodítko ke strukturování skriptu jazyka R podle všech změn popsaných v tomto článku.
# BEGIN R SCRIPT
# source the azureml_utils.R script which is needed to use the MLflow back end
# with R
source("azureml_utils.R")
# load your packages here. Make sure that they are installed in the container.
library(...)
# parse the command line arguments.
library(optparse)
parser <- OptionParser()
parser <- add_option(
parser,
"--output",
type = "character",
action = "store",
default = "./outputs"
)
parser <- add_option(
parser,
"--data_file",
type = "character",
action = "store",
default = "data/myfile.csv"
)
parser <- add_option(
parser,
"--brand",
type = "double",
action = "store",
default = 1
)
args <- parse_args(parser)
# your own R code goes here
# - model building/training
# - visualizations
# - etc.
# create the ./outputs directory
if (!dir.exists(args$output)) {
dir.create(args$output)
}
# log models and parameters to MLflow
mlflow_start_run()
mlflow_log_model(
model = crated_model, # the crate model object
artifact_path = "models" # a path to save the model object to
)
mlflow_log_param(<key-name>, <value>)
# mlflow_end_run() - causes an error, do not include mlflow_end_run()
## END OF R SCRIPT
Vytvořit prostředí
Ke spuštění skriptu R použijete ml
rozšíření pro Azure CLI, označované také jako CLI v2. Příkaz ml
používá soubor definic úloh YAML. Další informace o odesílání úloh pomocí az ml
tématu Trénování modelů pomocí rozhraní příkazového řádku služby Azure Machine Learning.
Soubor úlohy YAML určuje prostředí. Před spuštěním úlohy budete muset toto prostředí vytvořit ve svém pracovním prostoru.
Prostředí můžete vytvořit v studio Azure Machine Learning nebo pomocí Azure CLI.
Bez ohledu na to, kterou metodu použijete, použijete soubor Dockerfile. Aby bylo možné pracovat se službou Azure Machine Learning, musí mít všechny soubory kontextu Dockeru pro prostředí R následující specifikaci:
FROM rocker/tidyverse:latest
# Install python
RUN apt-get update -qq && \
apt-get install -y python3-pip tcl tk libz-dev libpng-dev
RUN ln -f /usr/bin/python3 /usr/bin/python
RUN ln -f /usr/bin/pip3 /usr/bin/pip
RUN pip install -U pip
# Install azureml-MLflow
RUN pip install azureml-MLflow
RUN pip install MLflow
# Create link for python
RUN ln -f /usr/bin/python3 /usr/bin/python
# Install R packages required for logging with MLflow (these are necessary)
RUN R -e "install.packages('mlflow', dependencies = TRUE, repos = 'https://cloud.r-project.org/')"
RUN R -e "install.packages('carrier', dependencies = TRUE, repos = 'https://cloud.r-project.org/')"
RUN R -e "install.packages('optparse', dependencies = TRUE, repos = 'https://cloud.r-project.org/')"
RUN R -e "install.packages('tcltk2', dependencies = TRUE, repos = 'https://cloud.r-project.org/')"
Základní image je rocker/tidyverse:latest
, která má mnoho balíčků R a jejich závislosti jsou již nainstalovány.
Důležité
Musíte nainstalovat všechny balíčky jazyka R, které váš skript bude muset spustit předem. Podle potřeby přidejte do kontextového souboru Dockeru další řádky.
RUN R -e "install.packages('<package-to-install>', dependencies = TRUE, repos = 'https://cloud.r-project.org/')"
Další návrhy
Můžete zvážit několik dalších návrhů:
- Použití funkce R
tryCatch
pro zpracování výjimek a chyb - Přidání explicitního protokolování pro řešení potíží a ladění