bilibili / ailab

5.6k stars 550 forks source link

关于屏幕字对景深识别的干扰和超范围 RGB32f 的处理 #24

Open Nuevo009 opened 2 years ago

Nuevo009 commented 2 years ago

首先非常感谢能够公开这个模型。以下是我的一些测试反馈

测试环境

1. 屏幕字对景深识别的干扰

real-cugan 相对于 realesrgan 来说会自动识别保护景深场景,这是非常值得肯定的,但是据我观察,识别的准确度还是有待提升(不过这东西难免出点错)。另外识别到景深场景时的效果和平常的效果非常不同,平常的锐度类似于 realesrgan ,而景深场景的锐度略弱于 waifu2x。这种差异当使用分块时会非常显著,比如一个1080p input 使用了 4 个 tiles,一帧画面中的不同分块的去雾策略会不一样。 (《在魔王城说晚安》,EP2,第 3109 帧) cugan_4tiles_3109

注意画面的上下两部分,有明显分界。

另外尝试了 conservative 版,依然是 tiles=4 cugan_con_3109

可看出依然有明显分界

这一问题在有屏幕字的画面上发生的很频繁,大概是把屏幕字背后的画面当作景深了,其他分块没有字的就正常处理。要解决嘛就是不分块2333。 cugan_3109

可以看到没有明显分界,整个画面相对来说都比较糊。

附上源

src_3109

附上 waifu2x 的 waifu2x_3109

还有realesrganv2的 realesrgan_3109

但就算是在一个分块内,有时候有屏幕字的部分和周围的画面也有明显分界。

(《来自风平浪静的明天》,EP2,第32230帧) test_32230

附上源 src_32230

2. 超过 RGB32f 范围的处理

AI 训练过程中大概并没见过这种东西吧2333,常见于 full range 的 YUV 但是 metadata 错标为了 limited,或者是 full range YUV 的图片(比如JPEG)被转换滤镜错误的当成了 limited,另外就算是正常的画面中也有几个位置超过了 limited YUV 范围(比如 limited 的画面 full range 的屏幕字,典型例子是上面的《来自风平浪静的明天》的白字超过了235,达到了255;《在魔王城说晚安》的屏幕字黑边低于16,达到了0。不过我在这类小范围的、放大倍率低的情景下并未发现显著影响),这种东西常规的滤镜比如 zimg 转换为 RGB integer 时会自动 clamp 到范围内,但是转换为浮点 RGB 就会超过 1。保守起见有些人会手动来一个 0 1 clip 。这种越界值 real-cugan 的处理非常奇怪。。。本来是该锐化的画面,real-cugan会把它变糊,甚至越界更严重或者放大倍数更高的话会出现负的值,waifu2x-cunet 的锐度没有影响,但是也会出现奇怪的瑕疵,而 realesrganv2 的效果则没有明显影响。

发现这一问题是我的误操作,拿 repo 里的 vs demo 直接读了一个 JPEG,但是 demo 里面 用了 mvf 来转换 RGB32f,它根本不读 frameprop,看见 YUV 就当成 limited 喂给 fmtcov 了。(是个非常经典的问题,需要手动指定 range 和 matrix)

原图为 pid-31765856

转换后的源目视效果是这样

我姑且导出来了一个浮点的 TIFF 格式的图片,这是经过错误的矩阵转换到 RGBS 后,部分像素越界的源,我已知的源滤镜中 imread 可以正确读取 image000.zip

(以下图我是从qq群聊天记录里面捡回来的,虽然被 qq 压成了 yuv420p8 的 jpeg 但是目视效果基本相同)

real-cugan 4x 效果是这样的 可以看出有明显的负的值被 clamp 成 0 了 取色器中显示最小值达到了 -7 。。。。

这是 2x 可以看出画面明显变糊。

waifu2x-cunet 4x QQ图片20220210014922

