RIFE-CUDA fp16 option and warplayer.py optimization

This commit is contained in:
N00MKRAD
2021-02-21 11:26:18 +01:00
parent 4a673744a5
commit 1d04d2d3ee
7 changed files with 79 additions and 25 deletions

View File

@@ -164,6 +164,8 @@
this.cmdDebugMode = new System.Windows.Forms.ComboBox();
this.titleLabel = new System.Windows.Forms.Label();
this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
this.label65 = new System.Windows.Forms.Label();
this.rifeCudaFp16 = new System.Windows.Forms.CheckBox();
this.settingsTabList.SuspendLayout();
this.generalTab.SuspendLayout();
this.tabListPage2.SuspendLayout();
@@ -821,6 +823,8 @@
// aiOptsPage
//
this.aiOptsPage.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(48)))), ((int)(((byte)(48)))), ((int)(((byte)(48)))));
this.aiOptsPage.Controls.Add(this.rifeCudaFp16);
this.aiOptsPage.Controls.Add(this.label65);
this.aiOptsPage.Controls.Add(this.label35);
this.aiOptsPage.Controls.Add(this.panel12);
this.aiOptsPage.Controls.Add(this.dainNcnnTilesize);
@@ -849,7 +853,7 @@
//
this.label35.AutoSize = true;
this.label35.ForeColor = System.Drawing.Color.Silver;
this.label35.Location = new System.Drawing.Point(412, 261);
this.label35.Location = new System.Drawing.Point(412, 291);
this.label35.Margin = new System.Windows.Forms.Padding(10, 10, 10, 7);
this.label35.Name = "label35";
this.label35.Size = new System.Drawing.Size(258, 13);
@@ -860,7 +864,7 @@
//
this.panel12.BackgroundImage = global::Flowframes.Properties.Resources.baseline_create_white_18dp_semiTransparent;
this.panel12.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
this.panel12.Location = new System.Drawing.Point(378, 257);
this.panel12.Location = new System.Drawing.Point(378, 287);
this.panel12.Name = "panel12";
this.panel12.Size = new System.Drawing.Size(21, 21);
this.panel12.TabIndex = 78;
@@ -880,7 +884,7 @@
"1024",
"1536",
"2048"});
this.dainNcnnTilesize.Location = new System.Drawing.Point(280, 257);
this.dainNcnnTilesize.Location = new System.Drawing.Point(280, 287);
this.dainNcnnTilesize.Margin = new System.Windows.Forms.Padding(3, 3, 8, 3);
this.dainNcnnTilesize.Name = "dainNcnnTilesize";
this.dainNcnnTilesize.Size = new System.Drawing.Size(87, 21);
@@ -889,7 +893,7 @@
// label27
//
this.label27.AutoSize = true;
this.label27.Location = new System.Drawing.Point(10, 260);
this.label27.Location = new System.Drawing.Point(10, 290);
this.label27.Margin = new System.Windows.Forms.Padding(10, 10, 10, 7);
this.label27.Name = "label27";
this.label27.Size = new System.Drawing.Size(93, 13);
@@ -900,7 +904,7 @@
//
this.label26.AutoSize = true;
this.label26.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold);
this.label26.Location = new System.Drawing.Point(10, 230);
this.label26.Location = new System.Drawing.Point(10, 260);
this.label26.Margin = new System.Windows.Forms.Padding(10, 10, 10, 7);
this.label26.Name = "label26";
this.label26.Size = new System.Drawing.Size(152, 16);
@@ -1884,6 +1888,25 @@
this.titleLabel.TabIndex = 1;
this.titleLabel.Text = "Settings";
//
// label65
//
this.label65.AutoSize = true;
this.label65.Location = new System.Drawing.Point(11, 210);
this.label65.Margin = new System.Windows.Forms.Padding(10, 10, 10, 7);
this.label65.Name = "label65";
this.label65.Size = new System.Drawing.Size(120, 13);
this.label65.TabIndex = 81;
this.label65.Text = "Fast Mode (CUDA Only)";
//
// rifeCudaFp16
//
this.rifeCudaFp16.AutoSize = true;
this.rifeCudaFp16.Location = new System.Drawing.Point(280, 210);
this.rifeCudaFp16.Name = "rifeCudaFp16";
this.rifeCudaFp16.Size = new System.Drawing.Size(15, 14);
this.rifeCudaFp16.TabIndex = 82;
this.rifeCudaFp16.UseVisualStyleBackColor = true;
//
// SettingsForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@@ -2058,5 +2081,7 @@
private System.Windows.Forms.ComboBox modelsBaseUrl;
private System.Windows.Forms.Label label42;
private System.Windows.Forms.Panel panel13;
private System.Windows.Forms.CheckBox rifeCudaFp16;
private System.Windows.Forms.Label label65;
}
}

