Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.git
__pycache__
.pytest_cache
*.pyc
*.pyo
*.pyd
.env
.venv
22 changes: 22 additions & 0 deletions DOC/Chapter01.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Chapter 01. 저장소 개요와 목표

이 저장소는 **Python 기반 생성형 이미지/영상 실험**을 중심으로 시작되었으며, 현재는 운영/테스트를 쉽게 하기 위해 FastAPI 백엔드 + 바닐라 JavaScript 프런트엔드 구조를 함께 갖추도록 확장되었습니다.

## 핵심 목표

1. 기존 실험 스크립트의 기술 스택을 문서화
2. 웹에서 확인 가능한 API/대시보드 제공
3. Docker 기반의 재현 가능한 테스트 환경 제공

## 기존 구성 요약

- 단일 Python 스크립트 중심 실험 (`cuda*.py`, `cpu.py`, `mp4make.py`)
- Hugging Face `diffusers` + `torch` 기반 이미지 생성
- `opencv`, `Pillow`, `ffmpeg` 기반 영상 후처리

## 확장 구성 요약

- `backend/app/main.py`: FastAPI 엔트리포인트
- `frontend/`: 정적 웹 UI (Vanilla JS)
- `tests/`: API 테스트
- `Dockerfile`, `docker-compose.yml`: 컨테이너 실행/테스트 환경
20 changes: 20 additions & 0 deletions DOC/Chapter02.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Chapter 02. Python 런타임과 핵심 라이브러리

## Python

- Python 3.11을 기준으로 컨테이너 이미지를 구성했습니다.
- FastAPI/테스트 생태계와 호환성이 좋고, 현대적인 타입 힌트 및 성능 이점을 활용할 수 있습니다.

## 핵심 라이브러리 역할

- `fastapi`: REST API 및 정적 파일 제공
- `uvicorn`: ASGI 서버 실행
- `pydantic`: 응답 모델 검증
- `pytest`: 자동 테스트
- `httpx`: 테스트/클라이언트 요청 유틸

## 기존 스크립트 생태계 라이브러리

- `torch`, `diffusers`: 생성형 모델 추론
- `opencv-python`, `Pillow`, `numpy`: 영상/이미지 처리
- `controlnet_aux`, `transformers`: 조건부 생성 파이프라인 보조
22 changes: 22 additions & 0 deletions DOC/Chapter03.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Chapter 03. 생성형 AI 파이프라인 스택

기존 저장소의 본질은 **생성형 모델 추론 파이프라인 실험**입니다.

## 주요 구성 요소

- Stable Diffusion 계열 텍스트→이미지 생성
- Img2Img 변형 생성
- ControlNet(OpenPose) 기반 조건부 생성
- 프레임 시퀀스 생성 후 동영상 합성

## 실행 특성

- GPU 환경(CUDA)에서 `float16` 사용 시 속도/메모리 효율 향상
- CPU fallback 경로 제공
- 프롬프트 품질, 시드, 스텝 수에 따라 결과가 크게 달라짐

## 운영 시 고려 사항

- VRAM/디스크 사용량 큼
- 모델 다운로드/캐시 관리 필요
- 장시간 작업(프레임 생성)에서 실패 복구 전략 필요
21 changes: 21 additions & 0 deletions DOC/Chapter04.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Chapter 04. 미디어 처리 및 FFmpeg 연동

생성 스크립트는 이미지 결과를 영상으로 결합하는 파이프라인을 포함합니다.

## 처리 단계

1. 프레임 이미지 생성
2. FPS/해상도 정규화
3. ffmpeg로 영상 인코딩
4. 필요 시 오디오 병합

## 장점

- 프레임 단위 제어가 쉬움
- 후처리 유연성 높음

## 주의점

- 인코딩 옵션에 따라 속도/품질 차이 큼
- ffmpeg 바이너리 설치가 필수
- 파일 경로/네이밍 규칙이 중요
15 changes: 15 additions & 0 deletions DOC/Chapter05.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Chapter 05. FastAPI 백엔드 아키텍처

새 백엔드는 기존 스크립트를 직접 대체하기보다, **스택 정보를 API로 노출하고 UI를 제공하는 관문 레이어**로 설계했습니다.

## 엔드포인트

- `GET /api/health`: 상태 확인
- `GET /api/stack`: 저장소 기술 스택 상세 정보
- `GET /api/files`: 루트 Python 스크립트 목록

## 설계 포인트

- 타입 안정성을 위한 Pydantic 모델 사용
- CORS 허용(로컬 개발 편의)
- 정적 파일(`frontend/`)을 루트(`/`)에 서빙
21 changes: 21 additions & 0 deletions DOC/Chapter06.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Chapter 06. 바닐라 JavaScript 프런트엔드

