R是统计计算和机器学习中最广泛使用的编程语言之一。许多数据科学家都喜欢它,特别是来自tidyverse的丰富的软件包世界,这是一个用于数据科学的R软件包的意见集合。除了tidyverse,CRAN(R的软件包库)上还有18000多个开源软件包。RStudio有桌面版和谷歌云市场版,是一个流行的集成开发环境(IDE),被数据专业人士用于可视化和机器学习模型开发。
一旦一个模型被成功建立,数据科学家中经常出现的一个问题是。"我如何将用R语言编写的模型以可扩展、可靠和低维护的方式部署到生产中?"
在这篇博文中,你将了解如何使用谷歌顶点AI来训练和部署用R语言构建的企业级机器学习模型。
概述
在顶点AI上管理机器学习模型可以通过多种方式进行,包括使用谷歌云控制台的用户界面、API调用或用于Python的顶点AI SDK。
由于许多R用户喜欢从RStudio以编程方式与Vertex AI进行交互,你将通过Vertex AI SDK通过reticulate包与Vertex AI交互。
Vertex AI提供了预构建的Docker容器,用于模型训练和为用tensorflow、scikit-learn和xgboost编写的模型提供预测。对于R来说,你可以自己建立一个容器,源自于Google Cloud Deep Learning Containers for R。
顶点AI上的模型可以通过两种方式创建。
-
在本地训练一个模型,并将其作为一个自定义模型导入顶点AI模型注册中心,从那里可以将其部署到一个端点,以提供预测。
-
创建一个
TrainingPipeline,运行一个CustomJob,并将产生的工件作为一个Model。
在这篇博文中,你将使用第二种方法,直接在顶点AI中训练一个模型,因为这允许我们在后期自动创建模型过程,同时也支持分布式超参数优化。
在顶点AI中创建和管理R模型的过程包括以下步骤。
-
启用谷歌云平台(GCP)的API并设置本地环境
-
创建用于训练和服务的自定义R脚本
-
创建一个Docker容器,支持用Cloud Build和Container Registry来训练和服务R模型
-
使用顶点AI训练训练一个模型,并将工件上传到谷歌云存储。
-
在顶点AI预测端点上创建一个模型端点,并部署该模型以服务在线预测请求
-
进行在线预测
数据集
为了展示这个过程,你要训练一个简单的随机森林模型来预测加州住房数据集上的住房价格。该数据包含1990年加州人口普查的信息。该数据集可从谷歌云存储中公开获得,网址为gs://cloud-samples-data/ai-platform-unified/datasets/tabular/california-housing-tabular-regression.csv
随机森林回归器模型将预测住房价格的中位数,给定经度和纬度,以及相应的人口普查区组的数据。区块组是美国人口普查局公布的最小的地理单元(一个区块组通常有600至3000人)。
环境设置
这篇博文假设你正在使用带有R内核的Vertex AI Workbench或RStudio。你的环境应该包括以下要求。
-
Google Cloud SDK
-
Git
-
R
-
Python 3
-
Virtualenv
为了执行shell命令,定义一个辅助函数。
code_block
[StructValue([(u'code', u'library(glue)\r\nlibrary(IRdisplay)\r\nsh <- function(cmd, args = c(), intern = FALSE) {\r\n if (is.null(args)) {r\n cmd <- glue(cmd)\r\n s <- strsplit(cmd, " " )[[1]]\r\n cmd <- s[1]\r\n args <- s[2:length(s)]/rr\n }\r\n ret <- system2(cmd, args, stdout = TRUE, stderr = TRUE)"errmsg"), "\n")\r\n if (intern) return(ret) else cat(paste(ret, collapse = "\n")\r\n}'), (u'language', u''), (u'caption', <wagtail.wagtailcore.rich_text.RichText object at 0x3e2cdc7c0ad0>)])。
你还应该安装一些R包,并更新Vertex AI的SDK。
code_block
[StructValue([(u'code', u'install.packages(c("reticulate", "glue"))\r\nsh("pip install --upgrade google-cloud-aiplatform")'), (u'language', u''), (u'caption', <wagtail.wagtailcore.rich_text.RichText object at 0x3e2cd2fcae90>)]
接下来,你定义变量以支持训练和部署过程,即。
-
PROJECT_ID:你的谷歌云平台项目ID -
REGION:目前,顶点AI支持us-central1、europe-west4和asia-east1三个地区;建议你选择离你最近的地区。 -
BUCKET_URI:存储与你的数据集和模型资源相关的所有数据的暂存桶 -
DOCKER_REPO:用于存储容器工件的Docker存储库名称 -
IMAGE_NAME:容器镜像的名称 -
IMAGE_TAG:顶点AI将使用的图像标签 -
IMAGE_URI:容器图像的完整URI
代码块
[StructValue([(u'code', u'PROJECT_ID <- "YOUR_PROJECT_ID"\r\nREGION <- "US-Central1"\r\nBUCKET_URI <- glue("gs://{PROJECT_ID}-vertex-r")/r/nDOCKER_REPO <- "vertex-r"/r/nIMAGE_NAME <- "vertex-r"/r/nIMAGE_TAG <- "atest"/r/nIMAGE_URI <- glue("{REGION_docker.pkg.dev/{PROJECT_ID}/{DOCKER_REPO}/{IMAGE_NAME}:{IMAGE_TAG}")'), (u'language', u''), (u'caption', <wagtail.wagtailcore.rich_text.RichText object at 0x3e2cc987c110>) ] ]
当你初始化Vertex AI SDK for Python时,你会指定一个云存储暂存桶。该暂存桶是与你的数据集和模型资源相关的所有数据在不同会话中保留的地方。
代码_块
[StructValue([(u'code', u'sh("gsutil mb -l {REGION} -p {PROJECT_ID} {BUCKET_URI}")], (u'language', u'), (u'caption', <wagtail.wagtailcore.rich_text.RichText object at 0x3e2cc987ce10>)]
接下来,你导入并初始化reticulate R包,以便与Vertex AI SDK对接,它是用Python编写的。
代码_block
[StructValue([(u'code', u'library(reticulate)\r\nlibrary(glue)\r\nuse_python(Sys.which("python3"))\r\n\rnaiplatform <- import("google.云。aiplatform")\r\naiplatform$init(project = PROJECT_ID, location = REGION, staging_bucket = BUCKET_URI)'), (u'language', u''), (u'caption', <wagtail.wagtailcore.rich_text.RichText object at 0x3e2cc987c990>) ] ]
为训练和服务R模型创建Docker容器镜像
你的自定义容器的docker文件是建立在深度学习容器之上的--这个容器也用于Vertex AI Workbench。此外,你还添加了两个R脚本,分别用于模型训练和服务。
在创建这样一个容器之前,你要启用Artifact Registry,并配置Docker以验证你所在地区对它的请求。
代码_块
[StructValue([(u'code', u'sh("gcloud artifacts repositories create {DOCKER_REPO} --repository-format=docker --location={REGION} --description="Docker repository\"")\r\nsh("gcloud auth configure-docker {REGION }-docker.pkg.dev --quiet")'), (u'language', u''), (u'caption', <wagtail.wagtailcore.rich_text.RichText object at 0x3e2cc987cbd0>)】]
接下来,创建一个Dockerfile 。
代码块
[StructValue([(u'code', u'# filename: Dockerfile - container specifications for using R in Vertex AI\r\nFROM gcr.io/deeplearning-platform-release/r-cpu.4-1latest\r\n\nWORKDIR /root\n\nCOPY train.R /root/train.R\rnCOPY serve.R /root/serve.R\r\n# Install Fortran\r\nRUN apt-get update\r\nRUN apt-get install gfortran -yyr\n\r\n# Install R packages\r\nRUN Rscript -e "install。packages(\'plumber\')"\r\nRUN Rscript -e "install.packages(\'randomForest\')"\r\n\nEXPOSE 8080'), (u'language', u''), (u'caption', <wagtail.wagtailcore.rich_text.RichText object at 0x3e2cdd499e10>)]
接下来,创建文件train.R ,用来训练你的R模型。该脚本在加州住房数据集上训练了一个随机森林模型。顶点人工智能设置了你可以利用的环境变量,由于这个脚本使用了顶点人工智能管理的数据集,数据分割由顶点人工智能执行,脚本接收指向训练、测试和验证集的环境变量。训练后的模型工件会被存储在你的云存储桶中。
代码_block
[StructValue([(u'code', u'#!/usr/bin/env Rscript\r\n#文件名:train.R - 在顶点AI管理的数据集上训练随机森林模型\r\nlibrary(tidyverse)\r\nlibrary(data.table)\r\nlibrary(randomForest)\r\nSys.getenv()\r\n\n# The GCP Project ID\r\nproject_id <- Sys.getenv("CLOUD_ML_PROJECT_ID")\r\n\n# The GCP Region\r\nlocation <- Sys.getenv("CLOUD_ML_REGION")\r\n\n# 上传训练好的模型工件的云存储URI到\r\nmodel_dir <- Sys.getenv("AIP_MODEL_DIR")\r\n\r\n# 接下来,你要创建目录来下载我们的训练、验证和测试集。创建("测试")\r\n\n# 你将顶点AI管理的数据集下载到本地的容器环境中。getenv("AIP_VALIDATION_DATA_URI"), "validation/"))\r\nsystem2("gsutil", c("cp", Sys.getenv("AIP_TEST_DATA_URI"), "test/"))\r\n\n# 对于每个数据集,你可能收到一个或多个CSV文件,你将读入数据框架。\训练_df <- list.files("training", full.names = TRUE) %>% map_df(~fread(.))\r\nvalidation_df <- list.files("validation", full.names = TRUE) %>% map_df(~fread(.))\r\ntest_df <- list.files("test", full.names = TRUE) %>% map_df(~fread(.))\r\n\nprint(" Starting Model Training")\r\nrf <- randomForest(median_house_value ~ .data=training_df, ntree=100)\r\nrf\nr\nsaveRDS(rf, "rf.rds")\r\nsystem2("gsutil", c("cp", "rf.rds", model_dir))'), (u'language', u''), (u'caption', <wagtail.wagtailcore.rich_text.RichText object at 0x3e2cdd499110>)】]
接下来,创建文件serve.R ,它用于服务你的R模型。该脚本从云存储下载模型工件,加载模型工件,并在8080端口监听预测请求。你有几个预测服务的环境变量供你使用,包括。
-
AIP_HEALTH_ROUTE:AI平台预测发送健康检查的容器上的HTTP路径。 -
AIP_PREDICT_ROUTE:AI Platform Prediction转发预测请求的容器上的HTTP路径。
代码_块
[StructValue([(u'code', u'#!/usr/bin/env Rscript\r\n#文件名:serve.R - serve predictions from a Random Forest model\r\nSys.getenv()\r\nlibrary(plumber)\r\nnsystem2("gsutil", c("cp", "-r", Sys.getenv("AIP_STORAGE_URI"), ".")\r\nsystem("du -a .")\r\nrf <- readRDS("artifacts/rf.rds")\r\nlibrary(randomForest)\r\npredict_route <- function(req, res) {\r\n print("处理预测请求")\r\n df <- as.data.frame(reqinstances)\r\n preds <- predict(rf, df)\r\n return(list(predictions=preds))\r\n}\r\n\nprint("Staring Serving")\r\npr() %>%\r\n pr_get(Sys.getenv("AIP_HEALTH_ROUTE"), function() "OK") %>%\r\n pr_post(Sys.getenv("AIP_PREDICT_ROUTE"), predict_route) %>%\r\n pr_run(host = "0.0.0.0", port=as.integer(Sys.getenv("AIP_HTTP_PORT", 8080))'), (u'language', u''), (u'caption', <wagtail.wagtailcore.rich_text.RichText object at 0x3e2cdd499a10>)】]
接下来,你在Cloud Build--无服务器CI/CD平台上构建Docker容器镜像。 构建Docker容器镜像可能需要10到15分钟。
代码_块
[StructValue([(u'code', u'sh("gcloud builds submit --region={REGION} --tag={IMAGE_URI} --timeout=1h")'), (u'language', u'), (u'caption', <wagtail.wagtailcore.rich_text.RichText object at 0x3e2cdd3e4fd0>)]
创建顶点AI管理数据集
你创建一个顶点AI管理的数据集,让顶点AI来处理数据集的分割。这是可选的,另外你可能想通过环境变量来传递数据集的URI。
代码块
[StructValue([(u'code', u'data_uri <- "gs://cloud-samples-data/ai-platform-unified/datasets/tabular/california-housing-tabular-regression.csv"\r\n\r\ndataset <- aiplatformcreate(\r\n display_name = "California Housing Dataset",\r\n gcs_source = data_uri\r\n) '), (u'language', u'), (u'caption', <wagtail.wagtailcore.rich_text.RichText object at 0x3e2cdd3e4f50>)] ]。
接下来的截图显示了云端控制台中新创建的Vertex AI托管数据集。
在顶点AI上训练R模型
自定义训练作业通过创建你的容器镜像的实例和执行train.R 进行模型训练和serve.R 进行模型服务来包装训练过程。
注意:你在训练和服务中使用相同的自定义容器。
代码_块
[StructValue([(u'code', u'job <- aiplatform$CustomContainerTrainingJob(\r\n display_name = "vertex-r",\r\n container_uri = IMAGE_URI, \r\n command = c("Rscript", "train.R"),\r/n model_serving_container_command = c("Rscript", "serve.R"),\r/n model_serving_container_image_uri = IMAGE_URI\r/n)'), (u'language', u''), (u'caption', <wagtail.wagtailcore.rich_text.RichText object at 0x3e2cc987cf90>)]
为了训练模型,你调用方法run() ,使用一个机器类型,其资源足以在你的数据集上训练一个机器学习模型。在本教程中,你使用一个n1-standard-4虚拟机实例。
代码_块
[StructValue([(u'code', u'model <- jobdisplay_name\r/nmodeluri'), (u'language', u'), (u'caption', <wagtail.wagtailcore.rich_text.RichText object at 0x3e2cdd3e4790>)])。
模型现在正在训练中,你可以在顶点AI控制台中观察进展。
提供一个端点资源并部署一个模型
你使用Endpoint.create()方法创建一个Endpoint资源。至少,你要指定端点的显示名称。另外,你可以指定项目和位置(区域);否则,这些设置将由你用init()方法初始化Vertex AI SDK时设置的值继承。
在这个例子中,指定了以下参数。
-
display_name:端点资源的一个可读名称。 -
project:你的项目ID。 -
location:您的地区。 -
labels:(可选)用户以键/值对的形式为Endpoint定义的元数据。
该方法返回一个Endpoint对象。
代码_块
[StructValue([(u'code', u'endpoint <- aiplatformcreate(\r\n display_name = "California Housing Endpoint",\r\n project = PROJECT_ID,\r\n location = REGION\r\n)'), (u'language', u'), (u'caption', <wagtail.wagtailcore.rich_text.RichText object at 0x3e2cdd636d50>)])。
你可以将一个或多个顶点AI模型资源实例部署到同一个端点。每个被部署的顶点AI模型资源将有自己的部署容器,用于服务二进制。
接下来,你将顶点AI模型资源部署到一个顶点AI端点资源。顶点AI模型资源已经为它定义了部署容器图像。为了部署,你指定以下额外的配置设置。
-
机器类型。
-
GPU的(如果有的话)类型和数量。
-
虚拟机实例的静态、手动或自动扩展。
在这个例子中,你用最小量的指定参数部署模型,如下所示。
-
model:模型资源。 -
deployed_model_displayed_name:部署的模型实例的人可读名称。 -
machine_type:每个虚拟机实例的机器类型。
由于配置资源的要求,这可能需要几分钟的时间。
注意:在这个例子中,你在上一步将模型工件上传到顶点AI模型资源中指定了R部署容器。
代码_块
[StructValue([(u'code', u'model$deploy(endpoint = endpoint, machine_type = "n1-standard-4")'), (u'language', u''), (u'caption', <wagtail.wagtailcore.rich_text.RichText object at 0x3e2cc987ccd0>)]
现在模型被部署到端点,你可以在顶点AI控制台看到结果。
使用新创建的端点进行预测
最后,您创建了一些示例数据来测试向您部署的模型发出预测请求。你在data_uri中使用原始数据文件中的五个JSON编码的示例数据点(没有标签median_house_value)。最后,你用你的例子数据做一个预测请求。在这个例子中,你使用REST API(例如Curl)来进行预测请求。
code_block
[StructValue([(u'code', u'library(jsonlite)\r\ndf <- read.csv(text=sh("gsutil cat {data_uri}", intern = TRUE))\r\nhead(df, 5)\r\ninstances <- list(instances=head(df[, names(df) != "median_house_value"], 5))\r\ninstances\r\njson_instances <- toJSON(instances)\r\nurl <- glue("https://{REGION}-aiplatform.googleapis.com/v1/{endpoint$resource_name}:predict")\r\naccess_token <- sh("gcloud auth print-access-token", intern = TRUE)\r\n/rsh("curl",\r\n c("-tr-encoding",\r\n"-s",\r\n"-X POST",\r\n glue("-H \ Authorization:Bearer {access_token}\'"),\r\n "-H \'Content-Type: application/json\'",\r\n url,\r\n glue("-d {json_instances}"),\r\n)'), (u'language', u'), (u'caption', <wagtail.wagtailcore.rich_text.RichText对象在0x3e2cdd3e4210>)])
该端点现在按照发送示例的相同顺序返回五个预测。
清理
要清理这个项目中使用的所有谷歌云资源,你可以删除你在教程中使用的谷歌云项目或删除创建的资源。
代码_块
[StructValue([(u'code', u'endpointdelete()\r\ndatasetdelete()\r\njob$delete()], (u'language', u'), (u'caption', <wagtail.wagtailcore.rich_text.RichText对象在0x3e2cdd3e4750>)])
总结
在这篇博文中,你已经经历了训练和部署R模型到顶点AI的必要步骤。为了便于复制,你可以参考GitHub上的这个笔记本。
鸣谢
这篇博文得到了很多人的帮助。特别是,我们要感谢Rajesh Thallam的战略和技术监督,Andrew Ferlitsch的技术指导、解释和代码审查,以及Yuriy Babenko的审查。




