Skip to content

Commit bd5f4fb

Browse files
authored
Merge pull request #126 from s9901/add-rife-4.26
update RIFE_VFI:supportRIFE 4.26 and RIFE 4.17
2 parents 1b1c990 + dc92c95 commit bd5f4fb

2 files changed

Lines changed: 184 additions & 28 deletions

File tree

vfi_models/rife/__init__.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
CKPT_NAME_VER_DICT = {
1111
"rife47.pth": "4.7",
1212
"rife49.pth": "4.7",
13+
"rife417.pth": "4.17",
14+
"rife426.pth": "4.26",
1315
"sudo_rife4_269.662_testV1_scale1.pth": "4.0",
1416
# Arch 4.10 doesn't work due to state dict mismatch
1517
# "rife410.pth": "4.10",
@@ -118,6 +120,10 @@ def vfi(
118120
torch_dtype = DTYPE_MAP[dtype]
119121
device = get_torch_device()
120122

123+
# 4.26 disable ensemble
124+
if arch_ver == "4.26":
125+
ensemble = False # 4.26 版本不支持 ensemble
126+
121127
# Cache the model by (ckpt_name, dtype, torch_compile) so repeated node
122128
# executions skip the load_state_dict + device transfer entirely.
123129
cache_key = (ckpt_name, dtype, torch_compile)
@@ -147,7 +153,11 @@ def vfi(
147153
multipliers = list(map(int, multiplier))
148154
multipliers += [2] * (n_pairs - len(multipliers))
149155

150-
scale_list = [8 / scale_factor, 4 / scale_factor, 2 / scale_factor, 1 / scale_factor]
156+
# 4.26 scale_list
157+
if arch_ver == "4.26":
158+
scale_list = [16 / scale_factor, 8 / scale_factor, 4 / scale_factor, 2 / scale_factor, 1 / scale_factor]
159+
else:
160+
scale_list = [8 / scale_factor, 4 / scale_factor, 2 / scale_factor, 1 / scale_factor]
151161

152162
# Build a flat list of all (pair_idx, timestep) tasks, skipping excluded pairs.
153163
# Each task produces exactly one intermediate frame.

vfi_models/rife/rife_arch.py

Lines changed: 173 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ def conv(
9292
),
9393
nn.PReLU(out_planes),
9494
)
95-
if arch_ver in ["4.2", "4.3", "4.5", "4.6", "4.7", "4.10"]:
95+
if arch_ver in ["4.2", "4.3", "4.5", "4.6", "4.7", "4.10", "4.17", "4.26"]:
9696
return nn.Sequential(
9797
nn.Conv2d(
9898
in_planes,
@@ -148,7 +148,7 @@ def deconv(in_planes, out_planes, kernel_size=4, stride=2, padding=1, arch_ver="
148148
),
149149
nn.PReLU(out_planes),
150150
)
151-
if arch_ver in ["4.2", "4.3", "4.5", "4.6", "4.7", "4.10"]:
151+
if arch_ver in ["4.2", "4.3", "4.5", "4.6", "4.7", "4.10", "4.17", "4.26"]:
152152
return nn.Sequential(
153153
torch.nn.ConvTranspose2d(
154154
in_channels=in_planes,
@@ -197,7 +197,7 @@ def __init__(self, in_planes, c=64, arch_ver="4.0"):
197197
)
198198
self.lastconv = nn.ConvTranspose2d(c, 5, 4, 2, 1)
199199

200-
if arch_ver in ["4.5", "4.6", "4.7", "4.10"]:
200+
if arch_ver in ["4.5", "4.6", "4.7", "4.10", "4.17"]:
201201
self.convblock = nn.Sequential(
202202
ResConv(c),
203203
ResConv(c),
@@ -212,11 +212,28 @@ def __init__(self, in_planes, c=64, arch_ver="4.0"):
212212
self.lastconv = nn.Sequential(
213213
nn.ConvTranspose2d(c, 4 * 5, 4, 2, 1), nn.PixelShuffle(2)
214214
)
215-
if arch_ver in ["4.6", "4.7", "4.10"]:
215+
if arch_ver in ["4.6", "4.7", "4.10", "4.17"]:
216216
self.lastconv = nn.Sequential(
217217
nn.ConvTranspose2d(c, 4 * 6, 4, 2, 1), nn.PixelShuffle(2)
218218
)
219219

220+
# add 4.26 support
221+
if arch_ver in ["4.26"]:
222+
self.convblock = nn.Sequential(
223+
ResConv(c),
224+
ResConv(c),
225+
ResConv(c),
226+
ResConv(c),
227+
ResConv(c),
228+
ResConv(c),
229+
ResConv(c),
230+
ResConv(c),
231+
)
232+
self.lastconv = nn.Sequential(
233+
nn.ConvTranspose2d(c, 4*13, 4, 2, 1),
234+
nn.PixelShuffle(2)
235+
)
236+
220237
def forward(self, x, flow=None, scale=1):
221238
x = F.interpolate(
222239
x, scale_factor=1.0 / scale, mode="bilinear", align_corners=False
@@ -233,7 +250,7 @@ def forward(self, x, flow=None, scale=1):
233250
feat = self.conv0(x)
234251
if self.arch_ver == "4.0":
235252
feat = self.convblock(feat) + feat
236-
if self.arch_ver in ["4.2", "4.3", "4.5", "4.6", "4.7", "4.10"]:
253+
if self.arch_ver in ["4.2", "4.3", "4.5", "4.6", "4.7", "4.10", "4.17", "4.26"]:
237254
feat = self.convblock(feat)
238255

239256
tmp = self.lastconv(feat)
@@ -242,11 +259,19 @@ def forward(self, x, flow=None, scale=1):
242259
tmp, scale_factor=scale * 2, mode="bilinear", align_corners=False
243260
)
244261
flow = tmp[:, :4] * scale * 2
245-
if self.arch_ver in ["4.5", "4.6", "4.7", "4.10"]:
262+
if self.arch_ver in ["4.5", "4.6", "4.7", "4.10", "4.17"]:
263+
tmp = F.interpolate(
264+
tmp, scale_factor=scale, mode="bilinear", align_corners=False
265+
)
266+
flow = tmp[:, :4] * scale
267+
if self.arch_ver in ["4.26"]:
246268
tmp = F.interpolate(
247269
tmp, scale_factor=scale, mode="bilinear", align_corners=False
248270
)
249271
flow = tmp[:, :4] * scale
272+
mask = tmp[:, 4:5]
273+
feat_out = tmp[:, 5:]
274+
return flow, mask, feat_out
250275
mask = tmp[:, 4:5]
251276
return flow, mask
252277

@@ -328,6 +353,48 @@ def forward(self, img0, img1, warped_img0, warped_img1, mask, flow, c0, c1):
328353
4.7: 4.7, 4.8, 4.9
329354
4.10: 4.10 4.11 4.12
330355
"""
356+
class Head_417(nn.Module):
357+
def __init__(self):
358+
super(Head_417, self).__init__()
359+
self.cnn0 = nn.Conv2d(3, 32, 3, 2, 1)
360+
self.cnn1 = nn.Conv2d(32, 32, 3, 1, 1)
361+
self.cnn2 = nn.Conv2d(32, 32, 3, 1, 1)
362+
self.cnn3 = nn.ConvTranspose2d(32, 8, 4, 2, 1)
363+
self.relu = nn.LeakyReLU(0.2, True)
364+
365+
def forward(self, x, feat=False):
366+
x0 = self.cnn0(x)
367+
x = self.relu(x0)
368+
x1 = self.cnn1(x)
369+
x = self.relu(x1)
370+
x2 = self.cnn2(x)
371+
x = self.relu(x2)
372+
x3 = self.cnn3(x)
373+
if feat:
374+
return [x0, x1, x2, x3]
375+
return x3
376+
377+
378+
class Head(nn.Module):
379+
def __init__(self):
380+
super(Head, self).__init__()
381+
self.cnn0 = nn.Conv2d(3, 16, 3, 2, 1)
382+
self.cnn1 = nn.Conv2d(16, 16, 3, 1, 1)
383+
self.cnn2 = nn.Conv2d(16, 16, 3, 1, 1)
384+
self.cnn3 = nn.ConvTranspose2d(16, 4, 4, 2, 1)
385+
self.relu = nn.LeakyReLU(0.2, True)
386+
387+
def forward(self, x, feat=False):
388+
x0 = self.cnn0(x)
389+
x = self.relu(x0)
390+
x1 = self.cnn1(x)
391+
x = self.relu(x1)
392+
x2 = self.cnn2(x)
393+
x = self.relu(x2)
394+
x3 = self.cnn3(x)
395+
if feat:
396+
return [x0, x1, x2, x3]
397+
return x3
331398

332399

333400
class IFNet(nn.Module):
@@ -347,7 +414,25 @@ def __init__(self, arch_ver="4.0"):
347414
self.encode = nn.Sequential(
348415
nn.Conv2d(3, 16, 3, 2, 1), nn.ConvTranspose2d(16, 4, 4, 2, 1)
349416
)
350-
if arch_ver in ["4.10"]:
417+
if arch_ver in ["4.10", "4.17"]:
418+
self.block0 = IFBlock(7 + 16, c=192, arch_ver=arch_ver)
419+
self.block1 = IFBlock(8 + 4 + 16, c=128, arch_ver=arch_ver)
420+
self.block2 = IFBlock(8 + 4 + 16, c=96, arch_ver=arch_ver)
421+
self.block3 = IFBlock(8 + 4 + 16, c=64, arch_ver=arch_ver)
422+
if arch_ver == "4.10":
423+
self.encode = nn.Sequential(
424+
nn.Conv2d(3, 32, 3, 2, 1),
425+
nn.LeakyReLU(0.2, True),
426+
nn.Conv2d(32, 32, 3, 1, 1),
427+
nn.LeakyReLU(0.2, True),
428+
nn.Conv2d(32, 32, 3, 1, 1),
429+
nn.LeakyReLU(0.2, True),
430+
nn.ConvTranspose2d(32, 8, 4, 2, 1),
431+
)
432+
else:
433+
self.encode = Head_417()
434+
435+
if arch_ver in ["old_4.10_delete_me"]:
351436
self.block0 = IFBlock(7 + 16, c=192)
352437
self.block1 = IFBlock(8 + 4 + 16, c=128)
353438
self.block2 = IFBlock(8 + 4 + 16, c=96)
@@ -362,6 +447,16 @@ def __init__(self, arch_ver="4.0"):
362447
nn.ConvTranspose2d(32, 8, 4, 2, 1),
363448
)
364449

450+
# add 4.26 support
451+
if arch_ver in ["4.26"]:
452+
self.block0 = IFBlock(7+8, c=192, arch_ver=arch_ver)
453+
self.block1 = IFBlock(8+4+8+8, c=128, arch_ver=arch_ver)
454+
self.block2 = IFBlock(8+4+8+8, c=96, arch_ver=arch_ver)
455+
self.block3 = IFBlock(8+4+8+8, c=64, arch_ver=arch_ver)
456+
self.block4 = IFBlock(8+4+8+8, c=32, arch_ver=arch_ver)
457+
self.encode = Head()
458+
459+
365460
if arch_ver in ["4.0", "4.2", "4.3"]:
366461
self.contextnet = Contextnet(arch_ver=arch_ver)
367462
self.unet = Unet(arch_ver=arch_ver)
@@ -372,7 +467,7 @@ def forward(
372467
img0,
373468
img1,
374469
timestep=0.5,
375-
scale_list=[8, 4, 2, 1],
470+
scale_list=[16, 8, 4, 2, 1],
376471
training=True,
377472
fastmode=True,
378473
ensemble=False,
@@ -402,20 +497,34 @@ def forward(
402497
merged = []
403498
mask_list = []
404499

405-
if self.arch_ver in ["4.7", "4.10"]:
500+
# add 4.26 support
501+
if self.arch_ver in ["4.7", "4.10", "4.17", "4.26"]:
406502
f0 = self.encode(img0[:, :3])
407503
f1 = self.encode(img1[:, :3])
408504

409505
warped_img0 = img0
410506
warped_img1 = img1
411507
flow = None
412508
mask = None
413-
block = [self.block0, self.block1, self.block2, self.block3]
509+
feat = None
510+
511+
# add 4.26 support
512+
if self.arch_ver in ["4.26"]:
513+
block = [self.block0, self.block1, self.block2, self.block3, self.block4]
514+
num_blocks = 5
515+
else:
516+
block = [self.block0, self.block1, self.block2, self.block3]
517+
num_blocks = 4
414518

415-
for i in range(4):
519+
for i in range(num_blocks):
416520
if flow is None:
417-
# 4.0-4.6
418-
if self.arch_ver in ["4.0", "4.2", "4.3", "4.5", "4.6"]:
521+
if self.arch_ver in ["4.26"]:
522+
flow, mask, feat = block[i](
523+
torch.cat((img0[:, :3], img1[:, :3], f0, f1, timestep), 1),
524+
None,
525+
scale=scale_list[i],
526+
)
527+
elif self.arch_ver in ["4.0", "4.2", "4.3", "4.5", "4.6"]:
419528
flow, mask = block[i](
420529
torch.cat((img0[:, :3], img1[:, :3], timestep), 1),
421530
None,
@@ -431,7 +540,7 @@ def forward(
431540
mask = (mask + (-m1)) / 2
432541

433542
# 4.7+
434-
if self.arch_ver in ["4.7", "4.10"]:
543+
if self.arch_ver in ["4.7", "4.10", "4.17"]:
435544
flow, mask = block[i](
436545
torch.cat((img0[:, :3], img1[:, :3], f0, f1, timestep), 1),
437546
None,
@@ -450,8 +559,34 @@ def forward(
450559
mask = (mask + (-m_)) / 2
451560

452561
else:
562+
# add 4.26 support
563+
if self.arch_ver in ["4.26"]:
564+
wf0 = warp(f0, flow[:, :2])
565+
wf1 = warp(f1, flow[:, 2:4])
566+
567+
# add 4.26 support
568+
input_tensor = torch.cat(
569+
(
570+
warped_img0[:, :3],
571+
warped_img1[:, :3],
572+
wf0,
573+
wf1,
574+
timestep,
575+
mask,
576+
feat,
577+
),
578+
1,
579+
)
580+
581+
fd, m0, feat = block[i](
582+
input_tensor,
583+
flow,
584+
scale=scale_list[i],
585+
)
586+
flow = flow + fd
587+
mask = m0
453588
# 4.0-4.6
454-
if self.arch_ver in ["4.0", "4.2", "4.3", "4.5", "4.6"]:
589+
elif self.arch_ver in ["4.0", "4.2", "4.3", "4.5", "4.6"]:
455590
f0, m0 = block[i](
456591
torch.cat(
457592
(warped_img0[:, :3], warped_img1[:, :3], timestep, mask), 1
@@ -491,7 +626,7 @@ def forward(
491626
)
492627

493628
# 4.7+
494-
if self.arch_ver in ["4.7", "4.10"]:
629+
if self.arch_ver in ["4.7", "4.10", "4.17"]:
495630
fd, m0 = block[i](
496631
torch.cat(
497632
(
@@ -534,7 +669,7 @@ def forward(
534669
m0 = (m0 + (-m1)) / 2
535670

536671
# 4.7+ ensemble
537-
if ensemble and self.arch_ver in ["4.7", "4.10"]:
672+
if ensemble and self.arch_ver in ["4.7", "4.10", "4.17"]:
538673
wf0 = warp(f0, flow[:, :2])
539674
wf1 = warp(f1, flow[:, 2:4])
540675

@@ -560,7 +695,7 @@ def forward(
560695
flow = flow + f0
561696
mask = mask + m0
562697

563-
if not ensemble and self.arch_ver in ["4.7", "4.10"]:
698+
if not ensemble and self.arch_ver in ["4.7", "4.10", "4.17"]:
564699
mask = m0
565700

566701
mask_list.append(mask)
@@ -569,18 +704,29 @@ def forward(
569704
warped_img1 = warp(img1, flow[:, 2:4])
570705
merged.append((warped_img0, warped_img1))
571706

572-
if self.arch_ver in ["4.0", "4.1", "4.2", "4.3", "4.4", "4.5", "4.6"]:
573-
mask_list[3] = torch.sigmoid(mask_list[3])
574-
merged[3] = merged[3][0] * mask_list[3] + merged[3][1] * (1 - mask_list[3])
575-
576-
if self.arch_ver in ["4.7", "4.10"]:
577-
mask = torch.sigmoid(mask)
578-
merged[3] = warped_img0 * mask + warped_img1 * (1 - mask)
707+
# add 4.26 support
708+
if self.arch_ver in ["4.26"]:
709+
final_mask = mask_list[-1] if mask_list else mask
710+
final_mask = torch.sigmoid(final_mask)
711+
merged_final = warped_img0 * final_mask + warped_img1 * (1 - final_mask)
712+
else:
713+
if self.arch_ver in ["4.0", "4.1", "4.2", "4.3", "4.4", "4.5", "4.6"]:
714+
final_idx = min(3, len(mask_list)-1) if len(mask_list) > 0 else 0
715+
if final_idx < len(mask_list):
716+
mask_list[final_idx] = torch.sigmoid(mask_list[final_idx])
717+
merged_final = merged[final_idx][0] * mask_list[final_idx] + merged[final_idx][1] * (1 - mask_list[final_idx])
718+
else:
719+
mask = torch.sigmoid(mask)
720+
merged_final = warped_img0 * mask + warped_img1 * (1 - mask)
721+
if self.arch_ver in ["4.7", "4.10", "4.17"]:
722+
mask = torch.sigmoid(mask)
723+
merged_final = warped_img0 * mask + warped_img1 * (1 - mask)
579724

580725
if not fastmode and self.arch_ver in ["4.0", "4.2", "4.3"]:
581726
c0 = self.contextnet(img0, flow[:, :2])
582727
c1 = self.contextnet(img1, flow[:, 2:4])
583728
tmp = self.unet(img0, img1, warped_img0, warped_img1, mask, flow, c0, c1)
584729
res = tmp[:, :3] * 2 - 1
585-
merged[3] = torch.clamp(merged[3] + res, 0, 1)
586-
return merged[3][:, :, :h, :w]
730+
merged_final = torch.clamp(merged_final + res, 0, 1)
731+
732+
return merged_final[:, :, :h, :w]

0 commit comments

Comments
 (0)