InstructPix2Pix은 Stable Diffusion과 GPT-3를 결합한 Image-to-Image 모델로 어떠한 이미지와 명령을 입력하면 그에 맞는 이미지로 변환해주는 딥러닝 모델이다.
중장년, 노년층의 이용자가 자신의 사진을 업로드하면 얼굴을 젊게 바꿔 주거나 만화풍으로 바꿔주는 기능을 구상하였으며, 이에 위 모델이 적합하다고 생각하여 채택하였다.
캡스톤 디자인 AI 체험존, 이미지 변환 파트에 사용될 InstructPix2Pix 모델을 Flask를 사용하여 서빙 해보자!
vscode와 python 최신 버전을 준비한다.
폴더를 새로 만든다.
ctrl + shift + p를 누르고, python : create enviroment를 검색, 선택한다.
venv를 선택하고 기다린다. 해당 폴더가 생성된 것을 확인한다.
터미널을 켜서 플라스크를 다운로드한다.
python -m pip install flask
from flask import Flask
app = Flask(__name__)
@app.route("/")
def home():
return "Hello, Flask!"
if __name__ == "__main__":
app.run(host="0.0.0.0", port=50)
# port 번호 바꿔도됨
# app.run(debug=True) -> 재시작 없이 업데이트 가능
터미널에 python serving.py를 입력하여 로컬 서버를 실행 시킨다.
http://127.0.0.1:50 에 접속해서 "Hello, Flask!" 가 잘 나온다면 성공!
https://huggingface.co/timbrooks/instruct-pix2pix
GPU없이 CPU만으로 구동하기 위해서 Diffusers의 InstructPix2Pix을 사용했다.
pip install diffusers accelerate safetensors transformers
위와 같은 패키지가 필요하니 먼저 설치해 준다.
POST 방식으로 이미지 파일과 명령어가 전송되면 이미지를 로드한 다음, 변환을 수행하고 결과 이미지에 대한 URL 생성하여 JSON 형식으로 반환하도록 코드를 짰다.
아래는 전체 코드이다.
from flask import Flask, request, jsonify, send_from_directory
import PIL
import os
import uuid
from diffusers import StableDiffusionInstructPix2PixPipeline, EulerAncestralDiscreteScheduler
app = Flask(__name__)
model_id = "timbrooks/instruct-pix2pix"
pipe = StableDiffusionInstructPix2PixPipeline.from_pretrained(model_id, safety_checker=None)
pipe.scheduler = EulerAncestralDiscreteScheduler.from_config(pipe.scheduler.config)
UPLOAD_FOLDER = 'uploads'
RESULT_FOLDER = 'results'
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['RESULT_FOLDER'] = RESULT_FOLDER
def load_image(file_path):
image = PIL.Image.open(file_path)
image = PIL.ImageOps.exif_transpose(image)
image = image.convert("RGB")
return image
def save_image(image, folder):
unique_filename = str(uuid.uuid4()) + '.jpg'
file_path = os.path.join(app.config[folder], unique_filename)
image.save(file_path)
return file_path
@app.route('/results/<filename>')
def result_file(filename):
return send_from_directory(app.config['RESULT_FOLDER'], filename)
@app.route('/ImageConversion', methods=['POST'])
def convert_image():
try:
file = request.files['file']
prompt = request.form['prompt']
# 업로드된 이미지를 임시로 저장
uploaded_image_path = save_image(load_image(file), 'UPLOAD_FOLDER')
app.logger.info(f"Uploaded file saved to: {uploaded_image_path}")
# 이미지를 로드하고 변환 수행
image = load_image(uploaded_image_path)
images = pipe(prompt, image=image, num_inference_steps=8, image_guidance_scale=1.5).images
result_image = images[0]
# 결과 이미지를 저장
result_image_path = save_image(result_image, 'RESULT_FOLDER')
# 결과 이미지에 대한 URL 생성
result_image_url = request.url_root + 'results/' + os.path.basename(result_image_path)
return jsonify({'result': 'success', 'image_url': result_image_url})
except Exception as e:
return jsonify({'result': 'error', 'message': str(e)})
if __name__ == '__main__':
app.run(host="0.0.0.0", port=50) # debug=True causes Restarting with stat
num_inference_steps는 이미지 생성 과정 중에 수행할 추론 단계의 횟수를 결정하며, 높은 값을 넣을 수록 일반적으로 더 정교하고 세밀한 결과를 얻을 수 있지만, 계산 비용이 많이 든다.
image_guidance_scale 은 이미지 생성 중에 입력 이미지에서 제공되는 안내의 강도를 제어하며, 높은 값은 결과 이미지가 입력 이미지의 특징을 보다 강하게 따르고, 낮은 값은 입력 이미지의 영향을 줄이고 모델이 더 자유롭게 생성할 수 있게 한다.
여러번 시도해본 결과 "make the person younger" 명령어에서는 num_inference_steps : 8 / image_guidance_scale : 1.5 일 때 가장 좋은 결과물이 나왔다.
먼저, Flask 서버가 실행된 상태에서 Postman을 아래와 같이 세팅한다.
"make the person younger", "사람을 젊게 하다" 라는 명령어를 입력했다.
이미지를 업로드 할 때는 설정 경로에 위치한 이미지를 업로드 해야 잘 인식된다.
그런 다음 Send를 누르면...
결과 이미지의 URL이 성공적으로 반환 되었다 !!
그런데 시간이 무려 20분이 걸렸다... CPU만 사용해서 그런 것 같은데 추후에 문제를 찾아서 해결해야겠다.
주소를 클릭한 다음, Send를 누르면 이미지를 확인할 수 있다.
원본은 이순재 배우님 사진이었는데 꽤 자연스럽게 잘 나왔다.
시간이 너무 오래걸리는 문제만 해결해 보자...
Hugging Face, timbrooks/instruct-pix2pix, https://huggingface.co/timbrooks/instruct-pix2pix
GitHub, timothybrooks/instruct-pix2pix,
https://github.com/timothybrooks/instruct-pix2pix?tab=readme-ov-file
초코찜빵의 studynote, [Flask] 파이썬 플라스크 프로젝트 생성 및 가상환경 세팅하기 (Create Python Flask Project in Visual Studio Code), https://chocohaim1121.tistory.com/120
wakaranai, [Postman] 사진/파일 전송하기
https://wakaranaiyo.tistory.com/382
ChatGPT 3.5, https://chat.openai.com