R betiğinizi üretimde çalışacak şekilde uyarlama

Bu makalede mevcut bir R betiğini alma ve Azure Machine Learning'de iş olarak çalıştırmak için uygun değişiklikleri yapma adımları açıklanmaktadır.

Bu makalede ayrıntılı olarak açıklanan değişikliklerin tümünü değil de çoğunu yapmanız gerekir.

Kullanıcı etkileşimlerini kaldırma

R betiğiniz katılımsız çalışacak şekilde tasarlanmalıdır ve kapsayıcı içindeki Rscript komut aracılığıyla yürütülür. Betikten etkileşimli girişleri veya çıkışları kaldırdığınızdan emin olun.

Ayrıştırma ekleme

Betiğiniz herhangi bir giriş parametresi gerektiriyorsa (çoğu betik bunu yapar), çağrı aracılığıyla girişleri betike Rscript geçirin.

Rscript <name-of-r-script>.R
--data_file ${{inputs.<name-of-yaml-input-1>}} 
--brand ${{inputs.<name-of-yaml-input-2>}}

R betiğinizde girişleri ayrıştırın ve uygun tür dönüştürmelerini yapın. Paketi kullanmanızı optparse öneririz.

Aşağıdaki kod parçacığı nasıl yapılacağını gösterir:

  • ayrıştırıcıyı başlatma
  • tüm girişlerinizi seçenek olarak ekleme
  • girişleri uygun veri türleriyle ayrıştırma

Ayrıca test için kullanışlı olan varsayılan değerleri de ekleyebilirsiniz. Betiğin herhangi bir çıkışının ./outputs depolanması için varsayılan değerine sahip bir --output parametre eklemenizi öneririz.

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 adlandırılmış bir listedir. Bu parametrelerden herhangi birini betiğinizin ilerleyen bölümlerinde kullanabilirsiniz.

Yardımcı betiğin azureml_utils.R kaynağını belirleme

Çalıştırılacak R betiğinin aynı çalışma dizininde betik adlı azureml_utils.R bir yardımcı betik kaynağı oluşturmanız gerekir. Çalışan R betiğinin MLflow sunucusuyla iletişim kurabilmesi için yardımcı betik gereklidir. Yardımcı betik, çalışan bir işte belirteç hızla değiştiğinden kimlik doğrulama belirtecini sürekli almak için bir yöntem sağlar. Yardımcı betik ayrıca modelleri, parametreleri, etiketleri ve genel yapıtları günlüğe kaydetmek için R MLflow API'sinde sağlanan günlük işlevlerini kullanmanıza olanak tanır.

  1. Dosyanızı şu azureml_utils.Rkodla oluşturun:

    # 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))
    
  2. R betiğinizi aşağıdaki satırla başlatın:

source("azureml_utils.R")

Veri dosyalarını yerel dosyalar olarak okuma

R betiğini iş olarak çalıştırdığınızda Azure Machine Learning, iş gönderiminde belirttiğiniz verileri alır ve çalışan kapsayıcıya bağlar. Bu nedenle, çalışan kapsayıcıdaki yerel dosyalar gibi veri dosyalarını okuyabileceksiniz.

  • Kaynak verilerinizin veri varlığı olarak kayıtlı olduğundan emin olun
  • veri varlığını iş gönderme parametrelerinde ada göre geçirme
  • Normalde yerel bir dosyayı okuduğunuz gibi dosyaları okuyun

Giriş parametresini parametreler bölümünde gösterildiği gibi tanımlayın. Veri varlığını okumak için kullanabileceğiniz bir yolun tamamını belirtmek için parametresini data-filekullanın read_csv(args$data_file) .

İş yapıtlarını (görüntüler, veriler vb.) kaydetme

Önemli

Bu bölüm modeller için geçerli değildir. Modele özgü kaydetme ve günlüğe kaydetme yönergeleri için aşağıdaki iki bölüme bakın.

Azure Machine Learning'de R betiği tarafından oluşturulan veri dosyaları, görüntüler, serileştirilmiş R nesneleri gibi rastgele betik çıkışlarını depolayabilirsiniz. Oluşturulan yapıtları (görüntüler, modeller, veriler vb.) depolamak için bir ./outputs dizin oluşturma 'a ./outputs kaydedilen tüm dosyalar çalıştırmaya otomatik olarak eklenir ve çalıştırmanın sonunda denemeye yüklenir. Giriş parametreleri bölümünde parametresi için varsayılan bir değer eklediğinizden, dizini oluşturmak için --output R betiğinize aşağıdaki kod parçacığını output ekleyin.

