Matrix-Game 4.0 只有一张消费级显卡 / 显存不够时该降分辨率还是减帧?

文章导读
显存吃紧时,先降分辨率,而不是先减帧。分辨率通常直接决定单帧张量大小,是显存峰值的底座;帧数和帧生成批次更多影响运行过程中的驻留与累积。顺序反了容易出现“帧数减到很少仍然 OOM”的情况:单帧本身就放不下,减帧只是缩短了跑多久,不解决放不放得下。可操作的做法是固定其他变量,先只把分辨率往下降,找到能稳定出画面的最低一档,再在这档上把帧数与批次调到够用。
📋 目录
  1. A 在配置文件里找出影响显存的三类参数
  2. B 固定其他变量,先只改分辨率
  3. C 再只改帧生成或批次相关参数
  4. D 把两组结果合并成可跑区间
  5. E 用同一输入复跑两次确认稳定
A A

显存吃紧时,先降分辨率,而不是先减帧。分辨率通常直接决定单帧张量大小,是显存峰值的底座;帧数和帧生成批次更多影响运行过程中的驻留与累积。顺序反了容易出现“帧数减到很少仍然 OOM”的情况:单帧本身就放不下,减帧只是缩短了跑多久,不解决放不放得下。可操作的做法是固定其他变量,先只把分辨率往下降,找到能稳定出画面的最低一档,再在这档上把帧数与批次调到够用。

适用场景:单卡消费级显卡跑 Matrix-Game 4.0,出现显存不足或跑到一半中断。操作动作:复制一份配置,固定输入(同一段素材、同一时长、同一种子),只改分辨率一个键跑一轮,记录峰值与运行时长;再只改帧数或批次跑一轮。验证方式:用 nvidia-smi 轮询记录显存曲线,看峰值出现的位置是启动瞬间还是运行途中。风险边界:降分辨率会直接损失画面细节,减帧会缩短可用时长,两者都不能靠调参换回;若某一档触发显存错误,就回退上一档并把它记为边界值。

在配置文件里找出影响显存的三类参数

先确认改动落在真正生效的那份配置上。Matrix-Game 类项目一般把配置放在仓库的 configs/ 或 conf/ 目录,也可能由启动命令的 `--config` 参数指定。用下面两条命令定位文件并列出候选字段,注意输出的是你本地文件里确实存在的键,不要凭印象往里加。

cd <你的仓库目录>
ls configs conf 2>/dev/null

grep -rnE '(resol|width|height|size|frames|num_frames|batch|chunk|window|cache|dtype|offload)' configs/

把 grep 出来的键按用途分三类,写进记录表再开始改:

  • 分辨率类:如 width/height、resolution、image_size 之类,决定单帧张量形状。
  • 帧生成批次类:如 num_frames、batch_size、frame_chunk、chunk_size,决定一次生成多少帧、分几批推进。
  • 缓存与精度类:如 dtype、cache、offload、vae_slicing 一类开关,影响中间结果是否留在显存。

名字相近但与显存无关的项要排除,例如日志里的 log_every、输出目录里的 frame_dir。改完后打印一次合并后的运行时配置(多数项目支持 `--dump-config` 或在启动日志开头打印),确认生效的就是你以为的那一项;只看 YAML 文件很容易被默认值覆盖。

Matrix-Game 4.0 只有一张消费级显卡 / 显存不够时该降分辨率还是减帧?

固定其他变量,先只改分辨率

这一轮只允许分辨率变化:同一份输入、同一时长、同样的批次与精度设置,其余键一个不动。启动生成之前,先在另一个终端开一个显存采样循环,然后把采样文件和生成日志放在同一个目录方便对照。

# 终端 A:先记录空载基线
nvidia-smi `--query-gpu`=memory.used `--format`=csv,noheader

# 终端 A:开始采样,间隔 500ms,输出到文件
nvidia-smi `--query-gpu`=timestamp,memory.used,utilization.gpu \
  `--format`=csv,noheader -lms 500 | tee mem_res.csv

# 终端 B:照常启动一次生成
python -m <你的入口> `--config` configs/<你的配置>.yaml

