TransparentLC/realesrgan-gui

请问大批量图片处理速度的主要因素

Benson1997 opened this issue · 5 comments

大佬好,请问由于平常需要处理大量的扫描图片,请问影响整体处理速度的硬件,主要是CPU还是GPU,或者是内存也有关。能否大致介绍一下影响处理速度方面的因素。

或者能帮忙给点硬件升级建议。😊
(据说是从1070Ti升级到3系速度提升不多,4系好像要一万多了,哈哈。)

以下是我电脑配置:
——————————
处理器 英特尔 Core i7-8700K @ 3.70GHz 六核
主板 华硕 PRIME Z370-P ( Z370 芯片组 )——支持双显卡
内存 32 GB ( 英睿达 DDR4 2400MHz / 金士顿 DDR4 2400MHz )
主硬盘 西数 WDC WDS100T2B0C-00PXH0 ( 1 TB / 固态硬盘 )
主显卡 Nvidia GeForce GTX 1070 Ti ( 8 GB / 七彩虹 )

主要的瓶颈是 GPU。

我用的是 i7-8750H (6C12T) 和 GTX 1070,用 realesrgan-x4plus-anime 模型放大 1920x1080 的图片,拆分大小自动设定,不开 TTA 的话,放大一次大概要 12-15s,内存占用 600 MB,在放大期间 GPU 的占用是满的,CPU 除了刚开始放大的时候以外基本没有占用。

不过因为你在隔壁提到了图片压缩所以也简单分析一下好了,这个占用的是 CPU,对于刚才放大得到的 7680x4320 的图片:

  • 用 cjpeg (mozjpeg) 压缩 cjpeg-static -outfile NUL -quality 80 -optimize -progressive input.png:大约 3s,不过 cjpeg 只占用单核,所以大量处理的话可以同时开 CPU 核心数/线程数的编码器进行压缩。
  • 用 cwebp (libwebp) 压缩 cwebp -q 80 -m * -sharp_yuv -mt input.png -o NUL-m 是用来选择压缩质量或速度的参数,-m 0 的话大概 4s,-m 6 大概 7s,另外虽然命令里用了 -mt 但是实际测试下来 cwebp 也只占用单核,所以多开也是有效的。
  • 用 avifenc (libavif) 压缩 avifenc --speed * --jobs all --depth 8 --yuv 420 --min 0 --max 63 -a end-usage=q -a cq-level=30 -a enable-chroma-deltaq=1 --autotiling --ignore-icc --ignore-xmp --ignore-exif input.png NUL--speed 10 大概 0.9s,--speed 6 大概 4s,--speed 4 大概 20s,--speed 0 大概 60s,avifenc 是会用多线程把 CPU 吃满的,多开意义不大。
  • 用 cjxl (libjxl) 压缩 cjxl input.png NUL -q 80 -e *-e 1 大概 1.1s,-e 4 大概 1.2s,-e 6 大概 3s,-e 9 的内存占用跑到了 7 GB 我这里是没办法测试了(隔壁 avifenc 的内存占用最多也才 640 MB),另外 cjxl 也有多线程。

对于图片压缩来说,对速度影响最大的是控制速度的参数(也会影响压缩质量,参见国外 CDN 厂商 Cloudinary 的分析结果)。升级更多核心的 CPU 或许会有帮助,不过压缩图片的速度(一般来说你并不需要使用最慢的选项)与放大图片相比还是快很多,所以还是优先升级 GPU 比较好。

好的,非常感谢您的时间,讲解的非常详细了。

您说的多开,是多开主程序对吧。之前有多开过2-3个主程序同时处理,每个主程序处理一个文件夹,不过经常会出现其中某个程序在执行过程中报错。不知道是不是GPU被挤满了,所以报错。

还是多开的时候,应该把整个程序所在的文件夹复制多份,再单独从每个不同的文件夹中运行 realesrgan-gui.exe,这样是不是不容易出错一些。

现在能记录错误日志了,下次我提交一下错误信息。😁

我没有测试过多开 realesrgan-gui 的情况,并且也不会考虑在 GUI 里添加并行压缩图片或者是一边放大一边压缩前面的图片的功能(太复杂了)。放大图片本身会占满 GPU,所以多开也是没有意义的,甚至有爆显存的可能。

好的,明白了,realesrgan-gui 开一个运行就可以了。速度瓶颈主要是再GPU上,不纠结了,谢谢🤞

如果想要多开编码器的话(这就和 realesrgan-gui 没有关系了),我倒是写过类似的 Python 代码,可以参考:

import os
import subprocess
from concurrent.futures import ThreadPoolExecutor

def compress(inputPath: str):
    outputPath = os.path.splitext(inputPath)[0] + '.webp'
    p = subprocess.Popen(
        (
            'cwebp',
            '-q', '80',
            '-z', '9',
            '-m', '6',
            '-f', '10',
            '-sharp_yuv',
            '-mt',
            inputPath,
            '-o', outputPath,
        ),
    )
    p.wait()

with ThreadPoolExecutor(os.cpu_count()) as executor:
    executor.map(
        compress,
        (os.path.join('dir', x) for x in os.listdir('dir'))
    )