toonify-lab 프로젝트 정리 - 아들의 한마디에서 시작한 이미지 변환 실험

아들이 건넨 사진을 애니메이션처럼 바꿔보고 싶어서 시작한 toonify-lab 프로젝트와 Codex 활용 기록

프로젝트 정리

toonify-lab는 사용자가 업로드한 이미지를 애니메이션풍, 캐릭터풍, 일러스트풍으로 변환해보는 이미지 변환 실험 프로젝트다.

시작은 아주 단순했다.

어느 날 아들이 사진을 하나 주면서 “이거 애니메이션처럼 바꿔줘”라고 했다. 처음에는 그냥 이미지 생성 서비스나 앱을 찾아서 한 번 바꿔주면 되는 일이라고 생각했다. 그런데 막상 해보려니 생각보다 마음에 걸리는 부분이 많았다.

사진 속 사람의 느낌은 유지되어야 하고, 너무 다른 얼굴이 되면 안 되고, 아이가 기대하는 “애니메이션 같은 느낌”도 살아 있어야 했다. 단순히 필터를 씌우는 것과 AI 이미지 변환으로 새 이미지를 만드는 것은 꽤 달랐다.

그때 든 생각이 있었다.

“이걸 내가 직접 작은 도구로 만들어보면 어떨까?”

그렇게 시작한 것이 toonify-lab이다. 처음부터 완성된 서비스를 목표로 한 것은 아니었다. 아들이 준 사진을 자연스럽게 변환해보고, 그 과정에서 이미지 변환의 흐름과 한계를 직접 이해해보는 것이 첫 목표였다.

이번 프로젝트에서는 Codex를 적극적으로 활용했다. 구현을 대신 맡기는 느낌보다는, 개발 중간중간 방향을 점검하고 선택지를 정리하는 동료처럼 사용했다.

Codex를 활용한 방식

Codex는 주로 다음 부분에서 활용했다.

  • FastAPI 기반 프로젝트 구조 정리
  • 이미지 업로드, 작업 생성, 상태 조회, 결과 다운로드 흐름 설계
  • mock, comfyui, openai provider를 나누는 방식 검토
  • Web UI에서 원본과 결과를 비교하는 화면 구성
  • ComfyUI workflow를 API에서 호출하는 방식 정리
  • prompt와 style 값을 어디까지 사용자가 조정하게 할지 고민
  • 테스트 코드와 README, ComfyUI 실행 문서 정리

특히 도움이 됐던 부분은 “지금 당장 구현할 것”과 “나중에 고민해도 되는 것”을 나누는 일이었다.

개인 프로젝트를 하다 보면 기능을 하나 만들다가도 로그인, 히스토리 저장, 배포, 비용 관리, 사용자 계정 같은 생각이 계속 따라온다. Codex를 사용하면서 이번 단계에서는 핵심 흐름에 집중하고, 나머지는 고민 목록으로 분리할 수 있었다.

고려했던 부분들

toonify-lab를 만들면서 가장 먼저 고민한 것은 원본 사진의 느낌을 얼마나 유지할 것인가였다.

아들이 원했던 것은 전혀 다른 캐릭터를 새로 만드는 것이 아니었다. 자신이 준 사진이 애니메이션처럼 바뀌는 것이었다. 그래서 prompt에는 preserve the person, same face, same pose, same clothing처럼 원본 인물과 구도를 유지하는 표현이 중요했다.

ComfyUI를 사용할 때는 denoise 값도 고민해야 했다. 값을 높이면 스타일은 강해지지만 원본 인물이나 구도가 무너질 수 있고, 값을 낮추면 원본은 잘 유지되지만 변환된 느낌이 약해질 수 있다. 현재 문서에서는 0.35 ~ 0.45 정도를 원본 보존과 스타일 변환의 균형 지점으로 잡아두었다.

사용자가 이미지를 올리고, 변환 방식을 선택하고, 결과를 확인하는 과정이 복잡하면 서비스의 장점이 흐려진다. 그래서 기능을 많이 보여주기보다 업로드 → 변환 → 결과 확인 흐름을 최대한 단순하게 가져가려 했다.

