PMRF
The face-restorer that rebuilds the face instead of polishing it
- images
- images
PMRF stands for Posterior-Mean Rectified Flow, which sounds like a physics exam question but really just means "the cleanest face consistent with what you handed it." It's a face restoration node: the one ComfyUI entry point for the ohayonguy/PMRF model, and the modern flow-matching heir to the old CodeFormer / GFPGAN "restore faces" step. When this shipped in October 2024 the community called it "best in class, a la codeformers." You reach for it when a face in an image is genuinely damaged - an old scanned photo, heavy JPEG mush, or a generation where the face came out soft and waxy - and you want it rebuilt, not just sharpened.
Where it fits matters. The upscaling ladder in our knowledge base is blunt: "A face you can recognise - give it its own pass." SUPIR and SeedVR2 are great at adding detail, but every generative rung rewrites identity, and faces are where that shows. PMRF does the opposite of an upscaler: it detects faces with RetinaFace, works only on the face region, and leaves the rest of the image alone. That's the correct shape for photo restoration - upscale the background, don't change the face.
How it works
PMRF is not a denoiser and not a GAN. It's a rectified-flow model - the same "predict a velocity, walk a near-straight line from noise to image" family that powers Flux and friends (arXiv 2410.00418). It was trained so that sampling approximates the posterior mean: the minimum-MSE estimate of the clean image given the degraded input, which is what keeps output photorealistic instead of smooth-filtered. The node runs the flow model on each aligned 512px face crop, upscales the background with RealESRGAN x2plus so the pasted face's resolution matches, pastes the restored faces back in, and resizes to your target scale. Because the flow starts from noise, the seed controls which plausible reconstruction you get.
The inputs that matter
The node is one box with five knobs, and you'll touch maybe three of them:
- images - one or more IMAGE tensors; it loops over the whole batch, so you can feed several faces at once.
- scale (default 1.0) - output size relative to input; push above 1.0 for an actual upscale. The face is rebuilt at 512px and the background is 2x'd to match, which is why results hold up at scale 2 without mush.
- num_steps (default 25) - flow integration steps. More tracks the ideal reconstruction more closely but costs time; the training default is 50, so 25 is already the sensible middle. Drop below ~10 and the face gets sloppy.
- seed (default 123) - reproducibility, and the first thing to change if a face comes out weird. A different seed is often a different (better) face.
- interpolation (default
lanczos4) - the resize method for crops and the final image. Leave it alone.
The single output, images, is an IMAGE tensor you wire into SaveImage or the next node in your chain - it's not an output-only node, so you can keep processing after it.
Install
The real install is a clone plus a restart:
cd ComfyUI/custom_nodes
git clone https://github.com/2kpr/ComfyUI-PMRF
Restart ComfyUI and the pack's startup script does the heavy lifting: it downloads the PMRF weights into models/pmrf/, grabs RealESRGAN_x2plus.pth and x4plus.pth into models/upscale_models/, patches a known basicsr/torchvision incompatibility, and pip-installs NATTEN plus a stack of deps (realesrgan, pytorch_lightning, timm, torch_fidelity, torch_ema...). ComfyUI Manager works too - search "ComfyUI-PMRF". Two heads-ups: it auto-upgrades torchvision to 0.19.0+ on every start, and torchvision 0.19 pairs with torch 2.4, so on an older torch install it can drag torch up along with it. And the first launch is slow - model downloads plus, on Linux, a NATTEN wheel compile.
Where people get burned
The NATTEN dependency is the whole story on Windows. NATTEN (Neighborhood Attention) is the attention mechanism PMRF's backbone uses, and it ships no official Windows builds. On Linux the script finds a wheel matching your CUDA (11.8–12.4) and torch (2.1–2.4). On Windows it can only auto-install its own prebuilt wheels if you're on Python 3.10–3.12 and CUDA 12.4 and torch 2.4; otherwise it prints an error pointing you at building NATTEN yourself with MSVC - the "kind of a bummer" the community flagged the week this node launched. If you don't match those specs, decide whether you want to compile before you commit.
Two model-level gotchas, not node bugs: PMRF famously ages faces - the release thread's top critique was that it adds wrinkles to young, middle-aged and East Asian faces, so expect portraits to come back a few years older. And it's a face node; feed it a face. A full-body shot gets one small crop resized up, and the community agreed from day one that this is for headshots. If the likeness comes out wrong on a good source, that's the trade-off baked into a posterior-mean reconstruction - try a different seed, and treat it as one pass in a photo-restoration chain rather than the whole answer.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | — | |
| scale | FLOAT | 1.01–40 | — |
| num_steps | INT | 251–400 | — |
| seed | INT | 1230–4294967296 | — |
| interpolation | COMBO | 7 options: lanczos4, nearest, linear, cubic, area, linear_exact, +1 |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| images | IMAGE | — |