EDSR (Γ—4) β€” Super-resolution (LiteRT GPU)

On-device Γ—4 single-image super-resolution running fully on the LiteRT CompiledModel GPU delegate (no CPU fallback). EDSR (CVPR 2017 winner) upscales a low-res image 4Γ— with sharp detail. The first super-resolution model in the litert-community zoo. ~23 ms/frame on a Pixel 8a.

  • Architecture: EDSR-baseline (16 residual blocks, no BatchNorm) + sub-pixel upsampler β€” pure CNN.
  • Weights: eugenesiow/edsr-base (super-image, DIV2K) Β· Apache-2.0.
  • Size: 7.7 MB.

EDSR Γ—4 super-resolution

Left: bicubic Γ—4. Right: EDSR Γ—4 (sharper fur / whiskers / eyes). Photo: Unsplash (free license).

I/O

  • Input: [1, 3, 128, 128] NCHW, RGB, x/255 (0–1).
  • Output: [1, 3, 512, 512] NCHW, RGB in 0–1 β€” clamp and Γ—255.

GPU conversion

EDSR is a pure CNN, but its PixelShuffle sub-pixel upsampler lowers to rank-5/6 reshapes that the Mali delegate rejects (the classic super-resolution wall). The fix (exact): PixelShuffle(r) ≑ a fixed-weight grouped-identity ConvTranspose2d(stride=r), which is then converted with ZeroStuffConvT2d (nearest-upsample + stride zero-stuff mask + flipped conv). Result: 68/68 nodes on the delegate, 1 partition; device corr 0.999946, ~23 ms. CPU-exact vs PyTorch (corr 1.0).

Minimal usage

Kotlin (Android, LiteRT CompiledModel GPU)

val options = CompiledModel.Options(Accelerator.GPU)
val model = CompiledModel.create(context.assets, "edsr.tflite", options, null)
val inBufs = model.createInputBuffers()
val outBufs = model.createOutputBuffers()

inBufs[0].writeFloat(lrNCHW)             // [1,3,128,128] RGB, x/255
model.run(inBufs, outBufs)
val sr = outBufs[0].readFloat()          // [3*512*512] RGB 0..1 (clamp, *255) -> HR bitmap

Python (LiteRT / ai-edge-litert)

import numpy as np
from ai_edge_litert.interpreter import Interpreter

it = Interpreter(model_path="edsr.tflite"); it.allocate_tensors()
inp, out = it.get_input_details(), it.get_output_details()
it.set_tensor(inp[0]["index"], x)        # [1,3,128,128] float32, RGB, x/255
it.invoke()
sr = it.get_tensor(out[0]["index"])[0]   # [3,512,512] 0..1 -> clamp, *255

Conversion

Converted with litert-torch (build_edsr.py): loads the Apache-2.0 EDSR-base weights, rewrites PixelShuffle β†’ ConvTranspose β†’ ZeroStuffConvT2d, and exports the Γ—4 graph.

License

Apache-2.0 (super-image / eugenesiow). EDSR trained on DIV2K.

Downloads last month
9
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support

Paper for litert-community/EDSR-x4-LiteRT