Stable Diffusion ile Upscaling: Düşük Çözünürlüklü Görselleri 4K’ya Yükseltme

Eski bir fotoğraf arşivin var, yüzlerce düşük çözünürlüklü görsel. Ya da bir müşteri senden “şu logoyu 4K’ya çıkar” diye istiyor ama elinde sadece 200×200’lük bir PNG var. Klasik upscaling araçları bu işi yapıyor ama sonuç hep o “bulanık büyütme” hissini veriyor. Stable Diffusion’ın img2img ve özelleşmiş upscaler modelleri bu sorunu gerçekten çözüyor. Gelin hem kurulumu hem de production ortamında nasıl kullanacağımızı adım adım ele alalım.

Temel Kavramlar: Neden Stable Diffusion Upscaling?

Geleneksel upscaling yöntemleri (bicubic, lanczos) matematiksel interpolasyon kullanır. Piksel değerlerini tahmin eder, yoktan veri üretmez. Sonuç: büyütülmüş ama detay kazanmamış görseller.

Stable Diffusion tabanlı upscaling ise farklı çalışır. Model, görüntüdeki içeriği “anlayarak” eksik detayları üretir. Bir taş duvar görselini büyütürken gerçek taş dokusunu ekler, bir yüz fotoğrafını büyütürken gözenekleri, kıl detaylarını yaratır. Bu sürece Super Resolution veya AI Upscaling deniyor.

Bunun için kullanılan başlıca yöntemler:

  • ESRGAN ve türevleri (RealESRGAN): Sadece upscaling için eğitilmiş sinir ağları, hızlı ve stabil
  • SD Upscaler (img2img + highres fix): Tam Stable Diffusion pipeline’ı, daha yaratıcı ama daha yavaş
  • Tiled Diffusion: Büyük görselleri parçalara bölerek VRAM sorununu aşar
  • Ultimate SD Upscale: Hem ESRGAN hem SD’yi birleştiren hibrit yaklaşım

Sistem Gereksinimleri ve Ortam Hazırlığı

Production kullanımı için minimum şunlar gerekiyor:

  • GPU: NVIDIA 8GB+ VRAM (RTX 3070 ideal başlangıç), AMD RX 6800 XT (ROCm ile)
  • RAM: 16GB minimum, 32GB önerilen
  • Disk: 50GB+ SSD (modeller büyük)
  • İşletim Sistemi: Ubuntu 22.04 LTS veya Windows 11

Ben bu yazıda Ubuntu 22.04 üzerinde gideceğim. Windows’ta adımlar AUTOMATIC1111 WebUI için benzer, sadece path ayraçları farklı.

AUTOMATIC1111 WebUI Kurulumu

En yaygın kullanılan arayüz AUTOMATIC1111. Pip ile değil, direkt repo üzerinden kuruyoruz:

# Önce bağımlılıkları kur
sudo apt update && sudo apt install -y wget git python3 python3-venv libgl1 libglib2.0-0

# Kurulum dizinini oluştur
mkdir -p /opt/stable-diffusion && cd /opt/stable-diffusion

# Repoyu klonla
git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git
cd stable-diffusion-webui

# Başlatma scripti izinlerini ver
chmod +x webui.sh

İlk çalıştırmada script gerekli Python bağımlılıklarını ve PyTorch’u otomatik indiriyor. Ama biz CUDA versiyonunu manuel belirtmek istiyoruz:

# CUDA 11.8 için PyTorch kurulumu (webui.sh'dan önce)
python3 -m venv venv
source venv/bin/activate
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118

# Webui'yi başlat (API modu aktif, headless sunucularda önemli)
./webui.sh --api --listen --port 7860 --xformers

--xformers parametresi bellek optimizasyonu için kritik. 8GB VRAM’de olmadan 4K upscaling imkansız.

Gerekli Modelleri İndirme

Upscaling için özelleşmiş modeller lazım. Bunları elle indirip doğru dizinlere koymak gerekiyor:

