Google Gemini API 사용하기 with Python

Simin Oh
13 min readJan 1, 2024

--

새로운 기술이 나오면 ‘어떻게 활용할 수 있을까?’ 고민해 보게 됩니다.

인간처럼 소통할 수 있는 멀티모달 모델 제미나이(Google Gemini)의 다양한
강점을 활용하면 놀라운 사례들이 나올 수 있을 것 같은데요, 저도 소박한 아이디어가 떠올라 Gemini API를 활용하여 테스트해 보았습니다.

아이디어 = 식당 메뉴 이미지와 맥락 전달로 메뉴 추천 받기
식당 메뉴 “(텍스트가 포함된)이미지” 전달> 날씨, 기분, 예산 등의 “텍스트" 정보 전달> Gemini에게 메뉴 추천 받기

테스트는 Gemini Pro API를 활용했고 우리에게 익숙한 Python으로 진행했습니다.

Gemini Pro API를 고객용 서비스에 적합하게, 더 정교하게, 활용도 높은 UI에서 사용하고 싶으시다면 단연 Google Cloud Vertex AI를 사용하시는 것을 추천합니다.

이번엔 제미나이와 조금 친해지기 위한 과정이니, 웹 브라우저에서 파이썬 코드를 빠르게 테스트해 볼 수 있는 Google Colab을 이용하였습니다.

참고) Google Colab을 사용하시면 웹 브라우저에서 사전 구성이나 별도의 설치 없이 파이썬 스크립트를 작성하고 실행할 수 있습니다. (Pandas, TensorFlow, PyTorch, NumPy 등)

Gemini API 활용에 관심 있으신 분들께 이 글이 조금이나마 도움이 되시길 바랍니다.

  1. 구글 클라우드 콘솔 접속 > 계정 생성 > 결제 수단 등록

2. 새 프로젝트 생성 > 프로젝트 ID 확인

3. Vertex AI API 활성화
[API 및 서비스] > [사용설정된 API 및 서비스] > API 라이브러리에서 “Vertex AI API”를 검색 후 클릭 > [사용] 버튼 클릭 > 활성화 완료

4. Google Colab 접속 > 새 노트북

5. Google Cloud 인증 진행

!pip install "google-cloud-aiplatform>=1.38"
!gcloud auth login #링크 클릭 후 아래 이미지와 같이 Copy하여 코드 입력란에 입력 

6. Google Gemini API 사용을 위한 패키지와 라이브러리 Import

from google.colab import auth
auth.authenticate_user()

7. vertex AI 라이브러리 사용을 위한 설치, 프로젝트 ID / 로케이션 초기화

import io
import http.client
import typing
import urllib.request
import base64
from PIL import Image as PILImage
import matplotlib.pyplot as plt
import vertexai
import vertexai.preview
from google.cloud import aiplatform
from vertexai.preview.generative_models import GenerativeModel, Image
vertexai.init(project="google-cloud-project-id", location="google-cloud-location")

“google-cloud-project-id”와 “google-cloud-location”를 각각 개인 프로젝트 정보에 맞게 대체하여 입력해 주세요. 저는 위에서 확인한 제 프로젝트 ID를 넣었고, 위치는 ‘asia-northeast3’로 설정했습니다.

8. Gemini API를 사용을 위한 함수 선언
프롬프트를 프로세스와 결과 출력을 위한 함수를 정의합니다.

def load_and_encode_images(prompts):
encoded_prompts = []
prompt_details = []
image_count = 0

for item in prompts:
prompt_detail = {"prompt": item}

if item.startswith('http'):
response = typing.cast(http.client.HTTPResponse, urllib.request.urlopen(item))
image_data = response.read()
pil_image = PILImage.open(io.BytesIO(image_data))
encoded_image = Image.from_bytes(image_data)
encoded_prompts.append(encoded_image)
prompt_detail["type"] = "image"
prompt_detail["pil_image"] = pil_image
image_count += 1
elif item.split('.')[-1].lower() in ['jpg', 'jpeg', 'png']:
with open(item, "rb") as image_file:
image_data = image_file.read()
pil_image = PILImage.open(io.BytesIO(image_data))
encoded_image = Image.from_bytes(image_data)
encoded_prompts.append(encoded_image)
prompt_detail["type"] = "image"
prompt_detail["pil_image"] = pil_image
image_count += 1
else:
encoded_prompts.append(item)
prompt_detail["type"] = "text"

prompt_details.append(prompt_detail)

return encoded_prompts, prompt_details, image_count

def display_response(prompt_details, response_text):
for prompt_detail in prompt_details:
if prompt_detail["type"] == "image":
plt.imshow(prompt_detail["pil_image"])
plt.axis('off')
plt.show()
print("Prompt: {} (type: {})".format(prompt_detail['prompt'], prompt_detail['type']))

for candidate in response_text.candidates:
for part in candidate.content.parts:
print("Gemini:{}".format(part.text))

def chat_gemini(prompts):
encoded_prompts, pil_images, image_count = load_and_encode_images(prompts)
if image_count > 0:
model_name = "gemini-pro-vision"
else:
model_name = "gemini-pro"

model = GenerativeModel(model_name)
response = model.generate_content(encoded_prompts)

print(f"Loaded {image_count} images using the '{model_name}' model.")
display_response(pil_images, response)

