Menggunakan Model Gemini untuk pendekatan MultiModal

Johanes Glenn
Google Cloud Indonesia
5 min readFeb 13, 2024

--

Latar Belakang

Pada 13 Desember 2023 yang lalu Google Cloud membuka preview akses untuk Gemini-Pro dan Gemini-Pro-Vision. Hal ini menambah opsi yang dapat kita gunakan sebagai pengguna dimana saya bisa memproses informasi jauh lebih kaya dari hanya dalam bentuk tulisan menjadi gambar dan video.

Pada tulisan singkat kali ini saya ingin mencoba model baru tersebut termasuk dengan beberapa fitur yang terdapat di dalam model yang ada diantaranya:
(1) Prompt untuk Multimodal
(2) Prompt untuk Chat
(3) Function Call
(4) Mendapatkan informasi Token Count

Catatan: Tulisan singkat dan kode yang ada hanya bertujuan untuk mencoba fitur yang ada. Untuk penggunaan yang jauh lebih sesuai untuk production mohon mengikuti dokumen dan penulisan yang tepat.

Konsep

Untuk percobaan ini saya ingin melakukan hal yang cukup simpel dimana sebuah aplikasi dapat:

(1) menerima gambar (monumen atau lokasi khusus) untuk di proses
(2) memberikan informasi di kota mana gambar tersebut dimabil
(3) memberikan informasi cuaca saat ini di kota tersebut dan beberapa informasi lainnya yang menarik tentang kota tersebut
(4) tambahan gambar yang dibuat oleh AI untuk menggambarkan kita sedang berada disana.

Untuk memenuhi tersebut dibawah ini adalah kode untuk percobaan yang ada

Untuk kebutuhan ini ada setidaknya 3 komponen utama/modul yang dibutuhkan:
1. VertexAI SDK for Python
2. Streamlit
3. Openweathermap api

Kita dapat memulai dengan membuat sebuah komponen untuk user dapat mengirmkan gambar yang ingin di proses

import vertexai
from vertexai.preview import generative_models
from vertexai.preview.generative_models import (
GenerativeModel,
Part,
Image,
)
from vertexai.preview.vision_models import ImageGenerationModel
import requests
import streamlit as st
import os

#init
vertexai.init(location="asia-southeast1")

#upload file
uploaded_file = st.file_uploader("Choose a file")

Lalu kita dapat membuat sebuah fungsi get_current_weather untuk memanggil informasi cuaca dari openweathermap dimana saya ingin menggunakan metrics unit (untuk mendapatkan Celcius daripada Kelvin). Dengan menggunakan gemini-pro (atau juga gemini-pro-vision) saya dapat membuat function call melalui deklarasi fungsi dan memberikan referensi tersebut ke dalam sebuah alat (Tool).

#getting weather from openweathermap
def get_current_weather(location, unit="metric"):
api_key = os.environ["API_KEY"]
url = f"https://api.openweathermap.org/data/2.5/weather?q={location}&units={unit}&appid={api_key}"
response = requests.get(url)

return response.json()

#function declaration
get_current_weather_func = generative_models.FunctionDeclaration(
name="get_current_weather",
description="Get the current weather in a given location",
parameters={
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city and state, e.g. San Francisco, CA"
},
"unit": {
"type": "string",
"enum": [
"celsius",
"fahrenheit",
]
}
},
"required": [
"location"
]
},
)

#adding tools
weather_tool = generative_models.Tool(
function_declarations=[get_current_weather_func]
)

Karena streamlit akan melakukan reload untuk keseluruan resources yang ada pada page tersebut, saya memberikan kondisi “jika sudah ada file yang di upload” kita akan menjalankan kode yang ada di bawahnya. Dimulai dengan memproses gambar yang ada dan mendapatkan informasi kota dan disimpan pada variable location1 (maaf nama variablenya masih sembarangan) dan proses ini akan menggunakan gemini-pro-vision.

#activity
if uploaded_file is not None:

st.image(uploaded_file)
bytes_data = uploaded_file.getvalue()
uploaded_file_read = Image.from_bytes(bytes_data)

my_bar.progress(10, text="processing image")

#getting location from image using gemini-pro-vision
model_vision = GenerativeModel("gemini-pro-vision")
response_vision = model_vision.generate_content([
uploaded_file_read, "give me only the name of the city where the picture is taken"
])

#print for debug
print("gemini-pro-vision\n",response_vision)
st.toast(response_vision._raw_response.usage_metadata)

#print for user
st.write("Location:",response_vision.text)

my_bar.progress(30, text="getting location from image")
location1 = response_vision.text