# ESRGAN modelleri için dizin
mkdir -p /opt/stable-diffusion/stable-diffusion-webui/models/ESRGAN

# RealESRGAN 4x+ modeli (fotoğraflar için en iyi)
wget -O models/ESRGAN/RealESRGAN_x4plus.pth 
  https://github.com/xinntao/Real-ESRGAN/releases/download/v0.1.0/RealESRGAN_x4plus.pth

# Anime görseller için optimize model
wget -O models/ESRGAN/RealESRGAN_x4plus_anime_6B.pth 
  https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.2.4/RealESRGAN_x4plus_anime_6B.pth

# LDSR modeli (daha yavaş ama kaliteli)
wget -O models/LDSR/model.ckpt 
  https://heibox.uni-heidelberg.de/f/578df07c8fc04ffbadf3/?dl=1

Ana SD modeli için Civitai veya HuggingFace’den Realistic Vision ya da SDXL Base modelini indirip models/Stable-diffusion/ altına koyuyorsunuz.

Komut Satırından Toplu Upscaling

Arayüzü manuel kullanmak yerine API üzerinden otomasyon kuralım. Bu gerçek sysadmin yaklaşımı.

WebUI API’si çalışırken Python ile direkt iletişim kurabiliyoruz:

# upscale_batch.py
import requests
import base64
import os
import json
from pathlib import Path

WEBUI_URL = "http://localhost:7860"
INPUT_DIR = "/mnt/nas/photos/low_res"
OUTPUT_DIR = "/mnt/nas/photos/upscaled_4k"

def encode_image(image_path):
    with open(image_path, "rb") as f:
        return base64.b64encode(f.read()).decode("utf-8")

def upscale_image(image_path, output_path, scale=4):
    encoded = encode_image(image_path)
    
    payload = {
        "resize_mode": 0,
        "show_extras_results": True,
        "gfpgan_visibility": 0,
        "codeformer_visibility": 0,
        "codeformer_weight": 0,
        "upscaling_resize": scale,
        "upscaling_resize_w": 0,
        "upscaling_resize_h": 0,
        "upscaling_crop": True,
        "upscaler_1": "RealESRGAN_x4plus",
        "upscaler_2": "None",
        "extras_upscaler_2_visibility": 0,
        "upscale_first": False,
        "image": encoded
    }
    
    response = requests.post(
        f"{WEBUI_URL}/sdapi/v1/extra-single-image",
        json=payload,
        timeout=300
    )
    
    if response.status_code == 200:
        result = response.json()
        img_data = base64.b64decode(result["image"])
        with open(output_path, "wb") as f:
            f.write(img_data)
        return True
    return False

# Toplu işleme
Path(OUTPUT_DIR).mkdir(parents=True, exist_ok=True)
images = list(Path(INPUT_DIR).glob("*.jpg")) + list(Path(INPUT_DIR).glob("*.png"))

for img_path in images:
    out_path = Path(OUTPUT_DIR) / f"{img_path.stem}_4k{img_path.suffix}"
    if not out_path.exists():
        success = upscale_image(str(img_path), str(out_path))
        print(f"{'OK' if success else 'FAIL'}: {img_path.name}")

Bu scripti cron ile gece çalıştırabilirsiniz:

# Scripti çalıştırılabilir yap
chmod +x /opt/scripts/upscale_batch.py

# Crontab'a ekle (her gece 02:00)
echo "0 2 * * * /opt/stable-diffusion/stable-diffusion-webui/venv/bin/python /opt/scripts/upscale_batch.py >> /var/log/upscale.log 2>&1" | crontab -

Tiled Diffusion ile Gerçek 4K Upscaling

ESRGAN hızlı ama Stable Diffusion modeli ile yapılan upscaling çok daha detaylı sonuç veriyor. Sorun şu: 4K bir görsel için gereken VRAM, çoğu GPU’yu aşıyor. Tiled Diffusion bunu çözüyor.

Önce Extension’ı kuralım:

# WebUI extensions dizinine git
cd /opt/stable-diffusion/stable-diffusion-webui/extensions

