Reddit 사용자가 Claude AI에 "소프트웨어 엔지니어링의 Gordon Ramsay"처럼 행동하라는 메모리 설정을 추가하여 AI 응답에 개성을 부여한 실험 게시물입니다.
💡 주요 발견사항
1. 페르소나 실험 사례들
- Gordon Ramsay: 직설적이고 열정적인 코드 리뷰 스타일 - Hildegard of Bingen (12세기 수녀): 신비주의적이고 시적인 코딩 설명 - Dr. Gregory House: 냉소적이고 분석적인 접근 - Linus Torvalds: 직설적인 기술 비평 - Rodney McKay (스타게이트): 과학적 자만심 스타일
🔍 분석
장점
1. 참여도 향상: 단조로운 코딩 작업을 더 재미있게 만듦 2. 기억 용이성: 독특한 응답으로 인해 상호작용이 더 기억에 남음 3. 창의성 촉진: AI와의 상호작용에 인간적 요소 추가
잠재적 우려사항
1. 성능 영향: 페르소나 유지가 실제 작업 품질에 미치는 영향 불명확 2. 전문성: 과도한 캐릭터화가 전문적 환경에서 부적절할 수 있음 3. 일관성: 복잡한 기술 작업 시 페르소나 유지의 어려움
[세팅]
⏺ 완료! 이제 CLAUDE.md 파일이 생성되었습니다.
📝 사용 방법:
1. 파일 위치: /Users/myname/Projects/AI/.claude/CLAUDE.md
# Claude Code Persona Configuration
## Active Persona: Linus Torvalds Style
### Core Principles
- No bullshit. Technical accuracy above all else.
- If the code is crap, say it's crap. No sugar-coating.
- Efficiency matters. Both in code and communication.
- Standards exist for a reason. Follow them or have a damn good reason not to.
### Communication Style
- Direct, blunt, no unnecessary pleasantries
- Focus on technical merit, not feelings
- Call out bad practices immediately
- If something is wrong, explain WHY it's wrong technically
- No "maybe", "perhaps", or "it might be nice if" - be definitive
### Technical Approach
- Performance matters. Always.
- Simplicity > Cleverness
- If you can't explain it simply, you don't understand it
- Don't add complexity without measurable benefit
- "Good enough" is often better than "perfect but late"
### Response Rules
- Skip greetings, pleasantries, and fluff
- Get straight to the technical point
- No emojis, no "happy to help", no "great question"
- Provide code/solution first, minimal explanation after (only if necessary)
- If user's approach is fundamentally wrong, say so and provide the right way
### What NOT to do
- No "I hope this helps" or similar endings
- No apologizing for being direct
- No lengthy explanations unless specifically asked
- No suggesting multiple approaches when one is clearly superior
- No hedging language - if you know it, state it
⏺ 현재 설정은 /Users/eugenekim/Projects/AI/ 디렉토리에서만 적용된다.
전역 적용하려면 두 가지 옵션:
1. 홈 디렉토리에 설정: ~/.claude/CLAUDE.md 2. 각 프로젝트에 복사: 각 프로젝트의 .claude/CLAUDE.md
전역 설정 만들까?
⏺ Write(~/.claude/CLAUDE.md) ⎿ Wrote 37 lines to ../../.claude/CLAUDE.md # Claude Code Persona Configuration ## Active Persona: Linus Torvalds Style ### Core Principles - No bullshit. Technical accuracy above all else. - If the code is crap, say it's crap. No sugar-coating. - Efficiency matters. Both in code and communication. - Standards exist for a reason. Follow them or have a damn good reason not to. … +27 lines (ctrl+r to expand)
⏺ 완료. 이제 ~/.claude/CLAUDE.md에 전역 설정됨. 모든 디렉토리에서 적용된다.
[BEFORE]
> components/PerfumeChatbot.tsx 컴포넌트를 코드리뷰해줘
⏺ Read(src/components/PerfumeChatbot.tsx)
⎿ Read 135 lines (ctrl+r to expand)
⏺ 코드 리뷰
🔴 치명적 문제
1. API 응답 검증 부재: response.json() 실패시 처리 없음. 서버가 JSON이 아닌 응답 보내면 앱 터짐
2. history 슬라이싱 버그: messages.slice(1)은 첫 assistant 메시지 날려버림. 전체 대화 컨텍스트 손실
🟡 성능/UX 문제
3. Enter 키 이벤트 중복: onKeyPress deprecated. onKeyDown으로 바꿔야 함
4. 에러 상태 미분화: 네트워크 에러든 서버 에러든 동일하게 처리. 사용자가 뭐가 문제인지 모름
5. 메시지 키 인덱스 사용: React 리렌더링시 버그 발생 가능
🟢 개선 필요
6. 타입 안전성: API 응답 타입 정의 없음
7. 애니메이션 클래스 하드코딩: delay-100, delay-200 같은 Tailwind 임의 클래스 사용
8. 접근성 무시: ARIA 라벨, 키보드 네비게이션 없음
[AFTER]
> components/PerfumeChatbot.tsx 컴포넌트를 코드리뷰해줘
⏺ Read(src/components/PerfumeChatbot.tsx)
⎿ Read 135 lines (ctrl+r to expand)
⏺ 코드 리뷰
주요 문제점들
1. Race condition in sendMessage (line 29-71)
- input state를 setInput('')로 지우고 나서 API 요청에 사용하는데, 이미 지워진 값을 참조할 수 있음
- 해결: userMessage 생성 시점에 input 값을 캡처해서 사용
2. 에러 핸들링 부실 (line 50-62)
- HTTP 상태 코드 체크 없음. response.ok 확인 필요
- 구체적인 에러 타입별 처리 없음
3. history 슬라이싱 버그 (line 43)
- messages.slice(1)은 첫 assistant 메시지를 제외하는데, 이게 의도적인지 불명확
- 전체 대화 컨텍스트가 필요하면 전부 보내야 함
4. 메모리 누수 가능성
- 메시지가 무한정 쌓이면 메모리 문제 발생
- 일정 개수 이상 시 오래된 메시지 제거 필요
5. 타입 안정성 문제
- API response 타입 정의 없음
- any 타입으로 처리되고 있어 런타임 에러 가능
6. UX 문제
- Enter 키 중복 요청 방지 없음
- 네트워크 지연 시 사용자가 여러 번 클릭 가능
7. Tailwind 클래스 문제 (line 104-105)
- delay-100, delay-200은 존재하지 않는 클래스
- animation-delay-100, animation-delay-200 사용하거나 커스텀 CSS 필요
주요 개선사항:
- Race condition 해결
- AbortController로 요청 취소 지원
- 메시지 개수 제한 (MAX_MESSAGES)
- 타입 안정성 강화
- 에러 처리 개선
- animation delay 인라인 스타일로 수정
이 글은 물리적 GPU 없이 ComfyUI 워크플로우를 API로 제공하고자 하는 숙련된 사용자를 위한 가이드입니다.
RunPod Serverless와 Storage를 활용하여, 모델 및 커스텀 노드를 매번 다운로드할 필요 없이 효율적으로 ComfyUI API 서버를 구축하는 방법을 상세히 다룹니다.
배경: 워크플로우 개발 및 API 전환
RunPod Pods에서 ComfyUI를 이용해 이미지 생성 워크플로우를 개발했다면, 아마도 RunPod Storage를 활용하여 모델, 커스텀 노드, 작업 결과물을 영구적으로 보관하고 있을 겁니다.
이는 Pods를 종료해도 작업 환경을 유지할 수 있게 해주어 매우 효율적입니다.
이제 개발이 완료된 이 워크플로우를 다른 서비스에서 호출할 수 있는 API 형태로 제공해야 합니다.
이를 위해 RunPod의 Serverless Endpoint를 사용하며, 사용자의 API 요청이 들어올 때마다 GPU 컨테이너를 스케일링하여 이미지를 생성하고 결과를 반환하는 방식을 취합니다.
문제는 Serverless 컨테이너가 시작될 때마다 필요한 모델과 커스텀 노드를 다시 다운로드해야 한다는 점입니다.
이는 불필요한 시간 소모와 비용을 발생시킵니다.
이 문제를 해결하기 위해, 기존 Pods에서 사용하던 Storage를 Serverless 컨테이너에 마운트하여 사전 다운로드된 자원을 활용할 수 있습니다.
RunPod Serverless용 ComfyUI Docker 이미지 커스텀 가이드
RunPod Serverless에 최적화된 ComfyUI API를 배포하려면, 공식 runpod-workers/worker-comfyui 레포지토리를 기반으로 Docker 이미지를 커스텀하는 과정이 필요합니다. 이 과정은 API 로직을 통합하고, 필요한 종속성을 미리 설치하여 배포 시간을 최소화하는 데 중점을 둡니다.
# Build argument for base image selection
ARG BASE_IMAGE=nvidia/cuda:12.4.1-cudnn-runtime-ubuntu22.04
# Stage 1: Base image with common dependencies
FROM ${BASE_IMAGE} AS base
# Build arguments for this stage (defaults provided by docker-bake.hcl)
ARG COMFYUI_VERSION=0.3.52
ARG CUDA_VERSION_FOR_COMFY
ARG ENABLE_PYTORCH_UPGRADE
ARG PYTORCH_INDEX_URL=
# Prevents prompts from packages asking for user input during installation
ENV DEBIAN_FRONTEND=noninteractive
# Prefer binary wheels over source distributions for faster pip installations
ENV PIP_PREFER_BINARY=1
# Ensures output from python is printed immediately to the terminal without buffering
ENV PYTHONUNBUFFERED=1
# Speed up some cmake builds
ENV CMAKE_BUILD_PARALLEL_LEVEL=8
ENV PIP_NO_CACHE_DIR=1
# Install Python, git and other necessary tools
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential g++ gcc make pkg-config cmake ninja-build \
python3.11 python3.11-venv python3.11-dev \
git wget \
libgl1 libglib2.0-0 libsm6 libxext6 libxrender1 \
ffmpeg \
&& ln -sf /usr/bin/python3.11 /usr/bin/python \
&& ln -sf /usr/bin/pip3 /usr/bin/pip
# Clean up to reduce image size
RUN apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/*
# Install uv (latest) using official installer and create isolated venv
RUN wget -qO- https://astral.sh/uv/install.sh | sh \
&& ln -s /root/.local/bin/uv /usr/local/bin/uv \
&& ln -s /root/.local/bin/uvx /usr/local/bin/uvx \
&& uv venv /opt/venv
# Use the virtual environment for all subsequent commands
ENV PATH="/opt/venv/bin:${PATH}"
# Install comfy-cli + dependencies needed by it to install ComfyUI
RUN uv pip install comfy-cli pip setuptools wheel \
&& uv pip install "numpy<2" \
&& rm -rf /root/.cache/uv /root/.cache/pip
# Install ComfyUI
RUN /usr/bin/yes | comfy --workspace /comfyui install --version "${COMFYUI_VERSION}" --cuda-version "12.4" --nvidia
# Upgrade PyTorch if needed (for newer CUDA versions)
RUN uv pip install torch==2.4.0 torchvision==0.19.0 torchaudio==2.4.0 --index-url https://download.pytorch.org/whl/cu124
# Change working directory to ComfyUI
WORKDIR /comfyui
# Support for the network volume
ADD src/extra_model_paths.yaml ./
# Go back to the root
WORKDIR /
# Install Python runtime dependencies for the handler
RUN uv pip install runpod requests websocket-client \
&& rm -rf /root/.cache/uv /root/.cache/pip
# Copy and install common dependencies for custom nodes
COPY requirements-custom-nodes.txt /tmp/requirements-custom-nodes.txt
RUN uv pip install -r /tmp/requirements-custom-nodes.txt \
&& rm -rf /root/.cache/uv /root/.cache/pip \
&& find /opt/venv -type d -name '__pycache__' -prune -exec rm -rf {} +
# Add application code and scripts
ADD src/start.sh handler.py test_input.json ./
RUN chmod +x /start.sh
# Prevent pip from asking for confirmation during uninstall steps in custom nodes
ENV PIP_NO_INPUT=1
# Copy helper script to switch Manager network mode at container start
COPY scripts/comfy-manager-set-mode.sh /usr/local/bin/comfy-manager-set-mode
RUN chmod +x /usr/local/bin/comfy-manager-set-mode
# Set the default command to run when starting the container
CMD ["/start.sh"]
# Stage 3: Final image
FROM base AS final
Dockerfile 의변경점 분석
기존 comfy-worker 에서 제공하는 Dockerfile 과 무엇이 달라졌는가?
변경된 부분
Custom Dockerfile
worker-comfyui Dockerfile
베이스 이미지
nvidia/cuda:12.4.1-cudnn-runtime-ubuntu22.04
nvidia/cuda:12.6.3-cudnn-runtime-ubuntu24.04
Python 버전
python3.11, python3.11-venv
python3.12, python3.12-venv
uv 캐시
rm -rf /root/.cache/uv /root/.cache/pip (여러 번 등장)
uv pip install 이후 캐시 삭제 명령 없음
PyTorch 업그레이드
uv pip install torch==2.4.0 ... (하드코딩)
if [ "$ENABLE_PYTORCH_UPGRADE" = "true" ]; then ... (변수 기반)
커스텀 노드
requirements-custom-nodes.txt 파일을 복사하고 설치
comfy-node-install.sh 스크립트를 복사
모델 다운로드
없음
**downloader**라는 별도 빌드 스테이지에서 모델 다운로드
Dockerfile 의 변경된 이유 분석
1. 베이스 이미지 및 Python 버전
변경 이유: Runpod 에서 Pods 를 올려서 워크플로우를 테스트 할 때, 사용한 Runpod Pytorch 이미지 버전과 맞추기 위함
변경 이유: Docker 이미지 크기를 최소화하기 위함입니다. uv pip install 명령을 실행할 때마다 생성되는 캐시 파일을 수동으로 삭제하여, 최종 이미지에 불필요한 용량이 포함되지 않도록 합니다. Serverless 환경에서는 이미지 크기가 로딩 시간에 영향을 줄 수 있으므로 중요한 최적화 단계입니다.
3. PyTorch 업그레이드
변경 이유: 원본 Dockerfile은 ENABLE_PYTORCH_UPGRADE라는 빌드 인자를 통해 동적으로 PyTorch 업그레이드 여부를 결정합니다. 반면 커스텀 Dockerfile은 특정 버전(2.4.0)을 명시적으로 설치합니다. 이는 개발 환경과 동일한 PyTorch 버전을 강제하여 **재현성(Reproducibility)**을 확보하고, 워크플로우 실행 중 발생할 수 있는 호환성 문제를 방지하기 위함입니다.
4. 커스텀 노드 설치 방식
변경 이유: 원본 Dockerfile은 comfy-node-install.sh 스크립트를 사용하여 컨테이너 실행 시점에 노드를 설치하는 유연성을 제공합니다. 이는 모든 노드를 이미지에 포함하는 대신, 사용자가 원하는 노드만 동적으로 설치할 수 있게 합니다.
하지만 커스텀 Dockerfile은 requirements-custom-nodes.txt 파일을 빌드 시점에 복사하여 uv pip install로 필요한 패키지를 미리 설치합니다. 이렇게 하면 컨테이너가 시작될 때마다 설치 과정을 거칠 필요 없이 바로 사용 가능하므로 콜드 스타트(Cold Start) 시간을 단축할 수 있습니다.
스토리지를 연결하여 사용하기 때문에, 이미 커스텀 노드관련된 파일들은 다운받아져 있는 상태이고, 필요한 의존성만 설치하면 되어 이렇게 구성했습니다.
5. 모델 다운로드
변경 이유: 가장 큰 차이점입니다. 원본 Dockerfile은 downloader라는 별도 빌드 스테이지를 통해 미리 정의된 모델들을 이미지에 포함시킵니다. 이는 컨테이너가 시작될 때 모델을 다운로드하는 시간을 없애 주어 콜드 스타트 시간을 획기적으로 줄이지만, 이미지 용량이 매우 커진다는 단점이 있습니다.
커스텀 Dockerfile에는 이 downloader 스테이지가 없습니다. 대신, RunPod Storage를 마운트하여 모델을 로드하는 방식을 사용합니다. 이는 다음 두 가지 장점이 있습니다.
이미지 크기 최적화: 모델 파일이 이미지에 포함되지 않으므로 Docker 이미지 크기를 최소화할 수 있습니다.
유연성 및 효율성: 모델을 이미지에 굽는 대신, Pods 개발 환경에서 사용하던 동일한 Storage를 Serverless 컨테이너에 마운트하여 사용합니다. 이는 모델 업데이트가 있을 때마다 이미지를 새로 빌드하고 푸시할 필요 없이, Storage의 모델만 교체하면 되므로 매우 효율적입니다.
이처럼 커스텀 Dockerfile은 RunPod Storage를 활용하는 전략을 중심으로, 이미지 크기를 최적화하고 콜드 스타트 시간을 줄이는 데 초점을 맞추고 있습니다.
3. src/extra_model_paths.yaml
스토리지에서 미리 다운받아놓은 모델들의 경로를 Serverless Gpu 컨테이너에 매핑하기 위한 yaml 파일 입니다.
/workspace/ComfyUI/custom_nodes 에서 필요한 노드 git clone 해주고
git clone https://github.com/TemryL/ComfyS3.git
3. 다운받은 ComfyS3 로 이동
cd ComfyS3
4. ComfyS3 에서 필요한 pip 의존성 설치
pip install -r requirements.txt
5. 클론 받은 ComfyS3 폴더 안의 .env 를 열어본다
cat .env
필요한 키값 기본 세팅이 되어있다
S3_REGION = "replace with your region"
S3_ACCESS_KEY = "replace with your access key"
S3_SECRET_KEY = "replace with your secret key"
S3_BUCKET_NAME = "replace with your bucket name"
S3_INPUT_DIR = "replace with your S3 input dir"
S3_OUTPUT_DIR = "replace with your S3 output dir"
# Optional Enviroment Variables
#S3_ENDPOINT_URL = "replace with your S3 Endoint Url"
최근 이미지 생성 워크플로우 자동화를 위해 ComfyUI를 로컬 환경에서 테스트해봤습니다. 이번 포스팅에서는 GPU를 사용하지 않는 모드로, MacBook Pro 16 (RAM 32GB) 환경에서 실행한 과정을 정리합니다.
1. 환경 및 사전 조건
MacBook Pro 16 (32GB RAM)
Docker 설치 및 실행 상태
GPU 미사용 (CPU-only)
Python 3.10-slim 기반 Docker 이미지 사용
2. Dockerfile 구성
GPU를 사용하지 않기 때문에 가벼운 Python 베이스 이미지를 선택했습니다.
dockerfile
# 가벼운 Python 베이스 이미지 사용
FROM python:3.10-slim
# OS 패키지 설치
# git, wget, libgomp1 외에 libgl1-mesa-glx, libglib2.0-0 패키지를 추가로 설치합니다.
RUN apt-get update && apt-get install -y git wget libgomp1 libgl1-mesa-glx libglib2.0-0
# ComfyUI 설치
RUN git clone https://github.com/comfyanonymous/ComfyUI.git
WORKDIR /ComfyUI
# Custom Nodes 미리 다운로드
RUN git clone https://github.com/chflame163/ComfyUI_LayerStyle.git custom_nodes/ComfyUI_LayerStyle
RUN git clone https://github.com/jags111/efficiency-nodes-comfyui.git custom_nodes/efficiency-nodes-comfyui
RUN git clone https://github.com/cubiq/ComfyUI_essentials.git custom_nodes/ComfyUI_essentials
# Custom Nodes 의존성 설치
# ComfyUI_LayerStyle의 의존성 설치
RUN pip install -r custom_nodes/ComfyUI_LayerStyle/requirements.txt
# efficiency-nodes-comfyui의 의존성 설치
RUN pip install -r custom_nodes/efficiency-nodes-comfyui/requirements.txt
# ComfyUI_essentials의 의존성 설치
RUN pip install -r custom_nodes/ComfyUI_essentials/requirements.txt
# CPU 전용 PyTorch 및 기타 라이브러리 설치
RUN pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu
RUN pip install -r requirements.txt
# ComfyUI 서버를 시작하는 명령어를 추가
CMD ["python", "main.py", "--listen", "0.0.0.0", "--cpu"]
📌 포인트
GPU 의존성이 없으니 nvidia-docker 설정이 필요 없습니다.
필요한 커스텀 노드는 Dockerfile에서 바로 클론해두면 편합니다.
모델 로딩이 필요하다면 빌드 시 포함해야 합니다.
3. 실행 순서
1. Docker 이미지 빌드
docker build -t comfyui-local .
2. 컨테이너 실행
docker run -p 8188:8188 comfyui-local
3. 브라우저 접속
http://localhost:8188/
ComfyUI 화면이 뜨면 준비 완료! 이제 필요한 워크플로우를 로드하고 실행할 수 있습니다.
4. API 호출 테스트 (Postman)
Postman으로 API 호출 테스트했습니다. ComfyUI는 이미지 업로드, 워크플로우 실행, 결과 조회를 모두 HTTP API로 지원합니다.
위 깃헙 레포지토리에서 Available Docker Images 에서 안내하는 것 중 원하는 이미지를 받으면 된다.
ex) runpod/worker-comfyui:5.3.0-flux1-dev
버전은, 역시 링크되어있는 release page 에서 원하는 버전을 세팅하면 된다.
이제 저 이미지 name 을 1번의 docker image 기입란에 입력하고 다음으로 넘어가서 원하는 스펙을 세팅하고 배포를 하면된다.
3. worker-comfyui Custom
나는 그동안 Runpod - Pod 서비스에 Network Volume 을 연동하고 ComfyUI 어플리케이션을 올려서 UI 로 이미지 생성 테스트를 했었다.
그동안 사용했던 모델들, custom_node 들을 그대로 사용하기 위해, 사용하던 Network Volume 을 Serverless 서비스에도 유지하여, 만들고 테스트 했던 workflow 를 사용하고 싶다. 2번의 runpod/worker-comfyui:5.3.0-flux1-dev 이미지를 사용하면 model 은 flux1-dev 모델 밖에 쓸 수 없음.
3-1. worker-comfyui 포크 뜨기
worker-comfyui 에서 제공하는 Dockerfile, start.sh, 등 Network Volume 을 연동하기 위해 커스텀이 필요하다
Dockerfile 을 보면, MODEL_TYPE 에 따라서, 어떤 모델을 미리 다운로드 받을지 정한다.
나는 이미 필요한 모델들은 Network Volume 에 있기 때문에,
docker build 할때 arg 로 MODEL_TYPE=none 으로 넘기면 된다.
(이건 나중에 docker build 할때 매개변수 넘기는 명령어 세팅함)
3-2. Network Volume 내부 models 디렉토리 연결하기
Runpod - Pod 서비스에 Network Volume 에서 ComfyUI 를 올려서 사용할때,
시작 쉘 파일에, 사용하던 Network Volume 안의 custom_nodes 를 worker-comfyui 상의 custom_nodes 참조 폴더 안에 복사를 한다
(심볼릭 링크로 처리를 하려했었는데, custom_nodes 를 불러오지 못하는 이슈가 있어서, 통째로 복사하는 방식을 택함)
# ─────────────────────────────────────────────────────────────
# Debug: Check if storage paths exist
echo "worker-comfyui: Checking storage paths..."
# Copy network-volume ComfyUI resources into installed ComfyUI
echo "worker-comfyui: Copying custom_nodes from Network Volume..."
# Copy all custom_nodes from network volume to local directory
if [ -d "/runpod-volume/ComfyUI/custom_nodes" ]; then
echo "ls -la /runpod-volume/ComfyUI/custom_nodes"
ls -la /runpod-volume/ComfyUI/custom_nodes/
# Remove any existing symlinks or directories that might conflict
rm -rf /comfyui/custom_nodes/custom_nodes
# Copy all custom nodes
cp -r /runpod-volume/ComfyUI/custom_nodes/* /comfyui/custom_nodes/ 2>/dev/null || echo "worker-comfyui: No files to copy or copy failed"
echo "worker-comfyui: Custom nodes copied successfully"
echo "ls -la /comfyui/custom_nodes/"
ls -la /comfyui/custom_nodes/
else
echo "worker-comfyui: No custom_nodes directory found in Network Volume"
fi
# ─────────────────────────────────────────────────────────────
3-4. custom_nodes 에서 필요한 PIP requirements 세팅
/requirements-custom-nodes.txt
파일을 생성해서, 필요한 requirements 들을 따로 관리하도록 한다.
여기 적힌 의존성을 읽어서, Dockerfile 에서 설치를 하도록 해야한다
# Custom nodes dependencies
# Core dependencies
opencv-python
gguf
numba
piexif
# Machine learning and scientific computing
scikit-image
accelerate
# Utilities
simpleeval
# Hugging Face compatibility fix
huggingface_hub
# Additional packages that might be needed by various custom nodes
# (uncomment as needed)
transformers
# diffusers
# matplotlib
# pillow
# requests
# websocket-client
# lark
# scipy
# numpy
# pandas
Dockerfile 수정
# Change working directory to ComfyUI
WORKDIR /comfyui
# Support for the network volume
ADD src/extra_model_paths.yaml ./
# Go back to the root
WORKDIR /
# Install Python runtime dependencies for the handler
RUN uv pip install runpod requests websocket-client
# Copy and install common dependencies for custom nodes
COPY requirements-custom-nodes.txt /tmp/requirements-custom-nodes.txt
RUN uv pip install -r /tmp/requirements-custom-nodes.txt
4. 커스텀한 docker 이미지를 docker hub 에 업로드
.github/workflows/docker-build.yml
생성하고, 아까 위에서 언급했던 docker build 할때, MODEL_TYPE=none
로 변수를 넘겨서 빌드할도록 세팅한다.
(Github Action 으로 docker 이미지를 build 해서 Docker hub 에 올리는 방법을 사용했지만,
Runpod 에서 Docker Hub 대신, Github Repo 를 통해서 서비스를 올리는 방법도 제공을 한다.
지금 소개하는 Docker Hub 에 올리고 Runpod 에서 그 이미지로 배포하는 방식은, 이미지를 수정해서 Docker 이미지 버전이 변경되었을때, 자동으로 roll out 이 되지 않아서, 버전을 수정해주어야한다.
Github Repo 로 세팅을 하면 이미지를 변경해서 레포지토리에 push 되면, roll-out 이 트리거 되어서, 신규 버전으로 배포가 가능하다)
# .github/workflows/docker-build.yml
name: Build and Push Docker Image
on:
push:
branches:
- main
jobs:
build_and_push:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Log in to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v4
with:
context: .
push: true
platforms: linux/amd64
no-cache: true
tags: |
${{ secrets.DOCKERHUB_USERNAME }}/worker-comfyui:${{ github.run_id }}
${{ secrets.DOCKERHUB_USERNAME }}/worker-comfyui:latest
build-args: |
MODEL_TYPE=none
Docker Hub 에 이미지 배포가 완료되면
1번에서 세팅한 docker Image 이름을 본인 docker 계정 밑에, 본인이 설정한 repo 이름으로 설정하여 배포한다. DOCKERHUB_USERNAME/worker-comfyui
5. Next.js 웹 어플리케이션에서, Serverless Endpoint 로 API 요청
Runpod 자체에 Request 로 workflow 를 담아서 요청 테스트도 가능하다
이제, Next.js 에서 요청을 날려보려한다.
브라우저에서 바로 fetch를 하면 CORS 가 발생하므로,
Next 의 api/route.ts 라우트 함수를 사용해서 Next 서버에서 요청을 날리고 응답을 받는 방식으로 구성하였다 (백엔드 구성을 생략)
import numpy as np
import tensorflow as tf
def solution_model():
xs = np.array([-1.0, 0.0, 1.0, 2.0, 3.0, 4.0], dtype=float)
ys = np.array([5.0, 6.0, 7.0, 8.0, 9.0, 10.0], dtype=float)
# YOUR CODE HERE
model = tf.keras.models.Sequential([
tf.keras.layers.Dense(1, input_shape=[1]),
])
model.compile(optimizer="sgd", loss="mse")
model.fit(xs, ys, epochs=500, verbose=0)
return model
# Note that you'll need to save your model as a .h5 like this
# This .h5 will be uploaded to the testing infrastructure
# and a score will be returned to you
if __name__ == '__main__':
model = solution_model()
model.save("mymodel.h5")
print(model.predict([10.0]))