Added RIFE UHD mode support, RTX 3070 (cudnn8005) benchmarks

This commit is contained in:
N00MKRAD
2020-12-17 23:26:25 +01:00
parent 4df2949681
commit 6947bd3e6c
14 changed files with 119 additions and 58 deletions

View File

@@ -12,14 +12,16 @@ Sample size means how many frames have been interpolated at the time you measure
## RIFE (CUDA)
| GPU | Ver | Size/Factor | Drive | Sample Size | Speed (FPS Out) |
| ------------------- | ---- | -------------- | -------- | ----------- | --------------- |
| RTX 2070 SUPER 8 GB | 1.18 | 1920x1080 - 2x | NVME SSD | \>2000 | 14 FPS |
| RTX 2070 SUPER 8 GB | 1.18 | 1280x720p - 2x | NVME SSD | \>14000 | 25.5 FPS |
| Quadro P5000 16 GB | 1.18 | 1920x1080 - 2x | SAN/SSHD | 1800 | 10.8 FPS |
| Quadro P5000 16 GB | 1.18 | 1280x720p - 2x | SAN/SSHD | 1800 | 20.2 FPS |
| GTX 1080 Ti 11 GB | 1.18 | 1920x1080 - 2x | NVME SSD | >1400 | 12.2 FPS |
| GTX 1080 Ti 11 GB | 1.18 | 1280x720p - 2x | NVME SSD | >1400 | 22.8 FPS |
| GPU | Ver | Size/Factor | Drive | Sample Size | Speed (FPS Out) |
| ----------------------------- | ---- | -------------- | -------- | ----------- | --------------- |
| RTX 2070 SUPER 8 GB | 1.18 | 1920x1080 - 2x | NVME SSD | \>2000 | 14 FPS |
| RTX 2070 SUPER 8 GB | 1.18 | 1280x720p - 2x | NVME SSD | \>14000 | 25.5 FPS |
| Quadro P5000 16 GB | 1.18 | 1920x1080 - 2x | SAN/SSHD | 1800 | 10.8 FPS |
| Quadro P5000 16 GB | 1.18 | 1280x720p - 2x | SAN/SSHD | 1800 | 20.2 FPS |
| GTX 1080 Ti 11 GB | 1.18 | 1920x1080 - 2x | NVME SSD | >1400 | 12.2 FPS |
| GTX 1080 Ti 11 GB | 1.18 | 1280x720p - 2x | NVME SSD | >1400 | 22.8 FPS |
| RTX 3070 Ti 8 GB [cuDNN 8.05] | 1.19 | 1920x1080 - 2x | NVME SSD | >1400 | 16 FPS |
| RTX 3070 Ti 8 GB [cuDNN 8.05] | 1.19 | 1280x720p - 2x | NVME SSD | >1400 | 33 FPS |
## RIFE-NCNN

View File

@@ -39,9 +39,9 @@ namespace Flowframes
string sizeStr = (size.Width > 1 && size.Height > 1) ? $"-s {size.Width}x{size.Height}" : "";
IOUtils.CreateDir(frameFolderPath);
string timecodeStr = timecodes ? "-copyts -r 1000 -frame_pts true" : "";
string scnDetect = sceneDetect ? $"-vf \"select='gt(scene,{Config.GetFloatString("scnDetectValue")})'\"" : "";
string scnDetect = sceneDetect ? $"\"select='gt(scene,{Config.GetFloatString("scnDetectValue")})'\"" : "";
string mpStr = deDupe ? ((Config.GetInt("mpdecimateMode") == 0) ? mpDecDef : mpDecAggr) : "";
string vf = (scnDetect.Length > 2 || mpStr.Length > 2) ? $"-vf {scnDetect},{mpStr}".ListCommaFix() : "";
string vf = (scnDetect.Length > 2 || mpStr.Length > 2) ? $"-vf {scnDetect},{mpStr} ".ListCommaFix() : "";
string pad = Padding.inputFrames.ToString();
string args = $"-i {inputFile.Wrap()} {pngComprArg} -vsync 0 -pix_fmt rgb24 {timecodeStr} {vf} {sizeStr} \"{frameFolderPath}/%{pad}d.png\"";
AvProcess.LogMode logMode = Interpolate.currentInputFrameCount > 50 ? AvProcess.LogMode.OnlyLastLine : AvProcess.LogMode.Hidden;

View File

