Vertex AI: Gemini API ã® Context caching ã®ç޹ä»
äœã®è©±ããšèšããš
Google Cloud ã§å©çšå¯èœãªãã«ãã¢ãŒãã«å¯Ÿå¿ã®åºç€ã¢ãã«ã§ãã Gemini 1.5 Pro / Flash ã«å¯ŸããŠãContext caching ã®æ©èœãå©çšå¯èœã«ãªããŸããããããã©ã®ãããªæ©èœã§äœã®åœ¹ã«ç«ã€ã®ããå®éã®äœ¿çšäŸãšããããŠããããããã説æããŸãã
Context caching ã®ãªãæ
Gemini ã¯ãã«ãã¢ãŒãã«å¯Ÿå¿ã¢ãã«ãªã®ã§ãããã³ããã«åç»ãªã©ã®ã¡ãã£ã¢ã³ã³ãã³ããåã蟌ãããšãã§ããŸããå ·äœçã«ã¯ã次ã®ããã« Python ã®ãªã¹ã圢åŒã§ããã³ãããæ§æããŸãã
prompt = [
'[åç»ãã¡ã€ã«]',
Part.from_uri(uri=f'{BUCKET}/{movie_file}', mime_type='video/mp4'),
'åç»ã®æåèµ·ãããããŠãã ããã'
]
ãã®ããã³ããã Gemini API ã«æå ¥ãããšã次ã®å³ã®ããã«åºç€ã¢ãã«ããã®å¿çãåŸãããŸãããã®éãå ¥åããŒã¯ã³ãšåºåããŒã¯ã³ã«å¯ŸããŠã³ã¹ããçºçããŸããå ·äœçãªäŸ¡æ Œã¯ãå ¬åŒããã¥ã¡ã³ãã§ç¢ºèªã§ããŸããã·ã³ãã«ã§ããïŒ

ãã«ãã¢ãŒãã«ããã³ããã Gemini API ã§åŠçãã
Context caching ã®ããæ
Context caching ãå©çšãããšãããã³ããã®äžéšåãäºåã«ã¯ã©ãŠãäžã®ãã£ãã·ã¥é åã«ã¢ããããŒãããŠããããšãã§ããŸããå ã»ã©ã®äŸã§ããã°ãååã®åç»ãã¡ã€ã«ãå«ãéšåãã¢ããããŒããããããªäœ¿ãæ¹ã«ãªããŸãã以äžã®å 容ããã£ãã·ã¥é åã«ä¿åããã€ã¡ãŒãžã§ãã
prompt_cached = [
'[åç»ãã¡ã€ã«]',
Part.from_uri(uri=f'{BUCKET}/{movie_file}', mime_type='video/mp4')
]
ãããŠã次ã®å³ã®ããã«ããã£ãã·ã¥é åããåãåºããããã³ãããšã¯ã©ã€ã¢ã³ãããå ¥åãã远å ã®ããã³ãããçµåããŠãåºç€ã¢ãã«ã«æå ¥ããããšãã§ããŸãããªãã ãè€éã§ããâŠã

