You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

解决SageMaker auto-stop-idle无法检测Papermill致实例提前关停问题

问题根因

AWS官方提供的auto-stop-idle生命周期脚本默认仅检测两类活动判定实例是否空闲:

  • Jupyter服务侧的API请求、内核代码执行记录
  • 实例上绑定到Jupyter会话的活跃内核进程CPU占用情况
    Papermill执行Notebook时是独立于Jupyter Web会话的Python进程,不管是手动在终端启动、还是通过定时/调度任务触发,都不会被默认的内核活动逻辑捕获,因此会被脚本误判为空闲,达到阈值后自动关停实例。
可行调整方案

按侵入性从低到高排序,可按需选择:

方案1:调度逻辑中临时启停自动停服规则

如果你的Papermill任务有明确的启动、结束触发点,不需要修改auto-stop脚本核心逻辑,直接在任务前后加控制命令即可:

  • Papermill任务启动前执行命令,暂停自动关停定时任务:
sed -i 's/^/#/' /etc/cron.d/auto-stop-idle
  • 所有Papermill任务执行完成后执行命令,恢复自动关停规则并重置空闲计时器:
sed -i 's/^#//' /etc/cron.d/auto-stop-idle
echo $(date +%s) > /home/ec2-user/SageMaker/auto-stop-idle/.idle_time

注意:如果任务执行中出现异常中断,会导致自动关停规则一直处于关闭状态,需要额外加异常捕获逻辑兜底。

方案2:修改auto-stop脚本,新增Papermill进程检测

这个方案最通用,不需要调整Papermill侧的执行逻辑,只需要补一段进程检测规则:

  1. 找到auto-stop脚本的核心执行文件,默认路径为/home/ec2-user/SageMaker/auto-stop-idle/autostop.py(生命周期配置中会把该脚本写到这个路径,由cron定时触发)
  2. 在脚本的空闲判定逻辑最前面,加入Papermill进程检测代码,检测到运行中任务时直接重置空闲计时器,跳过关停判断:
import psutil
import time

# 检测运行中/非僵尸状态的papermill进程
papermill_active = False
for proc in psutil.process_iter(attrs=['name', 'cmdline', 'status']):
    try:
        proc_name = proc.info['name'] or ''
        proc_cmd = proc.info['cmdline'] or []
        if 'papermill' in proc_name or any('papermill' in seg for seg in proc_cmd):
            if proc.info['status'] not in (psutil.STATUS_ZOMBIE, psutil.STATUS_DEAD):
                papermill_active = True
                break
    except (psutil.NoSuchProcess, psutil.AccessDenied):
        continue

# 存在活跃Papermill任务时,重置空闲时间后直接退出
if papermill_active:
    with open(IDLE_TIME_FILE, 'w') as f:
        f.write(str(time.time()))
    sys.exit(0)
  1. 保存修改后,不需要重启实例,下一次cron触发检测时就会自动加载新逻辑。
    该逻辑可以覆盖所有环境下启动的Papermill进程,包括conda虚拟环境、后台nohup启动的任务。

方案3:加心跳保活文件适配现有检测逻辑

如果不想改动进程检测相关逻辑,可以通过心跳文件的方式让现有脚本识别到活动:

  1. 在所有需要通过Papermill执行的Notebook最开头加入心跳线程,每隔1分钟更新一次保活文件的修改时间:
import os
import time
import threading

def papermill_keepalive():
    keepalive_path = "/home/ec2-user/SageMaker/.papermill_keepalive"
    # 先创建空文件
    open(keepalive_path, 'a').close()
    while True:
        # 更新文件最后修改时间为当前时间
        os.utime(keepalive_path, None)
        time.sleep(60)

# 启动后台保活线程,随任务退出自动终止
threading.Thread(target=papermill_keepalive, daemon=True).start()
  1. 修改auto-stop脚本的空闲判定逻辑,把保活文件的最后修改时间纳入判断维度:只要文件最后修改时间距当前时间小于设定的空闲阈值,就判定为非空闲,不执行关停。
验证步骤

修改完成后可以做简单校验避免误关停:

  • 手动启动一个耗时超过空闲阈值的Papermill测试任务
  • 等待时长超过设定的空闲阈值后,查看/var/log/auto-stop-idle.log日志,确认逻辑识别到Papermill活动、跳过了关停操作
  • 测试任务结束后,等待达到空闲阈值,确认实例可以正常自动关停

内容的提问来源于stack exchange,提问作者Led

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 23:27:36