Lalu dari informasi lokasi saya ingin mendapatkan informasi tambahan seperti suhu, deskripsi dari kota tersebut, bagaimana cara sampai kesana dari kota Jakarta (maaf masih hardcode) dan aktifitas apa yang bisa dilakukan disana. Untuk menjalankan ini saya akan menggunakan bantuan dari Tools (function call) dan menggunakan variable1 sebagai input.

    #getting result from prompt + function calling
prompt = f"Can please tell me what is current weather real temperature, description and feels like in {location1} today, summary about the location, give me recommendation things to do and how to get there from Jakarta"

model = GenerativeModel("gemini-pro",
tools=[weather_tool])

chat = model.start_chat()

#first init prompt gemini-pro
model_response = chat.send_message(prompt)

#print for debug
print("gemini-pro: first call\n", model_response)
my_bar.progress(50, text="prompt to gemini")

Contoh hasil yang saya harapkan

gemini-pro: first call
candidates {
content {
role: "model"
parts {
function_call {
name: "get_current_weather"
args {
fields {
key: "location"
value {
string_value: "London"
}
}
}
}
}
}

Dari function_call tersebut saya bisa memanggil openweathermap dengan variable yang saya inginkan sehingga saya bisa menambahkan informasi tersebut sebelum dikirimkan kembali ke user

    api_response = get_current_weather(model_response.candidates[0].content.parts[0].function_call.args['location'],"metric")
print("api_response",api_response)
print("api_response",api_response['main']['temp'])
temperature=api_response['main']['temp']

my_bar.progress(70, text="get weather")

#adding function_call
model_response = chat.send_message(
Part.from_function_response(
name="get_current_weather",
response={
"content": api_response,
}
),
)

my_bar.progress(85, text="add weather information")

#for debug
print("gemini-pro: adding function call", model_response)
st.toast(model_response._raw_response.usage_metadata)
st.write(model_response.text)

Satu hal tambahan disini adalah saya ingin menambahkan sentuhan khusus untuk menambahkan ketertarikan dari pengguna dimana saya ingin membuat gambar yang menggambarkan pengguna sedang berada di kota tersebut tentunya menggunakan Imagen-v2 model dan menuliskan “Imagen” pada baju di gambar tersebut.

Hal yang akan di lakukan adalah membuat informasi khusus (hardcoded user profile) tentang pengguna dan menggabungkan variable lokasi (location1) untuk imagen membuat gambar baru. Kita simpan sementara di temporary folder dan kita tampilkan melalui streamlit.

    my_bar.progress(85, text="add a personal touch")

#testing imagenv2
custprofile = {
"gender": "male",
"age": "30-40",
"ethnicity": "asian"
}

col1,col2 = st.columns(2)
model_imagen = ImageGenerationModel.from_pretrained("imagegeneration@005")
images = model_imagen.generate_images(
prompt=f"portrait of traveling to {location1} {custprofile['gender']} age {custprofile['age']} {custprofile['ethnicity']} {temperature} degrees celcius happy traveling, with word \"IMAGEN\" on clothes, taken from behind",
# Optional:
number_of_images=2
#seed=1
)

images[0].save(location="./temp/gen-img1.png", include_generation_parameters=True)
images[1].save(location="./temp/gen-img2.png", include_generation_parameters=True)

col1.image('./temp/gen-img1.png', caption=f'Travel to {location1}')
col2.image('./temp/gen-img2.png', caption=f'Travel to {location1}')

my_bar.progress(100, text="Complete")

Hasil dari aplikasi ini seperti dibawah

Catatan: Hasil ini hanya untuk percobaan dari fitur yang ada, baik prompting, pengolahan data ataupun penggunaan services / api yang tepat mohon mengikuti dokumen resmi yang ada.

Repo dari code diatas dapat di akses pada https://gitlab.com/alevz/alevz-genai-gemini-1.git dan untuk menjalankan mohon di persiapkan

  1. Authentication dari GCP untuk mengakses VertexAI (salah satunya GOOGLE_APPLICATION_CREDENTIALS)
  2. Install modules berdasarkan requirements.txt
  3. Openweathermap api key untuk mendapatkan weather information
export API_KEY=<api key>

Lalu jalankan untuk development menggunakan streamlit cli (contoh menggunakan port 8083 dan listen to 0.0.0.0

streamlit run travel.py --server.port 8083 --server.address 0.0.0.0

--

--

Johanes Glenn
Google Cloud Indonesia

Cloud Customer Engineer — Infrastructure Modernization @GoogleCloud. Stories are my own opinion. https://linktr.ee/alevz