如何在R中定期保存部分计算的模型?

时间:2015-08-04 07:05:22

标签: r server stan

我在R中运行一个rstan贝叶斯预测模型,大约需要60个小时才能确定结果。我目前正在本地桌面上执行此操作,因此我只是保持运行直到完成,但我们计划将其放在可能受不可预测的停机时间影响的服务器上。有没有办法,比方说,部分保存二进制文件,以便程序从服务器停机之前停止的地方恢复?

我不确定这个问题是否遵循SO的所有规则,或者之前是否已经得到解答 - 在任何一种情况下,如果您在标记之前指向备用资源,那将会很棒:)

由于

2 个答案:

答案 0 :(得分:2)

如果可以,最好的方法是使用savesave.imagesaveRDS根据需要在R代码中构建一些检查点。如果你不能(因为例如时间都花在C代码上),那么你可以看一些更通用的东西。

适用于最新版Linux的任何正在运行的任务的通用解决方案是使用criu。这种方法有几点需要注意。首先,criu必须以root身份运行,通常使用sudo。如果您在运行代码的服务器上没有root权限,这可能是一个破解者。您(或管理员)可以将criu添加到/ etc / suoders,但显然这具有安全隐患,特别是因为criu可以运行任意操作脚本,该脚本也将以root权限运行。

如果您确实能够以root身份运行进程,并且对潜在的安全问题感到满意,那么这是一个解决方案。我假设你有一个名为'long-running-script.r'的R脚本。

这是所需的文件:

run-long-run.sh:

#!/bin/bash
set -e
if [ -d "r-criu-current" ]
then
  RPID=$(ls r-criu-current/core*.img |perl -pe's/.*?(\d+)\.img/\1/')
  if (ps -p$RPID >/dev/null) then
    ps -p$RPID
    echo "A process is already running with the PID $RPID; perhaps the old process hasn't exited."
    exit 1
  fi
  bash r-criu-pre-restore.sh
  criu restore -D r-criu-current &
else
  setsid Rscript "long-running-script.r" </dev/null &>r-criu.log &
  RPID=$!
fi
echo $RPID
mkdir -p r-criu-current
while :; do
  sleep 5m # Change if needed
  if kill -0 "$RPID" 2>/dev/null
  then
    mkdir -p r-criu-temp
    criu dump -t $RPID --leave-running -D r-criu-temp --action-script ../r-criu-post-dump.sh
    rm -rf r-criu-old || true
    mv r-criu-current r-criu-old
    mv r-criu-temp r-criu-current
    echo "Snapshot saved at "$(date)
  else
    echo "R finished"
    exit
  fi
done

r-criu-pre-restore.sh:

#!/bin/bash
cp r-criu-current/r-criu.log .

r-criu-post-dump.sh :(请注意,这将在r-criu-temp中有一个工作目录,因此需要使用..引用文件)

#!/bin/bash
[ "$CRTOOLS_SCRIPT_ACTION" = post-dump ] || exit 0
cp ../r-criu.log .

长running.script.r:

i <- 0
while(TRUE) {
  i <- i + 1
  cat(i, "\n")
  Sys.sleep(10)
}

主要脚本的作用是检查以前的检查点。如果它存在且进程仍未运行,则从该检查点恢复进程。如果没有,它将在新会话中从头开始脚本,并将输出重定向到日志文件。然后,每隔5分钟(虽然可以改变),脚本会调用criu来检查正在运行的R进程,同时仍然让它运行。 r-criu-post-dump.sh脚本用于确保在转储时保留任何文件。在这种情况下,仅更改日志文件,但可以根据需要复制其他文件。然后在恢复检查点之前恢复这些文件。

在每个时间点,应该保留两个检查点,即当前的检查点和最近的检查点。这是为了防止在创建/移动检查点时发生崩溃/电源故障。

答案 1 :(得分:1)

你确定需要跑60个小时吗?您需要什么样的有效样本量?在链条收敛之前需要多长时间?此外,有多种方法可以通过矢量化加速Stan程序,使用足够的统计数据,重新定义早期块中的变量,重用重复的子表达式,用对角化协方差矩阵替换多元法线和矢量化单变量法线,根据数据大小重新参数化等。感觉费用让我们在Stan用户群上留下一条线 - 有更多的Stan用户和开发人员在那里听(虽然你可以看到我和Ben跳过,我们现在也在监视stackoverflow)。

您可以使用CmdStan流式传输绘图。在你到达预热结束之前没有办法保存适应状态,即使这样,也没有办法在该状态下重启,所以它无法解决你的问题。

我们正在为Stan 3重构底层C ++命令结构,这样可以同时保存状态并重新启动。