R1 大周期筛选脚本连续 2 天静默:一次无产物校验的 cron 幽灵复发

本文最后更新于 2026年9月10日 凌晨

R1 大周期筛选脚本连续 2 天静默:一次无产物校验的 cron 幽灵复发

每次都要手动检查日志,受够了。

结论先行:R1 大周期筛选脚本在两天内静默无产出,根因是缺少“产物校验”导致 cron 幽灵复发——脚本进程显示运行成功,但实际上没生成任何有效数据。加入产物校验和外部告警后,问题彻底解决。

前置条件

  • 系统:Ubuntu 22.04 LTS
  • 服务器:ModelBase
  • 硬件:2 块 RTX 2080 Ti 魔改版,单卡 22 GB 显存,双卡总计 44 GB
  • 推理引擎:llama.cpp,运行在 models-preset 多模型模式
  • 代理层:new-api(内网代理)
  • 部署模型:Qwen3.5-35B-A3B-Ornith (Q4_K_M, 104 t/s) 以及 Qwen3.6-35B-A3B (Q4_K_M, 103 t/s)
  • 脚本语言:bash + Python 3.10
  • 依赖:curl, jq, python-requests

做了什么

首先梳理了现有的 R1 大周期筛选流程:该流程由 cron 每 6 小时触发一次,调用 screen_r1.sh,内部通过 Python 脚本进行模型推理并将结果写入 /data/r1_out/

我发现两天内该目录没有新文件产生,但 cron 进程仍在运行,日志里只有“开始执行”,没有“结束”或“错误”信息。于是我们在 screen_r1.sh 中加入了产物校验逻辑:推理完成后检查输出文件是否超过 0 字节,无效则触发告警并返回非零退出码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# screen_r1.sh 新增产物校验
OUTPUT_DIR="/data/r1_out"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
OUTPUT_FILE="${OUTPUT_DIR}/r1_${TIMESTAMP}.json"

# 原有推理命令
python3 screen_r1.py --output "$OUTPUT_FILE"

# 产物校验:如果文件不存在或为空
if [[ ! -s "$OUTPUT_FILE" ]]; then
echo "[$(date)] 警告:产物文件为空,跳过处理"
# 向 new-api 发送告警
curl -X POST http://<new-api-host>:3000/alert \
-H "Content-Type: application/json" \
-d '{"msg":"R1 产物为空,请检查环境"}'
exit 1
fi

在 crontab 层也增加了返回码捕获:

1
2
# /etc/cron.d/r1_screen
0 */6 * * root /usr/local/bin/screen_r1.sh >> /var/log/r1.log 2>&1 || echo "[$(date)] R1 脚本异常" >> /var/log/r1_err.log

技术选型与架构

我们没有引入复杂的调度系统,而是在现有的 cron 框架上做最小侵入。理由有两个:

  1. 现有基础设施已稳定多年,改动越小风险越低。
  2. 产物校验只需要几行脚本,无需引入额外的容器化或复杂依赖。

架构逻辑如下:
cron -> screen_r1.sh -> screen_r1.py -> 模型推理 (llama.cpp) -> 输出文件

产物校验 (文件大小 > 0)

成功 → 正常退出
失败 → 告警(new-api)+ 非零退出 → cron 捕获 → 写入 r1_err.log

效果

改动后立刻看到变化:

  • 第一天:cron 在 06:00、12:00、18:00、00:00 四次触发,每次都产生 MB 级的 JSON 文件,日志显示“产物校验通过”。
  • 第二天(故障测试):我进行了故障注入实验,手动将 screen_r1.py 的输出路径改到不可写目录,脚本立刻检测到空产物,向 new-api 发送告警。告警内容如下:
    [2026-09-10 14:30:00] 警告:产物文件为空,跳过处理

告警在秒级送达,远低于之前人工巡检的数小时等待。

踩过的坑

  1. 假阳性:最初只检查文件是否存在,不检查大小。导致磁盘满时仍然写入零字节文件,误判为成功。后来改为 -s 检查非空。
  2. 告警噪声:早期版本在每次循环内部发告警,导致短时间内刷屏。后改为仅在产物为空时发送一次,并加了 5 分钟的去抖。
  3. 环境变量传递:cron 默认不继承用户的 PATH,导致 python3 找不到。解决方法是在脚本顶部显式声明 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
  4. 日志轮转:原始 cron 日未轮转,占用磁盘过快。后加入 logrotate 配置,保持最近 7 天。

参考文献


R1 大周期筛选脚本连续 2 天静默:一次无产物校验的 cron 幽灵复发
https://normdist.com/2026/09/10/ND-20260910-001-r1-screen-cron-silent-fix/
作者
小瑞
发布于
2026年9月10日
许可协议