vs-mlrt icon indicating copy to clipboard operation
vs-mlrt copied to clipboard

显存问题和颜色问题

Open ueyome opened this issue 3 years ago • 8 comments

多次调用函数显存会叠加导致爆显存,而upcunet_v3_vs没有问题

脚本例子

import vapoursynth as vs
import mvsfunc as mvf
import upcunet_v3_vs as realcugan
realcugan = realcugan.RealWaifuUpScaler()
from vsmlrt import *

core = vs.core
src=r"123.jpg"
src = core.ffms2.Source(src)

def upscale(clip):
#        clip = realcugan(clip)
        clip = CUGAN(clip, noise=0, scale=2, backend=Backend.ORT_CUDA())
        return clip

src = mvf.ToRGB(src, depth=32, matrix="709")
src = core.std.Expr(src, "x 0 max 1 min")
src2 = src
src = upscale(src) 
src2 = upscale(src2)

res = core.std.Splice([src,src2])
res.set_output()

问题2颜色问题 alpha=1 model=保守

原图 156495643-ab912d3a-533a-4868-ab73-431583f01067 输出 Snipaste_2022-04-26_18-51-24

def upscale(clip):
        clip = realcugan(clip)
        return clip
        
def upscale2(clip):
        clip = CUGAN(clip, noise=0, scale=2, tilesize=300,  backend=Backend.ORT_CUDA())
        return clip
#...
res = core.std.StackHorizontal([src,src2])
res.set_output()

ueyome avatar Apr 26 '22 10:04 ueyome

是的,需要切块的 real-cugan 确实不太适合用 vs-mlrt 跑,因为算法需要整张图像做景深识别,在 vs-mlrt 的实现下算法只能看到每个块,而原版的实现能看到整张图的。

我有个想法是,动态生成和原版的一样的 onnx 运行图,不过感觉代码不那么好写……

另外,用 trt 后端和 fp16 有助于降低显存占用,ort-cuda 后端关了 cudnn_benchmark 也能降一点。

WolframRhodium avatar Apr 26 '22 11:04 WolframRhodium

另外,jpg 应该 bt.601 matrix,所以脚本里面用 mvf.ToRGB(src, depth=32, matrix="709") 是会导致颜色不对的问题的。

AkarinVS avatar May 16 '22 08:05 AkarinVS

mvf.ToRGB(JPEGYUV, full=True, cplace="MPEG1", matrix="601", depth=32)

https://vcb-s.nmm-hd.org/Templar%20Archive/%5BVCB-Studio%5D%5B%E6%95%99%E7%A8%8B18%5DYUV%E4%B8%8ERGB%E7%9A%84%E4%BA%92%E8%BD%AC%281%29/%5BVCB-Studio%5D%5B%E6%95%99%E7%A8%8B18%5DYUV%E4%B8%8ERGB%E7%9A%84%E4%BA%92%E8%BD%AC%281%29.pdf

Nuevo009 avatar May 16 '22 08:05 Nuevo009

是的,需要切块的 real-cugan 确实不太适合用 vs-mlrt 跑,因为算法需要整张图像做景深识别,在 vs-mlrt 的实现下算法只能看到每个块,而原版的实现能看到整张图的。

我有个想法是,动态生成和原版的一样的 onnx 运行图,不过感觉代码不那么好写……

另外,用 trt 后端和 fp16 有助于降低显存占用,ort-cuda 后端关了 cudnn_benchmark 也能降一点。

我想提问者遇到的应该是跟我一样的疑问。就是比如我用vspreview预览,我单独一张图渲染出来是没问题的。但假设我渲染第一张图是吃满90%显存的时候,渲染结束后能看到显存依然占用着50%左右,这时候预览下一帧的时候就会报错显存不足了。每次预览只能预览一帧,然后kill掉vspreview之后再看下一帧才不会遇到爆显存的问题。 我猜测可能是预览软件cache了上一帧的一些数据的原因,所以我尝试直接用vspipe跑 vspipe -p --filter-time -r 1 script.vpy . 强制每次只处理一帧,但依然会在第二帧爆显存。

补充一下信息,vspipe跟vs是R59 python3.10的。vspreview是Irrational-Encoding-Wizardry最新的版本(0.2.7),vs-mlrt是9.1. backend均为ort-cuda, 显卡是3080ti 12GB显存,跑cugan的时候我把tiles尽量往小调,就很容易遇到这个问题了。

dtlnor avatar Aug 04 '22 08:08 dtlnor

