
인공지능과 데이터 분야에 대한 관심이 점점 커지고 있는 요즘, 많은 사람이 실제로 어떻게 기술을 활용할 수 있을지 고민하고 있다. 이번 강의는 파이썬과 OpenAI API를 이용해 데이터를 다루고, 의미 있는 결과물을 도출하는 과정을 다룬다. 파이썬을 어느 정도 다룰 줄 안다면 누구나 따라 할 수 있는 실습 프로젝트들로 구성되어 있어, 학습자가 자신의 실력을 자연스럽게 발전시킬 수 있는 기회를 제공한다.
8개의 다양한 프로젝트를 통해, 자연어 처리부터 감정 분석, 데이터 시각화까지 다루며 현업에서 바로 적용할 수 있는 스킬들을 익힐 수 있다. 실제로 데이터 수집부터 분석, 그리고 모델 튜닝까지의 전체 과정을 경험하면서 AI와 데이터 사이언스의 기본기를 확실히 다질 수 있을 것이다.
지금 이 강의를 통해, 데이터의 세계에서 원하는 결과를 보다 쉽게 얻어보라. 어렵게 느껴질 수 있는 AI 기술이 실습과 프로젝트를 통해 친숙해질 것이다.

이번 프로젝트는 GPT에 음식(재료) 사진을 입력하면 이를 토대로 생성할 수 있는 음식 레시피를 추천하는 봇을 만드는 것이다.
이때 레시피로 만들 수 있는 음식의 예상 이미지를 DALL-E 모델을 통해 생성한다.

따라서 이번 프로젝트의 진정한 목표는 하나의 모델만 사용하는 것이 아닌 여러 개의 모델을 융합하여 사용하는 API의 설계가 주 목적이라 보면 된다.
from dotenv import load_dotenv
from openai import OpenAI
import os
load_dotenv() # .env 파일의 환경 변수를 불러옴
api_key = os.getenv('OPENAI_API_KEY')
# API 키가 정상적으로 불러와졌는지 확인
#print(f"API Key: {api_key}")
client = OpenAI()
먼저 1차로 텍스트 정보(음식재료)만들 받아서 레시피(텍스트로만 생성)을 수행한다.
system_prompt = '''음식 레시피를 생성하며, 생성한 레시피 명도 같이 표기
레시피는 유저가 입력한 음식 재료 사진만을 활용하여 생성
레시피는 초보자도 쉽게 만드는 음식이어야 하며
레시피 명은 사용한 음식재료의 특징을 잘 반영해야 함'''
ingredients = ["닭가슴살", "마늘", "식용유", "햇반(즉석밥)"]
user_prompt = "음식 재료 : " + ", ".join(ingredients)
response = client.chat.completions.create(
model = 'gpt-4-turbo',
messages = [
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_prompt},
])

생성한 레시피는 텍스트로 입력한 주 음식재료를 기반으로 레시피가 생성되며, 이때 서빙제안이라는 항목에는
추가 음식재료를 활용한 제안도 진행된다.
출력한 response는 '레시피 명' 항목을 텍스트 추출하기 어렵기에 format를 추가한다.
format = '''### 레시피 명 : [ ]###
\n\n
### 음식 재료 : [재료1, 재료2 ...]###
\n\n
### 조리 방법 ###
1. ...
- ...
- ...
...
### 추가 서빙 제안 ###
...'''
def set_user_prompt(ingredients, format):
return f'''음식 재료 : {ingredients}를 바탕으로 레시피 생성
추천 레시피는 {format} 규격에 맞춰 텍스트 생성'''
response = client.chat.completions.create(
model = 'gpt-4-turbo',
messages = [
{"role": "system", "content": system_prompt},
{"role": "user", "content": set_user_prompt(ingredients, format)},
])

이제 레시피명, 음식재료, 조리방법, 추가 서빙제안
4개의 타이틀로 response항목을 텍스트 후처리가 용이하게끔 결과를 출력받았다.
response의 출력된 문자열 데이터는 항목별로 분리하는 후처리를 진행한다
이때의 코드는 아래와 같다.
import re
p1 = re.compile(r'\n{2,}|\s{5,}')
p2 = re.compile(r'#*|\**')
p3 = re.compile(r'\s*:\s*')
p4 = re.compile(r"[\[\]]")
p5 = re.compile(r'\s*,\s*')
p6 = re.compile(r"^.*?\n")
def parser_text(response):
raw_taxt = response.choices[0].message.content
data = p1.split(raw_taxt)
parser_dict = {}
for idx, vel in enumerate(data):
if idx < 2:
vel = p2.sub("", string=vel).strip()
vel = p3.split(vel)
if idx == 1:
vel[1] = p4.sub("", string=vel[1])
vel[1] = p5.split(vel[1])
parser_dict[vel[0]] = vel[1]
else:
vel = p2.sub("", string=vel).strip()
if idx == 2:
vel = p6.sub("", vel)
data[idx] = vel
parser_dict['조리 방법'] = data[2:-1]
return parser_dict