9. 테스트를 위한 이미지 업로드
Colab 파일 경로에 테스트 이미지를 업로드해주세요.
얼마 전에 하와이에서 다녀온 식당의 주류 메뉴판 이미지를 포함하여 여러 이미지를 업로드 했습니다. (각각의 파일은 [우클릭] > [경로 복사] 를 통해 코드에 입력해 주실 수 있습니다.)

10. (자 이제 드디어!) 프롬프트 선언을 해봅니다.

prompts = ["/content/photo2.jpeg", "Describe this image."]
chat_gemini(prompts)

11. 결과 확인

영문으로 이미지 설명 요청 > 아래와 같은답변을 받았습니다. (메뉴판에 없는 식당 이름까지 정확히 알려주네요…!)

Prompt: Describe this image.
Gemini: This image is a drink menu from a restaurant called ULU Ocean Grill and Sushi Lounge. The menu is divided into cocktails, mocktails, beer, sake, and wine. The cocktails are further divided into Island Inspired Cocktails and Classic Cocktails. The mocktails are divided into Virgin and Non-Alcoholic. The beers are divided into Draft and Bottled. The sakes are divided into Junmai, Honjozo, and Ginjo. The wines are divided into Red, White, and Sparkling.

‘WAIPIO LOOKOUT’이라는 팻말이 있는 사진을 주고 설명을 요청했습니다.

Prompt: 이 곳의 이름과 역사를 설명해줘
Gemini: 와이피오 계곡은 미국 하와이 섬 북부 해안에 위치한 계곡입니다. 와이피오 계곡은 하와이에서 가장 신성한 장소 중 하나로 여겨지며, 많은 전설과 신화가 전해집니다. 와이피오 계곡은 또한 하와이에서 가장 아름다운 계곡 중 하나로 여겨지며, 많은 관광객들이 찾는 곳입니다. 계곡은 1,000피트(300m)이 넘는 높이에서 바다로 떨어지는 절벽으로 둘러싸여 있으며, 계곡 바닥에는 타로 밭과 열대 우림이 있습니다. 와이피오 계곡은 하와이 원주민 문화가 잘 보존되어 있는 곳으로, 하와이 원주민들이 전통적인 생활 방식을 유지하고 있습니다. 계곡에는 약 1,200명의 사람들이 살고 있으며, 대부분이 하와이 원주민입니다. 와이피오 계곡은 하와이의 자연美와 문화를 동시에 볼 수 있는 곳으로, 많은 사람들이 찾는 곳입니다.

Prompt: 이 케이크를 만드려면 어떤 재료가 필요할까?
Gemini: * 계란 * 설탕 * 버터 * 우유 * 바나나 * 밀가루 * 베이킹파우더 * 소금

자 그럼 이제 메뉴를 추천 받겠습니다.

12. 메뉴 추천 받기 (국문 사용)

Prompt: 이 이미지(식당 메뉴 사진)를 설명해줘
Gemini: 이미지는 울루(ULU)라는 레스토랑의 음료 메뉴입니다. 칵테일, 모크테일, 맥주, 사케 등 다양한 음료가 있습니다. 칵테일은 알라 울라, 팔로마 파카, 비치 니즈, 그린 슈림프, 알로하 아미고스, 배럴 에이지드 네그로니가 있습니다. 모크테일은 라즈베리 모히토, 스파클링 레몬 에이드가 있습니다. 맥주는 코나 롱보드 라거, 코나 빅 웨이브 골든 에일, 코나 파이어 록 파인애플 위트, 아사히, 사포로, 히타치노 화이트 에일, 히타치노 레드 라이스 에일이 있습니다. 사케는 준마이 긴조, 다이긴죠 냉주, 게케칸 호린, 긴가 슈진후, 오와자 슈조 사와후네 쥰마이 긴조, 와카타케 오로시노 데몬 슬레이어 쥰마이 다이긴죠 등이 있습니다.

Prompt: 메뉴에서 추천을 받고 싶어, 지금은 여름이고, 생선 요리와 어울리는 음료가 필요해, 가격은 중간 정도가 적당할 것 같아.
Gemini: 모히토가 좋을 것 같습니다. 모히토는 럼, 라임, 민트, 설탕, 소다수로 만든 칵테일로, 여름에 시원하게 마시기에 좋습니다. 특히 생선 요리와 함께 먹으면 더욱 맛있습니다. 모히토의 가격은 15달러입니다.

이로서 마무리를 해보았습니다! 중간 중간 시간이 걸리는 부분이 있었지만 재미있는 과정이었습니다.

조금 더 정교하게 만든다면, 유저 데이터를 활용해서 더 건강하게 먹을 수 있도록 도와주는 주치의봇 같은 내용도 만들어 볼 수 있지 않을까 싶네요.

추가로 위와 같은 Gemini Pro API 테스트는 Vertex AI Studio에서는 코드 작성 없이도 더 수월하고 강력한 기능과 함께 진행실 수 있습니다. 더 정교한 프로토타이핑을 원하신다면 > 바로가기 : Vertex AI Gemini API 사용해 보기

아이디어가 있다면 바로바로 테스트해 보는 게 AI 모델 활용에 재미가 아닐까 합니다. 이 글이 Gemini Pro 모델의 얼리 어답터 분들의 아이디어와 경험이 풍부해 지는 계기가 되었으면 좋겠습니다.

--

--