Commit 0a45add1f9823974c0b9dd7e83a08e8eca1e118a
1 parent
817951ea
raylight watchdog.sh: 修复卡死误判——采样跑完后的VAE存盘阶段也套用了10分钟阈值
watchdog.sh按step字段判断denoise是否卡死,但没考虑到step到达total_steps(采样跑完)后 还有VAE解码+存盘这段没有独立进度信号的尾巴,step会停在最终值不变。这段被并入denoise 阶段的10分钟宽限,实测至少一个1344×768长帧数案例这个阶段本身就超过608秒,被误判卡死、 自动整机重启,打断了h3-showcase批量重跑中5个正在跑/排队的任务。修复:给这个阶段单独 一档30分钟宽限(STALL_LIMIT_POSTPROC)。已部署重启watchdog,被打断的5个任务已重新提交 (新任务ID同步进h3-showcase-cases.md)。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Showing
4 changed files
with
131 additions
and
16 deletions
CHANGELOG.md
| 1 | 1 | # 变更记录 |
| 2 | 2 | |
| 3 | +## 2026-08-25(凌晨)— 修复 watchdog.sh 误杀:把"采样跑完/VAE存盘中"当成卡死重启,打断了一批正在跑的任务 | |
| 4 | + | |
| 5 | +**背景**:批量重跑 16 个 h3-showcase 案例期间,队列跑到一半突然又出现"进程重启导致任务被取消/ | |
| 6 | +执行状态丢失"——5 个任务(1 个 failed + 4 个 cancelled)一次性被打断,一开始怀疑又是人为操作 | |
| 7 | +(跟8月24日PM2那次很像),查了才发现这次是机器自己的`watchdog.sh`干的。 | |
| 8 | + | |
| 9 | +**根因**:`watchdog.sh`(2026-08-23新增,按`step`字段判断任务卡死,不看总耗时)只区分了 | |
| 10 | +"FSDP初始化中(step=0)"和"denoise采样中(step>0)"两个阶段,没考虑到`step`到达`total_steps` | |
| 11 | +(采样跑完)之后还有VAE视频/音频解码+存盘这段没有独立进度信号的尾巴——`step`会一直停在最终值 | |
| 12 | +不变。这段被并入了denoise阶段的10分钟宽限,实测至少一个1344×768长帧数案例这个阶段本身就超过 | |
| 13 | +608秒,被误判"卡死"、自动`bash start.sh`整机重启,把当时排队中的一批任务连带打断。 | |
| 14 | + | |
| 15 | +**修复**:`watchdog.sh`给"`step>=total_steps`"这个采样完/存盘中阶段单独加一档30分钟宽限 | |
| 16 | +(`STALL_LIMIT_POSTPROC=1800`),不再跟denoise阶段共用10分钟的紧阈值。已部署并重启watchdog | |
| 17 | +进程(新PID替换旧的),被打断的5个任务已用存量`req_json`重新提交。详见 | |
| 18 | +`raylight/README.md`已知限制第10条。 | |
| 19 | + | |
| 20 | +**教训记录**:这台机器上至少有两套独立的自动重启机制(这个watchdog + 8月24日排查过的PM2托管 | |
| 21 | +服务),以后见到"进程重启导致任务被取消"这类错误,先查`watchdog.log`有没有"卡死判定触发", | |
| 22 | +比先怀疑人为操作更快定位。 | |
| 23 | + | |
| 3 | 24 | ## 2026-08-24(晚,续3)— 修复 raylight `/health` 骗人报健康的盲区,ComfyUI 崩了近20分钟没人发现 |
| 4 | 25 | |
| 5 | 26 | **背景**:续2记录的那次 ref2va OOM(`b659b60c6cbc`,FSDP初始化阶段GPU2/GPU3 OOM)实际上 | ... | ... |
docs/todo/h3-showcase-cases.md
| ... | ... | @@ -53,11 +53,11 @@ |
| 53 | 53 | |
| 54 | 54 | | # | 标题 | 模式 | 参考素材 | 状态 | 任务ID | 备注 | |
| 55 | 55 | |---|---|---|---|---|---|---| |
| 56 | -| 1 | 望远镜寻 MINIMAX 装置 | ref2va | 图1-4连续关键帧,已上传 | 已提交 | a59cae01ec39 | | | |
| 56 | +| 1 | 望远镜寻 MINIMAX 装置 | ref2va | 图1-4连续关键帧,已上传 | 已完成 | a59cae01ec39 | | | |
| 57 | 57 | | 2 | 史诗级太空歌剧院线短预告 | 纯文生(未确认) | 无/待确认 | 已完成 | 6639b07acc7b | | |
| 58 | -| 3 | 科幻悬疑电影短预告 | ref2va | 图1氛围/图2人物,已上传 | 已提交 | 97846542ab09 | | | |
| 59 | -| 4 | 高级时尚品牌视频(荒漠公路) | ref2va | 图1场景/图2人物/图3包袋/图4logo,已上传 | 已提交 | c1237b599bf4 | | | |
| 60 | -| 5 | 火场胶片时尚短片 | ref2va | 图1质感/图2人物,已上传 | 已提交 | 67ababbea78f | | | |
| 58 | +| 3 | 科幻悬疑电影短预告 | ref2va | 图1氛围/图2人物,已上传 | 已完成 | 97846542ab09 | | | |
| 59 | +| 4 | 高级时尚品牌视频(荒漠公路) | ref2va | 图1场景/图2人物/图3包袋/图4logo,已上传 | 已完成 | c1237b599bf4 | | | |
| 60 | +| 5 | 火场胶片时尚短片 | ref2va | 图1质感/图2人物,已上传 | 已完成 | 67ababbea78f | | | |
| 61 | 61 | |
| 62 | 62 | <details><summary>提示词原文</summary> |
| 63 | 63 | |
| ... | ... | @@ -85,7 +85,7 @@ |
| 85 | 85 | |
| 86 | 86 | | # | 标题 | 模式 | 参考素材 | 状态 | 任务ID | 备注 | |
| 87 | 87 | |---|---|---|---|---|---|---| |
| 88 | -| 1 | 悬疑犯罪电影片头 | ref2va | 多张风格参考图(7张),已上传 | 已提交 | 81711242178d | | | |
| 88 | +| 1 | 悬疑犯罪电影片头 | ref2va | 多张风格参考图(7张),已上传 | 已完成 | 81711242178d | | | |
| 89 | 89 | | 2 | 傍晚厨房手绘发光动画 | 纯文生 | 无 | 已完成 | c0e23beb4132 | | |
| 90 | 90 | | 3 | 深夜自助洗衣店手绘发光动画 | 纯文生 | 无 | 已完成 | 0fe0f2101c44 | | |
| 91 | 91 | | 4 | 手绘2.0,海边小集市指物变手绘 | 纯文生 | 无 | 已完成 | eaf2a1433c41 | | |
| ... | ... | @@ -113,7 +113,7 @@ |
| 113 | 113 | |
| 114 | 114 | | # | 标题 | 模式 | 参考素材 | 状态 | 任务ID | 备注 | |
| 115 | 115 | |---|---|---|---|---|---|---| |
| 116 | -| 1 | MiniMax H3 品牌开场 MG,波形 Logo | ref2va | 图1开场/图2波形logo,已上传 | 已提交 | 7ded7db676d3 | | | |
| 116 | +| 1 | MiniMax H3 品牌开场 MG,波形 Logo | ref2va | 图1开场/图2波形logo,已上传 | 已完成 | 7ded7db676d3 | | | |
| 117 | 117 | | 2 | MiniMax H3 品牌 MG「One becomes everyone」 | 纯文生 | 无 | 已完成 | 194e9bd77da6 | | |
| 118 | 118 | | 3 | 全中文文字动效实验影像 | 纯文生 | 无 | 已完成 | 125751cac1c8 | | |
| 119 | 119 | | 4 | Touch Designer 动效追踪 | ref2va(视频编辑) | @视频1基础素材 | 不支持 | | raylight 后端 GenReq 无"以视频为基础编辑"字段,无法提交 | |
| ... | ... | @@ -167,7 +167,7 @@ |
| 167 | 167 | |---|---|---|---|---|---|---| |
| 168 | 168 | | 1 | 古装武侠悬疑短剧,竹林 | 纯文生(未确认) | 无/待确认 | 已完成 | 57169e6751d0 | | |
| 169 | 169 | | 2 | 室内家庭争吵短剧(竖屏) | 纯文生 | 无 | 已完成 | 99e771bbb50d | 含具体人物「秦皓瑄」台词/语气要求 | |
| 170 | -| 3 | 海外吸血鬼爱情短剧预告(竖屏) | ref2va | 图1男女主/图2场景,已上传 | 已提交 | 71a4d093aebc | 720×1280竖屏提交 | | |
| 170 | +| 3 | 海外吸血鬼爱情短剧预告(竖屏) | ref2va | 图1男女主/图2场景,已上传 | 已完成 | 71a4d093aebc | 720×1280竖屏提交 | | |
| 171 | 171 | |
| 172 | 172 | <details><summary>提示词原文</summary> |
| 173 | 173 | |
| ... | ... | @@ -189,8 +189,8 @@ |
| 189 | 189 | |
| 190 | 190 | | # | 标题 | 模式 | 参考素材 | 状态 | 任务ID | 备注 | |
| 191 | 191 | |---|---|---|---|---|---|---| |
| 192 | -| 1 | 高级时尚眼镜广告,白棚双模特 | ref2va | 图1模特/图2外貌/图3眼镜,已上传 | 已提交 | b0d258352c3c | 720×1280竖屏提交 | | |
| 193 | -| 2 | Herman Miller 人体工学椅 360 展示 | ref2va | 图1产品详情/图2产品图,已上传(仅1张) | 已提交 | fe749aa533a0 | 文档里图1图2视觉上是同一素材,只上传了1张 | | |
| 192 | +| 1 | 高级时尚眼镜广告,白棚双模特 | ref2va | 图1模特/图2外貌/图3眼镜,已上传 | 已完成 | b0d258352c3c | 720×1280竖屏提交 | | |
| 193 | +| 2 | Herman Miller 人体工学椅 360 展示 | ref2va | 图1产品详情/图2产品图,已上传(仅1张) | 已完成 | fe749aa533a0 | 文档里图1图2视觉上是同一素材,只上传了1张 | | |
| 194 | 194 | | 3 | 北京烤鸭美食产品宣传 | 纯文生 | 无 | 已完成 | 4067993ff824 | | |
| 195 | 195 | |
| 196 | 196 | <details><summary>提示词原文</summary> |
| ... | ... | @@ -213,9 +213,9 @@ |
| 213 | 213 | |
| 214 | 214 | | # | 标题 | 模式 | 参考素材 | 状态 | 任务ID | 备注 | |
| 215 | 215 | |---|---|---|---|---|---|---| |
| 216 | -| 1 | 赛博朋克角色装备切换+UI+场景加载 | ref2va | 图1角色/图2 UI风格,已上传 | 已提交 | 2e18bf09b46a | 精确到秒的分镜时间轴,15s | | |
| 217 | -| 2 | 产品官网落地页 UI/UX 滚动演示 | ref2va | 图1产品图,已上传 | 已提交 | 234a2037e064 | | | |
| 218 | -| 3 | 网站 UI 标题滑动+汽车灯变色 | 按纯文生提交 | 无(提示词未引用@图片编号) | 已提交 | 88e3501a3fb9 | | | |
| 216 | +| 1 | 赛博朋克角色装备切换+UI+场景加载 | ref2va | 图1角色/图2 UI风格,已上传 | 已完成 | 2e18bf09b46a | 精确到秒的分镜时间轴,15s | | |
| 217 | +| 2 | 产品官网落地页 UI/UX 滚动演示 | ref2va | 图1产品图,已上传 | 已完成 | 234a2037e064 | | | |
| 218 | +| 3 | 网站 UI 标题滑动+汽车灯变色 | 按纯文生提交 | 无(提示词未引用@图片编号) | 已提交 | db125dc6a831 | | | |
| 219 | 219 | | 4 | 2D 手绘比格犬反应游戏界面 | 纯文生 | 无 | 已完成 | e1fd99e4ab97 | 原案例10s/4:3画幅,本次统一用1344×768/12.5s提交,用于观察分辨率适配效果 | |
| 220 | 220 | |
| 221 | 221 | <details><summary>提示词原文</summary> |
| ... | ... | @@ -240,7 +240,7 @@ |
| 240 | 240 | |
| 241 | 241 | | # | 标题 | 模式 | 参考素材 | 状态 | 任务ID | 备注 | |
| 242 | 242 | |---|---|---|---|---|---|---| |
| 243 | -| 1 | 机械臂抓取红色方块 | 纯文生 | 无 | 已提交 | 0a5ca897d076 | | | |
| 243 | +| 1 | 机械臂抓取红色方块 | 纯文生 | 无 | 已提交 | 282281777d1b | | | |
| 244 | 244 | | 2 | 精准替换视频背景为办公室场景 | 视频编辑 | 基于案例1输出 | 不支持 | | raylight 后端无视频编辑输入方式,且依赖案例1先跑完 | |
| 245 | 245 | |
| 246 | 246 | <details><summary>提示词原文</summary> |
| ... | ... | @@ -260,9 +260,9 @@ |
| 260 | 260 | |
| 261 | 261 | | # | 标题 | 模式 | 参考素材 | 状态 | 任务ID | 备注 | |
| 262 | 262 | |---|---|---|---|---|---|---| |
| 263 | -| 1 | 黏土动画狐狸跃崖 | 纯文生 | 无 | 已提交 | 760588dc9f82 | | | |
| 264 | -| 2 | 国风仙侠 3D 角色 PV | ref2va | 图1分镜/图2人物,已上传 | 已提交 | 28244b583d2d | | | |
| 265 | -| 3 | 乙游男主角色 PV | ref2va | 图2角色身份,已上传(合并图) | 已提交 | 329ed81249cd | 截图时未拆分图1/图2,用了含所需人物信息的合并图 | | |
| 263 | +| 1 | 黏土动画狐狸跃崖 | 纯文生 | 无 | 已提交 | 1a398591663e | | | |
| 264 | +| 2 | 国风仙侠 3D 角色 PV | ref2va | 图1分镜/图2人物,已上传 | 已提交 | 423a20afba5a | | | |
| 265 | +| 3 | 乙游男主角色 PV | ref2va | 图2角色身份,已上传(合并图) | 已提交 | d040eec16a88 | 截图时未拆分图1/图2,用了含所需人物信息的合并图 | | |
| 266 | 266 | |
| 267 | 267 | <details><summary>提示词原文</summary> |
| 268 | 268 | ... | ... |
raylight/README.md
| ... | ... | @@ -139,6 +139,19 @@ ssh admin@192.168.110.67 'cd /data/models/minimax-h3 && export H3_OFFLOAD=disk & |
| 139 | 139 | 探测一次8188,探测失败就把`ready`降级成0、`model`字段报`"comfyui_unreachable"`,不再 |
| 140 | 140 | 单纯相信内存里那个只写一次的标志位。**这条不能顶替第8条**——探测准了只是能更快发现 |
| 141 | 141 | 崩溃,8188死了以后还是要手动`bash start.sh`重启,自愈本身仍然没有。 |
| 142 | +10. **【2026-08-25修复】`watchdog.sh`的卡死判定漏了"采样跑完、VAE解码存盘中"这个阶段, | |
| 143 | + 把正常任务当卡死误杀重启**——`watchdog.sh`(2026-08-23新增,按`step`字段判断任务是否 | |
| 144 | + 卡死,见该脚本文件头注释)只区分"FSDP初始化中(step=0,20分钟宽限)"和"denoise采样中 | |
| 145 | + (step>0,10分钟宽限)"两个阶段,没考虑到`step`到达`total_steps`后(采样已经跑完)还有 | |
| 146 | + VAE视频/音频解码+存盘这段没有独立进度信号的尾巴,`step`会一直停在最终值不变。这段被 | |
| 147 | + 并入了10分钟宽限那档,实测至少一个1344×768长帧数案例这个阶段本身就超过608秒—— | |
| 148 | + watchdog判定"卡死"、自动执行`bash start.sh`整机重启,把当时排队中的一整批任务 | |
| 149 | + (h3-showcase-cases批量测试,5个)连带打断,跟"服务被别人手动重启"表现完全一样, | |
| 150 | + 一开始容易误判成人为操作。**已修**:给`step>=total_steps`这个"采样完/存盘中"阶段单独 | |
| 151 | + 一档`STALL_LIMIT_POSTPROC=1800`(30分钟宽限),不再跟denoise阶段共用10分钟的紧阈值。 | |
| 152 | + **排查经验**:见到"进程重启导致任务被取消"这类错误,先查`watchdog.log`有没有 | |
| 153 | + "卡死判定触发"字样,比先怀疑人为操作或`start.sh`被谁手动跑了更快定位——这台机器上 | |
| 154 | + 至少有两套独立的自动重启机制(这个watchdog + 8月24日排查过的PM2),别再默认是人。 | |
| 142 | 155 | |
| 143 | 156 | ## 多参考图生视频支持参考视频/独立音频参考(2026-08-24 新增) |
| 144 | 157 | ... | ... |
raylight/watchdog.sh
0 → 100644
| 1 | +#!/usr/bin/env bash | |
| 2 | +# 基于进度的卡死检测,取代之前"固定600秒墙钟时间"的误杀判定(2026-08-23)。 | |
| 3 | +# 判定标准:denoise 的 step 数字长时间不变才算卡死,不看总耗时——大分辨率/长帧数任务本来 | |
| 4 | +# 就该跑更久,不该被时间线误杀。 | |
| 5 | +# | |
| 6 | +# 【2026-08-25修复】漏了一个阶段:采样跑完(step达到total_steps)之后还有VAE视频/音频解码+ | |
| 7 | +# 存盘,这段没有独立进度信号,step会一直停在最终值不变——之前这段直接被并入 | |
| 8 | +# STALL_LIMIT_RUNNING(10分钟)判定,实测至少一个1344×768长帧数案例这个阶段本身就超过608秒, | |
| 9 | +# 被误判"卡死"重启,把一批正常在跑/排队的任务(showcase案例批次)集体打断。单独给这个阶段 | |
| 10 | +# 一个更宽的阈值,跟INIT阶段同样的思路——不同阶段没有可比的"正常耗时",不能共用一个数字。 | |
| 11 | +set -uo pipefail | |
| 12 | +BASE="http://127.0.0.1:8100" | |
| 13 | +STATE_FILE="/data/models/raylight/watchdog.state" | |
| 14 | +LOG_FILE="/data/models/raylight/watchdog.log" | |
| 15 | +STALL_LIMIT_RUNNING=600 # denoise 采样中(0<step<total_steps),step 10分钟不变才算卡死 | |
| 16 | +STALL_LIMIT_INIT=1200 # 还在FSDP初始化(step仍是0)阶段,给20分钟宽限 | |
| 17 | +STALL_LIMIT_POSTPROC=1800 # 采样已跑完(step>=total_steps),VAE解码/存盘阶段,给30分钟宽限 | |
| 18 | +POLL_INTERVAL=20 | |
| 19 | + | |
| 20 | +log() { echo "$(date '+%F %T') $*" >> "$LOG_FILE"; } | |
| 21 | + | |
| 22 | +# 状态文件格式:job_id step last_change_epoch | |
| 23 | +read_state() { cat "$STATE_FILE" 2>/dev/null || echo "none 0 0"; } | |
| 24 | +write_state() { echo "$1 $2 $3" > "$STATE_FILE"; } | |
| 25 | + | |
| 26 | +log "watchdog started" | |
| 27 | + | |
| 28 | +while true; do | |
| 29 | + sleep "$POLL_INTERVAL" | |
| 30 | + | |
| 31 | + HEALTH=$(curl -s --max-time 10 "$BASE/health" 2>/dev/null) | |
| 32 | + RUNNING=$(echo "$HEALTH" | python3 -c "import sys,json; print(json.load(sys.stdin).get('running',0))" 2>/dev/null) | |
| 33 | + if [ "$RUNNING" != "1" ]; then | |
| 34 | + write_state none 0 0 | |
| 35 | + continue | |
| 36 | + fi | |
| 37 | + | |
| 38 | + JOBS=$(curl -s --max-time 10 "$BASE/v1/videos?limit=5" 2>/dev/null) | |
| 39 | + CUR=$(echo "$JOBS" | python3 -c " | |
| 40 | +import sys, json | |
| 41 | +try: | |
| 42 | + jobs = json.load(sys.stdin) | |
| 43 | + for j in jobs: | |
| 44 | + if j.get('status') == 'running': | |
| 45 | + print(j['id']); break | |
| 46 | +except Exception: | |
| 47 | + pass | |
| 48 | +" 2>/dev/null) | |
| 49 | + [ -z "$CUR" ] && continue | |
| 50 | + | |
| 51 | + DETAIL=$(curl -s --max-time 10 "$BASE/v1/videos/$CUR" 2>/dev/null) | |
| 52 | + STEP=$(echo "$DETAIL" | python3 -c "import sys,json; print(json.load(sys.stdin).get('step',0))" 2>/dev/null) | |
| 53 | + [ -z "$STEP" ] && STEP=0 | |
| 54 | + TOTAL_STEPS=$(echo "$DETAIL" | python3 -c "import sys,json; print(json.load(sys.stdin).get('total_steps',0))" 2>/dev/null) | |
| 55 | + [ -z "$TOTAL_STEPS" ] && TOTAL_STEPS=0 | |
| 56 | + | |
| 57 | + read -r PREV_ID PREV_STEP PREV_TS < <(read_state) | |
| 58 | + NOW=$(date +%s) | |
| 59 | + | |
| 60 | + if [ "$CUR" != "$PREV_ID" ] || [ "$STEP" != "$PREV_STEP" ]; then | |
| 61 | + write_state "$CUR" "$STEP" "$NOW" | |
| 62 | + log "job=$CUR step=$STEP (progress, reset stall timer)" | |
| 63 | + continue | |
| 64 | + fi | |
| 65 | + | |
| 66 | + STALLED_FOR=$((NOW - PREV_TS)) | |
| 67 | + if [ "$STEP" = "0" ]; then | |
| 68 | + LIMIT=$STALL_LIMIT_INIT | |
| 69 | + elif [ "$TOTAL_STEPS" != "0" ] && [ "$STEP" -ge "$TOTAL_STEPS" ] 2>/dev/null; then | |
| 70 | + LIMIT=$STALL_LIMIT_POSTPROC | |
| 71 | + else | |
| 72 | + LIMIT=$STALL_LIMIT_RUNNING | |
| 73 | + fi | |
| 74 | + | |
| 75 | + if [ "$STALLED_FOR" -ge "$LIMIT" ]; then | |
| 76 | + log "job=$CUR step=$STEP 卡死判定触发:$STALLED_FOR 秒无进展(阈值 $LIMIT),执行重启" | |
| 77 | + bash /data/models/raylight/start.sh >> "$LOG_FILE" 2>&1 | |
| 78 | + write_state none 0 0 | |
| 79 | + log "重启完成" | |
| 80 | + fi | |
| 81 | +done | ... | ... |