# Tiled Diffusion + VAE eklentisini kur
git clone https://github.com/pkuliyi2015/multidiffusion-upscaler-for-automatic1111.git

# WebUI'yi yeniden başlat
# Ctrl+C ile durdur, tekrar ./webui.sh ile başlat

API üzerinden Tiled Diffusion ile img2img upscaling:

# tiled_upscale.py - Daha kaliteli, daha yavaş
import requests
import base64
from pathlib import Path

def tiled_upscale(input_path, output_path, denoise=0.35):
    with open(input_path, "rb") as f:
        encoded = base64.b64encode(f.read()).decode("utf-8")
    
    # Önce orijinal boyutu öğren
    import PIL.Image
    with PIL.Image.open(input_path) as img:
        orig_w, orig_h = img.size
    
    target_w = orig_w * 4
    target_h = orig_h * 4
    
    payload = {
        "init_images": [encoded],
        "resize_mode": 0,
        "denoising_strength": denoise,
        "prompt": "masterpiece, best quality, ultra detailed, 4k, sharp focus",
        "negative_prompt": "blur, noise, low quality, artifact",
        "steps": 20,
        "cfg_scale": 7,
        "width": target_w,
        "height": target_h,
        "sampler_name": "DPM++ 2M Karras",
        "script_name": "ultimate sd upscale",
        "script_args": [
            None,          # _ (ignored)
            512,           # tile_width
            512,           # tile_height
            8,             # mask_blur
            32,            # padding
            64,            # seams_fix_width
            0.35,          # seams_fix_denoise
            32,            # seams_fix_padding
            4,             # upscaler_index (RealESRGAN_x4plus)
            True,          # save_upscaled_image
            0,             # redraw_mode (Linear)
            False,         # save_seams_fix_image
            8,             # seams_fix_mask_blur
            0,             # seams_fix_type (None)
            0              # target_size_type
        ],
        "override_settings": {
            "sd_model_checkpoint": "realisticVisionV60B1_v51VAE.safetensors"
        }
    }
    
    response = requests.post(
        "http://localhost:7860/sdapi/v1/img2img",
        json=payload,
        timeout=600
    )
    
    if response.status_code == 200:
        result = response.json()
        img_data = base64.b64decode(result["images"][0])
        with open(output_path, "wb") as f:
            f.write(img_data)
        print(f"Tamamlandi: {output_path}")
        return True
    else:
        print(f"Hata: {response.status_code} - {response.text[:200]}")
        return False

denoise parametresi burada kritik. Değerlerin ne anlama geldiğini bilelim:

  • 0.1-0.2: Neredeyse sadece upscale, çok az detay ekleme
  • 0.3-0.4: Dengeli mod, orijinale sadık kalarak detay ekler
  • 0.5-0.6: Görsel yeniden yorumlanıyor, dramatik değişimler olabilir
  • 0.7+: Orijinalden uzaklaşma, yeni içerik üretimi başlar

Fotoğraf arşivleri için 0.35, logo ve grafik tasarım için 0.2 öneriyorum.

VRAM Yönetimi ve Performans Optimizasyonu

8GB VRAM ile 4K upscaling yaparken sistemin patlamasını istemiyoruz. Birkaç kritik ayar:

# WebUI başlatma komutuna eklenecek parametreler
./webui.sh 
  --api 
  --listen 
  --port 7860 
  --xformers 
  --medvram 
  --opt-split-attention 
  --no-half-vae 
  --opt-channelslast

Parametre açıklamaları:

  • –medvram: Orta VRAM modu, model katmanlarını ihtiyaç anında GPU’ya taşır
  • –opt-split-attention: Attention hesaplamalarını bölerek bellek kullanımını azaltır
  • –no-half-vae: VAE’yi float32’de tutar, renk bozulmalarını önler
  • –opt-channelslast: Bellek layout optimizasyonu, %5-10 hız artışı

GPU kullanımını izlemek için:

# Gerçek zamanlı GPU izleme
watch -n 1 nvidia-smi