Context caching ã䜿çšããå Žåã®ã€ã¡ãŒãžå³
Context caching ã®ã¡ãªãã
ããã§ã¯ãContext caching ã䜿ããšäœãå¬ããã®ã§ããããïŒã端çã«èšããšã³ã¹ãã®æé©åã§ãã
å ã»ã©ã®å³ã«ããããã«ãContext caching ã䜿ãå Žåãæ¬¡ã® 4 ã€ã®ã³ã¹ããçºçããŸãã
- å ¥åããŒã¯ã³ã«ãããã³ã¹ã
- ãã£ãã·ã¥ããã®å ¥åããŒã¯ã³ã«ãããã³ã¹ã
- ãã£ãã·ã¥ã®ä¿åã«ãããã³ã¹ã
- åºåããŒã¯ã³ã«ãããã³ã¹ã
ãã®éãããã£ãã·ã¥ããã®å ¥åããŒã¯ã³ã«ãããã³ã¹ããã¯ããå ¥åããŒã¯ã³ã«ãããã³ã¹ããã®25%ã«èšå®ãããŠããããã£ãã·ã¥ããå ¥åããæ¹ãã³ã¹ããäžãããŸãããã ãããããšã¯å¥ã«ããã£ãã·ã¥ã®ä¿åã«ãããã³ã¹ãããããã®ã§ããã£ãã·ã¥äžã®ããã³ããã 1 å䜿ãã ãã®å ŽåãContext caching ãå©çšããã³ã¹ãã¡ãªããã¯ãããŸãããçæéã®éã«ãã£ãã·ã¥ã«ä¿åããããã³ãããç¹°ãè¿ãå©çšãããããªã±ãŒã¹ã§ãã³ã¹ãã¡ãªãããçãŸããŸããå ·äœçãªäŸ¡æ Œã¯ãå ¬åŒããã¥ã¡ã³ãã§ç¢ºèªã§ããŸãããªãã»ã©ãŒã
å ã»ã©ã®äŸã§ã¯ãåç»ãã¡ã€ã«ã®æåèµ·ãããè¡ãæ³å®ã®ããã³ãããå©çšããŠããŸãããåãåç»ãã¡ã€ã«ã«å¯ŸããŠæåèµ·ããã®ä»ã«ããµããªãŒã®çæãã¹ããŒãªãŒããŒãã®çæãããããæåã®æœåºãªã©ãè€æ°ã®åŠçãè¡ãå Žåã«æå¹æŽ»çšã§ãããã§ãã
Context caching ã®å¶éäºé
æ¬èšäºå·çæç¹ã§ã¯ã次ã®ãããªå¶éäºé ããããŸãã
- ãªãŒãžã§ã³ã¯ us-central1 ã®ã¿ã«å¯Ÿå¿ïŒGemini API ã®ãªãŒãžã§ã³ã« us-central1 ãæå®ããå¿ èŠãããïŒ
- ãã£ãã·ã¥ã«ä¿åããããã³ããã¯ã32,769 ããŒã¯ã³ä»¥äžã®ãµã€ãºãå¿ èŠ
- ããã³ããã®å é éšåã®ã¿ããã£ãã·ã¥ã«ä¿åå¯èœïŒãã£ãã·ã¥ããåãåºããããã³ãããšã¯ã©ã€ã¢ã³ãããå ¥åããããã³ããã®é åºãå¶åŸ¡ããããšã¯ã§ããªãïŒ
Context caching ã®å©çšäŸ
äºåæºå
ããã§ã¯ã次ã®åç»ãã¡ã€ã«ã Gemini 1.5 Flash ã§åŠçããäŸã玹ä»ããŸãã
ãã®åç»ãã¡ã€ã«ã mp4 ã«å€æãããã®ã Cloud Storage ã®ãã±ããã«äºåã«ä¿åãããŠãããã®ãšããŸãããŸããContext caching ã䜿çšããéã¯ãVertex AI Service Agent ãå¿ èŠã«ãªããŸããããã¯ãCloud Shell ããæ¬¡ã®ã³ãã³ããå®è¡ããããšã§äœæã§ããŸãã
PROJECT_ID=$(gcloud config list --format 'value(core.project)')
curl -X POST -H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
https://us-central1-aiplatform.googleapis.com/v1/projects/$PROJECT_ID/locations/us-central1/endpoints \
-d ""
ãã®åŸã®äœæ¥ã¯ãVertex AI Workbench ã®ããŒãããã¯äžã§è¡ããŸããWorkbench ç°å¢ãæºåããæ¹æ³ã¯ã次ã®èšäºã®äºåæºåãåèã«ããŠãã ããã
ã¯ããã«ãClient SDK ãææ°ããŒãžã§ã³ã«ã¢ããããŒãããŠãKernel ããªã¹ã¿ãŒãããŸãã
!pip install --upgrade google-cloud-aiplatform
import IPython
app = IPython.Application.instance()
_ = app.kernel.do_shutdown(True)
次ã«å¿ èŠãªã¢ãžã¥ãŒã«ãã€ã³ããŒãããŸãããã®èšäºã®å·çæç¹ã§ã¯ã次ã®ããã« preview çã®ã¢ãžã¥ãŒã«ãå¿ èŠã«ãªããŸãã
import datetime, vertexai
from vertexai.preview.generative_models import GenerativeModel, Part
from vertexai.preview import caching
ãããŠããããžã§ã¯ã ID ãªã©ã®å€æ°ãã»ããããŠãClient SDK ãåæåããŸãã[Project ID]ã[Bucket Name]ã[Move File Path] ã®éšåã¯å®éã«äœ¿çšããç°å¢ã«ããããŠå
¥åããŠãã ããããŸãããã®äŸã«ããããã«ãlocation ã«ã¯ us-central1 ãæå®ããå¿
èŠããããŸãã
PROJECT_ID = '[Project ID]'
BUCKET = 'gs://[Buket Name]'
movie_file = '[Movie File Path]'
vertexai.init(project=PROJECT_ID, location='us-central1')
ãã£ãã·ã¥ãžã®ã¢ããããŒã
ãã£ãã·ã¥ã«ã¢ããããŒãããããã³ãããæ¬¡ã®ããã«å®çŸ©ããŸãã
prompt_cached = [
'[movie file]',
Part.from_uri(f'{BUCKET}/{movie_file}', mime_type='video/mp4'),
]
次ã®ã³ãã³ãã§ããã£ãã·ã¥ã«ã¢ããããŒãããŸãããã®äŸãããããããã«ããã®æç¹ã§ã䜿çšããåºç€ã¢ãã«ã model_name ãªãã·ã§ã³ã§æå®ããŸãããã®ä»ã«ã¯ãã·ã¹ãã ã€ã³ã¹ãã©ã¯ã·ã§ã³ã system_instruction ãªãã·ã§ã³ã§æå®ã§ããŸãã倿° cached_content ã«ã¯ããã£ãã·ã¥ãããå
容ã衚ããªããžã§ã¯ããä¿åãããŸãã
cached_content = caching.CachedContent.create(
model_name='gemini-1.5-flash-001',
contents=prompt_cached,
system_instruction='You are a video content analyst. Work on the following tasks.',
ttl=datetime.timedelta(minutes=60)
)
ãŸããæåŸã® ttl ãªãã·ã§ã³ã¯ããã£ãã·ã¥ã®ä¿ææéã§ãããã®æéïŒä»ã®å Žå㯠60 åïŒãçµéãããšãã£ãã·ã¥ã¯èªåçã«åé€ãããŸããèšå®å¯èœãªå€ã®äžéã¯ãªãã®ã§ã極端ã«å€§ããªå€ãèšå®ããã°ãå®è³ªçã«ç¡é倧ã«èšå®ããããšãã§ããŸãããŸããäžåºŠèšå®ããæéãåŸããæŽæ°ããŠãå»¶é·ããããšãå¯èœã§ãã
ãã£ãã·ã¥ã«ä¿åããããã³ããã«ã¯ããŠããŒã¯ãª ID ãèªåã§å²ãåœãŠãããŸããããã¯ã次ã®ã³ãã³ãã§ç¢ºèªã§ããŸãã
cached_content.name
[åºå]
'2753810434648702976'
ãŸããçŸåšãã£ãã·ã¥ã«ä¿åãããŠããããã³ããã®äžèЧã¯ã次ã®ã³ãã³ãã§è¡šç€ºãããŸãã
caching.CachedContent.list()
[åºå]
[<vertexai.caching._caching.CachedContent object at 0x7f83a2571ed0>: {
"name": "projects/[Project Number]/locations/us-central1/cachedContents/2753810434648702976",
"model": "projects/[Project ID]/locations/us-central1/publishers/google/models/gemini-1.5-flash-001",
"createTime": "2024-07-10T02:56:24.259968Z",
"updateTime": "2024-07-10T02:56:24.259968Z",
"expireTime": "2024-07-10T03:56:24.251354Z"
}]
name 屿§ã®æ«å°Ÿããå
ã»ã©ç¢ºèªãã ID ã«äžèŽããŠããŸãã
ä»ã¯å®è¡ããå¿ èŠãããŸããããæ¢åã®ãã£ãã·ã¥ãåå©çšããéã¯ã次ã®ã³ãã³ãã§ãã£ãã·ã¥ã®å 容ã衚ããªããžã§ã¯ããååŸã§ããŸãã
cached_content = caching.CachedContent(
cached_content_name='projects/[Project Number]/locations/us-central1/cachedContents/2753810434648702976')
ãã£ãã·ã¥ã«ä¿åããããã³ããã®å©çš
ããã§ã¯ããã£ãã·ã¥ã«ä¿åããããã³ãããçšããŠã¿ãŸãããããŸãã倿° cached_content ã«çšæããå
容ãçšããŠãã¢ãã«ã®ãªããžã§ã¯ããååŸããŸãã
model = GenerativeModel.from_cached_content(cached_content=cached_content)
ãã®ã¢ãã«ã«è¿œå ã®ããã³ãããäžãããšããã£ãã·ã¥ã«ä¿åããããã³ãããšçµåãããã®ãã¢ãã«ã«å¯Ÿããå ¥åã«ãªããŸããããã§ã¯ãåç»ã®ãµããªãŒãçæããŠã¿ãŸãããã
prompt = '''\
[tasks]
A. Summarize important topics of the video.
[conditions]
A. The summary has more than three sentences.
A. Try best to include as much detail as possible so that they clearly explain the sequence of the story.
[format instruction]
Output in Japanese. Use plaintext not markdown.
'''
response = model.generate_content(prompt, stream=False)
print(response.text)
[åºå]
ãã®åç»ã¯ãè¥ã女æ§ããã¯ã€ãæ
è¡ããæ§åãGoogle Pixelã§æ®åœ±ããæ åã§ãã空枯ã«å°ç
ãã圌女ã¯ãéã空ãšéãæµ·ãã€ã·ã®æšãªã©ããã¯ã€ããã颚æ¯ãGoogle Pixelã§æ®åœ±ããŠæ¥œãã
ã§ããŸãããã¡ãŒããŒãºããŒã±ããã§ã¯Google Pixelã®ã«ã¡ã©æ©èœã䜿ã£ãŠã©ã³ããŒã¿ã³ãªã©ã®
çããæç©ã調ã¹ãå°å
ã®äººãšäº€æµãããã®çŸå³ãããäœéšããŸããããã®åŸããã¯ã€ã®ç±åž¯æ€
ç©åã蚪ããããŸããŸãªæ€ç©ãGoogle Pixelã§æ®åœ±ããŸããããŸããä¹éЬäœéšã§ã¯ãGoogle Pixel
ã䜿ã£ãŠèªæ®ããããŠããã¯ã€ã®é倧ãªèªç¶ãæºå«ããŸããããããŠå€ã¯ãã¬ã¹ãã©ã³ã§é£äºã
楜ãã¿ãªããGoogle Pixelã§ã¡ãã¥ãŒã調ã¹ãåšå²ã®çŸããæ¯è²ãæ®åœ±ããŸããããã®ããã«
Google Pixelã䜿ã£ãŠã圌女ã¯ãã¯ã€æ
è¡ã®æãåºãé®®ããã«èšé²ããæ¥œããã§ããŸãã
åè¿°ã®ããã«ããã£ãã·ã¥ã«ä¿åããå 容ã¯ç¹°ãè¿ã䜿ããªããšã³ã¹ãã¡ãªãããåºãŸãããããã§ã¯ãããã²ãšã€ã®äŸãšããŠãåç»ã®å 容ã«å¯Ÿãã QA ãè¡ããŸãã
prompt = '''\
[task]
A. Find the most relevant scene with timestamp in the movie that can be used to answer the question.
B. Create a summary of the selected scene.
C. Create an answer to the question based on the selected scene.
[format instruction]
In Japanese. In plaintext, no markdowns. In the following format:
- Beginning of the output (don't show this line.)
åçã«çšããã·ãŒã³ïŒœ
<Timestamp in mm:ss - mm:ss>
<summary of the scene>
åç
<Answer to the question>
- End of the output (don't show this line.)
[question]
ãã®åç»ã«ç»å Žãã人ã¯ãGoogle Pixel ã䜿ã£ãŠäœã調ã¹ãŸãããïŒ
'''
response = model.generate_content(prompt, stream=False)
print(response.text)
[åºå]
åçã«çšããã·ãŒã³ïŒœ
00:16 - 00:20
女æ§ããèµ€ãæå®ã®å
¥ã£ãè¢ãGoogle Pixel ã®ã«ã¡ã©ã§æ®åœ±ãããšãããç»é¢ã«
ãã©ã³ããŒã¿ã³ããšè¡šç€ºãããã©ã³ããŒã¿ã³ã®èª¬æã衚瀺ãããŸãã
åç
ãã®åç»ã«ç»å Žãã人ã¯ãGoogle Pixel ã䜿ã£ãŠãèµ€ãæå®ãäœã§ãããã調ã¹ãŸããã
ããã®åç»ã«ç»å Žãã人ã¯ãGoogle Pixel ã䜿ã£ãŠäœã調ã¹ãŸãããïŒããšãã質åã«å¯ŸããŠãåçã®æ ¹æ ãšãªãã·ãŒã³ã®èª¬æãšããããçšããåçãåŸãããŸããããã®ããã«ãç¹å®ã®åç»ã«QAãç¹°ãè¿ããããªå Žåã¯ãç¹ã« Context caching ãæå¹æŽ»çšã§ããã§ãããã
ãã£ãã·ã¥ã®åé€
å©çšãçµãã£ããã£ãã·ã¥ã¯ã次ã®ã³ãã³ãã§åŒ·å¶çã«åé€ããããšãã§ããŸãã
cached_content.delete()
è€æ°ã¡ãã£ã¢ã®åæå©çš
ãããŸã§ãåç»ãã¡ã€ã«ããã£ãã·ã¥ã«ä¿åããäŸã§èª¬æããŸããããGemini 1.5 Pro / Flash ã§å©çšå¯èœãªã¡ãã£ã¢ã¯ãã¹ãŠãã£ãã·ã¥ã«ä¿åããããšãã§ããŸãããŸããè€æ°ã®ã¡ãã£ã¢ãå«ãããã³ãããä¿åããããšãå¯èœã§ããããšãã°ã次ã®å³ã®ããã«ãè€æ°ã®ç»åãšããã¹ããæ··ãã£ãããã³ãããèããŸãã

