Uw R-script aanpassen om in productie te worden uitgevoerd
In dit artikel wordt uitgelegd hoe u een bestaand R-script kunt gebruiken en de juiste wijzigingen kunt aanbrengen om het script uit te voeren als een taak in Azure Machine Learning.
U moet optimaal gebruikmaken van de wijzigingen die in dit artikel in detail worden beschreven.
Gebruikersinteractie verwijderen
Uw R-script moet zijn ontworpen om zonder toezicht uit te voeren en wordt uitgevoerd via de Rscript
opdracht in de container. Zorg ervoor dat u interactieve invoer of uitvoer uit het script verwijdert.
Parseren toevoegen
Als voor uw script een soort invoerparameter is vereist (de meeste scripts wel), geeft u de invoer via de aanroep door aan het Rscript
script door.
Rscript <name-of-r-script>.R
--data_file ${{inputs.<name-of-yaml-input-1>}}
--brand ${{inputs.<name-of-yaml-input-2>}}
Parseer de invoer in uw R-script en voer de juiste typeconversies uit. U wordt aangeraden het optparse
pakket te gebruiken.
In het volgende codefragment ziet u hoe u:
- de parser initiëren
- al uw invoer toevoegen als opties
- de invoer parseren met de juiste gegevenstypen
U kunt ook standaardinstellingen toevoegen, wat handig is voor het testen. U wordt aangeraden een --output
parameter met een standaardwaarde ./outputs
toe te voegen, zodat elke uitvoer van het script wordt opgeslagen.
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
is een benoemde lijst. U kunt een van deze parameters later in uw script gebruiken.
azureml_utils.R
Het helperscript bronen
U moet een helperscript met de naam azureml_utils.R
script in dezelfde werkmap van het R-script zoeken dat wordt uitgevoerd. Het helperscript is vereist voor het uitvoeren van het R-script om te kunnen communiceren met de MLflow-server. Het helperscript biedt een methode voor het continu ophalen van het verificatietoken, omdat het token snel verandert in een actieve taak. Met het helperscript kunt u ook de logboekregistratiefuncties in de R MLflow-API gebruiken om modellen, parameters, tags en algemene artefacten te registreren.
Maak uw bestand met
azureml_utils.R
deze code:# 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))
Start uw R-script met de volgende regel:
source("azureml_utils.R")
Gegevensbestanden lezen als lokale bestanden
Wanneer u een R-script uitvoert als een taak, neemt Azure Machine Learning de gegevens die u opgeeft in het verzenden van de taak en koppelt het aan de actieve container. Daarom kunt u de gegevensbestanden lezen alsof ze lokale bestanden in de actieve container zijn.
- Zorg ervoor dat uw brongegevens zijn geregistreerd als een gegevensasset
- Geef de gegevensasset op naam door in de parameters voor het verzenden van taken
- Lees de bestanden zoals u normaal gesproken een lokaal bestand zou lezen
Definieer de invoerparameter zoals wordt weergegeven in de sectie parameters. Gebruik de parameter, data-file
om een heel pad op te geven, zodat u de gegevensasset kunt read_csv(args$data_file)
lezen.
Taakartefacten opslaan (afbeeldingen, gegevens, enzovoort)
Belangrijk
Deze sectie is niet van toepassing op modellen. Zie de volgende twee secties voor modelspecifieke instructies voor opslaan en logboekregistratie.
U kunt willekeurige scriptuitvoer opslaan, zoals gegevensbestanden, afbeeldingen, geserialiseerde R-objecten, enzovoort, die worden gegenereerd door het R-script in Azure Machine Learning. Maak een ./outputs
map voor het opslaan van gegenereerde artefacten (afbeeldingen, modellen, gegevens, enzovoort) Alle bestanden die zijn opgeslagen ./outputs
, worden automatisch opgenomen in de uitvoering en geüpload naar het experiment aan het einde van de uitvoering. Omdat u een standaardwaarde hebt toegevoegd voor de --output
parameter in de sectie invoerparameters , neemt u het volgende codefragment op in uw R-script om de output
map te maken.
if (!dir.exists(args$output)) {
dir.create(args$output)
}
Nadat u de map hebt gemaakt, slaat u uw artefacten op in die map. Voorbeeld:
# 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
uw modellen met het carrier
pakket
De documentatie van de R MLflow-API geeft aan dat uw R-modellen van de crate
modelsmaak moeten zijn.
- Als uw R-script een model traint en u een modelobject produceert, moet
crate
u het op een later tijdstip kunnen implementeren met Azure Machine Learning. - Wanneer u de
crate
functie gebruikt, gebruikt u expliciete naamruimten bij het aanroepen van een pakketfunctie die u nodig hebt.
Stel dat u een tijdreeksmodelobject my_ts_model
hebt dat is gemaakt met het fable
pakket. Als u dit model aanroepbaar wilt maken wanneer het wordt geïmplementeerd, maakt u een crate
locatie waar u het modelobject en een prognoseperiode in het aantal perioden doorgeeft:
library(carrier)
crated_model <- crate(function(x)
{
fabletools::forecast(!!my_ts_model, h = x)
})
Het crated_model
object is het object dat u gaat registreren.
Logboekmodellen, parameters, tags of andere artefacten met de R MLflow-API
Naast het opslaan van gegenereerde artefacten, kunt u ook modellen, tags en parameters vastleggen voor elke uitvoering. Gebruik de R MLflow-API om dit te doen.
Wanneer u een model aanmeldt, meldt u het crated-model dat u hebt gemaakt, zoals beschreven in de vorige sectie.
Notitie
Wanneer u een model aanmeldt, wordt het model ook opgeslagen en toegevoegd aan de runartefacten. Het is niet nodig om een model expliciet op te slaan, tenzij u het niet hebt vastgelegd.
Een model en/of parameter registreren:
- De uitvoering starten met
mlflow_start_run()
- Logboekartefacten met
mlflow_log_model
,mlflow_log_param
ofmlflow_log_batch
- Beëindig de uitvoering niet met
mlflow_end_run()
. Sla deze aanroep over, omdat deze momenteel een fout veroorzaakt.
Als u bijvoorbeeld het crated_model
object wilt registreren zoals gemaakt in de vorige sectie, moet u de volgende code opnemen in uw R-script:
Tip
Als models
waarde gebruiken voor artifact_path
het vastleggen van een model, is dit een best practice (ook al kunt u dit een andere naam noemen.)
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()
Scriptstructuur en voorbeeld
Gebruik deze codefragmenten als richtlijn voor het structuren van uw R-script, waarbij u alle wijzigingen volgt die in dit artikel worden beschreven.
# 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
Een omgeving maken
Als u uw R-script wilt uitvoeren, gebruikt u de ml
extensie voor Azure CLI, ook wel CLI v2 genoemd. De ml
opdracht maakt gebruik van een YAML-taakdefinitiebestand. Zie Modellen trainen met Azure Machine Learning CLI voor meer informatie over het verzenden van takenaz ml
.
Het YAML-taakbestand geeft een omgeving op. U moet deze omgeving maken in uw werkruimte voordat u de taak kunt uitvoeren.
U kunt de omgeving maken in Azure Machine Learning-studio of met de Azure CLI.
Welke methode u ook gebruikt, u gebruikt een Dockerfile. Alle Docker-contextbestanden voor R-omgevingen moeten de volgende specificatie hebben om te kunnen werken met Azure Machine Learning:
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/')"
De basisinstallatiekopieën zijn rocker/tidyverse:latest
, waarop veel R-pakketten en hun afhankelijkheden al zijn geïnstalleerd.
Belangrijk
U moet R-pakketten installeren die uw script moet uitvoeren. Voeg indien nodig meer regels toe aan het Docker-contextbestand.
RUN R -e "install.packages('<package-to-install>', dependencies = TRUE, repos = 'https://cloud.r-project.org/')"
Aanvullende suggesties
Enkele aanvullende suggesties die u kunt overwegen:
- De functie R
tryCatch
gebruiken voor uitzonderings- en foutafhandeling - Expliciete logboekregistratie toevoegen voor probleemoplossing en foutopsporing