프런트엔드는 별도 프레임워크 없이, 브라우저 기본 API만 사용합니다.

## UI 구성

- 상태 패널(Health)
- 기술 스택 카드 목록
- Python 파일 목록

## 기술 선택 이유

- 의존성 최소화
- 빌드 단계 없이 즉시 실행
- Docker 데모/검증에 적합

## 확장 아이디어

- 필터/검색 UI 추가
- API 호출 에러 리트라이
- 생성 작업 큐 상태 시각화
18 changes: 18 additions & 0 deletions DOC/Chapter07.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Chapter 07. Docker 기반 실행 전략

## 기본 구성

- 단일 `Dockerfile`에서 앱 이미지 빌드
- `docker-compose.yml`로 포트/재시작 정책 관리

## 실행 흐름

1. 이미지 빌드
2. 컨테이너 실행 (`8000` 포트 노출)
3. 브라우저에서 UI 접근
4. API 엔드포인트로 기능 검증

## 장점

- 로컬 환경 차이를 줄여 재현성 확보
- 온보딩 비용 절감
16 changes: 16 additions & 0 deletions DOC/Chapter08.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Chapter 08. 테스트 전략과 품질 기준

## 자동 테스트

- `pytest` + FastAPI `TestClient`로 핵심 API 검증

## 테스트 항목

- `/api/health` 응답 코드/필드
- `/api/stack` 데이터 개수/구조
- `/api/files`에 기존 `.py` 스크립트가 노출되는지 확인

## 품질 기준

- 실패 시 원인 파악 가능한 메시지
- 스키마 변경 시 테스트 동반 업데이트
18 changes: 18 additions & 0 deletions DOC/Chapter09.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Chapter 09. 운영/보안/설정 관리

## 환경 변수

- HF 토큰 등 민감정보는 환경 변수로 주입
- 코드 하드코딩 지양

## 운영 포인트

- 로그 레벨 분리(dev/prod)
- 리버스 프록시(Nginx) 연계 가능
- 헬스체크 기반 배포 자동화 용이

## 보안 권장 사항

- CORS 허용 도메인 최소화
- API 입력 검증 강화
- 의존성 취약점 주기적 점검
17 changes: 17 additions & 0 deletions DOC/Chapter10.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Chapter 10. 로드맵

## 단기

- 기존 생성 스크립트 실행을 API 잡(Job)으로 래핑
- 실행 상태/결과 파일 다운로드 API 제공

## 중기

- 작업 큐(Celery/RQ) 도입
- WebSocket 기반 실시간 진행률 표시

## 장기

- 멀티 모델 라우팅
- 사용자별 프로젝트/이력 관리
- 클라우드 GPU 오토스케일링 연계
12 changes: 12 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
FROM python:3.11-slim

WORKDIR /app

COPY backend/requirements.txt /app/backend/requirements.txt
RUN pip install --no-cache-dir -r /app/backend/requirements.txt

COPY . /app

EXPOSE 8000

CMD ["uvicorn", "backend.app.main:app", "--host", "0.0.0.0", "--port", "8000"]
75 changes: 31 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,53 +3,40 @@
간단한 Python 기반 이미지/영상 생성 실험 저장소입니다.
`diffusers`와 `torch`를 이용해 텍스트→이미지, 이미지→이미지, 포즈 기반 영상 프레임 생성, ffmpeg 후처리(영상 합성/오디오 병합)를 수행합니다.

## 기술 스택

- **언어**: Python 3
- **AI/생성 모델**:
- `diffusers` (Stable Diffusion, Img2Img, ControlNet Pipeline)
- `torch` (CUDA/CPU 실행)
- Hugging Face 모델 허브 모델 사용
- **컴퓨터 비전/이미지 처리**:
- `opencv-python` (`cv2`) - 프레임 기반 영상 생성
- `Pillow` (`PIL`) - 이미지 입출력/리사이즈
- `numpy`
- **포즈/조건부 생성**:
- `controlnet_aux` (`OpenposeDetector`)
- ControlNet (`lllyasviel/sd-controlnet-openpose`)
- **미디어 파이프라인**:
- `ffmpeg` (프레임↔영상 변환, FPS 변환, 오디오 병합)
- `subprocess` 기반 외부 명령 호출
- **기타**:
- `transformers` (`CLIPImageProcessor` 일부 스크립트에서 사용)

## 파일 구성

