mirror of
https://github.com/n00mkrad/flowframes.git
synced 2025-12-16 16:37:48 +01:00
Added RIFE UHD mode support, RTX 3070 (cudnn8005) benchmarks
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
75
Code/Forms/SettingsForm.Designer.cs
generated
75
Code/Forms/SettingsForm.Designer.cs
generated
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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())
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
@@ -1,2 +0,0 @@
|
||||
2 # added --output arg
|
||||
1 # initial - increased output zero-padding to 8
|
||||
Reference in New Issue
Block a user