또 하나 고민한 부분은 결과물에 대한 기대치였다.

AI 이미지 변환은 결과가 항상 일정하지 않을 수 있다. 사용자가 기대한 느낌과 다르게 나올 수도 있고, 원본 이미지의 품질이나 구도에 따라 결과 차이가 커질 수도 있다. 그래서 단순히 “변환 성공”만 보는 것이 아니라, 실패했을 때 어떤 메시지를 보여줄지, 다시 시도할 수 있게 할지, 결과물을 어떻게 비교하게 할지도 중요했다.

운영 관점에서는 비용과 속도도 고려해야 했다. 이미지 변환은 일반적인 텍스트 API보다 시간이 오래 걸릴 수 있고, 요청당 비용도 부담이 될 수 있다. 개인 프로젝트라도 사용자가 늘어나면 저장 공간, 트래픽, API 호출 비용을 생각해야 한다.

그래서 처음부터 provider를 나눴다.

  • mock: 개발 중에는 원본을 복사해서 전체 흐름만 확인
  • comfyui: Mac 로컬 ComfyUI 서버와 연동해서 실제 변환 테스트
  • openai: OpenAI Image API로 변환할 수 있는 선택지

이 구조를 선택하면 API와 화면 흐름은 유지하면서, 변환 엔진만 바꿔가며 실험할 수 있다.

선택한 것들

이번 단계에서는 모든 기능을 한 번에 넣기보다, 작은 범위에서 완성도를 높이는 쪽을 선택했다.

1. FastAPI 기반으로 작게 시작

처음부터 큰 프론트엔드 프로젝트나 복잡한 백엔드를 만들기보다는 FastAPI로 작게 시작했다.

현재 구현은 이미지 업로드, 변환 작업 생성, 상태 조회, 결과 이미지 조회, 간단한 Web UI에 집중되어 있다. 핵심 기능이 제대로 동작하지 않으면 주변 기능이 많아도 의미가 없다고 봤다.

2. provider 구조로 변환 엔진 분리

이미지 변환은 실험할 것이 많다.

처음에는 전체 API 흐름을 확인하기 위해 mock provider를 두었다. 이 provider는 변환하지 않고 원본을 결과로 복사한다. 덕분에 ComfyUI나 OpenAI 연동이 완성되기 전에도 업로드, 작업 생성, 상태 조회, 결과 다운로드 흐름을 먼저 테스트할 수 있었다.

실제 변환은 comfyuiopenai provider로 분리했다. 로컬에서 모델과 workflow를 튜닝하고 싶을 때는 ComfyUI를 사용하고, API 기반으로 빠르게 결과를 보고 싶을 때는 OpenAI Image API를 사용할 수 있게 열어두었다.

3. 원본과 결과를 나란히 보는 Web UI

화면은 단순하게 유지했다.

이미지를 선택하고, 스타일을 고르고, 프롬프트를 입력한 뒤 변환을 시작한다. 결과 화면에서는 원본과 결과를 나란히 보여준다. 이 프로젝트에서 중요한 것은 멋진 설명보다 “정말 원하는 느낌으로 바뀌었는지”를 바로 비교하는 일이었다.

4. ComfyUI workflow 문서화

ComfyUI는 잘 동작하면 강력하지만, 설정이 조금만 어긋나도 원인을 찾기 어렵다.

그래서 docs/comfyui-local-plan.md에 로컬 실행 방식, workflow 구조, positive prompt, negative prompt, denoise, steps, CFG, checkpoint 변경 방법을 따로 정리했다.

특히 사람이 사라지거나 배경만 남는 경우를 줄이기 위해 negative prompt와 denoise 기준을 문서에 남겨두었다.

5. 완성보다 반복 가능한 구조를 우선

처음부터 완벽한 품질을 목표로 하면 프로젝트가 무거워진다.