- `1.py`: 텍스트 프롬프트 기반 이미지 프레임 생성 후 mp4 저장
- `3.py`: 챔피언 프롬프트 기반 이미지 생성
- `cpu.py`, `cuda.py`, `cuda2.py`, `cuda3.py`, `cuda22.py`: 다양한 생성 파이프라인 실험 스크립트
- `cuda2_rife.py`, `cuda2_rife_v2.py`: 프레임 생성 후 보간/합성(고FPS/오디오 결합)
- `mp4make.py`: 프레임 기반 영상 생성 및 합성 유틸 성격 스크립트
- `imgwork.py`: 다수 프롬프트 배치 생성 스크립트

## 실행 환경 메모

1. CUDA GPU가 있으면 `torch.float16` + `cuda` 경로를 사용하고, 없으면 CPU 경로(`float32`)를 사용합니다.
2. 일부 스크립트는 대량 프레임을 생성하므로 VRAM/디스크 여유 공간이 필요합니다.
3. ffmpeg가 설치되어 있어야 영상 합성 스크립트가 정상 동작합니다.

## 보안/콘텐츠 정리 사항

- 저장소 내 하드코딩된 Hugging Face 토큰은 마스킹 처리되었고, 아래 형태로 환경변수 사용을 권장합니다.
- `HF_TOKEN = os.getenv("HF_TOKEN", "hf_***MASKED***")`

## 빠른 시작 예시
## 기술 문서

상세 기술 스택 문서는 `DOC/Chapter01.md` ~ `DOC/Chapter10.md`를 참고하세요.

## 웹 대시보드 (FastAPI + Vanilla JS)

- 백엔드: FastAPI
- 프런트엔드: Vanilla JS (정적 파일)
- 주요 API
- `GET /api/health`
- `GET /api/stack`
- `GET /api/files`

## 로컬 실행

```bash
python3 -m venv .venv
source .venv/bin/activate
export HF_TOKEN="hf_your_real_token"
python 3.py
pip install -r backend/requirements.txt
uvicorn backend.app.main:app --reload
```

필요 시 각 스크립트 내 `model_id`, `prompt`, `fps`, `width/height`, `num_frames`를 목적에 맞게 조정하세요.
브라우저에서 `http://localhost:8000` 접속.

## Docker 실행

```bash
docker compose up --build
```

브라우저에서 `http://localhost:8000` 접속.

## 테스트

```bash
pytest -q
```
69 changes: 69 additions & 0 deletions backend/app/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
from pathlib import Path

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import FileResponse
from fastapi.staticfiles import StaticFiles
from pydantic import BaseModel

BASE_DIR = Path(__file__).resolve().parents[2]
FRONTEND_DIR = BASE_DIR / "frontend"


class HealthResponse(BaseModel):
status: str


class StackItem(BaseModel):
name: str
category: str
description: str


class FilesResponse(BaseModel):
python_files: list[str]


app = FastAPI(title="python-generate-image dashboard", version="1.0.0")

app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)


@app.get("/api/health", response_model=HealthResponse)
def health() -> HealthResponse:
return HealthResponse(status="ok")


@app.get("/api/stack", response_model=list[StackItem])
def stack() -> list[StackItem]:
return [
StackItem(name="Python 3", category="Language", description="Core runtime for scripts and API service."),
StackItem(name="FastAPI", category="Backend", description="REST API and static file serving."),
StackItem(name="Vanilla JavaScript", category="Frontend", description="Lightweight browser UI without framework."),
StackItem(name="PyTorch", category="AI", description="Tensor runtime for CPU/GPU inference."),
StackItem(name="Diffusers", category="AI", description="Stable Diffusion and related image generation pipelines."),
StackItem(name="OpenCV/Pillow", category="Media", description="Frame and image processing utilities."),
StackItem(name="FFmpeg", category="Media", description="Video encoding and audio merge pipeline."),
StackItem(name="Docker", category="DevOps", description="Container-based local execution and testing."),
]


@app.get("/api/files", response_model=FilesResponse)
def files() -> FilesResponse:
python_files = sorted(path.name for path in BASE_DIR.glob("*.py"))
return FilesResponse(python_files=python_files)


if FRONTEND_DIR.exists():
app.mount("/static", StaticFiles(directory=FRONTEND_DIR), name="static")


@app.get("/")
def index() -> FileResponse:
return FileResponse(FRONTEND_DIR / "index.html")
5 changes: 5 additions & 0 deletions backend/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
fastapi==0.111.1
uvicorn[standard]==0.30.6
pydantic==2.8.2
pytest==8.3.2
httpx==0.27.2
9 changes: 9 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
version: "3.9"

services:
web:
build: .
container_name: python-generate-image-web
ports:
- "8000:8000"
restart: unless-stopped
Loading
Loading