【问题标题】:Keep R Model in memory for Rest API将 R 模型保存在内存中以供 Rest API
【发布时间】:2017-08-01 20:01:03
【问题描述】:

我们有一个大小约为 2 GB 的 GLM R 模型。我们正在使用此模型为 REST API 提供服务。我们需要

在高层次上:

  1. 为 REST API 提供服务。

  2. 在内存中保留数 GB 的模型。

  3. 将响应时间保持在 3 秒以下。

我们尝试过但不起作用的东西:

  1. 缩小模型的大小。我们的数据科学家说,这是他能做到的。

  2. 我在 saveRDS 上尝试过压缩和其他设置。我能做的最好的事情是 12 秒从文件中加载模型。

  3. 我们尝试了 Microsoft R Server。所有 Web API 请求都将被重定向到同一个会话。问题是我们必须围绕保持会话活动包装大量代码。即使那样它也会经常剥落。

  4. Microsoft R Server Real Time 已过时,因为它只接受 ScaleR 生成的模型。我知道 ScaleR 有 GLM 功能,但有人告诉我它不是一个选项。

  5. 更快的 IO 似乎没有帮助。看来瓶颈是 rData 文件的反序列​​化。 R 是单线程并没有帮助。

编辑: 问题是 REST API 库/服务的 R 将允许我们在调用之间有状态地将模型保存在内存中。

【问题讨论】:

  • 你有什么问题?
  • 一个 2 GB GLM :thinking: 我会仔细检查你确定不能把它变小。
  • 我认为问题在于 GLM 模型在保存时保留了训练数据的副本。为什么不手动导出系数和分数(即让 API 生成分数)?使用简单的线性模型应该足够简单,因为它只是 y = Beta1 * var1 + Beta2 * var2... 等等。
  • 正如另一个响应中提到的,我们想要计算置信区间和概率区间。我们现在正在寻找将这种计算转移到数据库中的方法。

标签: r rest


【解决方案1】:

继续我上面的评论以及@TenniStats 的建议,最好的方法是减小 GLM 的大小。考虑以下几点:

#generating some sample data that's fairly large
sample.data <- data.frame('target' = sample(c(1:10), size = 5000000, replace = T),
                          'regressor1' = rnorm(5000000),
                          'regressor2' = rnorm(5000000),
                          'regressor3' = rnorm(5000000),
                          'regressor4' = rnorm(5000000),
                          'regressor5' = rnorm(5000000),
                          'regressor6' = rnorm(5000000),
                          'regressor7' = rnorm(5000000),
                          'regressor8' = rnorm(5000000),
                          'regressor9' = rnorm(5000000),
                          'regressor10' = rnorm(5000000))

#building a toy glm - this one is about 3.3 GB
lm.mod <- glm(sample.data, formula = target ~ ., family = gaussian)

#baseline predictions
lm.default.preds <- predict(lm.mod, sample.data)

#extracting coefficients
lm.co <- coefficients(lm.mod)

#applying coefficients to original data set by row and adding intercept
lightweight.preds <- lm.co[1] +
  apply(sample.data[,2:ncol(sample.data)],
        1,
        FUN = function(x) sum(x * lm.co[2:length(lm.co)]))

#clearing names from vector for comparison
names(lm.default.preds) <- NULL

#taa daa
all.equal(lm.default.preds, lightweight.preds)

那么我们可以做以下事情:

#saving for our example and starting timing
saveRDS(lm.co, file = 'myfile.RDS')
start.time <- Sys.time()

#reading from file
coefs.from.file <- readRDS('myfile.RDS')
#scoring function
light.scoring <- function(coeff, new.data) {
  prediction <- coeff[1] + sum(coeff[2:length(coeff)] * new.data)
  names(prediction) <- NULL
  return(prediction)
}

#same as before
light.scoring(coefs.from.file, sample.data[1, 2:11])
#~.03 seconds on my machine
Sys.time() - start.time

【讨论】:

  • 与我们的数据科学家聊天。最大的问题是我们需要计算置信区间和概率区间以配合我们的预测。这给了我们一条下坡路。
猜你喜欢
  • 1970-01-01
  • 2016-01-06
  • 1970-01-01
  • 2019-06-24
  • 2018-08-08
  • 2014-08-27
  • 2016-10-13
  • 2013-01-23
相关资源
最近更新 更多