이번에는 작게 만들고, 직접 써보고, 부족한 부분을 다시 고치는 구조가 더 중요하다고 봤다. 그래서 기능을 크게 벌리기보다 다음 버전에서 개선할 수 있는 여지를 남겨두는 방향을 선택했다.

고민해야 하는 것들

아직 더 고민해야 할 부분도 많다.

  • 아들이 기대한 “애니메이션 같은 느낌”을 어떤 스타일 기준으로 잡을지
  • 원본 인물의 얼굴, 자세, 옷을 얼마나 강하게 보존할지
  • ComfyUI의 denoise, steps, CFG 값을 어떤 기본값으로 둘지
  • 변환 결과의 품질을 어떻게 일정하게 유지할지
  • 실패하거나 시간이 오래 걸리는 요청을 UI에서 어떻게 보여줄지
  • 사용자가 여러 번 시도했을 때 OpenAI API 비용을 어떻게 관리할지
  • 결과 이미지를 저장할지, 저장한다면 얼마나 보관할지
  • 원본 이미지와 결과 이미지의 개인정보 문제를 어떻게 안내할지
  • 모바일 화면에서 업로드와 결과 비교를 어떻게 편하게 만들지
  • 기능을 늘릴 때 화면이 복잡해지지 않게 어떻게 정리할지

특히 이미지 데이터를 다룬다는 점은 계속 신경 써야 한다.

사용자가 올리는 이미지는 개인적인 정보가 들어 있을 수 있다. 그래서 저장 정책, 삭제 방식, 안내 문구를 가볍게 보면 안 된다. 개인 프로젝트라도 사용자의 파일을 받는 순간부터 책임이 생긴다.

이번 프로젝트에서 느낀 점

이번 프로젝트는 기술적으로는 이미지 변환 실험이지만, 시작점은 꽤 개인적인 요청이었다.

아들이 건넨 사진 한 장과 “애니메이션처럼 바꿔줘”라는 말이 없었다면, 아마 이렇게까지 직접 만들어보지는 않았을 것 같다. 덕분에 단순히 AI 이미지 API를 호출하는 것보다, 사람이 기대하는 결과와 실제 모델이 만들어내는 결과 사이의 차이를 더 신경 쓰게 됐다.

Codex를 사용하면서 가장 크게 느낀 것은, AI 도구가 코드를 빠르게 만들어주는 것보다 생각을 정리하게 해주는 점이 더 크다는 것이다.

기능을 만들다 보면 머릿속에는 구현, 디자인, 비용, 배포, 문서화가 한꺼번에 섞인다. 이때 Codex와 대화하면서 지금 필요한 결정을 분리하고, 우선순위를 다시 세울 수 있었다.

물론 Codex가 항상 정답을 주는 것은 아니다. 오히려 중요한 것은 내가 어떤 기준으로 선택할지 정하는 일이었다. Codex는 선택지를 보여주고, 놓친 부분을 짚어주는 역할에 가까웠다.

이번 프로젝트는 아직 끝난 프로젝트라기보다, 계속 다듬어가야 할 실험에 가깝다. 그래도 한 가지는 분명하다.

AI 도구를 잘 쓰려면, 단순히 “만들어줘”라고 하는 것보다 내가 무엇을 만들고 싶은지, 무엇을 포기할 수 있는지, 어디까지 책임질 수 있는지를 계속 정리해야 한다.

“Codex는 코드를 대신 써주는 도구이기도 하지만, 프로젝트의 방향을 계속 묻게 만드는 도구이기도 했다.”


정리한 목록

  1. 시작 계기: 아들이 사진을 주며 애니메이션처럼 바꿔달라고 한 요청
  2. 프로젝트 핵심 흐름: 이미지 업로드, 변환 작업 생성, 상태 조회, 결과 확인
  3. Codex 활용 방식: 구조 설계, provider 분리, 구현 점검, 문서 정리
  4. 선택한 것: FastAPI, Web UI, mock/comfyui/openai provider 구조
  5. 앞으로 고민할 것: 원본 보존, 품질 안정성, 비용, 개인정보, 저장 정책