我在R中运行一个rstan贝叶斯预测模型,大约需要60个小时才能确定结果。我目前正在本地桌面上执行此操作,因此我只是保持运行直到完成,但我们计划将其放在可能受不可预测的停机时间影响的服务器上。有没有办法,比方说,部分保存二进制文件,以便程序从服务器停机之前停止的地方恢复?
我不确定这个问题是否遵循SO的所有规则,或者之前是否已经得到解答 - 在任何一种情况下,如果您在标记之前指向备用资源,那将会很棒:)
由于
答案 0 :(得分:2)
如果可以,最好的方法是使用save
,save.image
或saveRDS
根据需要在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 ++命令结构,这样可以同时保存状态并重新启动。