Commit 4c45f719adffa22519cf289832a37e0e3f5d4fed

Authored by yibo
1 parent fc46beb9

h3-console: /v1/models 的分辨率档位改成实时查 raylight,不再是过期的3档硬编码

/v1/models 之前硬编码3个预设,模型文件名对应的是已删除的 api.py/gateway.py 那套旧
架构(minimax-h3-fl2va-nf4.safetensors 等),跟 raylight 现在实际加载的模型
(minimax_h3_fl2va_pruned_int8_convrot.safetensors 等)完全对不上,档位也只有3个,
跟前端下拉框实际支持的8个分辨率(RESOLUTION_CEILINGS)不一致——外部调这个接口查
"支持哪几档"拿到的是错的过期数据。

raylight/server.py 加 GET /v1/resolutions,返回 RESOLUTION_CEILINGS 的实时内容;
h3-console 的 /v1/models 改成实时调这个接口拼 presets,顺带把 partitions 里的模型
文件名也换成当前实际使用的。

已在服务器上重启验证:/v1/resolutions 返回全部8档,h3-console /v1/models 端到端
拿到一致数据;重启过程中17条排队任务全部保留(用到了上一次改的排队恢复逻辑)。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PA1AWh8e7wJ3vyhKBAEQux
h3-console/server.py
... ... @@ -584,22 +584,30 @@ async def reset_gpu():
584 584  
585 585  
586 586 @api.get("/v1/models")
587   -def models():
588   - # 静态信息,对应服务器上 api.py 里的 PARTITIONS 常量。只读展示,不做运行时切换。
  587 +async def models():
  588 + # partitions 是静态信息,对应 raylight/server.py 里的 DIT_FL2VA/DIT_REF2VA 常量,只读展示。
  589 + # 2026-09-03:presets 之前是硬编码的3档旧数据(模型文件名对应的是已删除的 api.py/gateway.py
  590 + # 那套旧架构,跟 raylight 现在实际用的模型对不上),改成实时问 raylight 的
  591 + # /v1/resolutions(RESOLUTION_CEILINGS 的镜像),保证跟实际支持的分辨率档位一致,
  592 + # 不用两边手动同步一份数字。
  593 + try:
  594 + resp = await client.get(f"{GATEWAY_URL}/v1/resolutions")
  595 + resolutions = resp.json()["resolutions"] if resp.status_code == 200 else []
  596 + except httpx.HTTPError:
  597 + resolutions = []
  598 + presets = [
  599 + {"label": f"{r['width']}×{r['height']},最多 {r['max_frames']} 帧(≈{r['max_frames']/24:.1f}s@24fps)",
  600 + "width": r["width"], "height": r["height"], "max_frames": r["max_frames"]}
  601 + for r in resolutions
  602 + ]
589 603 return {
590 604 "partitions": {
591   - "fl2va": {"dit": "minimax-h3-fl2va-nf4.safetensors",
592   - "lora": "minimax_h3_fl2v_turbo_4step_v1.0_768p_bf16.safetensors",
  605 + "fl2va": {"dit": "minimax_h3_fl2va_pruned_int8_convrot.safetensors",
593 606 "desc": "首末帧条件生成"},
594   - "ref2va": {"dit": "minimax-h3-ref2va-nf4.safetensors",
595   - "lora": "minimax_h3_ref2v_turbo_4step_v0.1_comfyui_bf16.safetensors",
  607 + "ref2va": {"dit": "minimax_h3_ref2va_pruned_int8_convrot.safetensors",
596 608 "desc": "文生视频 / 多参考图生成"},
597 609 },
598   - "presets": [
599   - {"label": "标准档 832×480×124f(5.17s)", "width": 832, "height": 480, "frames": 124},
600   - {"label": "长时长档 448×256×362f(15s)", "width": 448, "height": 256, "frames": 362},
601   - {"label": "高分辨率档 1344×768×64f(2.7s)", "width": 1344, "height": 768, "frames": 64},
602   - ],
  610 + "presets": presets,
603 611 }
604 612  
605 613  
... ...
raylight/scripts/server.py
... ... @@ -715,3 +715,11 @@ def list_videos(limit: int = 50):
715 715 jobs = sorted(JOBS.values(), key=lambda j: j.created_at, reverse=True)[:limit]
716 716 return [{"id": j.id, "status": j.status, "created_at": j.created_at,
717 717 "size_bytes": j.size_bytes, "error": j.error} for j in jobs]
  718 +
  719 +
  720 +@app.get("/v1/resolutions")
  721 +def list_resolutions():
  722 + """实测过显存/画质边界的分辨率档位——RESOLUTION_CEILINGS 的只读镜像,给 h3-console
  723 + 的 /v1/models 之类的外部查询接口用,不要在别处重复硬编码这份表。"""
  724 + return {"resolutions": [{"width": w, "height": h, "max_frames": max_frames}
  725 + for (w, h), max_frames in RESOLUTION_CEILINGS.items()]}
... ...
raylight/server.py
... ... @@ -715,3 +715,11 @@ def list_videos(limit: int = 50):
715 715 jobs = sorted(JOBS.values(), key=lambda j: j.created_at, reverse=True)[:limit]
716 716 return [{"id": j.id, "status": j.status, "created_at": j.created_at,
717 717 "size_bytes": j.size_bytes, "error": j.error} for j in jobs]
  718 +
  719 +
  720 +@app.get("/v1/resolutions")
  721 +def list_resolutions():
  722 + """实测过显存/画质边界的分辨率档位——RESOLUTION_CEILINGS 的只读镜像,给 h3-console
  723 + 的 /v1/models 之类的外部查询接口用,不要在别处重复硬编码这份表。"""
  724 + return {"resolutions": [{"width": w, "height": h, "max_frames": max_frames}
  725 + for (w, h), max_frames in RESOLUTION_CEILINGS.items()]}
... ...