结论(09-15 20:xx 二次修订):不是 SageAttention 复发、不是供电瞬断、也不是单纯过热——最可能是 生成时宿主内存被吃干 + ComfyUI 允许 pin 住 27.1 GiB 不可换页内存所导致的内存回收/驱动路径卡死。 依据:① 掉线期间屏幕仍显示画面、光标静止不闪、键盘无反应 → 供电正常,是整机内核冻结; ② 同样满载数小时的 LLM 从不掉线,只有 ComfyUI 生成 H3 才冻死 → 热量/电源/时长不是主因; ③ 生成中实测 ComfyUI RSS 28.3 GiB / 31.1 GiB、
MemAvailable仅 1.64 GB、8 GB 交换文件 100% 满、vmstat出现 si=1479/so=2234 的换页抖动,而 ComfyUI 的 pinned 上限按公式算正好是 27.1 GiB。 journald 在 18:38:35 CST 直接断掉,无 Xid / NVRM / 温度 / MCE / hung task / panic 任何一条, 整机网络(ARP/ICMP/SSH)同时消失,一直死到 22 分 42 秒后人工按电源复位——因为这台机器被配置成 「死机就永久死着」(panic=0、hung_task_panic=0、softlockup_panic=0、hardlockup_panic=0、 无 pstore、无 kdump),所以没留下死因。
| 时间 | 事件 | 来源 |
|---|---|---|
| 09-14 22:37:17 | 上一个 boot 启动(本次连续生成会话所在的那次开机) | journalctl --list-boots boot -1 |
| 09-15 18:10:49 | 最后一个成功产出:MiniMaxH3_Director_rv2v_00020_.mp4 入库相册 | gallery-sync.log 10:10:49 新收录 |
| 09-15 18:37 前后 | ComfyUI 正在跑一个 2 段 × 200 帧(共 400 帧 @24fps)的 rv2v、10 步任务,已到 segment 2/2 的 7/10 步(≈54.5 秒/步);segment 1/2 已完成(200 帧) | ComfyUI 日志末行 70%||███| 7/10 [07:16<02:43, 54.45s/it],文件 mtime 10:37 |
| 09-15 18:38:35 | 机器最后一条日志:一次来自 192.168.31.114(DSH 机)的 SSH 会话打开(gallery rsync 周期),此后 journald 再无任何记录 | journalctl -b -1 --since 10:37:00 末行 |
| 09-15 18:39:35 | gallery sync 首个失败:rsync exit 30 io timeout after 30 seconds → 随即 Connection timed out → No route to host | gallery-sync.log |
| 09-15 19:01:22 | 新 boot 启动(boot 0 f40d43c2…)→ 从挂死到恢复共 22 分 42 秒 | journalctl --list-boots |
| 09-15 19:01+ | 复检:GPU 正常(RTX 5060 Ti / 610.43.02 / 0% / 18 MiB / 38 °C / 8.8 W),ComfyUI 进程不在(本机设计为不自启) | nvidia-smi / ps |
shutdown system down 记录)。journalctl -b -1 -k | grep -iE "xid|nvrm|nvidia|gsp|thermal|throttl|mce|edac|hung task|blocked for more|Oops|BUG:|panic|watchdog|pcie.*(error|down)" → 除开机时的常规 PCIe/EDAC/NVRM 加载信息外,零命中。No route to host,说明不是「ComfyUI 崩了但机器还在」。grep -i sage 命中 7 处,全是 message / Usage 这类假匹配 → 本次运行没有 PathchSageAttentionKJ / MiniMaxH3MemoryEfficientSageAttentionPatch 之类节点。09-14 的元凶与本次无关,那次的修复是有效的。RuntimeWatchdogSec=off(systemd 默认注释)、/dev/watchdog 不存在 (没加载硬件看门狗驱动)、nmi_watchdog=1(只打印 hardlockup,不会重启)。/var/log/journal 存在(持久化 ✓),但 journald 默认 SyncIntervalSec=5m → 崩溃前最多 5 分钟的数据可能还在页面缓存里没落盘(这次丢掉的正是最后约 1 分钟)。「无任何内核报错 + 日志瞬断 + 整机网络同时消失」这个组合,符合以下三类之一:
| 假设 | 支持点 | 反对/待验证 |
|---|
用户现场观察(决定性证据,09-15 19:2x 补充):掉线期间屏幕仍在显示画面,但光标静止不闪烁、 键盘输入无任何反应。
| 假设 | 支持点 | 结论 |
|---|---|---|
| A. 供电瞬断 / PSU 保护动作 | 日志瞬断、无任何报错 | ❌ 基本排除:真断电会让显示器失去信号(黑屏 / No Signal);而画面还亮着、只是冻住 |
| B. 整机级内核冻结(CPU / GPU 驱动锁死) | 屏幕继续扫描出最后一帧(显示控制器与内核 VT 仍在输出)但光标不闪、输入无响应、不回 ARP/ICMP、22 分钟不自愈——这是内核已停止调度的典型表现 | ✅ 当前主因。缺的是「为什么锁死」:可能是 NVIDIA 驱动(NVRM/GSP)阻塞把整机拖进 D 状态,或 CPU 硬锁死 |
| C. 硬件复位(VRM / 主板 / 内存) | 无 | 降权:本质仍是断电重启,同样解释不了「屏幕还亮着」 |
结论:供电未断,是整机内核冻结。 之所以拿不到原因,是因为这台机器根本没有崩溃捕获能力:
| 机制 | 现状 | 后果 |
|---|---|---|
kernel.panic | 0 | 崩溃后不自动重启 |
kernel.panic_on_oops | 0 | oops 不升级为 panic |
kernel.hung_task_panic | 0(timeout 120s) | 进程卡 D 状态 120 秒也不 panic |
kernel.softlockup_panic / hardlockup_panic | 0 / 0 | 软/硬锁死只打印不重启(nmi_watchdog=1 只在还能写盘时有用) |
/sys/fs/pstore | 空 | 固件不上报崩溃残留 |
kdump-tools | 未安装(not-found) | 没有 vmcore |
| journald | 持久化 ✓,但 SyncIntervalSec=5m | 崩溃前最多 5 分钟日志可能丢(这次丢了最后约 1 分钟) |
另外两种可能已被排除:
last -x 也没有对应的 shutdown 记录;用户补充的关键对照事实:跑 LLM(LM Studio / ridge,llama.cpp)时同样连续满载数小时,从不掉线; 只有 ComfyUI 生成 H3 才会冻死。 这就把「热量 / 电源 / 时长」基本排除——同样是 100% 满载、同样 81 ℃、 同样 145 W,LLM 不出事。差别在宿主内存与驱动路径:
生成中实测(同一时刻采样):
| 指标 | 实测值 | 说明 |
|---|---|---|
ComfyUI 进程 RSS (VmRSS) | 28,999,508 kB ≈ 28.3 GiB | 占 31.1 GiB 物理内存的 91%;第二名 dockerd 只有 35 MB |
ComfyUI 被换出的内存 (VmSwap) | 5.37 GiB | 连它自己的页都被换到磁盘 |
MemFree / MemAvailable | 372 MB / 1.64 GB | 剩余可用内存几乎为零 |
| Swap 使用 | 8.4 GB(/swap.img 8 GB 100% 满) | 第二个 64 GB 的 /swap2.img 才用了 196 MB |
vmstat 换页 | 一次采样 si=1479 / so=2234 页/秒;SwapCached 2.4 GB | 典型的换页抖动(thrash),页面被反复换出又换回 |
| OOM kill / 分配失败 | 0 次 | 内核没杀进程,而是靠抖动硬扛 → 更容易演变成长时间卡死 |
而 --lowvram 模式下 ComfyUI 自己算出来的「可锁定内存上限」更是雪上加霜(源码 comfy/model_management.py:1585-1593):
MAX_PINNED_MEMORY = max(ram*0.40, min(ram*0.90, ram - 4*GiB, ram + swap - 16*GiB))
本机 ram=31.1 GiB、swap=72 GiB 代入:max(12.5, min(28.0, 27.1, 87.1)) = 27.1 GiB → 日志里那句 Enabled pinned memory 27792 就是它:ComfyUI 允许自己 pin 住 27.1 GiB 的 「不可换页」宿主内存,而机器只有 31.1 GiB。pinned 内存无法被换出,一旦内存已经吃紧、 内核再去 reclaim,就极易在内存回收 / 驱动内存管理路径上长时间停住——这与「屏幕还亮着、 光标不动、输入无反应、无任何内核报错、22 分钟不自愈」的表现一致。
为什么 LLM 没事:llama.cpp / LM Studio 是把 GGUF mmap 进来、KV cache 一次分配, RSS 有界(十几 GB),没有 cudaMalloc 抖动,也没有「按 RAM 比例算出来的 pinned 池」; 所以同样满载数小时不触发内存回收风暴。
⚠️ 诚实边界:以上是「运行在内存抖动区间」的机制性证据,不等于已经证明死锁发生在 reclaim 路径里——要坐实仍需 netconsole / panic 捕获(本报告 P0 那套,你目前选择不装)。
可用的现成开关(都在 ComfyUI 自己的参数里,无需改代码):
--disable-pinned-memory(cli_args.py:202,官方说明 "Disable pinned memory use.")→ 直接去掉那 27 GB 的不可换页池;--cache-lru 20(cli_args.py:142,官方说明 "May use more RAM/VRAM")→ 降到 2 或去掉;--fast-disk(cli_args.py:182,"Prefer disk-backed dynamic loading and offload over unpinned RAM")→ 保留,方向正确;比装任何监控都直接——把这次冻死的土壤去掉(32 GB 内存跑 20 GB 模型 + 5 GB VAE 的 --lowvram 本就吃紧):
--disable-pinned-memory(当前它允许 pin 27.1 GiB 不可换页内存);--cache-lru 20 → --cache-lru 2 或直接去掉(官方原话 "May use more RAM/VRAM");--fast-disk(它明确偏向磁盘后备、少占非 pinned RAM,方向是对的);while :; do grep -E "MemAvailable|SwapFree" /proc/meminfo | tr '\n' ' '; echo; sleep 30; done
MemAvailable 掉到 1 GB 以下、或 SwapFree 持续下降 → 已经进入危险区;
modinfo netconsole → /lib/modules/6.8.0-139-generic/kernel/drivers/net/netconsole.ko.zst ✓
把内核 printk 通过 UDP 实时发到 DSH 机(192.168.31.76)。整机冻死时磁盘写不进去,但网卡的 printk 路径仍可能把最后几条带出去——这是「屏幕冻住」这类故障唯一可靠的取证手段。 配套:DSH 侧跑一个 UDP 接收器落盘(~/netconsole-recv.py + systemd 单元,日志 netconsole-<host>.log)。
| 参数 | 建议值 | 作用 |
|---|---|---|
kernel.hardlockup_panic | 1 | CPU 硬锁死 → panic(nmi_watchdog 已在跑) |
kernel.softlockup_panic | 1 | CPU 软锁死 → panic |
kernel.hung_task_panic | 1(hung_task_timeout_secs 提到 300) | 进程卡 D 状态 → panic(300s 避免慢 I/O 误触发) |
kernel.panic | 10 | panic 后 10 秒自动重启 |
效果:这次那种「死着等人来按电源」22 分钟 → 约 2 分钟内自动重启,且 panic 内容会被 netconsole 带走。
journald SyncIntervalSec=5s(默认 5m → 5s,代价是更频繁的小写入)。
需要 crashkernel= 预留内存 + 安装 kdump-tools + 重启,能拿到完整内存转储; 代价是牺牲一部分内存、配置更复杂。要彻底定位「哪个驱动锁死」时再上。
~/restart_comfy.sh 已有)。先前建议的 gpu-forensic-logger.sh 是用户态进程——内核已经停止调度时它根本不会被执行, 所以抓不到这次的故障(它适合温度/功耗趋势、部分降级、GPU 单点异常这类「系统还活着」的场景)。 针对这次这种屏幕冻住的整机锁死,正确的工具是内核态路径:netconsole + panic-on-lockup。
| 文件 | 用途 | 部署位置 |
|---|---|---|
scripts/gpu-forensic-logger.sh | 崩溃前取证记录器(20s 一次,含 fsync) | GPU 机 ~/gpu-forensic-logger.sh |
scripts/gpu-forensic-logger.service | 上述记录器的 systemd 单元(Restart=always,CPUQuota=10%) | GPU 机 /etc/systemd/system/ |
scripts/comfyui-stall-watchdog.sh | 生成中途卡死检测(默认只记录,REBOOT_ON_STALL=1 才重启) | GPU 机 ~/comfyui-stall-watchdog.sh |
日志位置:~/gpu-forensic.log(200MB 轮转)、~/comfyui-stall.log。