# Daha detaylı monitoring scripti
cat << 'EOF' > /opt/scripts/gpu_monitor.sh
#!/bin/bash
while true; do
    TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
    GPU_UTIL=$(nvidia-smi --query-gpu=utilization.gpu --format=csv,noheader,nounits)
    VRAM_USED=$(nvidia-smi --query-gpu=memory.used --format=csv,noheader,nounits)
    VRAM_TOTAL=$(nvidia-smi --query-gpu=memory.total --format=csv,noheader,nounits)
    TEMP=$(nvidia-smi --query-gpu=temperature.gpu --format=csv,noheader,nounits)
    echo "$TIMESTAMP | GPU: ${GPU_UTIL}% | VRAM: ${VRAM_USED}/${VRAM_TOTAL}MB | Temp: ${TEMP}C"
    sleep 5
done
EOF
chmod +x /opt/scripts/gpu_monitor.sh

Systemd Service ile WebUI’yi Daemon Olarak Çalıştırma

Sunucuyu her açışta Manuel başlatmak istemiyoruz. Systemd service dosyası yazalım:

# Service dosyası oluştur
cat << 'EOF' > /etc/systemd/system/stable-diffusion-webui.service
[Unit]
Description=Stable Diffusion WebUI
After=network.target

[Service]
Type=simple
User=sduser
WorkingDirectory=/opt/stable-diffusion/stable-diffusion-webui
ExecStart=/bin/bash webui.sh --api --listen --port 7860 --xformers --medvram --no-half-vae
Restart=on-failure
RestartSec=10
StandardOutput=append:/var/log/sd-webui.log
StandardError=append:/var/log/sd-webui-error.log
Environment="COMMANDLINE_ARGS=--api --listen --xformers"

[Install]
WantedBy=multi-user.target
EOF

# Servisi etkinleştir
systemctl daemon-reload
systemctl enable stable-diffusion-webui
systemctl start stable-diffusion-webui

# Durumu kontrol et
systemctl status stable-diffusion-webui

Gerçek Dünya Senaryosu: E-ticaret Ürün Görselleri

Bir e-ticaret sitesi düşünün. Tedarikçiden gelen ürün görselleri 300×300 piksel, siz 1200×1200 veya daha büyük görseller istiyorsunuz. Bu senaryoyu otomasyona döküyoruz:

#!/bin/bash
# product_upscale_pipeline.sh
# Yeni gelen ürün görsellerini izle, otomatik upscale et

WATCH_DIR="/var/www/shop/uploads/pending"
OUTPUT_DIR="/var/www/shop/uploads/processed"
LOG_FILE="/var/log/product_upscale.log"
PYTHON="/opt/stable-diffusion/stable-diffusion-webui/venv/bin/python"
SCRIPT="/opt/scripts/upscale_batch.py"

log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}

# inotifywait ile dizini izle
inotifywait -m -e close_write --format '%f' "$WATCH_DIR" | while read FILENAME; do
    # Sadece görsel dosyaları işle
    case "${FILENAME##*.}" in
        jpg|jpeg|png|webp)
            log "Yeni görsel tespit edildi: $FILENAME"
            
            INPUT_PATH="$WATCH_DIR/$FILENAME"
            OUTPUT_PATH="$OUTPUT_DIR/${FILENAME%.*}_4x.${FILENAME##*.}"
            
            # WebUI hazır mı kontrol et
            if curl -s "http://localhost:7860/sdapi/v1/options" > /dev/null 2>&1; then
                log "Upscaling basliyor: $FILENAME"
                $PYTHON $SCRIPT "$INPUT_PATH" "$OUTPUT_PATH"
                
                if [ $? -eq 0 ]; then
                    log "Basarili: $OUTPUT_PATH"
                    # Orijinali arsive tasi
                    mv "$INPUT_PATH" "/var/www/shop/uploads/originals/"
                else
                    log "HATA: $FILENAME isleme basarisiz"
                fi
            else
                log "WebUI hazir degil, $FILENAME kuyruga alindi"
                echo "$INPUT_PATH" >> "$WATCH_DIR/.queue"
            fi
            ;;
    esac