@@ -139,6 +139,11 @@
this.cmdDebugMode = new System.Windows.Forms.ComboBox();
this.titleLabel = new System.Windows.Forms.Label();
this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
this.label28 = new System.Windows.Forms.Label();
this.label29 = new System.Windows.Forms.Label();
this.label30 = new System.Windows.Forms.Label();
this.panel6 = new System.Windows.Forms.Panel();
this.uhdThresh = new System.Windows.Forms.ComboBox();
this.settingsTabList.SuspendLayout();
this.generalTab.SuspendLayout();
this.tabListPage2.SuspendLayout();
@@ -740,6 +745,11 @@
// aiOptsPage
//
this.aiOptsPage.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(48)))), ((int)(((byte)(48)))), ((int)(((byte)(48)))));
this.aiOptsPage.Controls.Add(this.label30);
this.aiOptsPage.Controls.Add(this.panel6);
this.aiOptsPage.Controls.Add(this.uhdThresh);
this.aiOptsPage.Controls.Add(this.label29);
this.aiOptsPage.Controls.Add(this.label28);
this.aiOptsPage.Controls.Add(this.panel12);
this.aiOptsPage.Controls.Add(this.label44);
this.aiOptsPage.Controls.Add(this.ncnnThreads);
@@ -1491,6 +1501,66 @@
this.titleLabel.TabIndex = 1;
this.titleLabel.Text = "Settings";
//
// label28
//
this.label28.AutoSize = true;
this.label28.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold);
this.label28.Location = new System.Drawing.Point(10, 150);
this.label28.Margin = new System.Windows.Forms.Padding(10, 10, 10, 7);
this.label28.Name = "label28";
this.label28.Size = new System.Drawing.Size(158, 16);
this.label28.TabIndex = 61;
this.label28.Text = "RIFE (CUDA) Settings";
//
// label29
//
this.label29.AutoSize = true;
this.label29.Location = new System.Drawing.Point(10, 180);
this.label29.Margin = new System.Windows.Forms.Padding(10, 10, 10, 7);
this.label29.Name = "label29";
this.label29.Size = new System.Drawing.Size(151, 13);
this.label29.TabIndex = 62;
this.label29.Text = "UHD Mode Threshold (Height)";
//
// label30
//
this.label30.AutoSize = true;
this.label30.ForeColor = System.Drawing.Color.Silver;
this.label30.Location = new System.Drawing.Point(412, 181);
this.label30.Margin = new System.Windows.Forms.Padding(10, 10, 10, 7);
this.label30.Name = "label30";
this.label30.Size = new System.Drawing.Size(347, 13);
this.label30.TabIndex = 67;
this.label30.Text = "Minimum height to enable UHD mode which helps high-res interpolations";
//
// panel6
//
this.panel6.BackgroundImage = global::Flowframes.Properties.Resources.baseline_create_white_18dp_semiTransparent;
this.panel6.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
this.panel6.Location = new System.Drawing.Point(378, 177);
this.panel6.Name = "panel6";
this.panel6.Size = new System.Drawing.Size(21, 21);
this.panel6.TabIndex = 65;
this.toolTip1.SetToolTip(this.panel6, "Allows custom input.");
//
// uhdThresh
//
this.uhdThresh.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
this.uhdThresh.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.uhdThresh.ForeColor = System.Drawing.Color.White;
this.uhdThresh.FormattingEnabled = true;
this.uhdThresh.Items.AddRange(new object[] {
"4320",
"2160",
"1440",
"1080",
"720"});
this.uhdThresh.Location = new System.Drawing.Point(280, 177);
this.uhdThresh.Margin = new System.Windows.Forms.Padding(3, 3, 8, 3);
this.uhdThresh.Name = "uhdThresh";
this.uhdThresh.Size = new System.Drawing.Size(87, 21);
this.uhdThresh.TabIndex = 66;
//
// SettingsForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@@ -1638,5 +1708,10 @@
private System.Windows.Forms.Label label48;
private System.Windows.Forms.CheckBox sbsAllowAutoEnc;
private System.Windows.Forms.Label label53;
private System.Windows.Forms.Label label30;
private System.Windows.Forms.Panel panel6;
private System.Windows.Forms.ComboBox uhdThresh;
private System.Windows.Forms.Label label29;
private System.Windows.Forms.Label label28;
}
}

View File

@@ -67,6 +67,7 @@ namespace Flowframes.Forms
ConfigParser.SaveGuiElement(torchGpus);
ConfigParser.SaveGuiElement(ncnnGpus);
ConfigParser.SaveGuiElement(ncnnThreads);
ConfigParser.SaveGuiElement(uhdThresh);
// Video Export
ConfigParser.SaveGuiElement(minOutVidLength, ConfigParser.StringMode.Int);
ConfigParser.SaveComboxIndex(mp4Enc);
@@ -108,6 +109,7 @@ namespace Flowframes.Forms
ConfigParser.LoadGuiElement(torchGpus);
ConfigParser.LoadGuiElement(ncnnGpus);
ConfigParser.LoadGuiElement(ncnnThreads);
ConfigParser.LoadGuiElement(uhdThresh);
// Video Export
ConfigParser.LoadGuiElement(minOutVidLength);
ConfigParser.LoadComboxIndex(mp4Enc);

