Restore Old Photos Locally and Free, on 8GB VRAM
Want to go deeper than this article?
Free account unlocks the first chapter of all 25 courses — RAG, agents, MCP, voice AI, MLOps, real GitHub repos.
Got the hardware sorted? Now build on it. You know what to buy — the courses show you what to actually run, fine-tune, and ship on it. First chapter free, no card.
The chain that works on 8GB is four stages in this exact order: repair damage → restore faces → colorize → upscale. Bringing-Old-Photos-Back-to-Life handles scratches and creases, CodeFormer (18,109 stars) rebuilds faces from a 359MB checkpoint, DDColor (1,493 stars, Apache 2.0) adds colour from about 912MB of weights, and Real-ESRGAN (36,504 stars, BSD-3) does the final resolution bump from a 63MB file. Total download for the minimum set is roughly 1.5GB. No watermark, no upload limit, no photo of your grandmother sitting on someone else's server.
If you only remember one thing from this page, remember the order. Every "why does my restored photo look plastic" thread ends up being someone who upscaled first.
A note on what we can and cannot tell you: the star counts, file sizes, licences and commands below are all read straight from the upstream repositories on August 18, 2026 and are quoted as such. Where we say something is a mechanism argument rather than a benchmark, we say so — we are not going to invent tokens-per-second for a convnet or publish a VRAM figure we did not measure.
The Four-Stage Chain
Four tools, four jobs, ~1.5GB of free weights, all of it offline. Here is the whole stack in one table, with the numbers pulled from each repository on August 18, 2026:
| Stage | Tool | Fixes | Weights | Licence | Last upstream push |
|---|---|---|---|---|---|
| 1 | Bringing-Old-Photos-Back-to-Life (via ComfyUI nodes) | Scratches, creases, tears, general degradation | Bundled checkpoint archives | MIT (upstream), MIT (nodes) | Upstream: Oct 26, 2023 · Nodes: Jun 30, 2025 |
| 2 | CodeFormer | Blown-out, blurry, low-detail faces | codeformer.pth 359MB + face detector | NTU S-Lab 1.0 — non-commercial | Nov 18, 2025 |
| 3 | DDColor | Black-and-white → colour | ~912MB (ddcolor_modelscope) | Apache 2.0 | Jan 17, 2026 |
| 4 | Real-ESRGAN | Resolution, print size | RealESRGAN_x4plus.pth 63MB | BSD-3-Clause | Aug 6, 2024 |
Two honest observations from that table before you download anything.
First, the upstream Microsoft repo has not been touched since October 2023 (15,700 stars, MIT, not archived). It still works — the weights do not rot — but you will fight its Python dependencies. That is exactly why the ComfyUI port exists, and why we route stage 1 through ComfyUI below rather than through the original codebase.
Second, GFPGAN was last pushed in July 2024. It is still an excellent face restorer and it is Apache 2.0, which matters if you are doing this for money. But CodeFormer is the actively maintained one and its fidelity dial gives you control GFPGAN does not.
Reading articles is good. Building is better.
Free account = the first chapter of all 25 courses, with a per-chapter AI tutor. No card.
Why the Order Is Not Optional
Repair → faces → colour → upscale. Each stage feeds the next one cleaner input, and reversing any pair costs you detail you cannot get back.
This is a mechanism argument, and it is worth understanding rather than memorising:
- Upscale last, always. Real-ESRGAN is a super-resolution network trained to make plausible high-frequency detail. Point it at an unrepaired scan and it does its job on the damage too — a crease becomes a crisp black line, film grain becomes fake texture, and dust becomes confident little dots. The repair network then has to remove an artefact that is now sharper and more self-consistent than it was in the original scan. You have made stage 1 harder by running stage 4 first.
- Faces before colour. DDColor infers colour from the structures it can see. A washed-out face gives it nothing to work with, so it lays down flat, generic skin tone across the whole region. Restore the face first and the colorizer has eyes, lips, shadow under the jaw — actual structure to colour differently.
- Damage before faces. CodeFormer crops and aligns each detected face to 512x512, rebuilds it, then fuses it back into the background. A scratch running across a cheek is inside that crop. Remove it first or CodeFormer will faithfully reconstruct a face that has a scratch-shaped feature in it.
We have not published a side-by-side of the wrong order on our own scan set, because we would rather tell you the mechanism than show you one cherry-picked crop. Run it both ways on two of your own photos — it takes ten minutes and it is far more convincing than anything we could post.
Stage 1 — Scratches, Creases and Tears
Use the ComfyUI port, not the original repo. The comfyui-old-photo-restoration extension runs Bringing-Old-Photos-Back-to-Life natively inside ComfyUI, which spares you the 2023-era dependency stack. If you do not have ComfyUI yet, our ComfyUI complete guide is the fastest path in.
Install it from ComfyUI-Manager, then check the custom node folder contains lib_bopb2l. If it does not, the README tells you to grab backend.zip from the extension's Releases page and extract the folder yourself. You then need three checkpoint archives, all from the author's sd-webui-old-photo-restoration Releases page:
global_checkpoints.zip→ extract thecheckpointsfolder intolib_bopb2l/Globalface_checkpoints.zip→ extract thecheckpointsfolder intolib_bopb2l/Face_Enhancementshape_predictor_68_face_landmarks.zip→ extract the.datfile intolib_bopb2l/Face_Detection
The README is emphatic about the folder-not-files distinction, which tells you what the most common install failure is.
Then wire it up:
- Photo with no visible scratches → connect the image to the Global Restoration node.
- Photo with scratch artefacts → use Global Restoration with Scratch Processing instead. This is the node you want for a shoebox of shuffled prints.
- No NVIDIA GPU, or hitting out-of-memory → set GPU_ID to
-1to run on CPU. Slow, but it finishes. - HR toggles higher-parameter processing. Turn it on for large scans, off if you are memory-constrained.
The extension has 66 stars, which is small — treat it as a useful wrapper around a well-cited Microsoft Research paper (arXiv 2004.09484) rather than as a heavily battle-tested project.
Stage 2 — Faces
CodeFormer with -w 0.7 on the whole image is the default that works for family photos. The fidelity weight w runs 0 to 1: lower w produces a higher-quality, more idealised face; higher w stays closer to the original. That trade-off is the whole game with face restoration, and it is why "AI restored photos look like someone else" is a real complaint — people run it at low fidelity and get a beautiful stranger.
Install, per the upstream README:
git clone https://github.com/sczhou/CodeFormer
cd CodeFormer
conda create -n codeformer python=3.8 -y
conda activate codeformer
pip3 install -r requirements.txt
python basicsr/setup.py develop
Pull the weights (this is the step that downloads the 359MB checkpoint plus the face-detection models):
python scripts/download_pretrained_models.py facelib
python scripts/download_pretrained_models.py CodeFormer
Then run it. Two modes matter for scanned photos:
# Whole scanned photo — detects faces, restores, fuses back into the background
python inference_codeformer.py -w 0.7 --input_path ./repaired
# Already-cropped, aligned 512x512 face
python inference_codeformer.py -w 0.5 --has_aligned --input_path ./faces
Two flags worth knowing. --bg_upsampler realesrgan enhances the background regions with Real-ESRGAN, and --face_upsample further upsamples the restored face. Both are convenient, and both quietly move stage 4 into stage 2 — if you are running the full chain, leave them off and let the dedicated upscale stage do its job on the whole image consistently.
On fidelity, our advice is to start at -w 0.7 and only go lower if the face is genuinely destroyed. For a photograph of a real person somebody remembers, resemblance beats sharpness every time.
If the face in your scan is masked by a tear rather than merely blurry, CodeFormer also ships inference_inpainting.py for cropped, aligned faces where you have painted the damaged area white in an image editor first. That is a manual, one-photo-at-a-time workflow — worth it for the three photos that matter, not for the box.
Run this on your own machine and stop paying every month
Pay once and keep it. No renewal, no per-token bill, and nothing you feed it ever leaves your hardware.
Stage 3 — Colour
DDColor is the free colorizer to use, and it is Apache 2.0 — the only stage in this chain you can safely run commercially. It is an ICCV 2023 paper out of DAMO Academy / Alibaba Group that optimises learnable colour queries against multi-scale visual features, and its own README leads with historical black-and-white photos as the target case.
Install and run:
conda create -n ddcolor python=3.9
conda activate ddcolor
pip install torch==2.2.0 torchvision==0.17.0 --index-url https://download.pytorch.org/whl/cu118
pip install -r requirements.txt
The path of least resistance is the Hugging Face route, which skips the basicsr dependency entirely:
python scripts/infer.py --model_name ddcolor_modelscope --input ./faces-restored
Four checkpoints are published: ddcolor_paper, ddcolor_modelscope, ddcolor_artistic and ddcolor_paper_tiny. Start with ddcolor_modelscope (911.9MB on Hugging Face) — it is the one behind the public ModelScope demo. Drop to ddcolor_paper_tiny (220MB, released December 13, 2023, and it wants --model_size tiny) if you are memory-constrained or batching thousands of images.
A word on expectations. No colorizer knows what colour your grandfather's jacket was. DDColor produces a plausible, consistent, natural-looking colour field — it does not recover information that was never in the negative. For photos where the colour actually matters, colorize, then hand-correct the two or three regions you have family knowledge about in any image editor. That is a better use of an hour than trying twenty checkpoints.
Stage 4 — Upscale
Real-ESRGAN x4plus, with --tile set, is the whole of stage 4 on an 8GB card. The upstream README documents -t, --tile as "tile size, 0 for no tile during testing" — tiling processes the image in chunks, which is precisely the knob that decouples peak memory from input resolution. On a small card, set it; on a large card, leave it at 0 for slightly cleaner seams.
wget https://github.com/xinntao/Real-ESRGAN/releases/download/v0.1.0/RealESRGAN_x4plus.pth -P weights
python inference_realesrgan.py -n RealESRGAN_x4plus -i ./colorized -o ./final --outscale 2 -t 512
Model choice, with the release file sizes:
| Model | Size | Use for |
|---|---|---|
RealESRGAN_x4plus.pth | 63MB | Real photographs — this is your default |
realesr-general-x4v3.pth | 4.7MB | Tiny general-scene model, supports -dn to balance denoising and avoid over-smoothing |
RealESRGAN_x4plus_anime_6B.pth | 17MB | Anime/illustration only — wrong tool for a family photo |
Note --outscale 2 rather than 4 in the command above. The x4 model can output any size because the script does a cheap resize after inference, and 2x is usually the honest ceiling for a consumer flatbed scan. 4x on a 300dpi scan of a 4x6 print mostly manufactures detail.
We keep the deep version of this stage on a separate page — local AI image upscaling covers ESRGAN variants, GFPGAN and the 4x model zoo properly. If you are deciding what card to buy for any of this, best GPU for image generation and our hardware hub are the relevant reads.
Batching 200 Photos
Every tool in the chain accepts a folder, so the 200-photo job is one script and four folders. This is the reason to do it locally at all — no free web tool will take a whole shoebox.
#!/usr/bin/env bash
set -euo pipefail
SRC=./01-scans # your raw scans go here
REPAIRED=./02-repaired # produced by ComfyUI stage 1
FACES=./03-faces
COLOUR=./04-colour
FINAL=./05-final
mkdir -p "$FACES" "$COLOUR" "$FINAL"
# Stage 1 runs in ComfyUI. Point its batch loader at $SRC and save to $REPAIRED.
# Do that once, then run the rest of the chain here.
# Stage 2 — faces
conda run -n codeformer python inference_codeformer.py \
-w 0.7 --input_path "$REPAIRED" --output_path "$FACES"
# Stage 3 — colour
conda run -n ddcolor python scripts/infer.py \
--model_name ddcolor_modelscope --input "$FACES" --output "$COLOUR"
# Stage 4 — upscale
python inference_realesrgan.py -n RealESRGAN_x4plus \
-i "$COLOUR" -o "$FINAL" --outscale 2 -t 512
Adjust the output flags to match the version you installed — the CodeFormer and DDColor scripts have both changed argument names across releases, and the README of the version you cloned is the authority.
Three rules that will save you a re-run:
- Test on ten images, not two hundred. Keep every intermediate folder. When something looks wrong at the end you need to know which stage did it.
- Never write over
01-scans. The scan is the artefact. Every stage after it is disposable and reproducible. - Sort by damage type first. Photos with scratches go through stage 1 with scratch processing; clean-but-faded photos skip stage 1 entirely and start at stage 2. Running the scratch network over an undamaged print costs you a little sharpness for nothing.
Two hundred photos through this chain is an evening of wall-clock time on a mid-range GPU, and it is unattended. That is the actual pitch versus a web tool that caps you at five images a day.
The Edit-Model Route, Honestly
A 20B-class image-edit model is the interesting alternative, and it is not an 8GB tool. Qwen-Image-Edit-2511 is Apache 2.0, has 233,996 downloads and 1,280 likes as of August 18, 2026, and its release notes list reduced image drift, improved character consistency, built-in LoRA support and better multi-person consistency for group photos — which reads like it was written for exactly this use case.
Here is what the model card does not say: any VRAM figure at all. What it does show is a repository with the transformer split across five safetensors shards and a text encoder across four more, loaded in bfloat16 onto CUDA. That is not a card that fits an 8GB budget at full precision, and we have not benchmarked the community quantized builds, so we are not going to publish a number for them.
If you want to try this route, here is what to check rather than what we would guess: find a GGUF or otherwise-quantized build of the 2511 weights, check the file size of the transformer shard against your free VRAM with a few gigabytes of headroom for the text encoder and VAE, and expect to offload. Our VRAM calculator and the 8GB Stable Diffusion picks will get you in the right ballpark before you download 40GB of weights.
One correction worth making, because it circulates in restoration threads: the popular dx8152/Qwen-Image-Edit-2509-Light_restoration LoRA (247 likes, Apache 2.0) is not a photo-restoration LoRA. Its actual weight files are named 移除光影 — "remove lighting and shadows". It is a lighting/glare removal adapter. Genuinely useful if your scan has flash glare or a harsh window shadow across it, and completely irrelevant to scratches.
Our verdict for the reader this page is written for: on 8GB, the classical four-stage chain is not a compromise, it is the right answer. It is ~1.5GB of weights instead of tens of gigabytes, it is deterministic, each stage is separately inspectable, and a 20B edit model's biggest risk on a family photo — quietly redrawing a face into someone who never existed — is the one risk you cannot accept here.
Licences: Read This Before Charging Anyone
CodeFormer is non-commercial. This is the single most-ignored fact in the free-restoration ecosystem.
The licence file is explicit: NTU S-Lab License 1.0, "redistribution and use for non-commercial purpose in source and binary forms". The upstream README also carries an unusually pointed warning that a long list of restoration websites, APIs and apps "use our models without any license or authorization", and names only the Hugging Face, Replicate and OpenXLab demos as author-maintained.
For a box of your own family photos, none of this is a problem — that is squarely non-commercial use. If you are restoring photos for paying clients:
| Tool | Licence | Commercial use |
|---|---|---|
| CodeFormer | NTU S-Lab 1.0 | No |
| GFPGAN | Apache 2.0 (third-party components carry their own terms) | Yes, with care |
| Real-ESRGAN | BSD-3-Clause | Yes |
| DDColor | Apache 2.0 | Yes |
| Bringing-Old-Photos-Back-to-Life | MIT | Yes |
Swap CodeFormer for GFPGAN v1.4 (332MB) in stage 2 and the chain becomes commercially clean. Note the caveat on the GFPGAN licence file itself: the Apache 2.0 grant is "except for the third-party components listed below" — read those before you build a business on it, because some of them descend from NVIDIA's StyleGAN2 terms.
What This Cannot Fix
Restoration is reconstruction, not recovery. Four things are genuinely out of reach:
- Faces too small or too damaged to detect. CodeFormer needs the detector to find a face before it can restore one. A 40-pixel-tall face in a group shot will be missed. Crop it, upscale that crop separately, then restore.
- The identity problem. At low fidelity weight, a restored face is a plausible face, not necessarily the face. If nobody alive remembers what the person looked like, you cannot verify the output. Keep
-whigh and keep the original. - Colour you never had. DDColor gives you a natural-looking guess. It is not evidence about what anyone wore.
- Missing regions. A torn-off corner is inpainting, not restoration. CodeFormer's inpainting script only handles cropped, aligned faces; for a missing background chunk you are into manual masking territory, one image at a time.
None of that is a reason to skip the chain. It is a reason to keep every original scan forever and treat the restored versions as a derivative you can always regenerate with better models later. The models will get better. Your scan will not.
Sources
All figures verified against upstream on August 18, 2026:
- sczhou/CodeFormer — 18,109 stars, NTU S-Lab License 1.0, commands and fidelity-weight behaviour from the project README
- piddnad/DDColor — 1,493 stars, Apache 2.0, ICCV 2023 (arXiv 2212.11613); checkpoint sizes from Hugging Face
- xinntao/Real-ESRGAN — 36,504 stars, BSD-3-Clause; model file sizes from GitHub Releases
- TencentARC/GFPGAN — 37,654 stars, Apache 2.0 with third-party component exceptions
- microsoft/Bringing-Old-Photos-Back-to-Life — 15,700 stars, MIT, arXiv 2004.09484; Haoming02/comfyui-old-photo-restoration for the ComfyUI nodes
- Qwen/Qwen-Image-Edit-2511 — Apache 2.0, download and like counts from the Hugging Face model API
FAQ
Got the hardware sorted? Now build on it.
You know what to buy — the courses show you what to actually run, fine-tune, and ship on it. First chapter free, no card.
Decide before you spend a thousand pounds
The AI Hardware course sizes your build properly — VRAM ladder, real bottlenecks, budget builds — and Pick the Right Model tells you what to run on it.
Liked this? 25 full AI courses are waiting.
From fundamentals to RAG, agents, MCP servers, voice AI, and production deployment with real GitHub repos. First chapter free, every course.
Build Real AI on Your Machine
RAG, agents, NLP, vision, and MLOps - chapters across 25 courses that take you from reading about AI to building AI.
Want the structured version?
Hands-on courses on local AI, from $8.99 a month. The first chapter of each is free.
Keep going
- PILLARLocal AI Hardware Requirements (2026): Complete Guide
- AI Hardware Requirements: CPU, GPU and RAM for Beginners
- AI RAM Requirements 2026: How Much for 7B, 13B, 70B Models?
- AI Server Build Under $1,500: Parts List and What Fits
- AMD GPU Not Supported by ROCm? HSA_OVERRIDE Values
- AMD MI50 32GB for Local LLMs: The Used VRAM King, Honestly
- AMD Ryzen AI Max+ 395 (Strix Halo) for Local AI 2026
- Apple M4 for Local AI: Mac Studio + MacBook Guide (2026)
- Benchmark Your Local AI Setup: tok/s, TTFT, VRAM
- Best GPU for AI Video Generation: By VRAM Tier (2026)
Comments (0)
No comments yet. Be the first to share your thoughts!