if (!dir.exists(args$output)) {
  dir.create(args$output)
}

Dizini oluşturduktan sonra yapıtlarınızı bu dizine kaydedin. Örneğin:

# 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 paketiyle carrier modellerinizi

R MLflow API belgeleri, R modellerinizin model çeşidine crate sahip olması gerektiğini belirtir.

  • R betiğiniz bir modeli eğitiyorsa ve bir model nesnesi oluşturursanız, azure machine learning ile daha sonra dağıtabilmeniz için bu betiği kullanmanız gerekir crate .
  • işlevini kullanırken crate , ihtiyacınız olan herhangi bir paket işlevini çağırırken açık ad alanlarını kullanın.

Paketle fable oluşturulan adlı my_ts_model bir timeseries model nesneniz olduğunu varsayalım. Bu modelin dağıtıldığında çağrılabilmesini sağlamak için, model nesnesini geçireceğiniz bir crate yer ve dönem sayısı olarak bir tahmin ufku oluşturun:

library(carrier)
crated_model <- crate(function(x)
{
  fabletools::forecast(!!my_ts_model, h = x)
})

Nesne crated_model , günlüğe kaydedeceğimiz nesnedir.

R MLflow API'siyle modelleri, parametreleri, etiketleri veya diğer yapıtları günlüğe kaydetme

Oluşturulan yapıtları kaydetmeye ek olarak, her çalıştırma için modelleri, etiketleri ve parametreleri de günlüğe kaydedebilirsiniz. Bunu yapmak için R MLflow API'sini kullanın.

Bir modeli günlüğe kaydettiğinizde, oluşturduğunuz kasalı modeli önceki bölümde açıklandığı gibi günlüğe kaydedersiniz.

Not

Bir modeli günlüğe kaydettiğinizde, model de kaydedilir ve çalıştırma yapıtlarına eklenir. Bir modeli günlüğe kaydetmediğiniz sürece açıkça kaydetmeniz gerekmez.

Bir modeli ve/veya parametreyi günlüğe kaydetmek için:

  1. Çalıştırmayı şu şekilde başlatın: mlflow_start_run()
  2. , mlflow_log_paramveya ile mlflow_log_modelyapıtları günlüğe kaydetmemlflow_log_batch
  3. çalıştırmayı ile mlflow_end_run()sonlandırmayın. Şu anda bir hataya neden olduğundan bu çağrıyı atlayın.

Örneğin, nesneyi önceki bölümde oluşturulduğu gibi günlüğe kaydetmek crated_model için R betiğinize aşağıdaki kodu eklersiniz:

İpucu

Bir modeli günlüğe kaydetme işlemi için artifact_path değer olarak kullanınmodels; bu en iyi yöntemdir (başka bir adla adlandırabilirsiniz.)

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()

Betik yapısı ve örneği

Bu makalede açıklanan tüm değişiklikleri izleyerek R betiğinizi yapılandırmak için bu kod parçacıklarını kılavuz olarak kullanın.

# 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

Ortam oluşturun

R betiğinizi çalıştırmak için CLI v2 olarak da adlandırılan Azure CLI uzantısını kullanacaksınız ml . ml komutu bir YAML iş tanımları dosyası kullanır. ile az mliş gönderme hakkında daha fazla bilgi için bkz . Azure Machine Learning CLI ile modelleri eğitme.

YAML iş dosyası bir ortam belirtir. İşi çalıştırabilmeniz için önce çalışma alanınızda bu ortamı oluşturmanız gerekir.

Ortamı Azure Machine Learning stüdyosu veya Azure CLI ile oluşturabilirsiniz.

Hangi yöntemi kullanırsanız kullanın, dockerfile kullanacaksınız. Azure Machine Learning üzerinde çalışabilmek için R ortamları için tüm Docker bağlam dosyalarının aşağıdaki belirtimlere sahip olması gerekir:

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/')"

Temel görüntü, birçok R paketinin ve bağımlılıklarının zaten yüklü olduğu şeklindedir rocker/tidyverse:latest.

Önemli

Betiğinizin önceden çalışması gereken tüm R paketlerini yüklemeniz gerekir. Docker bağlam dosyasına gerektiğinde daha fazla satır ekleyin.

RUN R -e "install.packages('<package-to-install>', dependencies = TRUE, repos = 'https://cloud.r-project.org/')"

Ek öneriler

Dikkate almak isteyebileceğiniz bazı ek öneriler:

  • Özel durum ve hata işleme için R'nin tryCatch işlevini kullanma
  • Sorun giderme ve hata ayıklama için açık günlük kaydı ekleme

Sonraki adımlar