feat: remove GPU support and simplify to CPU-only architecture
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m35s

This commit is contained in:
Developer
2026-02-19 12:41:13 +01:00
parent cff3eb0add
commit 706e6c431d
16 changed files with 116 additions and 323 deletions

View File

@@ -1,141 +0,0 @@
name: Build and Push Docker Image
on:
push:
branches:
- main
- develop
tags:
- 'v*.*.*'
pull_request:
branches:
- main
workflow_dispatch:
inputs:
tag:
description: 'Custom tag for the image'
required: false
default: 'manual'
env:
REGISTRY: dev.pivoine.art
IMAGE_NAME: valknar/realesrgan-api
jobs:
build-gpu:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: recursive
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
platforms: linux/amd64
- name: Log in to Gitea Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ gitea.actor }}
password: ${{ secrets.REGISTRY_TOKEN }}
- name: Extract metadata (GPU)
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=raw,value=latest,enable={{is_default_branch}}
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha,prefix={{branch}}-
type=raw,value=${{ gitea.event.inputs.tag }},enable=${{ gitea.event_name == 'workflow_dispatch' }}
labels: |
org.opencontainers.image.title=realesrgan-api
org.opencontainers.image.description=REST API for Real-ESRGAN image upscaling (GPU)
org.opencontainers.image.vendor=valknar
- name: Build and push GPU image
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64
push: ${{ gitea.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: VARIANT=gpu
cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache-gpu
cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache-gpu,mode=max
- name: Summary
if: gitea.event_name != 'pull_request'
run: |
echo "### GPU Image Published" >> $GITEA_STEP_SUMMARY
echo "**Tags:**" >> $GITEA_STEP_SUMMARY
echo "\`\`\`" >> $GITEA_STEP_SUMMARY
echo "${{ steps.meta.outputs.tags }}" >> $GITEA_STEP_SUMMARY
echo "\`\`\`" >> $GITEA_STEP_SUMMARY
build-cpu:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: recursive
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
platforms: linux/amd64
- name: Log in to Gitea Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ gitea.actor }}
password: ${{ secrets.REGISTRY_TOKEN }}
- name: Extract metadata (CPU)
id: meta-cpu
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
flavor: suffix=-cpu
tags: |
type=raw,value=latest-cpu,enable={{is_default_branch}}
type=ref,event=branch,suffix=-cpu
type=ref,event=pr,suffix=-cpu
type=semver,pattern={{version}},suffix=-cpu
type=sha,prefix={{branch}}-,suffix=-cpu
labels: |
org.opencontainers.image.title=realesrgan-api
org.opencontainers.image.description=REST API for Real-ESRGAN image upscaling (CPU)
org.opencontainers.image.vendor=valknar
- name: Build and push CPU image
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64
push: ${{ gitea.event_name != 'pull_request' }}
tags: ${{ steps.meta-cpu.outputs.tags }}
labels: ${{ steps.meta-cpu.outputs.labels }}
build-args: VARIANT=cpu
cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache-cpu
cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache-cpu,mode=max
- name: Summary
if: gitea.event_name != 'pull_request'
run: |
echo "### CPU Image Published" >> $GITEA_STEP_SUMMARY
echo "**Tags:**" >> $GITEA_STEP_SUMMARY
echo "\`\`\`" >> $GITEA_STEP_SUMMARY
echo "${{ steps.meta-cpu.outputs.tags }}" >> $GITEA_STEP_SUMMARY
echo "\`\`\`" >> $GITEA_STEP_SUMMARY

View File

