You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中同时运行Blender渲染子进程与nvidia-smi监控子进程并解析输出?

如何在Python中同时运行Blender渲染子进程与nvidia-smi监控子进程并解析输出?

这个需求我之前也碰到过,其实用Python的subprocess模块就能轻松搞定——核心思路就是同时启动两个子进程,一边跑Blender渲染,一边让nvidia-smi持续输出监控数据,还能实时解析。下面给你一步步拆解实现方法:

1. 核心实现思路

我们可以用subprocess.Popen来分别启动Blender渲染进程和nvidia-smi监控进程,因为Popen是非阻塞的,所以两个进程能同时运行。然后我们可以实时读取nvidia-smi的输出流,一边解析数据,一边等待Blender进程结束后再终止监控进程。

2. 完整代码示例

直接上可运行的代码,里面加了详细注释,你可以根据自己的需求调整:

import subprocess
import re

def parse_nvidia_smi_output(line):
    """解析nvidia-smi的单行输出,提取已用显存"""
    # 匹配类似 "2048 MiB" 这样的格式
    match = re.search(r'(\d+) MiB', line)
    if match:
        return int(match.group(1))
    return None

def main():
    # 1. 定义你的Blender渲染命令(和你原来的逻辑一致)
    render_executable = "blender"  # 换成你的Blender实际路径
    file_to_render = "your_scene.blend"  # 换成你的Blend文件路径
    massager_script = "your_script.py"  # 换成你的Python脚本路径
    num_spheres = 10
    new_filename_full_path = "output.png"

    render_command = [
        render_executable, file_to_render,
        "--background", "--python", massager_script,
        "--", "--number", str(num_spheres), "--save", new_filename_full_path
    ]

    # 2. 启动Blender渲染子进程(非阻塞)
    render_process = subprocess.Popen(
        render_command,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        text=True
    )

    # 3. 启动nvidia-smi监控子进程(非阻塞,每秒输出一次)
    nvidia_smi_command = [
        "nvidia-smi",
        "--query-gpu=memory.used",
        "--format=csv",
        "-l", "1"
    ]

    nvidia_process = subprocess.Popen(
        nvidia_smi_command,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        text=True,
        bufsize=1,  # 行缓冲,保证实时读取输出
        universal_newlines=True
    )

    # 4. 实时监控+解析,同时等待Blender结束
    print("开始渲染并监控GPU显存...")
    try:
        # 逐行读取nvidia-smi的输出
        for line in nvidia_process.stdout:
            line = line.strip()
            # 跳过第一行的表头(内容是 "memory.used [MiB]")
            if line.startswith("memory.used"):
                continue
            # 解析显存数据
            used_memory = parse_nvidia_smi_output(line)
            if used_memory is not None:
                print(f"当前已用显存: {used_memory} MiB")
            
            # 检查Blender进程是否已经结束
            if render_process.poll() is not None:
                print("Blender渲染已完成!")
                break
    finally:
        # 确保监控进程被正确终止,避免后台残留
        if nvidia_process.poll() is None:
            nvidia_process.terminate()
            nvidia_process.wait()
        print("GPU监控已停止")

        # 可选:读取Blender的输出用于调试
        render_stdout, render_stderr = render_process.communicate()
        if render_stdout:
            print("\nBlender标准输出:")
            print(render_stdout)
        if render_stderr:
            print("\nBlender错误输出:")
            print(render_stderr)

if __name__ == "__main__":
    main()

3. 关键细节说明

  • 非阻塞启动:用subprocess.Popen而非subprocess.run,因为run会阻塞主程序直到进程结束,而Popen会立即返回进程对象,让两个进程能并行运行。
  • 实时输出读取:给nvidia-smi的Popen设置bufsize=1和text=True,保证我们能逐行实时获取输出,不会因为缓冲区积压导致数据延迟。
  • 可靠解析数据:用正则表达式匹配显存数值,比简单的字符串分割更稳定,能适配nvidia-smi输出格式的小变动。
  • 进程清理:在finally块中终止监控进程,避免Blender结束后监控进程还在后台持续运行。

4. 针对短渲染的优化

你提到有些渲染只有5秒以内,这个方案完全适用——nvidia-smi每秒输出一次,短渲染也能捕捉到足够的监控数据。如果需要更精细的监控,你可以把-l 1改成-l 0.5(每0.5秒输出一次),不过注意太频繁的输出可能会增加一点系统开销,一般1秒一次足够了。

备注:内容来源于stack exchange,提问作者easythrees

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 15:38:04