è€æ°ã®ç»åãšããã¹ããæ··ãã£ãããã³ãã
ããã¯ãPython ã®ã³ãŒãã§ã¯æ¬¡ã®ããã«è¡šçŸãããã§ãããã察å¿ããç»åãã¡ã€ã«ã¯ãäºåã« Cloud Storage ã®ãã±ããã«ä¿åããŠããæ³å®ã§ãã
prompt_cached = [
'[reference information]',
Part.from_uri(f'{BUCKET}/01_chrome_dino.png', mime_type='image/png'),
'This character is "ã¯ããŒã ã®æç«".',
Part.from_uri(f'{BUCKET}/02_google_color.png', mime_type='image/png'),
'These four colors are "Googleã«ã©ãŒ".',
Part.from_uri(f'{BUCKET}/03_gbike.png', mime_type='image/png'),
'The bicycle with "Googleã«ã©ãŒ" is "Googleãã€ã¯".'
]
ãããå
ã»ã©ãšåæ§ã«ãcaching.CachedContent.create() ã¡ãœããã«æå®ããã° OK ã§ããïŒãã ãããã®äŸã§ã¯ããŒã¯ã³æ°ãå°ãªãããåè¿°ã®æäœããŒã¯ã³æ°ã®å¶éã§ãšã©ãŒã«ãªããŸããå®éã«ã¯ããã£ãšå€§éã®ç»åãšãã®èª¬ææãçšæããå¿
èŠããããŸããïŒ
cached_content = caching.CachedContent.create(
model_name='gemini-1.5-flash-001',
contents=prompt_cached,
system_instruction='You are a fashion advisor. Work on the following tasks.',
ttl=datetime.timedelta(minutes=60)
)
ããã«æ¬¡ã®ããã³ããã远å ããŠãTã·ã£ãã®çµµæã®èª¬ææãçæããŸãããã€ã©ã€ãéšåã«ããããã«ãå ã»ã©ã®èª¬ææãåç §ããããã«æç€ºããŠããŸãã