View File

@@ -84,6 +84,7 @@ namespace Flowframes.Forms
ConfigParser.SaveGuiElement(ncnnGpus);
ConfigParser.SaveGuiElement(ncnnThreads);
ConfigParser.SaveGuiElement(uhdThresh);
ConfigParser.SaveGuiElement(rifeCudaFp16);
ConfigParser.SaveGuiElement(dainNcnnTilesize, ConfigParser.StringMode.Int);
// Video Export
ConfigParser.SaveGuiElement(minOutVidLength, ConfigParser.StringMode.Int);
@@ -135,6 +136,7 @@ namespace Flowframes.Forms
ConfigParser.LoadGuiElement(ncnnGpus);
ConfigParser.LoadGuiElement(ncnnThreads);
ConfigParser.LoadGuiElement(uhdThresh);
ConfigParser.LoadGuiElement(rifeCudaFp16);
ConfigParser.LoadGuiElement(dainNcnnTilesize);
// Video Export
ConfigParser.LoadGuiElement(minOutVidLength);

View File

@@ -152,6 +152,7 @@ namespace Flowframes.IO
if (key == "minVidLength") return WriteDefault(key, "2");
// AI
if (key == "uhdThresh") return WriteDefault(key, "1440");
if (key == "rifeCudaFp16") return WriteDefault(key, NvApi.HasTensorCores().ToString());
if (key == "ncnnThreads") return WriteDefault(key, "1");
if (key == "dainNcnnTilesize") return WriteDefault(key, "768");
// Debug / Other / Experimental

View File

@@ -120,7 +120,8 @@ namespace Flowframes
string outPath = Path.Combine(inPath.GetParentDir(), outDir);
string wthreads = $"--wthreads {2 * (int)interpFactor}";
string rbuffer = $"--rbuffer {Config.GetInt("rifeCudaBufferSize", 200)}";
string args = $" --input {inPath.Wrap()} --output {outDir} --model {mdl} --exp {(int)Math.Log(interpFactor, 2)} {wthreads} {rbuffer}";
string prec = Config.GetBool("rifeCudaFp16") ? "--fp16" : "";
string args = $" --input {inPath.Wrap()} --output {outDir} --model {mdl} --exp {(int)Math.Log(interpFactor, 2)} {wthreads} {rbuffer} {prec}";
// if (parallel) args = $" --input {inPath.Wrap()} --output {outPath} --model {mdl} --factor {interpFactor}";
// if (parallel) script = "rife-parallel.py";

View File

@@ -24,7 +24,7 @@ namespace Flowframes.OS
return;
gpu = gpus[0];
Logger.Log($"Initialized NvApi. GPU: {gpu.FullName}");
Logger.Log($"Initialized NvApi. GPU: {gpu.FullName} - Tensor Cores: {HasTensorCores()}");
}
catch (Exception e)
{
@@ -50,7 +50,7 @@ namespace Flowframes.OS
{
return (gpu.MemoryInformation.CurrentAvailableDedicatedVideoMemoryInkB / 1000f / 1024f);
}
catch (Exception e)
catch
{
return 0f;
}
@@ -72,5 +72,18 @@ namespace Flowframes.OS
return "";
}
}
public static bool HasTensorCores ()
{
if (gpu == null)
Init();
if (gpu == null)
return false;
string gpuName = gpu.FullName;
return (gpuName.Contains("RTX 20") || gpuName.Contains("RTX 30") || gpuName.Contains("Tesla V") || gpuName.Contains("Tesla T"));
}
}
}

View File