采样间隔建议 200–500ms,太粗会漏掉启动瞬间的峰值,太密则文件膨胀。生成结束后用 Ctrl+C 停掉采样,取峰值:

cut -d, -f2 mem_res.csv | tr -dc '0-9\n' | sort -n | tail -1

把每档分辨率的结果按同一格式记下来,“峰值”一列要同时写空载基线,否则下次换了桌面环境就对比不了:

批次改动项旧值 → 新值其余项空载基线峰值显存运行时长报错/画面
R1分辨率原始 → 第 1 档不变待记录待记录待记录待记录
R2分辨率第 1 档 → 第 2 档不变待记录待记录待记录待记录

如果两档之间峰值几乎没变,说明分辨率不是当前的限制项,先别继续往下砍,转去查帧数与批次。

Matrix-Game 4.0 只有一张消费级显卡 / 显存不够时该降分辨率还是减帧?

再只改帧生成或批次相关参数

回到上一轮能出画面的分辨率,把分辨率锁死,只动 num_frames 或 chunk_size。这一轮要回答的是:显存被单帧占住了,还是被运行过程中的累积占住了。判断方法是看峰值出现的位置和运行时长。

# 记录运行时长,生成结束后立刻再读一次显存
start=$(date +%s)
python -m <你的入口> `--config` configs/<你的配置>.yaml
echo "elapsed: $(( $(date +%s) - start ))s"
nvidia-smi `--query-gpu`=memory.used `--format`=csv,noheader
  • 峰值在启动后很短时间内到达平台、之后基本持平,且减半批次峰值明显下降:属于单帧或单批占用主导,继续减批次有效。
  • 峰值随运行时长缓慢爬升,结束那一刻读数最高:属于中间结果或缓存累积,减帧数只能延缓,不能根治,需要同时确认缓存释放相关开关。
  • 帧数减到很少仍然报显存错误:瓶颈不在帧数,回到分辨率那一步继续降。

对比时把改动前后的峰值读数和运行时长成对写进同一张表,只写峰值不写时长会误判:时长缩短导致峰值下降,并不等于单帧变小了。

把两组结果合并成可跑区间

把分辨率那一列和批次那一列并排看,取交集。推荐组合的构造方式是:分辨率取“能稳定出画面”的最低一档,帧数与批次取“能覆盖你需要的最长时长”的最小值,并在峰值上留出余量——建议不低于空载与峰值差值的十分之一,或者留几百 MB,具体看你的桌面环境占多少显存。

Matrix-Game 4.0 只有一张消费级显卡 / 显存不够时该降分辨率还是减帧?
# 推荐组合示例(键名以你本地 grep 结果为准)
resolution: <能稳定出画面的最低档>
num_frames: <覆盖所需时长所需的最小帧数>
chunk_size: <缩到不再抬高峰值的最小批次>   # 若配置里没有此键则跳过
dtype: <维持原有设置,不在这一轮改动>

边界值同样要写清楚:把失败那次的参数记成“上限越界点”,例如某分辨率下批次取到某一档出现显存分配失败,那么这一档就是边界,实际使用取它下面一档。边界值比推荐值更有用,因为下次换输入时你能立刻知道还有多少余量。

用同一输入复跑两次确认稳定

一次成功可能只是上一次进程没退干净、显存刚好腾出来了。用完全相同的输入和参数连跑两次,两次之间确认没有残留进程:

nvidia-smi `--query-compute-apps`=pid,process_name,used_memory `--format`=csv
# 若有上一次留下的进程,先确认归属再结束它,不要直接 kill 陌生 PID

两次各存一份采样文件(如 mem_run1.csv、mem_run2.csv),分别取峰值和运行时长。判断标准是:两次峰值接近、都低于你设定的余量线、两次日志里都没有显存分配失败或 OOM 关键字、两次输出画面在帧数和内容上一致。若第二次峰值明显高于第一次,说明存在未释放的缓存或临时占用,这个组合还不能算可跑区间,需要重启运行时后再复测。若两次都出现同一条警告但画面正常,也把它记进表格,避免下次误判为回归。