Skip to content

LaNguAx/upscale-ai

Repository files navigation

UPscale

AI-powered video restoration and super-resolution. B.Sc. Computer Science final project (Deep Learning specialization).

A pnpm + Turborepo monorepo with three apps and a shared full-stack contract chain:

apps/
├── frontend    Vite 8 + React 19 SPA (Tailwind v4, shadcn/ui, RTK Query)   :5173
├── backend     NestJS 11 API under /api (uploads, jobs, SSE, streaming)    :3000
└── ai          Python FastAPI + PyTorch inference service                  :8000
packages/
├── consts      Endpoint path strings and app constants
├── schemas     Zod 4 schemas + inferred types (single source of truth)
├── contracts   Typed EndpointContract objects (consts + schemas)
├── eslint-config       Shared ESLint 9 flat-config presets
└── typescript-config   Shared strict tsconfig presets

How it works

  1. The frontend uploads a video (POST /api/upload, multipart, XHR progress) and receives a jobId.
  2. The backend stores the file on disk (Multer), tracks the job in memory, and calls the AI service (POST /process), consuming an NDJSON progress stream.
  3. The AI service runs BasicVSR + SPyNet (V3 checkpoint, 4x scale) over the video frames and writes the enhanced output to storage/results.
  4. The frontend follows progress over SSE (/api/upload/events/:jobId, with polling fallback), then plays/downloads the result via HTTP Range streaming (/api/upload/stream/:jobId).
  5. Jobs can be cancelled end-to-end (POST /api/upload/cancel/:jobId bridges to the AI service).

Errors follow RFC 7807 (ProblemDetails) with a traceId from the request-id middleware. All request/response shapes live in @repo/schemas; the backend wraps them with nestjs-zod DTOs and the frontend validates responses against @repo/contracts.

Prerequisites

  • Node >= 24 (see .nvmrc)
  • pnpm 10 (corepack enable or npm i -g pnpm)
  • Python 3.11+ with pip (for the AI service)
  • The model checkpoint at apps/ai/checkpoints/vsr_model_best.pth (not in git)

Getting started

pnpm install

# one-time Python setup
pnpm --filter ai setup

# copy env examples (optional — sane defaults exist)
cp apps/backend/.env.development.example apps/backend/.env.development
cp apps/frontend/.env.development.example apps/frontend/.env.development

# start everything (frontend 5173, backend 3000, ai 8000)
pnpm dev

Swagger UI is served at http://localhost:3000/docs in development.

Commands

Command Purpose
pnpm dev Start all apps in watch mode
pnpm dev:web Start frontend + backend only (no AI service)
pnpm dev:ai Start the AI inference service only
pnpm build Build all packages and apps (bottom-up, cached)
pnpm preview Build, then run in local production-rehearsal mode
pnpm preview:web Build, then run frontend + backend only
pnpm preview:ai Run the AI service in production mode (no reload)
pnpm start:prod Build, then run in pure production mode
pnpm start:prod:web Build, then run frontend + backend in prod mode
pnpm start:prod:ai Run the AI service in production mode
pnpm lint Lint everything (--max-warnings 0)
pnpm check-types Type-check everything
pnpm format Prettier-format the repo

Filter to one app: pnpm --filter backend dev, pnpm --filter backend test:e2e, etc.

Environment variables

Each app commits .env.development.example / .env.production.example. Backend env is Zod-validated at startup (apps/backend/src/utils/env.validation.ts) — see CLAUDE.md for the full table. Key ones:

  • backend: PORT, CORS_ORIGIN, AI_SERVICE_URL, UPLOAD_DIR, RESULT_DIR, MAX_FILE_SIZE_MB, ALLOWED_VIDEO_EXTENSIONS
  • frontend: VITE_PORT, VITE_API_BASE_URL (backend origin, no /api suffix)
  • ai: CHECKPOINT_PATH, DEVICE, MAX_INPUT_HEIGHT, HOST, PORT

The AI model

apps/ai/baseline/ contains the V3 architecture: BasicVSR with a SPyNet optical-flow backbone (sequence length 15, 4x upscale). vsr_inference.py exposes VSRInferenceEngine with frame-window batching, progress callbacks, and cooperative cancellation. Training artifacts live in Model_v3.ipynb. Inference parameters are owned by the engine/checkpoint — the backend does not override them.

There is no mock fallback: if the AI service is down or the checkpoint is missing, jobs fail with a clear error.

Known limitations

  • Job state is in-memory; a backend restart loses all jobs.
  • Single-node disk storage (storage/, gitignored).
  • Deploy script builds the frontend but static hosting must be configured separately (see deploy-upscale-ai.sh).

Deployment

deploy-upscale-ai.sh (triggered via .github/workflows/deploy.yml over SSH) pulls main, runs pnpm install && pnpm build, and restarts the backend and AI service under PM2. See the script header for the remaining manual steps.

Project documentation

The full project characterization (architecture decisions, pipeline design, milestones) lives in docs/Upscale-Project-Characterization.pdf. Agent-facing guides: AGENTS.md (root and per-app) and CLAUDE.md.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors