RIFE_fp32_timestep

FuryTMP/RIFE_fp32 with its baked timestep exposed as a runtime input, so the model can synthesise a frame at any phase between two inputs instead of only the midpoint.

Nothing about the weights changed. The output at t = 0.5 is bit-identical to the original model.

Why

RIFE v4.x IFNet is timestep-conditioned: it takes a constant-valued t plane alongside the two frames and feeds it to the head of every IFBlock. The upstream ONNX export was traced with timestep = 0.5, which folded that value into a Constant node and left the graph with a 6-channel input. The capability was still in the graph, just unreachable β€” passing a 7th channel changed the output by exactly 0.0.

Internally the plane is built as:

t_plane = ((Slice_4 * 0) + 1) * Constant_50   where Constant_50 = 0.5

This model deletes /Constant_50 and rewires its single consumer (/Mul_3) to a new scalar graph input named timestep. See patch_rife_timestep.py, which reproduces this file byte-for-byte from the upstream RIFE_fp32.onnx.

Inputs / outputs

name type shape notes
input float32 [1, 6, H, W] planar RGB in [0, 1]; frame0 in channels 0-2, frame1 in channels 3-5
timestep float32 [] (scalar) interpolation phase, 0 < t < 1
output float32 [1, 3, H, W] planar RGB, cropped back to H x W

H and W are arbitrary β€” the graph pads to a multiple of 32 internally and crops back.

The endpoints are not exact. t = 0 does not reproduce frame0 and t = 1 does not reproduce frame1. This is a property of the upstream weights, not of the patch. It is harmless for interpolation, where the endpoints are the source frames and are passed through verbatim. Use 0 < t < 1.

Usage

import numpy as np, onnxruntime as ort

sess = ort.InferenceSession("RIFE_fp32_timestep.onnx")

x = np.zeros((1, 6, H, W), np.float32)
x[0, 0:3] = frame0          # planar RGB, [0, 1]
x[0, 3:6] = frame1

# timestep must be a 0-d array; a bare np.float32 scalar raises
# "Unable to handle object of type <class 'numpy.float32'>"
out = sess.run(None, {"input": x, "timestep": np.array(0.25, dtype=np.float32)})[0][0]

For a fully-GPU graph under onnxruntime-web's WebGPU EP, pin the free dimensions at session creation. Without this, the meshgrid construction falls back to the CPU execution provider:

await ort.InferenceSession.create(bytes, {
  executionProviders: ["webgpu"],
  graphOptimizationLevel: "all",
  freeDimensionOverrides: { dynamic_dim_0: 1, dynamic_dim_1: 6, dynamic_dim_2: H, dynamic_dim_3: W },
})

With those overrides the graph folds to 336 nodes and zero shape-computation ops β€” the same node count as the unpatched model. Exposing the timestep costs nothing.

Quality

Midpoint reconstruction against ground truth, 720p, 48 frames from three Xiph derf sequences (park_joy, old_town_cross, in_to_tree). Each dropped frame is rebuilt from its two neighbours and compared to the original.

model PSNR paired wins
this model / FuryTMP/RIFE_fp32 30.01 dB 42/48
RIFE 4.26 29.64 dB 6/48
RIFE 4.26-heavy 29.63 dB 6/48

At non-midpoint phases (gaps of 3, 4 and 8) this model wins at every phase on every clip by 0.4–0.9 dB. Reaching a given phase directly versus by recursive halving measures within Β±0.2 dB with no consistent winner, so prefer direct β€” the intermediates are then independent of one another and can be evaluated in any order.

License and attribution

MIT, inherited unchanged.

  • FuryTMP/RIFE_fp32 β€” the ONNX export this file is derived from.
  • hzwer/Practical-RIFE β€” MIT; the README places the model weights under the same MIT license.
  • Megvii ECCV2022-RIFE β€” MIT; the original Real-Time Intermediate Flow Estimation for Video Frame Interpolation.
Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support

Model tree for walterlow/RIFE_fp32_timestep

Quantized
(1)
this model