From 83626817ea535fd039311c3f6a03fac4c00e92b9 Mon Sep 17 00:00:00 2001 From: yibo Date: Mon, 24 Aug 2026 20:05:59 +0800 Subject: [PATCH] minimax-h3 api.py: 加 cfg_scale/negative_prompt 入口,quality-tuning-plan 补实测记录 --- docs/todo/quality-tuning-plan.md | 35 ++++++++++++++++++++++++++--------- minimax-h3/api.py | 12 ++++++++++-- 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/docs/todo/quality-tuning-plan.md b/docs/todo/quality-tuning-plan.md index 8c96a7e..9c0ce43 100644 --- a/docs/todo/quality-tuning-plan.md +++ b/docs/todo/quality-tuning-plan.md @@ -10,9 +10,16 @@ H3 原生分辨率是 1344×768(短边 768px)。我们线上默认 **832×48 真实上限被 `api.py` 的 `ROWS_LIMIT=20000`(帧数×宽×高的显存安全线)卡死——这是 Turing 显卡 fp32-only(无高效 bf16/fp16 attention)导致的显存代价,不是随手设的参数。 -**要做的实测**:在服务器上直接跑一次接近原生的分辨率(比如 1344×768,短时长/低帧数控制 -rows 不超限),跟现在的 832×480 默认档同 prompt/seed 对比,看画质差距有多大、显存/耗时代价 -多大。`ROWS_LIMIT` 支持 `H3_ROWS_LIMIT` 环境变量临时覆盖,不用改代码就能测。 +**2026-08-21 已实测**:ref2va 分区,同 prompt/seed=42,`0f22388f7847`(1344×768×64帧, +峰值显存 15.49GB)vs `06bb43196c46`(832×480×124帧,峰值显存 11.47GB,其余参数相同)—— +**原生分辨率肉眼明显更好**。但不是没问题:三条对比测试(含下面第 2 项那条)肉眼看**都还有 +瑕疵**——画面模糊/细节糊、运镜或动作的抖动/拖影、人物五官变形,原生分辨率只是相对最好。 +判断是口头目测,没有做客观指标也没有逐帧截图定位具体哪几秒出问题。详见 +`CHANGELOG.md` 2026-08-21(下午)一节。 + +**还没做的**:默认分辨率之外的中间档(比如 1024×576)没试过;原生分辨率因为 +`ROWS_LIMIT` 只能压到 64 帧(2.7秒),跟 832×480 能跑到 124 帧(5.2秒)不是等时长对比, +时长本身对观感的影响还没拆开看。 ## 2. Turbo 4 步 vs 关闭 Turbo 跑 20+ 步——现成的开关,从没系统测过 @@ -20,9 +27,12 @@ rows 不超限),跟现在的 832×480 默认档同 prompt/seed 对比,看ç (`fl2va`/`ref2va` 各一个)。不用换文件就能验证的路径:console 早就支持关掉 Turbo、跑 20/50 步全精度(`turbo=false`),但**默认值是"Turbo 开/4步"**(为了速度),从没系统对比过画质。 -**要做的实测**:同 prompt/seed,Turbo 开(4步) vs 关(20步) 各跑一条,对比帧间差异/音频响度/ -肉眼观感。之前在纯文生视频上测过一次类似的(结论是步数越多帧间差异越小、音质越好,见 -`CHANGELOG.md` 「15 秒时长实测」一节),但没有在现在的默认分辨率/R2V 场景下重新验证过。 +**2026-08-21 已实测(结论跟之前的纯 T2V 结论相反)**:ref2va 分区,同 832×480×124帧/ +prompt/seed=42,`06bb43196c46`(Turbo开/4步,峰值显存 11.47GB)vs `807e042dce0d` +(Turbo关/20步,峰值显存 9.56GB)——**Turbo开/4步肉眼反而更好**。之前在纯文生视频上测过 +一次类似的(结论是步数越多帧间差异越小、音质越好,见 `CHANGELOG.md` 「15 秒时长实测」 +一节)这次在 ref2va 场景下**没有复现**,说明这条不是通用结论,是分区相关的(T2V vs +ref2va,或者还有别的没控制住的变量),**每个分区要分别测,不能只测一次就定档**。 ## 3. CFG scale / negative prompt——入口已经加上了,还没做过 A/B @@ -49,8 +59,15 @@ pipeline 本身支持 `cfg_scale`(默认 1.0,等于没有 CFG 引导)和 ` 对应的模型文件,不是改个参数就行**,工作量和网络下载时间都要单独评估(服务器出口带宽约 5.9MB/s,见顶层 `CLAUDE.md`「硬件的三条硬限制」)。 +**2026-08-21 更新**:这一项的前提被第 2 项的实测推翻了——ref2va 场景下 Turbo开/4步肉眼 +反而比关闭 Turbo 跑 20 步更好,且更快、显存更省。**没有理由再为了"画质换速度"去下载 8 步 +LoRA**,除非以后测别的分区/场景发现关 Turbo 明显更好,才重新评估。暂时搁置。 + ## 建议的实测顺序 -1 和 2 不需要下载任何新文件、不需要改代码,最快能出结果,优先做。3 的入口已经加上了 -(见上面),直接在 console 里填参数测就行。4 需要小改 `api.py` 把 `audio_flow_shift` 串上 -(目前还没有入口)。5 最后再看要不要投入。 +**2026-08-21 更新**:1、2 两项已在 ref2va 分区跑过一轮实测(结论见上面对应小节),但三条 +测试肉眼看都还有瑕疵(模糊、抖动/拖影、五官变形),说明光调分辨率/Turbo 不够,**接下来 +应该做 3**(cfg_scale/negative_prompt,入口已经加上,直接在 console 填参数测,看能不能 +压住这些瑕疵)。4 需要小改 `api.py` 把 `audio_flow_shift` 串上(目前还没有入口)。5 已经 +搁置(见上面)。另外 1、2 的实测目前只在 ref2va 一个分区做过,fl2va/纯 T2V 是否同样结论 +还没验证,也没有拆开看是"分辨率"还是"帧数/时长"在起作用。 diff --git a/minimax-h3/api.py b/minimax-h3/api.py index a54c852..3dd52b2 100644 --- a/minimax-h3/api.py +++ b/minimax-h3/api.py @@ -67,6 +67,11 @@ class GenReq(BaseModel): # 短边 480 时约 390 行,而目标视频本身才 14430 行。 reference_image_urls: list[str] = [] ref_image_short_edge: int = Field(480, ge=64, le=2048) + # CFG 引导强度 / 负面提示词。pipeline 自己默认 cfg_scale=1.0(约等于不引导)、 + # negative_prompt="",我们的代码之前从没传过,一直裸跑默认值。Optional,留空=不覆盖, + # 跟以前行为一样;蒸馏 LoRA(turbo)模型引导太强有时反而出伪影,调高前留意这点。 + cfg_scale: Optional[float] = Field(None, ge=0) + negative_prompt: Optional[str] = Field(None, max_length=2000) @model_validator(mode="after") def _check_rows(self): @@ -226,9 +231,12 @@ def worker(): if not j.req.turbo: pipe.clear_lora() keyframes, keyframe_indices = _keyframes(j.req) - video, audio = pipe(prompt=j.req.prompt, height=j.req.height, width=j.req.width, + cfg_scale = j.req.cfg_scale if j.req.cfg_scale is not None else 1.0 + negative_prompt = j.req.negative_prompt if j.req.negative_prompt is not None else "" + video, audio = pipe(prompt=j.req.prompt, negative_prompt=negative_prompt, + height=j.req.height, width=j.req.width, num_frames=j.req.frames, num_inference_steps=j.req.steps, - seed=j.req.seed, flow_shift=fs, + seed=j.req.seed, flow_shift=fs, cfg_scale=cfg_scale, keyframes=keyframes, keyframe_indices=keyframe_indices, references=_references(j.req), ref_image_short_edge=j.req.ref_image_short_edge) -- libgit2 0.21.4