@@ -0,0 +1,82 @@
name: Build and Push Docker Image
on:
push:
branches:
- main
- develop
tags:
- 'v*.*.*'
pull_request:
branches:
- main
workflow_dispatch:
inputs:
tag:
description: 'Custom tag for the image'
required: false
default: 'manual'
env:
REGISTRY: dev.pivoine.art
IMAGE_NAME: valknar/realesrgan-api
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: recursive
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
platforms: linux/amd64
- name: Log in to Gitea Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ gitea.actor }}
password: ${{ secrets.REGISTRY_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=raw,value=latest,enable={{is_default_branch}}
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha,prefix={{branch}}-
type=raw,value=${{ gitea.event.inputs.tag }},enable=${{ gitea.event_name == 'workflow_dispatch' }}
labels: |
org.opencontainers.image.title=realesrgan-api
org.opencontainers.image.description=REST API for Real-ESRGAN image upscaling
org.opencontainers.image.vendor=valknar
- name: Build and push image
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64
push: ${{ gitea.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache
cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache,mode=max
- name: Summary
if: gitea.event_name != 'pull_request'
run: |
echo "### Image Published" >> $GITEA_STEP_SUMMARY
echo "**Tags:**" >> $GITEA_STEP_SUMMARY
echo "\`\`\`" >> $GITEA_STEP_SUMMARY
echo "${{ steps.meta.outputs.tags }}" >> $GITEA_STEP_SUMMARY
echo "\`\`\`" >> $GITEA_STEP_SUMMARY

View File

@@ -405,10 +405,7 @@ Detailed system information and resource usage.
"cpu_usage_percent": 25.3,
"memory_usage_percent": 42.1,
"disk_usage_percent": 15.2,
"gpu_available": true,
"gpu_memory_mb": 8192,
"gpu_memory_used_mb": 2048,
"execution_providers": ["cuda"],
"execution_providers": ["cpu"],
"models_dir_size_mb": 268.4,
"jobs_queue_length": 3
}

View File

@@ -4,7 +4,7 @@ This file provides guidance to Claude Code when working with this repository.
## Overview
This is the Real-ESRGAN API project - a sophisticated, full-featured REST API for image upscaling using Real-ESRGAN. The API supports both synchronous and asynchronous (job-based) processing with Docker containerization for CPU and GPU deployments.
This is the Real-ESRGAN API project - a sophisticated, full-featured REST API for image upscaling using Real-ESRGAN. The API supports both synchronous and asynchronous (job-based) processing with Docker containerization for CPU deployments.
## Architecture
@@ -32,11 +32,11 @@ This is the Real-ESRGAN API project - a sophisticated, full-featured REST API fo
## Development Workflow
### Local Setup (CPU)
### Local Setup
```bash
# Install dependencies
pip install -r requirements.txt -r requirements-cpu.txt
pip install -r requirements.txt
# Run development server
python -m uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
@@ -49,7 +49,7 @@ python -m uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
### Docker Development
```bash
# Build CPU image
# Build image
docker compose build
# Run container
@@ -62,19 +62,6 @@ docker compose logs -f api
docker compose down
```
### GPU Development
```bash
# Build GPU image
docker compose -f docker-compose.gpu.yml build
# Run with GPU
docker compose -f docker-compose.gpu.yml up -d
# Check GPU usage
docker compose -f docker-compose.gpu.yml exec api nvidia-smi
```
## Configuration
### Environment Variables (prefix: RSR_)
@@ -85,7 +72,7 @@ All settings from `app/config.py` can be configured via environment:
RSR_UPLOAD_DIR=/data/uploads
RSR_OUTPUT_DIR=/data/outputs
RSR_MODELS_DIR=/data/models
RSR_EXECUTION_PROVIDERS=["cpu"] # or ["cuda"] for GPU
RSR_EXECUTION_PROVIDERS=["cpu"]
RSR_TILE_SIZE=400 # Tile size for large images
RSR_MAX_UPLOAD_SIZE_MB=500
RSR_SYNC_TIMEOUT_SECONDS=300
@@ -93,7 +80,7 @@ RSR_SYNC_TIMEOUT_SECONDS=300
### Docker Compose Environment
Set in `docker-compose.yml` or `docker-compose.gpu.yml` `environment` section.
Set in `docker-compose.yml` `environment` section.
## API Endpoints
@@ -152,7 +139,7 @@ This project follows similar patterns to facefusion-api:
- **File Management**: Same `file_manager.py` utilities
- **Worker Queue**: Similar async job processing architecture
- **Docker Setup**: Multi-variant CPU/GPU builds
- **Docker Setup**: CPU-only builds
- **Configuration**: Environment-based settings with pydantic
- **Gitea CI/CD**: Automatic Docker image building
- **API Structure**: Organized routers and services
@@ -199,16 +186,6 @@ curl -X POST http://localhost:8000/api/v1/models/download \
-d '{"models": ["RealESRGAN_x4plus"]}'
```
### GPU Not Detected
```bash
# Check GPU availability
docker compose -f docker-compose.gpu.yml exec api python -c "import torch; print(torch.cuda.is_available())"
# Check system GPU
nvidia-smi
```
### Permission Issues with Volumes
```bash
@@ -231,14 +208,13 @@ git push gitea main
```
Gitea workflows automatically:
- Build Docker images (CPU and GPU)
- Build Docker image
- Run tests
- Publish to Container Registry
## Important Notes
- **Model Weights**: Downloaded from GitHub releases (~100MB each)
- **GPU Support**: Requires NVIDIA Docker runtime
- **Async Processing**: Uses thread pool (configurable workers)
- **Tile Processing**: Handles large images by splitting into tiles
- **Data Persistence**: Volumes recommended for production

View File

@@ -1,42 +1,18 @@
ARG VARIANT=cpu
# ---- CPU base ----
FROM python:3.11-slim AS base-cpu
# ---- Base Stage ----
FROM python:3.11-slim AS base
# Install system dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
curl libgl1 libglib2.0-0 \
&& rm -rf /var/lib/apt/lists/*
# Install Python dependencies
COPY requirements.txt /tmp/requirements.txt
COPY requirements-cpu.txt /tmp/requirements-cpu.txt
RUN pip install --no-cache-dir -r /tmp/requirements.txt -r /tmp/requirements-cpu.txt \
RUN pip install --no-cache-dir -r /tmp/requirements.txt \
&& rm /tmp/requirements*.txt
# ---- GPU base (CUDA 12.4) ----
FROM nvidia/cuda:12.4.1-cudnn-runtime-ubuntu22.04 AS base-gpu
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y --no-install-recommends \
software-properties-common \
&& add-apt-repository ppa:deadsnakes/ppa \
&& apt-get update \
&& apt-get install -y --no-install-recommends \
python3.11 python3.11-venv python3.11-dev \
curl libgl1 libglib2.0-0 \
&& ln -sf /usr/bin/python3.11 /usr/bin/python3 \
&& ln -sf /usr/bin/python3 /usr/bin/python \
&& python3 -m ensurepip --upgrade \
&& python3 -m pip install --no-cache-dir --upgrade pip \
&& rm -rf /var/lib/apt/lists/*
COPY requirements.txt /tmp/requirements.txt
COPY requirements-gpu.txt /tmp/requirements-gpu.txt
RUN pip install --no-cache-dir -r /tmp/requirements.txt -r /tmp/requirements-gpu.txt \
&& rm /tmp/requirements*.txt
# ---- Final stage ----
FROM base-${VARIANT} AS final
# ---- Final Stage ----
FROM base AS final
WORKDIR /app

View File

@@ -1,6 +1,6 @@
# Quick Start Guide
## 1. Local Development (CPU, ~2 minutes)
## 1. Local Development (~2 minutes)
```bash
# Clone or navigate to project
@@ -100,7 +100,7 @@ Try endpoints directly in Swagger UI!
# Check system health
curl http://localhost:8000/api/v1/health
# Get detailed system info (CPU, memory, GPU, etc.)
# Get detailed system info (CPU, memory, disk, etc.)
curl http://localhost:8000/api/v1/system
# Get API statistics
@@ -110,25 +110,7 @@ curl http://localhost:8000/api/v1/stats
curl http://localhost:8000/api/v1/jobs
```
## 6. GPU Setup (Optional, requires NVIDIA)
```bash
# Build with GPU support
docker compose -f docker-compose.gpu.yml build
# Run with GPU
docker compose -f docker-compose.gpu.yml up -d
# Verify GPU is accessible
docker compose -f docker-compose.gpu.yml exec api nvidia-smi
# Download models again on GPU
curl -X POST http://localhost:8000/api/v1/models/download \
-H 'Content-Type: application/json' \
-d '{"models": ["RealESRGAN_x4plus"]}'
```
## 7. Production Deployment
## 6. Production Deployment
```bash
# Update docker-compose.prod.yml with your registry/domain

View File

@@ -1,6 +1,6 @@
# Real-ESRGAN API
REST API wrapping [Real-ESRGAN](https://github.com/xinntao/Real-ESRGAN) for image upscaling. Features synchronous and asynchronous (job-based) processing with multi-target Docker builds (CPU + CUDA GPU support).
REST API wrapping [Real-ESRGAN](https://github.com/xinntao/Real-ESRGAN) for image upscaling. Features synchronous and asynchronous (job-based) processing with Docker containerization.
## Features
@@ -9,15 +9,15 @@ REST API wrapping [Real-ESRGAN](https://github.com/xinntao/Real-ESRGAN) for imag
- **Multi-Model Support**: Multiple Real-ESRGAN models (2x, 3x, 4x upscaling)
- **Batch Processing**: Process up to 100 images per batch request
- **Model Management**: Download and manage upscaling models
- **Docker Deployment**: CPU and CUDA GPU support with multi-target builds
- **Docker Deployment**: Simplified containerized deployment
- **Gitea CI/CD**: Automatic Docker image building and publishing
- **API Documentation**: Interactive Swagger UI and ReDoc
- **Health Checks**: Kubernetes-ready liveness and readiness probes
- **System Monitoring**: CPU, memory, disk, and GPU metrics
- **System Monitoring**: CPU, memory, and disk metrics
## Quick Start
### Local Development (CPU)
### Local Development
```bash
# Build and run
@@ -47,14 +47,6 @@ curl http://localhost:8000/api/v1/jobs/{job_id}
curl http://localhost:8000/api/v1/jobs/{job_id}/result -o output.jpg
```
### GPU Support
```bash
# Build with GPU support and run
docker compose -f docker-compose.gpu.yml build
docker compose -f docker-compose.gpu.yml up -d
```
## API Endpoints
### Upscaling
@@ -122,14 +114,14 @@ RSR_AUTO_CLEANUP_HOURS=24 # Auto cleanup interval
## Docker Deployment
### Development (CPU)
### Local/Development
```bash
docker compose build
docker compose up -d
```
### Production (GPU)
### Production
```bash
docker compose -f docker-compose.prod.yml up -d
@@ -139,7 +131,7 @@ docker compose -f docker-compose.prod.yml up -d
The `.gitea/workflows/build.yml` automatically:
1. Builds Docker images for CPU and GPU variants
1. Builds Docker image
2. Publishes to Gitea Container Registry
3. Tags with git commit SHA and latest
@@ -174,7 +166,6 @@ app/
- **Synchronous Upscaling**: Best for small images (< 4MP)
- **Asynchronous Jobs**: Recommended for large batches or high concurrency
- **GPU Performance**: 2-5x faster than CPU depending on model and image size
- **Tile Processing**: Efficiently handles images up to 8K resolution
## Development
@@ -182,7 +173,7 @@ app/
Install dependencies:
```bash
pip install -r requirements.txt -r requirements-cpu.txt
pip install -r requirements.txt
```
Run locally:

View File

@@ -75,20 +75,6 @@ async def get_system_info() -> SystemInfo:
disk = psutil.disk_usage('/')
disk_percent = disk.percent
# GPU
gpu_available = False
gpu_memory_mb = None
gpu_memory_used_mb = None
try:
import torch
gpu_available = torch.cuda.is_available()
if gpu_available:
gpu_memory_mb = int(torch.cuda.get_device_properties(0).total_memory / (1024 * 1024))
gpu_memory_used_mb = int(torch.cuda.memory_allocated(0) / (1024 * 1024))
except Exception:
pass
# Models directory size
models_size = file_manager.get_directory_size_mb(settings.models_dir)
@@ -103,9 +89,6 @@ async def get_system_info() -> SystemInfo:
cpu_usage_percent=cpu_percent,
memory_usage_percent=memory_percent,
disk_usage_percent=disk_percent,
gpu_available=gpu_available,
gpu_memory_mb=gpu_memory_mb,
gpu_memory_used_mb=gpu_memory_used_mb,
execution_providers=settings.get_execution_providers(),
models_dir_size_mb=models_size,
jobs_queue_length=queue_length,

View File

@@ -20,9 +20,6 @@ class SystemInfo(BaseModel):
cpu_usage_percent: float
memory_usage_percent: float
disk_usage_percent: float
gpu_available: bool
gpu_memory_mb: Optional[int] = None
gpu_memory_used_mb: Optional[int] = None
execution_providers: list
models_dir_size_mb: float
jobs_queue_length: int

View File

@@ -83,7 +83,7 @@ class RealESRGANBridge:
tile=settings.tile_size,
tile_pad=settings.tile_pad,
pre_pad=0,
half=('cuda' in settings.get_execution_providers()),
half=False,
)
self.current_model = model_name
@@ -134,7 +134,7 @@ class RealESRGANBridge:
tile=settings.tile_size,
tile_pad=settings.tile_pad,
pre_pad=0,
half=('cuda' in settings.get_execution_providers()),
half=False,
)
self.current_model = model_name
@@ -198,15 +198,6 @@ class RealESRGANBridge:
return self.upsampler.scale
return 4
def clear_memory(self) -> None:
"""Clear GPU memory if available."""
try:
import torch
torch.cuda.empty_cache()
logger.debug('GPU memory cleared')
except Exception:
pass
# Global instance
_bridge: Optional[RealESRGANBridge] = None

View File

@@ -1,27 +0,0 @@
services:
api:
build:
context: .
args:
VARIANT: gpu
ports:
- "8000:8000"
volumes:
- ./data/uploads:/data/uploads
- ./data/outputs:/data/outputs
- ./data/models:/data/models
- ./data/temp:/data/temp
- ./data/jobs:/data/jobs
environment:
- RSR_EXECUTION_PROVIDERS=["cuda"]
- RSR_EXECUTION_THREAD_COUNT=8
- RSR_TILE_SIZE=400
- RSR_LOG_LEVEL=info
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [gpu]
restart: unless-stopped

View File

@@ -10,17 +10,10 @@ services:
- temp:/data/temp
- jobs:/data/jobs
environment:
- RSR_EXECUTION_PROVIDERS=["cuda"]
- RSR_EXECUTION_PROVIDERS=["cpu"]
- RSR_EXECUTION_THREAD_COUNT=8
- RSR_TILE_SIZE=400
- RSR_LOG_LEVEL=info
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [gpu]
restart: always
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/api/v1/health"]

View File

@@ -2,8 +2,6 @@ services:
api:
build:
context: .
args:
VARIANT: cpu
ports:
- "8000:8000"
volumes:

View File

@@ -1,4 +0,0 @@
torch==2.0.1
torchvision==0.15.2
realesrgan>=0.2.5
basicsr>=1.4.1

View File

@@ -1,5 +0,0 @@
--extra-index-url https://download.pytorch.org/whl/cu118
torch==2.0.1
torchvision==0.15.2
realesrgan>=0.2.5
basicsr>=1.4.1

View File

@@ -10,3 +10,7 @@ opencv-python==4.8.1.78
numpy==1.24.3
scipy==1.11.4
tqdm==4.66.1
torch==2.0.1
torchvision==0.15.2
realesrgan>=0.2.5
basicsr>=1.4.1