交接文档 · 2026-09-03(最新)
给下次进来的人(或进程)。先读这份,再读
CLAUDE.md。 权威细节在llm-setup.md(整机)、raylight/README.md(视频线,2026-08-22起的生产 后端)、h3-console/README.md(Web 管理台)。时间线在CHANGELOG.md。 这里只写「现在是什么状态、下一步该干什么」——下面 2026-08-20 及更早的几节是历史记录, 架构已经变了(minimax-h3 旧代码已删除,raylight 是现在的生产后端),仍有效的踩坑经验 保留,但状态类的表格/结论以这一节为准,不要用旧的。
2026-09-03:现在是什么状态
一句话:生产 H3 后端是 raylight/(ComfyUI + Raylight 插件,4卡当一个 FSDP 集群,
详见 CLAUDE.md「当前负载」表),minimax-h3/ 旧架构代码已经在 8/24 删除只剩权重。
今天这轮会话围绕 raylight + h3-console 做了一批修复/功能,全部已部署到服务器验证通过、
已提交推送到 git(最新 46fa265),细节见 CHANGELOG.md 2026-09-03 那两节:
- 修了一个真实 bug:参考图/参考视频文件名带中文时,
raylight/server.py的_fetch_to_input()用urllib.request.urlopen直接崩UnicodeEncodeError(HTTP 请求行必须纯 ASCII,中文没 percent-encode)。 - 排队优先级/插队:
Job加queue_seq,Q从queue.Queue()换成queue.PriorityQueue(),新增POST /v1/videos/{jid}/prioritize,console 详情页/ 列表菜单都加了"优先插队"按钮。 - 重启不再清空排队任务:这是顺带发现的架构问题——
start.sh重启前,排队中的任务 会被无条件标记cancelled(内存队列重启即空,sqlite 里的记录没有任何路径被重新入队)。 现在重启会把排队中的任务原样保留、按序重新入队,只有"正好卡在重启瞬间"那条真运行中的 任务救不回来(这个改不了,GPU 执行状态确实丢了)。这条改动很重要:以后改raylight/server.py要重启,不用再担心把排队任务清空了,只需要挑当前没有任务在跑 的时机(或者接受损失那一条正在跑的)。 - 补回一个 8/24 提交过、但从未真正部署到服务器的 ComfyUI 存活探测(
_comfyui_alive, 修/health在 ComfyUI 进程崩溃后仍骗人报 ready 的监控盲区)。顺带把本地长期分叉的raylight/server.py(顶层)和raylight/scripts/server.py两份文件同步一致。 h3-console的GET /v1/models之前硬编码 3 档过期数据(模型文件名指向已删除的api.py/gateway.py旧架构),改成实时问 raylight 新增的GET /v1/resolutions(RESOLUTION_CEILINGS的镜像),现在正确返回全部 8 档。- 任务详情页加了两个排查用字段(默认折叠):原始参数(
req原样 JSON)、 ComfyUI History(懒加载,问 raylight 新增的GET /v1/videos/{jid}/comfy_history, 透传 ComfyUI 自己的/history/{prompt_id}——这份数据在 ComfyUI 内存里,进程重启就没了, 不是 bug)。生成结果视频从页面底部挪到了状态/操作按钮那一行下面。
当前各服务实际状态(2026-09-03 晚实测,不是文档推测)
| 服务 | 状态 | 说明 |
|---|---|---|
raylight(ComfyUI 8188 + server.py 8100) |
在跑,4卡满载 100% | 16 条排队 + 1 条运行中(正常工作负载,不是卡住) |
h3-console(8080,LAN) |
在跑 | systemctl is-active → active,今天带新代码重启过 |
h3-console(8081,公网 /console 子路径) |
在跑 | 同上 |
llm38 / whisper / m3e-embedding(docker) |
停(Exited,2周前) |
不是本次操作停的,沿用既有目标状态(这台机器当前只跑 H3) |
| GPU 显存 | 4×22528MiB 卡各用 ~11.5G,100% 利用率 | raylight 一直有任务在跑,正常 |
磁盘 / |
81% used,剩 43G | 没报警但在收紧,留意 |
磁盘 /data |
89% used,剩 199G | 同上 |
下一步 / 需要留意的点
- 没有阻塞性待办——这轮改动都已验证上线,git 已推送。
- 排队积压 16 条是正常业务量(用户在批量提交任务测试),不是系统故障,仅供下次进来的人 了解上下文,别误判成"卡住了"。
h3-console的/v1/models里partitions字段的模型文件名这次顺手改成了 raylight 现在实际用的(minimax_h3_fl2va_pruned_int8_convrot.safetensors等),去掉了对不上号 的lora字段——这块用户没有明确要求改,只是顺手核实清楚了,如果有外部消费者依赖旧字段 形状需要留意。- 磁盘两边都过 80% 了,暂时没影响什么,但没有余量报警,紧张起来会跟其它任务一样直接写
失败——跟
llm-setup.md里旧的磁盘提醒是同一类风险,值得找时间清一次。
交接文档 · 2026-08-20(历史,状态类结论已过时,见上面最新一节)
⚠️ 下面这节写的时候
minimax-h3/gateway.py还是生产后端,raylight/还没上线。 2026-08-22 起 raylight 才是生产默认后端,minimax-h3 代码已在 8/24 删除。看这节纯为 保留历史踩坑记录,不要照着下面的服务状态表操作。
2026-08-20 夜:现在是什么状态
一句话:h3-console(Web 管理台)今天从零做到部署上线并经过好几轮真实使用反馈迭代
(重跑、回收站、任务记录落盘、假运行中修复、公网子路径接入),本地代码已建 git 仓库推到
git@gitlab-wuwei.hexpm.com:yibo/2080tiserver.git。同时发现一个容易踩的坑:
qwen.wudaima.com 这个域名现在实际没有在提供 Qwen LLM 服务——见下面「重要」。
⚠️ 重要:qwen.wudaima.com 现在不是 LLM,是 minimax-h3 的 gateway.py
docker ps是空的——llm38容器现在没有在跑(不是本次改的,是之前某个时间点被停的, 可能是之前的会话为了腾显存给 H3 四卡停的,没有记录明确是谁什么时候停的)。- 端口 8000 现在被
minimax-h3/gateway.py占着(ss -lptn能看到是个 python 进程,不是 llama.cpp)。frp 的qwen-llm代理转发的正是本机 8000 端口,所以公网http://qwen.wudaima.com/health现在返回的是 gateway.py 的 JSON({"ready":4,...,"backends": [...]}),不是 Qwen 的/health,qwen.wudaima.com/v1/videos现在也是能直接无鉴权提交 视频生成任务的(跳过了 h3-console 那层)。 - 要恢复 Qwen LLM 公网服务:先确认 minimax-h3 的四个 worker 不在关键任务中途,
停掉占着 8000 的 gateway.py(
ss -lptn "sport = :8000" | grep -o "pid=[0-9]*"找 PID 再kill——不是 PM2 托管的,直接 kill 有效),再docker start llm38(约 15 秒)。 两者不能共存在同一个 8000 端口上。
当前各服务实际状态(2026-08-20 深夜实测,不是文档推测)
| 服务 | 状态 | 说明 |
|---|---|---|
llm38(Qwen3.8-27B,docker) |
停(docker ps 为空) |
恢复见上面「重要」一节 |
whisper(docker,8002) |
停 | 同上,docker 里没有容器在跑 |
PM2 m3e / sd-forge |
停 | 沿用 2026-08-19 就定的目标状态,没有变化 |
minimax-h3 四个 api.py worker(8010-8013) |
在跑 | 分区会被弹性调度器动态 flip,此刻实测是 3 张 fl2va + 1 张 ref2va(GPU0 ref2va,GPU1/2/3 fl2va),不是固定的,正常 |
minimax-h3/gateway.py(8000) |
在跑,占着 qwen.wudaima.com |
见上面「重要」 |
h3-console(8080) |
在跑 | 局域网直连 http://192.168.110.67:8080,开着弹性调度器(H3_ENABLE_SUPERVISOR=1) |
h3-console(8081,子路径专用) |
在跑 | 公网 http://qwen.wudaima.com/console,H3_CONSOLE_BASE_PATH=/console,不开弹性调度器(两个调度器同时抢会重现"一个请求切三张卡"的老 bug),跟 8080 那个共享同一份 console.sqlite3/assets/ |
GPU 显存(nvidia-smi) |
GPU0 5.3G / GPU1 21.3G / GPU2 19.4G / GPU3 18.5G(共 88G) | llm38 停着,所以余量看着比 CLAUDE.md 顶部旧表格写的宽松,但四张卡跑满 minimax-h3 也会吃紧,起新负载前还是先看一眼 |
今天做的事(详细踩坑记录都在 CHANGELOG.md,这里只列条目)
- h3-console 任务详情页加「重跑」按钮(第一版直接后台重投,被否决后改成回填表单跳转新建页)。
- 修复「后端进程重启后任务永远显示假运行中」——
_refresh_from_gateway遇到 404 现在正确判failed。 api.py的frames硬顶 124 改成按rows(分辨率×帧数)动态判定,ROWS_LIMIT=20000(支持H3_ROWS_LIMIT环境变量临时覆盖,仅供边界探测用)。start-all.sh冷启动默认分区从「4 张全 ref2va」改成 2/2 固定分裂(GPU0/1 ref2va,GPU2/3 fl2va)。- 左下角后端状态行补上
running×N/queued×N,之前明明有任务在跑也只显示ok。 api.py任务记录改成落盘(jobs_gpu{N}.sqlite3),弹性调度器 kill+restart 某张卡时不再 把这张卡上正在跑的任务从内存里一起清空。- 任务列表加软删除/回收站(
deleted_at列 +?trash=true+ 恢复接口)。 - 排查清楚
gateway.wudaima.com独立域名为什么公网打不通——缺口在 frp 服务端60.205.214.169,不是这台机器能改的,没有再等它。 - 改走
qwen.wudaima.com/console子路径对外开放 h3-console(H3_CONSOLE_BASE_PATH支持- 起第二个 8081 实例 + frp
locations=/console分流),验证通过、qwen.wudaima.com原有 服务没受影响(因为它现在本来就不是 LLM,见上面「重要」)。
- 起第二个 8081 实例 + frp
- 补齐了本地
minimax-h3/镜像里此前一直缺失的gateway.py等 13 个文件(和服务器漂移的 缺口),本地建了 git 仓库并推到git@gitlab-wuwei.hexpm.com:yibo/2080tiserver.git。CLAUDE.md里明文写着的 SSH 密码也一起提交了,跟用户确认过、这是有意为之。
下一步(按优先级)
- 决定 Qwen LLM 要不要恢复——现在公网
qwen.wudaima.com实际在裸露 minimax-h3 的 gateway API(无鉴权),如果这不是有意的,需要判断是先恢复 llm38 还是先给 gateway.py/ h3-console 补鉴权。这是产品/安全决策,需要用户拍板,不要擅自停 gateway.py 起 llm38 ——四个api.pyworker 现在正被gateway.py管着,直接停可能打断正在跑的生成任务。 gateway.wudaima.com独立域名:如果还想要这条线(而不是永久用 qwen 子路径顶替), 需要找到能登录60.205.214.169的人补一条 nginx vhost 转发规则。- 鉴权:h3-console 和 gateway.py 现在都无鉴权,公网可直调。
h3-console/DESIGN.md问题3 有现成方案(Authorization: Bearer+ 环境变量),跑通了再加,一直没排上。 - 磁盘
/只剩 29G,/data83% 满——暂时没出问题,但没有余量报警,真紧张时会和其它任务一样 直接写失败。
交接文档 · 2026-08-18(历史,状态类结论已过时,见上面最新一节)
一句话
今天做了两件事:llm38 单请求上下文 32K → 256K(已完成、已验收、已恢复), MiniMax-H3 文生视频从零部署到出片 + 封了 HTTP API(已出片、已验收,服务当前在跑,环境未恢复)。
2026-08-19 16:30 更新:断连 13 小时后重连
- 50 步全质量已完成并验收(6.4 MB · 5364 s · 107.3 s/步 · 峰值 9.1 G · 帧间差异 7.366 · 音频 −27.2 dB)。
两档都出片,详见
minimax-h3/README.md验收记录。 - 断连原因是本地网络:Mac 到 192.168.110.x 的路由被 VPN 隧道(
utun7/198.18.0.1)劫持。 期间nc -z对所有端口都返回成功(连 9999 和只听 127.0.0.1 的 7860 也"通")—— 那是假阳性,别据此判断服务状态。用ping+route -n get确认路径。 - 期间另有进程在这台机器上工作:两个 H3 API 实例常驻(8010 → GPU1 13.0 G / 8011 → GPU2 7.7 G,
两者
/health均 ok),api.py被改过(新增PARTITION字段),新增restart-8010.sh,outputs/里有 6 个非本次生成的视频。
★ 当前是用户指定的目标状态:只留 H3 ★
2026-08-19 16:40 用户明确:「停止 llm38」「只留着 h3 即可」。 所以下面这四个停着是对的,不要"顺手"起回来:
| 服务 | 状态 | 说明 |
|---|---|---|
llm38(8000) |
停 | 配置已是 256K 单请求上下文并验收过,需要时 docker start llm38 |
whisper(8002) |
停 | docker start whisper |
PM2 m3e(7590) |
停 | /usr/local/node/bin/pm2 start m3e |
PM2 sd-forge(7860) |
停 | /usr/local/node/bin/pm2 start sd-forge |
| H3 API 8010 / 8011 | 运行中 | 唯一保留的负载,占 GPU1+GPU2 共 20.8 G |
GPU0 与 GPU3 全空(各 22002 MiB)。恢复命令详见 deploy-scripts/RESTORE-GPU.md。
⚠️ 要恢复 llm38 时注意:它跑 256K 需四卡各约 14.3 G,而 GPU1 现被 8010 占着只剩 8.95 G。 要共存就用
--parallel 1 --ctx-size 262144(单请求仍 256K,并发降为 1,省 16 G), 或先停一个 H3 实例。
⚠️ 立刻要知道的三件事
- 四个服务当前是停的,而这是用户要的状态(见上一节),不是未完成的收尾。
需要时按
deploy-scripts/RESTORE-GPU.md恢复,恢复后验 7590 / 7860 / 8000 / 8002 四个端口。 m3e和sd-forge由 PM2 托管(God Daemon PID 1467)。kill它们没用, 60 秒内会被拉回来;必须/usr/local/node/bin/pm2 stop m3e sd-forge。恢复是pm2 start。 pm2 不在默认 PATH 里,非交互 shell 下写全路径。- 一条 50 步全质量视频还在跑(GPU2,22:22 启动,约 90 分钟,预计 23:50 左右完), H3 的 API 服务也在跑(GPU1,端口 8010)。恢复环境前先确认这两个结束/停掉。
状态速查
| 东西 | 状态 | 位置 |
|---|---|---|
| llm38(Qwen3.8-27B) | 已停。配置已改成 256K 单请求上下文,验收过 | deploy-scripts/ctx256k.sh |
llm38 旧容器 llm38_prev |
保留着(32K 配置),确认稳定后可 docker rm |
/ 只剩 29 G,别忘 |
| whisper / m3e / sd-forge | 已停 | deploy-scripts/RESTORE-GPU.md |
| MiniMax-H3 权重 34 GB | 下载完 + 字节级校验 ALL GOOD |
/data/models/minimax-h3/models/ |
| H3 出片 | 成功,已验收(见下) | outputs/t2va_20260818-223136.mp4 |
| H3 API | 在跑,GPU1:8010 | minimax-h3/API.md |
| 50 步全质量 | 进行中,结果未验 | logs/real-full50.log |
今天最重要的一条结论
minimax-h3/README.md 原第一节写「bfloat16 → float16(致命)」是错的。
改成 fp16 才是这条线一直出不了片的原因。
对照实验(唯一变量是 dtype,448×256×28f):
| fp32 | fp16 | |
|---|---|---|
| 视频 | mean 140.9 std 50.6 | mean 0 std 0 |
| 音频 | finite | NaN |
| 结果 | 出片 ✅ | 纯黑 ❌ |
原因:模型按 bf16 训练(bf16 有 fp32 的动态范围),sm_75 没有 bf16,
fp16 的 65504 上限装不下——dit.blocks.0 输入 absmax 89 就放大到 38176,50 层残差累积必爆。
逐点修 fp16 是行不通的,我试了四条弯路全部失败(--fp32-accum 无效、替换 forward 绕过换入、
转换处溢出、钳位到上限反而自造故障),细节和实测数据都在 minimax-h3/README.md。
t2va.py 的 --dtype 现在默认 fp32,保留 fp16 只为复现故障。
验收数据(都是实测,没有推测)
H3 出片:832×480 · 24fps · 124 帧 · 5.17 s · 7.5 MB · 像素 std 57.85 · 帧间差异 16.99(证明是动态视频) · 音频 aac 32 kHz 立体声 mean −34.0 dB / rms 0.0199(证明不是静音)。
性能(fp32,单任务):全分辨率 Turbo 4 步约 107 s/步,峰值显存 12.2 G, 首次加载 238 s,page cache 命中后 12–20 s。fp16 是 36.8 s/步但出不了片。
llm38 256K:n_ctx_slot = 262144(模型原生上限,GGUF 元数据 qwen35.context_length),
150 K token 大海捞针 truncated=0 通过,显存 57.3 G,并发从 4 降到 2,
256 K 提示 prefill 约 4.5 分钟。
下一步(按优先级)
- 收尾:等 50 步跑完 → 验收(
bash /tmp/verify-out.sh <文件>,脚本在服务器/tmp, 要长期用得挪到scripts/)→ 补README.md验收记录 → 恢复四个服务并验端口。 - 决定 llm38 与 H3 的共存策略。两者显存放不下(57.3 + 12.3 > 单卡余量)。
选项:H3 按需起停;或 llm38 降到
--parallel 1 --ctx-size 262144(保 256 K 单请求, 并发降为 1,省 16 G);或换卡。这是产品决策,需要用户拍板。 - 安全:
qwen.wudaima.com公网无鉴权可直调 27B;H3 API 也无鉴权。 SSH 22 经 FRP 映射到公网 6000 且允许密码登录、admin 在 sudo 组。都没动,等授权。 - 可选:
t2va.py:47的max(6.0, ...)地板值在空闲显存
踩过的坑(别重踩)
- 退出码不可信:原
t2va.py只查 audio,全黑视频照样[done]+ 退出码 0。 已补 video 纯色检查,坏产物退出码 3。API 的 worker 也会验 std 和音频有限性。 - 诊断配置必须和故障配置逐项一致:我用中文 prompt 诊断、英文默认 prompt 复现, 溢出点不同,白跑几轮。
- prompt 必须从文件读:
ssh … bash -c "…"三层 shell 会吃掉引号,传进去是空串, 报错是cannot reshape tensor of 0 elements——看着像 transformers 的 bug,实际是输入为空。 cmd1 && cmd2 &的&作用于整条链:cat > file && ... &会让文件写入和执行竞争, 我因此跑了一个 0 字节的脚本还以为它成功了。上传和启动要分两步。pgrep -f "gunicorn.*7590"会匹配到你自己那条 SSH 命令行,照着 kill 会误杀。 用nvidia-smi --query-compute-apps=pid反查。ffmpeg -af volumedetect的输出容易被 grep 漏掉,误报"无音频流"。 用 PyAV 直接解码算 rms 更可靠。- 合成小张量的 probe 测不出真问题:
probe-nf4-fp16.py验证「单层 NF4 fp16 不溢出」通过, 但推不出「50 层残差不溢出」。
本地与服务器的对应
| 本地 | 服务器 |
|---|---|
deploy-scripts/ |
/home/admin/qwen38-deploy/ |
llm-setup.md |
/home/admin/llm-setup.md |
minimax-h3/scripts/、API.md、README.md |
/data/models/minimax-h3/(run.sh/api.py/realrun.sh 在顶层) |
服务器那份才是运行的那份,两边会漂移。今天就因为只在服务器上修了导入、 本地那份没同步,重新生成脚本时把旧 bug 带了回去,白跑一轮。