我想提问者遇到的应该是跟我一样的疑问。就是比如我用vspreview预览,我单独一张图渲染出来是没问题的。但假设我渲染第一张图是吃满90%显存的时候,渲染结束后能看到显存依然占用着50%左右,这时候预览下一帧的时候就会报错显存不足了。每次预览只能预览一帧,然后kill掉vspreview之后再看下一帧才不会遇到爆显存的问题。 我猜测可能是预览软件cache了上一帧的一些数据的原因,所以我尝试直接用vspipe跑 vspipe -p --filter-time -r 1 script.vpy . 强制每次只处理一帧,但依然会在第二帧爆显存。

补充一下信息,vspipe跟vs是R59 python3.10的。vspreview是Irrational-Encoding-Wizardry最新的版本(0.2.7),vs-mlrt是9.1. backend均为ort-cuda, 显卡是3080ti 12GB显存,跑cugan的时候我把tiles尽量往小调,就很容易遇到这个问题了。

感谢,可以确认这个问题是存在的

按理来说,在滤镜初始化才会申请显存,在释放滤镜实例时才释放,这样在用 vspipe 途中显存占用会是固定的;但现在的确发现,跑的过程中仍会申请显存,这样不仅影响速度,还容易出现显存不足了

我去研究下是哪里的问题

WolframRhodium avatar Aug 04 '22 10:08 WolframRhodium

我想提问者遇到的应该是跟我一样的疑问。就是比如我用vspreview预览,我单独一张图渲染出来是没问题的。但假设我渲染第一张图是吃满90%显存的时候,渲染结束后能看到显存依然占用着50%左右,这时候预览下一帧的时候就会报错显存不足了。每次预览只能预览一帧,然后kill掉vspreview之后再看下一帧才不会遇到爆显存的问题。 我猜测可能是预览软件cache了上一帧的一些数据的原因,所以我尝试直接用vspipe跑 vspipe -p --filter-time -r 1 script.vpy . 强制每次只处理一帧,但依然会在第二帧爆显存。

麻烦测下 v9.2.

这个问题看起来和 ort 内部会动态优化显存占用有关。

vs-mlrt v9 之前的版本这功能被关掉了,但 v9 里被我改代码时删掉了…

WolframRhodium avatar Aug 07 '22 07:08 WolframRhodium

我想提问者遇到的应该是跟我一样的疑问。就是比如我用vspreview预览,我单独一张图渲染出来是没问题的。但假设我渲染第一张图是吃满90%显存的时候,渲染结束后能看到显存依然占用着50%左右,这时候预览下一帧的时候就会报错显存不足了。每次预览只能预览一帧,然后kill掉vspreview之后再看下一帧才不会遇到爆显存的问题。 我猜测可能是预览软件cache了上一帧的一些数据的原因,所以我尝试直接用vspipe跑 vspipe -p --filter-time -r 1 script.vpy . 强制每次只处理一帧,但依然会在第二帧爆显存。

麻烦测下 v9.2.

这个问题看起来和 ort 内部会动态优化显存占用有关。

vs-mlrt v9 之前的版本这功能被关掉了,但 v9 里被我改代码时删掉了…

在这种情况下(一般情况),运行很完美:

RGBSClip = RGBSClip[0] + RGBSClip[1] + RGBSClip[2]
ToCUGAN(RGBSClip)

但如果遇到调用多次,或者分别调用不同滤镜,显存还是会增长,然后爆掉 (可能这个不在预期的功能里面,不过还是报告一下)

ToCUGAN(RGBSClip[0]) + ToCUGAN(RGBSClip[1]) + ToCUGAN(RGBSClip[2])

or

ToCUGAN(RGBSPart1) + ToCUGANPro(RGBSPart2)

dtlnor avatar Aug 08 '22 06:08 dtlnor

这种时候目前会创建多个滤镜实例,vs 的执行逻辑是:

  1. ToCUGAN(RGBSPart1) 时,申请一次显存
  2. ToCUGANPro(RGBSPart2) 时,再申请一次显存
  3. py 里执行到 vpy 里的 set_output()
  4. (通常来说) 先处理 ToCUGAN(RGBSPart1) 里的处理,再执行 ToCUGANPro(RGBSPart2) 里的处理,两者在不同的显存上执行
  5. 最后,清理 ToCUGAN(RGBSPart1)ToCUGANPro(RGBSPart2) 分配的显存

这样就没法复用了

TRT 后端的确能实现复用显存且不怎么掉速,但 OV 和 ORT 后端还不知道怎么做

WolframRhodium avatar Aug 08 '22 07:08 WolframRhodium