部署 MoWorld 这类本地模型时,最先要回答的问题不是“能不能跑”,而是“显卡够不够用、生成速度能不能接受”。这两件事都可以在启动前和运行中用系统工具与脚本直接测量。先理清模型文件、Python 与 CUDA 环境,再记录显存峰值,然后测量单帧延迟,最后根据余量调整配置。整个过程不依赖猜测,也不需要第三方监控服务。
判断方向:先用最小配置启动,观察显存峰值与单帧耗时;若显存不足,优先降低 max_length,其次减小 batch_size。验证方式:用 nvidia-smi 定时采样记录显存,用 perf_counter 包裹生成调用并分阶段计时。适用场景:本地单卡部署与调试;风险边界:不同驱动、CUDA 版本和模型量化方式会影响数值,应结合本机日志确认。
部署前先确认模型文件与依赖环境
在跑测之前,需要确认几个基础条件:模型文件是否真的在本机、Python 能否调用 CUDA、依赖包版本是否匹配。很多显存报错其实来自模型没加载完整或 CUDA 不可用。
先检查模型目录权限与文件完整性:
ls -lh /path/to/moworld_model
# 确认目录可读,且包含权重文件与配置文件
stat -c '%A %n' /path/to/moworld_model
然后确认 Python 环境中的 CUDA 状态:
python -c "import torch; print(torch.cuda.is_available())"
输出为 True 才继续。如果为 False,先检查驱动与 PyTorch 版本是否匹配,不要直接调模型。接着打印依赖包版本列表:
pip list | grep -E "torch|transformers|accelerate|moworld"
记录当前版本,后续如果出现与实现相关的报错,可以回看这里。建议将版本输出保存到文本文件,便于与模型仓库要求的版本对照。
用 nvidia-smi 记录推理峰值显存
显存占用不能靠感觉,需要在推理过程中持续采样。nvidia-smi -l 1 可以每秒输出一次显存状态,把输出重定向到日志文件,就能得到一条时间线上的显存变化。
推荐做法:先启动一个后台推理进程,再用 nvidia-smi 采样。
# 终端一:启动推理服务(后台示例)
nohup python run_moworld.py `--model` /path/to/moworld_model > inference.log 2>&1 &
echo $!
记录下 PID,然后在另一个终端运行:
nvidia-smi -l 1 `--query-gpu`=timestamp,memory.used,memory.total,utilization.gpu `--format`=csv > gpu_mem.log
让采样持续到一次完整生成结束。用 Ctrl+C 停止采样,然后查看日志里的 memory.used 最大值:
sort -t, -k3 -n gpu_mem.log | tail -1
这样拿到的峰值是真实观测值。如果 memory.used 在生成过程中一直逼近显卡总显存,说明余量很小;如果频繁出现 out of memory,则说明配置需要下调。
用计时脚本测量单帧生成延迟
显存够用不代表速度可用。生成延迟可以用 time.perf_counter() 包住单次生成调用,分别记录首帧输出时间和稳定期每帧耗时。下面是一个最小计时骨架:
import time
import torch
def generate_one(prompt):
start = time.perf_counter()
# 这里调用模型生成,返回第一帧 token
first_token = model.generate(prompt, max_new_tokens=1)
first_t = time.perf_counter() - start
frame_times = []
start = time.perf_counter()
# 继续生成剩余 token,每生成一个记录一次耗时
for _ in range(remaining_tokens):
next_token = model.generate(prompt, max_new_tokens=1)
frame_times.append(time.perf_counter() - start)
start = time.perf_counter()
return first_t, frame_times
first_t, frame_times = generate_one("你的测试提示词")
print(f"首帧耗时: {first_t:.4f}s")
print(f"稳定期平均帧耗时: {sum(frame_times)/len(frame_times):.4f}s")
注意 token 生成通常会包含预填充阶段,首帧耗时可能明显高于后续 token 耗时。记录稳定期帧耗时是为了判断每秒能生成多少 token,而不是被首帧拉高平均值。建议至少跑三次,取中间值。
根据显存余量调整最大生成长度
如果采样日志中出现了 CUDA out of memory,或者峰值显存已接近上限,第一步是降低最大生成长度。因为生成长度越长,保存中间状态所需的显存越多。先看推理日志中的 OOM 信息:
grep -i "out of memory" inference.log
然后在模型配置或启动参数中找到 max_length 或 max_new_tokens,把它调小。例如原先是 max_length=512,可以先改为 256。同时检查是否有 batch_size 参数,如果当前为 4,可以先降到 2 或 1。
# 修改后重新启动
python run_moworld.py `--model` /path/to/moworld_model `--max`_length 256 `--batch`_size 1
改完后重复执行 nvidia-smi 采样和计时脚本。如果显存峰值降到可用范围,但单帧耗时明显变长,需要结合你的使用场景判断是否可接受。如果降级后仍然 OOM,可能是模型本身超过了显卡容量,需要换更小模型或量化版本。
通过日志验证吞吐是否稳定
单次计时有偶然性,可能受系统调度、温度降频或其它进程干扰。为了排除偶发卡顿导致的误判,可以按组统计耗时。建议每组跑 10 次生成,记录每次的总耗时,然后计算均值和方差。
import time
import statistics
times = []
for i in range(10):
t0 = time.perf_counter()
# 执行一次完整生成
result = model.generate(prompt, max_new_tokens=50)
times.append(time.perf_counter() - t0)
mean_t = statistics.mean(times)
var_t = statistics.pstdev(times)
print(f"10次平均耗时: {mean_t:.4f}s")
print(f"标准差: {var_t:.4f}s")
观察标准差是否远小于平均值。如果某次耗时明显高于均值,需要回看该时间点系统是否在做别的事,比如数据加载、日志刷盘或其它进程占用 GPU。也可以把 nvidia-smi 的时间戳和生成日志对齐,识别是否有 GPU 利用率掉到接近 0 的情况。稳定期的小幅波动属于正常,但连续掉速就需要进一步排查。
最后记得把上述观测记录保存下来,后续改动配置时再跑一遍同样流程,才能判断变化是否有效。