Адаптация скрипта R для выполнения в рабочей среде
В этой статье объясняется, как выполнить существующий скрипт R и внести соответствующие изменения для его запуска в качестве задания в Машинное обучение Azure.
Вам придется сделать большую часть, если не все, изменения, описанные в этой статье.
Удаление взаимодействия с пользователем
Скрипт R должен быть разработан для автоматического выполнения и будет выполняться с помощью Rscript
команды в контейнере. Убедитесь, что вы удалили все интерактивные входные или выходные данные из скрипта.
Добавление синтаксического анализа
Если для скрипта требуется любой тип входного параметра (большинство сценариев делают), передайте входные данные в скрипт через Rscript
вызов.
Rscript <name-of-r-script>.R
--data_file ${{inputs.<name-of-yaml-input-1>}}
--brand ${{inputs.<name-of-yaml-input-2>}}
В скрипте R выполните синтаксический анализ входных данных и выполните правильные преобразования типов. Рекомендуется использовать optparse
пакет.
В следующем фрагменте кода показано, как:
- инициирование средства синтаксического анализа
- добавьте все входные данные в качестве параметров
- анализ входных данных с соответствующими типами данных
Вы также можете добавить значения по умолчанию, которые удобны для тестирования. Рекомендуется добавить --output
параметр со значением ./outputs
по умолчанию, чтобы сохранить все выходные данные скрипта.
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
— именованный список. Вы можете использовать любой из этих параметров позже в скрипте.
Источник вспомогательного azureml_utils.R
скрипта
Необходимо создать вспомогательный скрипт, называемый azureml_utils.R
скриптом в том же рабочем каталоге скрипта R, который будет выполняться. Вспомогательный скрипт необходим для запуска скрипта R, чтобы иметь возможность взаимодействовать с сервером MLflow. Вспомогательный скрипт предоставляет метод непрерывного извлечения маркера проверки подлинности, так как маркер быстро изменяется в выполняемом задании. Вспомогательный скрипт также позволяет использовать функции ведения журнала, предоставляемые в API MLflow R, для журналов моделей, параметров, тегов и общих артефактов.
Создайте файл с
azureml_utils.R
помощью этого кода:# 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))
Запустите скрипт R со следующей строкой:
source("azureml_utils.R")
Чтение файлов данных в виде локальных файлов
При запуске скрипта R в качестве задания Машинное обучение Azure принимает данные, указанные в отправке задания, и подключает его к работающему контейнеру. Таким образом, вы сможете считывать файлы данных, как если бы они были локальными файлами в работающем контейнере.
- Убедитесь, что исходные данные зарегистрированы в качестве ресурса данных
- Передача ресурса данных по имени в параметрах отправки задания
- Чтение файлов, как правило, считывает локальный файл.
Определите входной параметр, как показано в разделе параметров. Используйте параметр, data-file
чтобы указать весь путь, чтобы считывать read_csv(args$data_file)
ресурс данных.
Сохранение артефактов заданий (изображения, данные и т. д.)
Внимание
Этот раздел не применяется к моделям. Ознакомьтесь со следующими двумя разделами для конкретных инструкций по сохранению и ведению журнала модели.
Вы можете хранить произвольные выходные данные скрипта, такие как файлы данных, изображения, сериализованные объекты R и т. д., созданные скриптом R в Машинное обучение Azure. ./outputs
Создайте каталог для хранения любых созданных артефактов (изображений, моделей, данных и т. д.) Все сохраненные файлы ./outputs
будут автоматически включены в выполнение и отправлены в эксперимент в конце выполнения. Так как вы добавили значение по умолчанию для --output
параметра в разделе входных параметров , добавьте следующий фрагмент кода в скрипт R для создания output
каталога.
if (!dir.exists(args$output)) {
dir.create(args$output)
}
После создания каталога сохраните артефакты в этом каталоге. Например:
# 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
модели с пакетом carrier
Документация по API MLflow R указывает, что модели R должны соответствовать вкусуcrate
модели.
- Если скрипт R обучает модель и создает объект модели, его необходимо
crate
будет развернуть позже с помощью Машинное обучение Azure. - При использовании функции используйте явные
crate
пространства имен при вызове любой нужной функции пакета.
Предположим, что у вас есть объект модели таймерий, созданный my_ts_model
с fable
помощью пакета. Чтобы сделать эту модель вызываемой при развертывании, создайте crate
место, где вы будете передавать объект модели и горизонт прогнозирования в количестве периодов:
library(carrier)
crated_model <- crate(function(x)
{
fabletools::forecast(!!my_ts_model, h = x)
})
Объект crated_model
— это тот, который вы будете записывать.
Модели журналов, параметры, теги или другие артефакты с ПОМОЩЬЮ API R MLflow
Помимо сохранения созданных артефактов, можно также регистрировать модели, теги и параметры для каждого запуска. Используйте API MLflow R для этого.
При журнале модели вы регистрируете созданную модель с рейтингом , как описано в предыдущем разделе.
Примечание.
При регистрации модели модель также сохраняется и добавляется в артефакты запуска. Нет необходимости явно сохранять модель, если вы не выполнили ее журнал.
Чтобы регистрировать модель и /или параметр, выполните приведенные ниже действия.
- Запуск с помощью
mlflow_start_run()
- Артефакты журнала с
mlflow_log_model
,mlflow_log_param
илиmlflow_log_batch
- Не завершайте выполнение с
mlflow_end_run()
помощью . Пропустите этот вызов, так как в настоящее время вызывает ошибку.
Например, чтобы записать crated_model
объект, созданный в предыдущем разделе, в скрипт R можно включить следующий код:
Совет
Используйте models
в качестве значения artifact_path
для ведения журнала модели, это рекомендуется (даже если вы можете назвать его чем-то другим.)
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()
Структура скрипта и пример
Используйте эти фрагменты кода в качестве руководства по структуре скрипта R, следуя всем изменениям, описанным в этой статье.
# 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
Создать среду
Чтобы запустить скрипт R, вы будете использовать ml
расширение для Azure CLI, также называемое CLI версии 2. Команда ml
использует файл определений заданий YAML. Дополнительные сведения о отправке заданий с помощью см. в разделе "Обучение моделей с az ml
помощью интерфейса командной строки Машинное обучение Azure".
Файл задания YAML указывает среду. Перед запуском задания необходимо создать эту среду в рабочей области.
Среду можно создать в Студия машинного обучения Azure или с помощью Azure CLI.
Какой бы метод вы ни использовали, вы будете использовать Dockerfile. Все файлы контекста Docker для сред R должны иметь следующую спецификацию, чтобы работать с Машинное обучение Azure:
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/')"
Базовый образ— это rocker/tidyverse:latest
, который содержит множество пакетов R и их зависимостей, уже установленных.
Внимание
Необходимо заранее установить все пакеты R, которые потребуется запустить скрипт. Добавьте дополнительные строки в файл контекста Docker по мере необходимости.
RUN R -e "install.packages('<package-to-install>', dependencies = TRUE, repos = 'https://cloud.r-project.org/')"
Дополнительные предложения
Некоторые дополнительные предложения, которые вы можете рассмотреть, выполните следующие действия.
- Использование функции R
tryCatch
для обработки исключений и ошибок - Добавление явного ведения журнала для устранения неполадок и отладки