线条周围出现瑕疵。注意这并不是被 qq 二压的(

real-esrganv2 4x

QQ图片20220210014929 没有任何瑕疵,和用 0 1 clip 处理越界后的源没有明显区别。

虽然这种越界值并不是很常见,而且手动加个 clip 就能解决,但毕竟 b 站应该是要用这个东西实际投入生产的,也算是个提醒?毕竟real-cugan 的这个表现太奇怪而且相对来说更严重更明显。。

VapourSynth 用户 在把图像喂给类似的 AI 滤镜之前,转换为 RGBS 后,尽管确认源的 YUV 范围没有很大越界,但也要最好手动加一个 rgbs.akarin.Expr("x 0 1 clip") 或者 rgbs.std.Expr("x 0 max 1 min")


以上是我个人的简单反馈,再次感谢。

lj1995-computer-vision commented 2 years ago

首先非常感谢楼主的测试! 关于第一个问题, 1、你用的应该是waifu2x-caffe的替换版,原版模型在tile后会产生切割线是在预期内的,原版的tile策略是不能用的,因为tile后他看不见全局,无法判断谁要增强谁要保留。我们有开发新版tile,我刚才测试了下没有切割线(2倍denoise3x如图),不过caffe版本目前没有人修正到新版的tile。还是建议不tile。 景深bad case_2x_tile4 2、有关效果,模型判断字很锐利,背景画面较模糊,被认为是景深,没有太过增强处理,效果上我个人还算可以接受,突出了原作staff(我指的是case1)信息,这个见仁见智,你说全部增强的话,效果也可以认可。唯一有问题的应该是,没有锐利的文字,整体画面依然未做增强,这种情况。为什么RealESRGAN的模型能增强好,因为他们没有做有关景深的处理(截止20220210),直接全部都做增强,反而是很容易的,不仅大模型可以做,小模型也可以做。我们手里在RealESRGANv2(for anime video)公开前也已经有比他更快的小模型,不过考虑到还没有做景深处理,并没有公开。 关于第二个问题, 楼主遇到的2个坑我们已经踩过了,投入生产的部分不会再出现问题,不过还是感谢关心。 1、在别的域(比如YUV)上,且输入的数值范围在(0,1)的图,跑我们在RGB域上训练的模型,整体结构会保留,但是会出现模糊 2、对于因为判断错误导致转换越界的问题,虽然开源的代码目前版本已经加上clip01后处理,但是由于模型没有见过[0,1]外的值,输出该值附近的位置会产生随机的值。加上clip01的前处理可以解决,但是我觉得这个不应该归超分模块管,还是应该大伙在域转换的时候做这个逻辑。 3、投入生产的模型,不是在RGB域上做的,不一定会开源(还未决定)。

Nuevo009 commented 2 years ago

1、你用的应该是waifu2x-caffe的替换版,原版模型在tile后会产生切割线是在预期内的,原版的tile策略是不能用的

模型是从 google 网盘里面的 weights 文件夹中拿的,转换为 ONNX Runtime。我没有使用 waifu2x-caffe ,况且这玩意在 30 系显卡上几乎等于不能用

2、有关效果,模型判断字很锐利,背景画面较模糊,被认为是景深,没有太过增强处理,效果上我个人还算可以接受

就效果来说我也可以接受,但是第二个示例中没有分块,文字周围依然出现了明显的分界,整个画面有不协调感。。

Nuevo009 commented 2 years ago

不过如果你要说 Pytorch 的分块策略和 ONNX 不同么,我还没有测试,主要是 torch 在1080p input 下显存直接爆了,我再多开点tiles 试试

Nuevo009 commented 2 years ago

但是我觉得这个不应该归超分模块管,还是应该大伙在域转换的时候做这个逻辑。

是,毕竟训练集里不太可能来个越界值,但毕竟这个效果跟其他模型对比来说太反常了。嘛我就是给大家提醒一下,你们注意到了其他用户也可能没注意到呢。建议更新一下 README 和 vs demo

Nuevo009 commented 2 years ago

不过如果你要说 Pytorch 的分块策略和 ONNX 不同么,我还没有测试,主要是 torch 在1080p input 下显存直接爆了,我再多开点tiles 试试

确实是效果不一样。我开了 tile_mode = 4。 STB_S3_3109

第二个不开分块的效果也是不一样,之前提到的文字周围模糊的现象也没了 STB_S3_32230

这应该要回去看看我们那的代码了。。。。。

Nuevo009 commented 2 years ago

我们手里在RealESRGANv2(for anime video)公开前也已经有比他更快的小模型,不过考虑到还没有做景深处理,并没有公开。

非常期待这个小模型的发布,现在的模型跑起来还是太慢了,fps (同平台竞技 ONNX Runtime CUDA)大概是 realesrganv2 的 1/3,显存占用是 realesrganv2 的 5倍左右,如果 realesrganv2 用上了 tensorrt 还能更快,如果realcugan跑在 torch 上的话显存占用还会更多,而且也更慢。所以。。。在当前版本景深判断偶尔会出错的情况下,相对于经过可靠手段限制副作用下的 realesrgan,realcugan 带来的效果提升是否有必要多花3倍的时间去做。。。也是个问题。

Nuevo009 commented 2 years ago

你用的应该是waifu2x-caffe的替换版,原版模型在tile后会产生切割线是在预期内的,原版的tile策略是不能用的,因为tile后他看不见全局,无法判断谁要增强谁要保留。我们有开发新版tile,我刚才测试了下没有切割线(2倍denoise3x如图),不过caffe版本目前没有人修正到新版的tile。还是建议不tile。

你说的这个新版 tiles 是 pytorch 的模型转换到 caffe 的时候必须的一些额外处理吗。那可能 torch 转换到 ort 的时候也需要做类似的东西。

lj1995-computer-vision commented 2 years ago

@Nuevo009 是推理阶段需要的额外处理哈,模型转换应该没有问题的

lj1995-computer-vision commented 2 years ago

你用的应该是waifu2x-caffe的替换版,原版模型在tile后会产生切割线是在预期内的,原版的tile策略是不能用的,因为tile后他看不见全局,无法判断谁要增强谁要保留。我们有开发新版tile,我刚才测试了下没有切割线(2倍denoise3x如图),不过caffe版本目前没有人修正到新版的tile。还是建议不tile。

你说的这个新版 tiles 是 pytorch 的模型转换到 caffe 的时候必须的一些额外处理吗。那可能 torch 转换到 ort 的时候也需要做类似的东西。

Real-CUGAN也可以用tensorrt转完加速的,不过forward切块策略比较尴尬,很可能就不能切了

lj1995-computer-vision commented 2 years ago

@Nuevo009 你可以看看forward那一块有关tile_mode的pytorch代码。RealCUGAN的tile策略是半切割,对于景深处理的关键模块,是让他重新聚合看到全局信息的

lj1995-computer-vision commented 2 years ago

非常期待这个小模型的发布,现在的模型跑起来还是太慢了

他很可能就不叫CUGAN了,是比2018年出的waifu2x里的CUNet新挺多的网络结构

Nuevo009 commented 2 years ago

你用的应该是waifu2x-caffe的替换版,原版模型在tile后会产生切割线是在预期内的,原版的tile策略是不能用的,因为tile后他看不见全局,无法判断谁要增强谁要保留。我们有开发新版tile,我刚才测试了下没有切割线(2倍denoise3x如图),不过caffe版本目前没有人修正到新版的tile。还是建议不tile。

你说的这个新版 tiles 是 pytorch 的模型转换到 caffe 的时候必须的一些额外处理吗。那可能 torch 转换到 ort 的时候也需要做类似的东西。

Real-CUGAN也可以用tensorrt转完加速的,不过forward切块策略比较尴尬,很可能就不能切了

trt 似乎没法在 Turing/Ampere 架构上跑 CUNET。这问题给 NV 开了issue也没人理,请问你在跑 trt backend的 realcugan 的时候有遇到这问题吗

类似的问题在跑 waifu2x-cunet 的时候也遇见过

Nuevo009 commented 2 years ago

你用的应该是waifu2x-caffe的替换版,原版模型在tile后会产生切割线是在预期内的,原版的tile策略是不能用的,因为tile后他看不见全局,无法判断谁要增强谁要保留。我们有开发新版tile,我刚才测试了下没有切割线(2倍denoise3x如图),不过caffe版本目前没有人修正到新版的tile。还是建议不tile。

你说的这个新版 tiles 是 pytorch 的模型转换到 caffe 的时候必须的一些额外处理吗。那可能 torch 转换到 ort 的时候也需要做类似的东西。

Real-CUGAN也可以用tensorrt转完加速的,不过forward切块策略比较尴尬,很可能就不能切了

trt 似乎没法在 Turing/Ampere 架构上跑 CUNET。这问题给 NV 开了issue也没人理,请问你在跑 trt backend的 realcugan 的时候有遇到这问题吗

类似的问题在跑 waifu2x-cunet 的时候也遇见过

NV 说在修了(目前 Turing/Ampere 架构还是不能用

Nuevo009 commented 2 years ago

@lj1995-computer-vision 经过验证之后确实是分块策略出了问题,不分块的话,onnx 和 torch 的表现是一样的,第一个问题的case 2 那张图其实还是分块做的,我当时可能弄混了。

但是经过测试后发现了新问题。VapourSynth 的 torch wrapper 似乎有明显的变糊和偏色问题?

就我上面发的几张图也能看出来区别 比如这张用 vs 的 torch wrapper 出的结果

不过如果你要说 Pytorch 的分块策略和 ONNX 不同么,我还没有测试,主要是 torch 在1080p input 下显存直接爆了,我再多开点tiles 试试

确实是效果不一样。我开了 tile_mode = 4。 STB_S3_3109

以及您发的这个

首先非常感谢楼主的测试! 关于第一个问题, 1、你用的应该是waifu2x-caffe的替换版,原版模型在tile后会产生切割线是在预期内的,原版的tile策略是不能用的,因为tile后他看不见全局,无法判断谁要增强谁要保留。我们有开发新版tile,我刚才测试了下没有切割线(2倍denoise3x如图),不过caffe版本目前没有人修正到新版的tile。还是建议不tile。 景深bad case_2x_tile4

有明显的偏色和变糊问题

ONNX 不分块的结果也是正常的

这一问题在有屏幕字的画面上发生的很频繁,大概是把屏幕字背后的画面当作景深了,其他分块没有字的就正常处理。要解决嘛就是不分块2333。 cugan_3109

可以看到没有明显分界,整个画面相对来说都比较糊。

另外还测试了 Windows CLI demo 和 Python PyTorch wrapper 出来的结果也是正常的,唯独 vs wrapper 的行为不正常

我们做了以下尝试

  1. 更改传入模型的RGB通道顺序 RGB -> BGR -> model -> RGB
  2. 使用 fp32
  3. https://github.com/bilibili/ailab/blob/main/Real-CUGAN/VapourSynth/upcunet_v3_vs.py#L18

    把这里的 torch.mean 改成两次 torch.mean: torch.mean(x, dim=(2,), keepdim=True).mean(dim=(3,), keepdim=True) 以及把这里的维度 2 3 交换下顺序

均无效。。。尚不清楚导致此问题的原因。。。

麻烦您那边用 VapouSynth 做一下看看能否复现?

lj1995-computer-vision commented 2 years ago

@lj1995-computer-vision 经过验证之后确实是分块策略出了问题,不分块的话,onnx 和 torch 的表现是一样的,第一个问题的case 2 那张图其实还是分块做的,我当时可能弄混了。

但是经过测试后发现了新问题。VapourSynth 的 torch wrapper 似乎有明显的变糊和偏色问题?

就我上面发的几张图也能看出来区别 比如这张用 vs 的 torch wrapper 出的结果

不过如果你要说 Pytorch 的分块策略和 ONNX 不同么,我还没有测试,主要是 torch 在1080p input 下显存直接爆了,我再多开点tiles 试试

确实是效果不一样。我开了 tile_mode = 4。 STB_S3_3109

以及您发的这个

首先非常感谢楼主的测试! 关于第一个问题, 1、你用的应该是waifu2x-caffe的替换版,原版模型在tile后会产生切割线是在预期内的,原版的tile策略是不能用的,因为tile后他看不见全局,无法判断谁要增强谁要保留。我们有开发新版tile,我刚才测试了下没有切割线(2倍denoise3x如图),不过caffe版本目前没有人修正到新版的tile。还是建议不tile。 景深bad case_2x_tile4

有明显的偏色和变糊问题

ONNX 不分块的结果也是正常的

这一问题在有屏幕字的画面上发生的很频繁,大概是把屏幕字背后的画面当作景深了,其他分块没有字的就正常处理。要解决嘛就是不分块2333。 cugan_3109 可以看到没有明显分界,整个画面相对来说都比较糊。

另外还测试了 Windows CLI demo 和 Python PyTorch wrapper 出来的结果也是正常的,唯独 vs wrapper 的行为不正常

我们做了以下尝试

  1. 更改传入模型的RGB通道顺序 RGB -> BGR -> model -> RGB
  2. 使用 fp32
  3. https://github.com/bilibili/ailab/blob/main/Real-CUGAN/VapourSynth/upcunet_v3_vs.py#L18

    把这里的 torch.mean 改成两次 torch.mean: torch.mean(x, dim=(2,), keepdim=True).mean(dim=(3,), keepdim=True) 以及把这里的维度 2 3 交换下顺序

均无效。。。尚不清楚导致此问题的原因。。。

麻烦您那边用 VapouSynth 做一下看看能否复现?

@Nuevo009 我抽空看看,你们测试的视频片段求发下

Nuevo009 commented 2 years ago

@lj1995-computer-vision 经过验证之后确实是分块策略出了问题,不分块的话,onnx 和 torch 的表现是一样的,第一个问题的case 2 那张图其实还是分块做的,我当时可能弄混了。 但是经过测试后发现了新问题。VapourSynth 的 torch wrapper 似乎有明显的变糊和偏色问题? 就我上面发的几张图也能看出来区别 比如这张用 vs 的 torch wrapper 出的结果

不过如果你要说 Pytorch 的分块策略和 ONNX 不同么,我还没有测试,主要是 torch 在1080p input 下显存直接爆了,我再多开点tiles 试试

确实是效果不一样。我开了 tile_mode = 4。 STB_S3_3109

以及您发的这个

首先非常感谢楼主的测试! 关于第一个问题, 1、你用的应该是waifu2x-caffe的替换版,原版模型在tile后会产生切割线是在预期内的,原版的tile策略是不能用的,因为tile后他看不见全局,无法判断谁要增强谁要保留。我们有开发新版tile,我刚才测试了下没有切割线(2倍denoise3x如图),不过caffe版本目前没有人修正到新版的tile。还是建议不tile。 景深bad case_2x_tile4

有明显的偏色和变糊问题 ONNX 不分块的结果也是正常的

这一问题在有屏幕字的画面上发生的很频繁,大概是把屏幕字背后的画面当作景深了,其他分块没有字的就正常处理。要解决嘛就是不分块2333。 cugan_3109 可以看到没有明显分界,整个画面相对来说都比较糊。

另外还测试了 Windows CLI demo 和 Python PyTorch wrapper 出来的结果也是正常的,唯独 vs wrapper 的行为不正常 我们做了以下尝试

  1. 更改传入模型的RGB通道顺序 RGB -> BGR -> model -> RGB
  2. 使用 fp32
  3. https://github.com/bilibili/ailab/blob/main/Real-CUGAN/VapourSynth/upcunet_v3_vs.py#L18

    把这里的 torch.mean 改成两次 torch.mean: torch.mean(x, dim=(2,), keepdim=True).mean(dim=(3,), keepdim=True) 以及把这里的维度 2 3 交换下顺序

均无效。。。尚不清楚导致此问题的原因。。。 麻烦您那边用 VapouSynth 做一下看看能否复现?

@Nuevo009 我抽空看看,你们测试的视频片段求发下

测试用的上面的发的两个原图 不过应该任何源都能发现问题

lj1995-computer-vision commented 2 years ago

你用的应该是waifu2x-caffe的替换版,原版模型在tile后会产生切割线是在预期内的,原版的tile策略是不能用的,因为tile后他看不见全局,无法判断谁要增强谁要保留。我们有开发新版tile,我刚才测试了下没有切割线(2倍denoise3x如图),不过caffe版本目前没有人修正到新版的tile。还是建议不tile。

你说的这个新版 tiles 是 pytorch 的模型转换到 caffe 的时候必须的一些额外处理吗。那可能 torch 转换到 ort 的时候也需要做类似的东西。

Real-CUGAN也可以用tensorrt转完加速的,不过forward切块策略比较尴尬,很可能就不能切了

trt 似乎没法在 Turing/Ampere 架构上跑 CUNET。这问题给 NV 开了issue也没人理,请问你在跑 trt backend的 realcugan 的时候有遇到这问题吗 类似的问题在跑 waifu2x-cunet 的时候也遇见过

NV 说在修了(目前 Turing/Ampere 架构还是不能用

@Nuevo 我用TRT转成功了,用的这个库https://github.com/grimoire/torch2trt_dynamic 版本是8.2.4 之后直接TRTModule,输入输出还是pytorch-gpu-tensor的格式 加速比不大(效率增加30%,但是V100GPU占用率会从99%掉到90%所以加速15%左右,T4占用率从100%掉到95%也会损失一点点),但是聊胜于无;另外,不同分辨率显存占用都差不多,可以不用管cache_mode了;不过6G(480P)-8G(1080P)显存还是需要的

lj1995-computer-vision commented 2 years ago

TRT加持后,1080P T4可以跑1s2.5f

Nuevo009 commented 2 years ago

TRT更新了之后现在20系30系的卡也能用了 确实会快一些 另外 我们这边vapoursynth的实现也在一直更新。虽然目前还是没办法做到分块处理。不过至少输出的结果是正常的 https://github.com/AmusementClub/vs-mlrt/releases