Nacho

[냉부] 👨‍🍳 레시피 AI 만드는 여정 (1) 본문

Toys

[냉부] 👨‍🍳 레시피 AI 만드는 여정 (1)

Nacho_13 2024. 11. 10. 02:35
반응형

요즘 AI 미쳤다.

 

시작은 이러하다.

어머니는 왜 자꾸 이상한 요리를 만드는가.
제발 그만...

 

어머니가 저녁으로 만들어주신 "카레 + 그린커리"의 맛은 일본과 태국 사이 그 어딘가 그 쯤 바다에 표류하는

해적선에서 먹을 것 같은 오묘한 맛..

이쯤 어딘가 아마도 중국 해적일 듯

 

그래서 시작되었다.

레시피 AI 만드는 여정...!!

 

본문에서는...

  • 끝까지 해결하지 못한 오류
  • OpenAi 한테 호구 당한 이야기
  • Flask 서버
  • EC2
  • LLama3.1 파인튜닝
  • 웹 크롤링

과 같은 내용을 다룹니다..(눈물)

 

 

1. 프로젝트 구상

우선 첫 목표는 레시피를 기가막히게 작성하는 Ai가 필요하다.

돈도 없고 능력도 없는 "나" GPU 도 없다..!

 

1. 조용히 Colab pro를 구독하고 Llama3.1-8B 모델을 불러온다.

2. 기깔나는 만개의 레시피 명예의 전당 레시피를 긁어모은다.

3. 깔롱지게 파인튜닝 -> json 으로 출력

4. 로컬에서 Flask 모델 서버 구동

5. EC2에 간단한 POST 받고 보내줄 서버 

6. 얼렁뚱땅 저비용 Ai 서비스 완성!!!

 

완벽한 계획이었다.

 

2. 웹 크롤링(Web Crowling)

웹 클롤링 관련 내용은 사실 전에 포스팅을 했다.

https://nacho-13.tistory.com/15

 

(Python) Web Crowling 웹크롤링 (멜론 차트 TOP 100)

멜론차트를 데이터프레임으로 만들어보자..! 우선 라이브러리를 불어온다. import pandas as pd import requests from bs4 import BeautifulSoup pandas : 데이터를 데이터프레임으로 만든다. requests : 파이썬에서 명

nacho-13.tistory.com


그냥 한번 보시라고.. 

 

만개의 레시피 명예의 전당은 멜론에서 조금 응용만 하면 쉽게 크롤링 할 수 있다.

 

import pandas as pd
import requests
from bs4 import BeautifulSoup

main_URL = "https://m.10000recipe.com/" # 만개의 레시피


headers = {
    'User-Agent': '본인 환경에 맞게 설정'
}

recipes = []

for i in range(1,35): #총 34 페이지 까지 
  url = f'https://m.10000recipe.com/more_item.html?q_act=1&q_mode=topic&seq=&cid=9999scrap&page={i}'
  response = requests.post(url, headers=headers)
  dom_ly = BeautifulSoup(response.text, 'html.parser')
  elements = dom_ly.select('.rcp_list2022_new_cont_tit > a') 
  recipe_url = list(map(lambda x: str(x).split('"')[1], elements)) # 레시피 주소 파싱
  recipes += recipe_url

 

만개의 레시피 명예의 전당(개발자 도구 : 네트워크)

만개의 레시피 명예의 전당은 더보기를 통해서 다음 페이지를 로드하기 때문에 개발자도구 네트워크에서 쉽게 html를 Get 링크를 찾을 수 있다. 

 

여기서 레시피 각각의 url를 배열로 저장하고 for문으로 레시피를 긁어 오면 된다. 그냥 for문을 두 번 쓴 거다.

 

all_recipes = []

for recipe_url in recipes:
  url = main_URL + recipe_url
  response = requests.get(url, headers=headers)
  dom_ly = BeautifulSoup(response.text, 'html.parser')

  #제목
  top_tit_element = dom_ly.select_one('.view3_top_tit')
  top_tit = top_tit_element.get_text(strip=True) if top_tit_element else 'No Title'

  #summary
  top_summary_element = dom_ly.select_one('.view3_top_summary')
  top_summary = top_summary_element.get_text(strip=True) if top_summary_element else 'No Summary'
  #재료
  ingre_list = dom_ly.select('.view3_ingre .ingre_list_name a')
  ingre_ea = dom_ly.select('.view3_ingre .ingre_list_ea')

  ingredients = []

  for ingredient, quantity in zip(ingre_list, ingre_ea):
    ingredient_name = ingredient.get_text(strip=True)  
    quantity_value = quantity.get_text(strip=True)     
    ingredients.append(f"{ingredient_name}: {quantity_value}")
  #레시피
  step_list = dom_ly.select('.step_list li')

  recipe_steps = []

  for step in step_list:

    step_number = step.select_one('.step_list_num').get_text(strip=True) if step.select_one('.step_list_num') else ''

    step_description = step.select_one('.step_list_txt_cont').get_text(strip=True) if step.select_one('.step_list_txt_cont') else ''
	#팁
    step_tip = step.select_one('.step_list_txt_tip').get_text(strip=True) if step.select_one('.step_list_txt_tip') else ''

    step_details = f"{step_number}\nDescription: {step_description}"
    if step_tip:
        step_details += f"\nTip: {step_tip}"

    recipe_steps.append(step_details)

  recipe = {'Title' : top_tit, 'Summary': top_summary, "Ingredients" : ingredients, 'Steps' : recipe_steps}
  all_recipes.append(recipe)

 

이런 식으로 하면 

{'Title': '정말 맛있는 우삼겹 덮밥 규동 레시피! 간단한 한끼로 딱입니다.',
  'Summary': '오늘도 역시나 누구나 쉽고 간편하게 만들 수 있는 레시피를준비해봤어요!! 바로 이번에는 우삼겹덮밥!!달콤짭짤한 간장양념에 우삼겹을 맛있게 볶아만 주세요!!덮밥으로도 좋고 반찬으로도 좋아요!꼭 따라해보세요~',
  'Ingredients': ['우삼겹: 250g',
   '양파: 1/4개',
   '설탕: 1큰술',
   '맛술: 1큰술',
   '올리고당: 1큰술',
   '간장: 2큰술',
   '다진마늘: 1큰술'],
  'Steps': ['STEP1/7\nDescription: 양파 1/4개는 송송 썰어줍니다',
   'STEP2/7\nDescription: 양념장을 만들어주세요.설탕 1큰술, 맛술 1큰술, 올리고당 1큰술,간장 2큰술, 다진마늘 1큰술',
   'STEP3/7\nDescription: 팬에 우삼겹 250g을 넣고 먼저 볶아주세요.',
   'STEP4/7\nDescription: 고기가 다 익으면 양파를 넣고후추 살짝 뿌려 1분간 볶아줍니다.',
   'STEP5/7\nDescription: 양파가 반투명하게 익으면키친타올로 우삼겹의 기름을 닦아주세요.\nTip: 기름을 안닦고 요리하면 엄청..느끼해져요!',
   'STEP6/7\nDescription: 양념장을 넣고 2분간 볶아주세요.\nTip: 고춧가루, 청양고추, 페페론치노 추가해도 좋아요',
   'STEP7/7\nDescription: 뜨거운 밥 위에 올려서 드시면 됩니다.\nTip: 계란후라이, 달걀노른자 추가하면 더 좋아요']},

 

이렇게 json 형식으로 가져올 수 있다.

다음은 Llama3.1 파인튜닝에 대해 적어보겠다..

반응형