View File

@@ -105,7 +105,7 @@ namespace Flowframes.IO
if (key == "gifColors") return WriteDefault(key, "128 (High)");
if (key == "minVidLength") return WriteDefault(key, "2");
// AI
//if (key == "rifeMode") return WriteDefault(key, ((NvApi.GetVramGb() > 7f) ? 1 : 0).ToString()); // Enable by default if GPU has >7gb VRAM
if (key == "uhdThresh") return WriteDefault(key, "1440");
if (key == "ncnnThreads") return WriteDefault(key, "1");
// Debug / Other / Experimental
if (key == "ffEncPreset") return WriteDefault(key, "medium");

View File

@@ -193,12 +193,6 @@ namespace Flowframes.Main
i.Cancel("Selected AI not available.", true);
return false;
}
if(!PkgUtils.IsUpToDate(ai.pkg, ai.minPkgVer))
{
ShowMessage("The selected AI is installed, but not up to date!\nYou can update it in the Package Installer.", "Error");
i.Cancel("Selected AI is outdated.", true);
return false;
}
return true;
}

View File

@@ -142,19 +142,11 @@ namespace Flowframes
public static async Task RunRifeCuda(string framesPath, int interpFactor)
{
string script = "interp-parallel.py";
//if(Config.GetInt("rifeMode") == 0 || IOUtils.GetAmountOfFiles(framesPath, false) < 6)
// script = "interp-basic.py";
string rifeDir = Path.Combine(Paths.GetPkgPath(), Path.GetFileNameWithoutExtension(Packages.rifeCuda.fileName));
string args = $" --input {framesPath.Wrap()} --times {(int)Math.Log(interpFactor, 2)}";
if (File.Exists(Path.Combine(rifeDir, "inference_video.py"))) // Use updated script
{
script = "inference_video.py";
args = $" --img {framesPath.Wrap()} --exp {(int)Math.Log(interpFactor, 2)}";
}
string script = "inference_video.py";
bool uhd = IOUtils.GetVideoRes(Interpolate.current.inPath).Height >= Config.GetInt("uhdThresh");
string uhdStr = uhd ? "--UHD" : "";
string args = $" --img {framesPath.Wrap()} --exp {(int)Math.Log(interpFactor, 2)} {uhdStr} --imgformat {InterpolateUtils.GetExt()} --output {Paths.interpDir}";
if (!File.Exists(Path.Combine(rifeDir, script)))
{
@@ -165,8 +157,8 @@ namespace Flowframes
Process rifePy = OSUtils.NewProcess(!OSUtils.ShowHiddenCmd());
AiStarted(rifePy, 3500);
rifePy.StartInfo.Arguments = $"{OSUtils.GetCmdArg()} cd /D {PkgUtils.GetPkgFolder(Packages.rifeCuda).Wrap()} & " +
$"set CUDA_VISIBLE_DEVICES={Config.Get("torchGpus")} & {Pytorch.GetPyCmd()} {script} {args} --imgformat {InterpolateUtils.GetExt()} --output {Paths.interpDir}";
Logger.Log($"Running RIFE ({script})...", false);
$"set CUDA_VISIBLE_DEVICES={Config.Get("torchGpus")} & {Pytorch.GetPyCmd()} {script} {args}";
Logger.Log($"Running RIFE {(uhd ? "(UHD Mode)" : "")} ({script})...".TrimWhitespaces(), false);
Logger.Log("cmd.exe " + rifePy.StartInfo.Arguments, true);
if (!OSUtils.ShowHiddenCmd())
{

View File

@@ -13,8 +13,6 @@ namespace Flowframes.OS
class NvApi
{
static PhysicalGPU gpu;
static float vramGb;
static float vramFreeGb;
public static async void Init()
{
@@ -26,7 +24,7 @@ namespace Flowframes.OS
return;
gpu = gpus[0];
Logger.Log("Init NvApi");
Logger.Log($"Initialized NvApi. GPU: {gpu.FullName}");
}
catch (Exception e)
{
@@ -34,20 +32,6 @@ namespace Flowframes.OS
}
}
public static void RefreshVram()
{
if (Form.ActiveForm != Program.mainForm || gpu == null) // Don't refresh if not in focus or no GPU detected
return;
vramGb = (gpu.MemoryInformation.AvailableDedicatedVideoMemoryInkB / 1000f / 1024f);
vramFreeGb = (gpu.MemoryInformation.CurrentAvailableDedicatedVideoMemoryInkB / 1000f / 1024f);
Color col = Color.White;
if (vramFreeGb < 2f)
col = Color.Orange;
if (vramFreeGb < 1f)
col = Color.OrangeRed;
//Program.mainForm.SetVramLabel($"{gpu.FullName}: {vramGb.ToString("0.00")} GB VRAM - {vramFreeGb.ToString("0.00")} GB Free", col);
}
public static float GetVramGb ()
{
try

View File

@@ -18,7 +18,7 @@ abspath = os.path.abspath(__file__)
dname = os.path.dirname(abspath)
print("Changing working dir to {0}".format(dname))
os.chdir(os.path.dirname(dname))
print("Added {0} to PATH".format(dname))
print("Added {0} to temporary PATH".format(dname))
sys.path.append(dname)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
@@ -28,6 +28,13 @@ if torch.cuda.is_available():
torch.backends.cudnn.benchmark = True
else:
print("WARNING: CUDA is not available, RIFE is running on CPU! [ff:nocuda-cpu]")
try:
print("\nSystem Info:")
print("Python: {} - Pytorch: {} - cuDNN: {}".format(sys.version, torch.__version__, torch.backends.cudnn.version()))
print("Hardware Acceleration: Using {} device(s), first is {}".format( torch.cuda.device_count(), torch.cuda.get_device_name(0)))
except:
print("Failed to get hardware info!")
parser = argparse.ArgumentParser(description='Interpolation for a pair of images')
parser.add_argument('--video', dest='video', type=str, default=None)
@@ -35,6 +42,7 @@ parser.add_argument('--img', dest='img', type=str, default=None)
parser.add_argument('--output', required=False, default='frames-interpolated')
parser.add_argument('--imgformat', default="png")
parser.add_argument('--montage', default=False, dest='montage', action='store_true', help='montage origin video')
parser.add_argument('--UHD', dest='UHD', action='store_true', help='support 4k video')
parser.add_argument('--skip', dest='skip', default=False, action='store_true', help='whether to remove static frames before processing')
parser.add_argument('--fps', dest='fps', type=int, default=None)
parser.add_argument('--png', dest='png', default=True, action='store_true', help='whether to vid_out png format vid_outs')
@@ -53,9 +61,8 @@ model.device()
path = args.img
name = os.path.basename(path)
print('name: ' + name)
interp_output_path = (args.output).join(path.rsplit(name, 1))
print('interp_output_path: ' + interp_output_path)
print("\ninterp_output_path: " + interp_output_path)
if not args.video is None:
videoCapture = cv2.VideoCapture(args.video)
@@ -114,7 +121,7 @@ def build_read_buffer(user_args, read_buffer, videogen):
def make_inference(I0, I1, exp):
global model
middle = model.inference(I0, I1)
middle = model.inference(I0, I1, args.UHD)
if exp == 1:
return [middle]
first_half = make_inference(I0, middle, exp=exp - 1)
@@ -124,8 +131,13 @@ def make_inference(I0, I1, exp):
if args.montage:
left = w // 4
w = w // 2
ph = ((h - 1) // 32 + 1) * 32
pw = ((w - 1) // 32 + 1) * 32
if args.UHD:
print("UHD mode enabled.")
ph = ((h - 1) // 64 + 1) * 64
pw = ((w - 1) // 64 + 1) * 64
else:
ph = ((h - 1) // 32 + 1) * 32
pw = ((w - 1) // 32 + 1) * 32
padding = (0, pw - w, 0, ph - h)
#pbar = tqdm(total=tot_frame)
skip_frame = 1

View File

@@ -188,9 +188,11 @@ class Model:
torch.save(self.contextnet.state_dict(), '{}/contextnet.pkl'.format(path))
torch.save(self.fusionnet.state_dict(), '{}/unet.pkl'.format(path))
def predict(self, imgs, flow, training=True, flow_gt=None):
def predict(self, imgs, flow, training=True, flow_gt=None, UHD=False):
img0 = imgs[:, :3]
img1 = imgs[:, 3:]
if UHD:
flow = F.interpolate(flow, scale_factor=2.0, mode="bilinear", align_corners=False) * 2.0
c0 = self.contextnet(img0, flow)
c1 = self.contextnet(img1, -flow)
flow = F.interpolate(flow, scale_factor=2.0, mode="bilinear",
@@ -207,7 +209,7 @@ class Model:
else:
return pred
def inference(self, img0, img1):
def inference(self, img0, img1, K=False):
imgs = torch.cat((img0, img1), 1)
flow, _ = self.flownet(imgs)
return self.predict(imgs, flow, training=False).detach()

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,2 +0,0 @@
2 # added --output arg
1 # initial - increased output zero-padding to 8