ç»åã®åèæ
å ±ãå©çšããããã³ããã®äŸ
å®éã®ã³ãŒããšåºåäŸã¯æ¬¡ã®ããã«ãªããŸãã
prompt = [
"""\
[task]
A. Describe the printed patterns and illustrations of each item.
[condition]
A. Use the reference information to make descriptions.
A. Each description has a few short sentences. Try best to include as much detail as possible.
A. Be cautious on number of items.
[format instruction]
In Japanese. In plain text, no markdowns.
Output only descriptions in a bullet list starting with '-'.
[items]
""",
Part.from_uri(f'{BUCKET}/t_shirt1.png', mime_type='image/png'),
Part.from_uri(f'{BUCKET}/t_shirt2.png', mime_type='image/png'),
Part.from_uri(f'{BUCKET}/t_shirt3.png', mime_type='image/png'),
Part.from_uri(f'{BUCKET}/t_shirt4.png', mime_type='image/png')
]
response = model.generate_content(prompt, stream=False)
print(response.text)
[åºå]
- ãã®ã»ãŒã¿ãŒã¯ãçœãããŒã¹ã«ãéãšã°ã¬ãŒã®æš¡æ§ã§ãã¶ã€ã³ãããŠããŸããæš¡æ§ã«ã¯ããã¯ããŒã ã®
æç«ããšãµããã³ãæãããŠããŸãã
- ãã®Tã·ã£ãã¯ããã³ã¯ããé»è²ãçœãéãžãšã°ã©ããŒã·ã§ã³ã§æããããŠããŸããTã·ã£ãã®è£Ÿã«ã¯ã
ãGoogleãã®æåãçœã§å°å·ãããŠããŸãã
- ãã®ãµã€ã¯ã«ãžã£ãŒãžã¯ãé»ãããŒã¹ã«ãGoogleã«ã©ãŒã®æ°Žå¹³ã®ã¹ãã©ã€ãããã¶ã€ã³ãããŠããŸãã
ã¹ãã©ã€ãã¯ãéãèµ€ãé»è²ãç·ã®é ã«é
眮ãããŠããŸãããžã£ãŒãžã®å·Šèžã«ã¯ããGoogleãã®ããŽã
çœã§å°å·ãããŠããŸãã
- ãã®Tã·ã£ãã¯ãçœãããŒã¹ã«ãGoogleãã€ã¯ãã¢ããŒãã«ãã¶ã€ã³ãããŠããŸãããã€ã¯ã®ãã¬ãŒã ã
è»èŒªããµãã«ããã³ãã«ããŒããã¹ã±ãããã«ã©ãã«ãªGoogleã«ã©ãŒã§å°å·ãããŠããŸãã
ãã¯ããŒã ã®æç«ããGoogleã«ã©ãŒããGoogleãã€ã¯ããªã©ããã£ãã·ã¥äžã®ããã³ããã§ç€ºããåç§°ã䜿ã£ã説ææãçæãããŠããããšãããããŸãã
ãŸãšã
æ¬æã§èª¬æããããã«ãContext caching ã®å©çšç®çã¯ãããŒã¯ã³æ°ã倧ããªã³ã³ãã³ããç¹°ãè¿ãå©çšããéã®ã³ã¹ããæé©åããç¹ã«ãããŸããç¹ã« Gemini 1.5 Pro / Flash ã§ã¯ã2MããŒã¯ã³ïŒProïŒã1MããŒã¯ã³ïŒFlashïŒã®ãã³ã°ã³ã³ããã¹ãã䜿çšã§ããã®ã§ãããã³ããã«å€§éã®ããŒã¿ãå«ããããšã§å¿çã®å質ãäžããã¢ãããŒããå¢ãããšæãããŸããåäžã®ããŒã¿ãç¹°ãè¿ãå©çšããéã¯ãContext caching ãæ€èšãããšããã§ãããã
æ¬èšäºã§ç޹ä»ãã以å€ã®æ©èœã«ã€ããŠã¯ã次ã®å ¬åŒããã¥ã¡ã³ããåèã«ããŠãã ããã
Discussion