대략
레시피 명 : 레시피 명에 대한 음식이름명
음식 재료 : 레시피를 구성하는 음식 재료 리스트
조리 방법 : 레시피를 수행하는 단계별 리스트
3가지 데이터를 추출해 낸 것을 확인할 수 있다.
이제 DALL-E 모델을 활용하여 생성한 레시피 음식 명을 이미지로 생성하는 작업을 진행하고자 한다.
이미지 생성에 관한 문서는 https://platform.openai.com/docs/guides/images
에서 확인할 수 있으며
OpenAI에서는 현재 DALL-E 3, DALL-E 2를 모델로 사용해 이미지 생성 작업을 지원하고 있다.

해당 홈페이지에서 제공하는 Get in start의 코드는 아래와 같다.
from openai import OpenAI
client = OpenAI()
response = client.images.generate(
model="dall-e-3", # 사용할 모델
prompt="a white siamese cat", # 입력할 프롬포트
size="1024x1024", # 생성이미지 사이즈
quality="standard", # 이미지 퀄리티
n=1, # 이미지 몇개 생성할지
)
# 생성한 이미지를 빠르게 접근하려면 아래의 코드 사용
image_url = response.data[0].url
위 예제코드를 기반으로 이미지를 생성해보자
def img_gen_prompt(recipe_title):
return f'''현실감 있는 이미지로 {recipe_title} 요리 이미지를 생성,
이때 요리 이미지는 흰 접시에 담겨 있으며,
스튜디오 조명 환경에서 촬영한 이미지
'''
response_img = client.images.generate(
model = "dall-e-3",
prompt = img_gen_prompt(res['레시피 명']),
size = "1024x1024",
quality = "standard",
n=1,
)
image_url = response_img.data[0].url
response_img
ImagesResponse(created=1727815948,
data=[Image(b64_json=None,
revised_prompt='Create a photo-realistic
image of a dish of stir-fried chicken breast with garlic, served on a white plate.
The plate of food should appear as if it was photographed in a professional studio with studio lighting using a DSLR camera.
This dish should be highly detailed, showcasing the succulent chicken breast pieces stir-fried with fragrant garlic, immediately invoking an insatiable feeling of hunger.',
url='https://oaidalleapiprodscus.blob.core.windows.net/private/org-vafjTcQFcbfMkyhb83rp0bho/user-GOd95ZmVF8e2auj0YT2tarpi/img-uwdaF09sfzCx7P27nKnwPzzA.png?st=2024-10-01T19%3A52%3A28Z&se=2024-10-01T21%3A52%3A28Z&sp=r&sv=2024-08-04&sr=b&rscd=inline&rsct=image/png&skoid=d505667d-d6c1-4a0a-bac7-5c84a87759f8&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2024-10-01T19%3A08%3A02Z&ske=2024-10-02T19%3A08%3A02Z&sks=b&skv=2024-08-04&sig=5x29l%2BzFtfQhLr%2B9m/RXdDOl6If0LJj5N9mEa3tEvwE%3D')])

image_url항목만 접근하면 웹사이트 링크가 담기며,
해당 링크를 클릭하면 생성한 이미지에 접근할 수 있다.

입력한 프롬포트 내 레시피 명에 맞게 이미지를 생성하는 것을 확인할 수 있다.
이제 링크로 페이지에 접속하여 데이터를 확인하는 것은 옳지 않으니 해당 파일을 저장하는 후처리 코드를 작성하자.
import requests
def save_image(url, save_path):
req = requests.get(url)
if req.status_code == 200 : # 이미지 요청이 성공적
with open(save_path, 'wb') as file:
file.write(req.content)
print(f'이미지 저장 성공 : {save_path}')
else:
print(f'이미지 저장 실패')

위 코드를 통해 이미지 저장을 수행하면 지정한 경로(data)폴더 내에 OpenAI - DALLE 모델로 생성한 이미지를 저장할 수 있다.

마지막으로 주피터노트북의 셀 상에서 확인을 하고 싶다면
위 PIL, Ipython.display 라이브러리를 사용하여
이미지를 바로 열람할 수 있다.
이때 이미지의 크기가 크게 열릴 수 있으니 적당히 사이즈를 조정하여 열람하자.
본 포스트는 메타코드 서포터즈로서 작성하였습니다