@@ -8,9 +8,9 @@ backwarp_tenGrid = {}
def warp(tenInput, tenFlow):
k = (str(tenFlow.device), str(tenFlow.size()))
if k not in backwarp_tenGrid:
tenHorizontal = torch.linspace(-1.0, 1.0, tenFlow.shape[3]).view(
tenHorizontal = torch.linspace(-1.0, 1.0, tenFlow.shape[3], device=device).view(
1, 1, 1, tenFlow.shape[3]).expand(tenFlow.shape[0], -1, tenFlow.shape[2], -1)
tenVertical = torch.linspace(-1.0, 1.0, tenFlow.shape[2]).view(
tenVertical = torch.linspace(-1.0, 1.0, tenFlow.shape[2], device=device).view(
1, 1, tenFlow.shape[2], 1).expand(tenFlow.shape[0], -1, -1, tenFlow.shape[3])
backwarp_tenGrid[k] = torch.cat(
[tenHorizontal, tenVertical], 1).to(device)
@@ -19,4 +19,4 @@ def warp(tenInput, tenFlow):
tenFlow[:, 1:2, :, :] / ((tenInput.shape[2] - 1.0) / 2.0)], 1)
g = (backwarp_tenGrid[k] + tenFlow).permute(0, 2, 3, 1)
return torch.nn.functional.grid_sample(input=tenInput, grid=torch.clamp(g, -1, 1), mode='bilinear', padding_mode='zeros', align_corners=True)
return torch.nn.functional.grid_sample(input=tenInput, grid=torch.clamp(g, -1, 1), mode='bilinear', padding_mode='zeros', align_corners=True)

View File

@@ -19,11 +19,29 @@ os.chdir(os.path.dirname(dname))
print("Added {0} to temporary PATH".format(dname))
sys.path.append(dname)
parser = argparse.ArgumentParser(description='Interpolation for a pair of images')
parser.add_argument('--input', dest='input', type=str, default=None)
parser.add_argument('--output', required=False, default='frames-interpolated')
parser.add_argument('--model', required=False, default='models')
parser.add_argument('--imgformat', default="png")
parser.add_argument('--rbuffer', dest='rbuffer', type=int, default=200)
parser.add_argument('--wthreads', dest='wthreads', type=int, default=4)
parser.add_argument('--fp16', dest='fp16', action='store_true', help='half-precision mode')
parser.add_argument('--UHD', dest='UHD', action='store_true', help='support 4k video')
parser.add_argument('--exp', dest='exp', type=int, default=1)
args = parser.parse_args()
assert (not args.input is None)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
torch.set_grad_enabled(False)
if torch.cuda.is_available():
torch.backends.cudnn.enabled = True
torch.backends.cudnn.benchmark = True
if(args.fp16):
torch.set_default_tensor_type(torch.HalfTensor)
print("RIFE is running in FP16 mode.")
else:
print("WARNING: CUDA is not available, RIFE is running on CPU! [ff:nocuda-cpu]")
@@ -34,18 +52,6 @@ try:
except:
print("Failed to get hardware info!")
parser = argparse.ArgumentParser(description='Interpolation for a pair of images')
parser.add_argument('--input', dest='input', type=str, default=None)
parser.add_argument('--output', required=False, default='frames-interpolated')
parser.add_argument('--model', required=False, default='models')
parser.add_argument('--imgformat', default="png")
parser.add_argument('--rbuffer', dest='rbuffer', type=int, default=200)
parser.add_argument('--wthreads', dest='wthreads', type=int, default=4)
parser.add_argument('--UHD', dest='UHD', action='store_true', help='support 4k video')
parser.add_argument('--exp', dest='exp', type=int, default=1)
args = parser.parse_args()
assert (not args.input is None)
try:
from model.RIFE_HD import Model
model = Model()
@@ -104,6 +110,12 @@ def make_inference(I0, I1, exp):
first_half = make_inference(I0, middle, exp=exp - 1)
second_half = make_inference(middle, I1, exp=exp - 1)
return [*first_half, middle, *second_half]
def pad_image(img):
if(args.fp16):
return F.pad(img, padding).half()
else:
return F.pad(img, padding)
if args.UHD:
print("UHD mode enabled.")
@@ -122,7 +134,7 @@ for x in range(args.wthreads):
_thread.start_new_thread(clear_write_buffer, (args, write_buffer, x))
I1 = torch.from_numpy(np.transpose(lastframe, (2,0,1))).to(device, non_blocking=True).unsqueeze(0).float() / 255.
I1 = F.pad(I1, padding)
I1 = F.pad(I1, padding).half()
while True:
frame = read_buffer.get()
@@ -130,7 +142,7 @@ while True:
break
I0 = I1
I1 = torch.from_numpy(np.transpose(frame, (2,0,1))).to(device, non_blocking=True).unsqueeze(0).float() / 255.
I1 = F.pad(I1, padding)
I1 = pad_image(I1)
output = make_inference(I0, I1, args.exp)
write_buffer.put([cnt, lastframe])