done

Bu script inotifywait kullanıyor. Paket kurulumuyla başlayın:

sudo apt install -y inotify-tools

Kalite Karşılaştırması ve Doğrulama

Upscaling sonuçlarını otomatik değerlendirmek için SSIM (Structural Similarity Index) kullanabiliriz:

# quality_check.py
from skimage.metrics import structural_similarity as ssim
from skimage.metrics import peak_signal_noise_ratio as psnr
import cv2
import numpy as np
import sys

def compare_images(original_path, upscaled_path):
    orig = cv2.imread(original_path)
    upsc = cv2.imread(upscaled_path)
    
    # Karşılaştırma için aynı boyuta getir
    orig_resized = cv2.resize(orig, (upsc.shape[1], upsc.shape[0]), 
                               interpolation=cv2.INTER_LANCZOS4)
    
    # Gri tonlamaya çevir
    orig_gray = cv2.cvtColor(orig_resized, cv2.COLOR_BGR2GRAY)
    upsc_gray = cv2.cvtColor(upsc, cv2.COLOR_BGR2GRAY)
    
    ssim_score = ssim(orig_gray, upsc_gray)
    psnr_score = psnr(orig_gray, upsc_gray)
    
    print(f"Dosya: {upscaled_path}")
    print(f"Boyut: {orig.shape[1]}x{orig.shape[0]} -> {upsc.shape[1]}x{upsc.shape[0]}")
    print(f"SSIM: {ssim_score:.4f} (1.0 = identik)")
    print(f"PSNR: {psnr_score:.2f} dB (>30 = kaliteli)")
    
    # SSIM 0.7 altiysa uyar
    if ssim_score < 0.70:
        print("UYARI: Dusuk SSIM, gorsel cok degismis olabilir!")
    
    return ssim_score, psnr_score

if __name__ == "__main__":
    compare_images(sys.argv[1], sys.argv[2])

Yaygın Sorunlar ve Çözümleri

Sahada en çok karşılaşılan problemler:

CUDA out of memory hatası: --medvram yerine --lowvram deneyin. Hala oluyorsa tile boyutunu 512’den 256’ya düşürün.

Renk kayması: --no-half-vae parametresini ekleyin. VAE’nin float16 hesaplamalarında renk tonları kayıyor.

Yüzler bozuk çıkıyor: GFPGAN veya CodeFormer face restoration’ı aktif edin. API çağrısında gfpgan_visibility: 0.5 değerini artırın.

İşlem çok yavaş: --xformers kurulu mu kontrol edin. Değilse: pip install xformers komutuyla WebUI’nin venv’i içinde kurun.

WebUI başlamıyor, port meşgul: fuser -k 7860/tcp ile portu temizleyin.

Sonuç

Stable Diffusion tabanlı upscaling, klasik yöntemlerin ötesinde gerçek içerik üretimi yapıyor. Sysadmin perspektifinden bakıldığında bu bir servis, yani kurulum, otomasyon ve monitoring şart. Anlattığım şeyleri özetleyeyim:

  • RealESRGAN hızlı toplu işlem için ideal, sabah işe gelene kadar 500 görseli bitirir
  • Tiled Diffusion kalite öncelikli işler için, tile mantığı VRAM sorununu gerçekten çözüyor
  • API üzerinden otomasyon kurarsanız arayüzle uğraşmak zorunda kalmıyorsunuz
  • Systemd service ile çalıştırın, cron ile toplu işlem zamanlayın
  • SSIM ile otomatik kalite kontrolü ekleyin, müşteriye bozuk görsel gitmesin

Denoise strength’i kendiniz ayarlamaya başladığınızda her iş için farklı değerler bulacaksınız. Fotoğraf arşivi için 0.3, ürün görselleri için 0.25, sanat eserleri için 0.4 gibi bir başlangıç noktası var elinizde. Bundan sonrası kendi veri setinize göre ince ayar meselesi.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir