[Udacity] Gemini API by Google 課程分享

image-20240716202826521

(課程連結: https://www.udacity.com/enrollment/cd13416)

image-20240717155058420

前言

Google 跟 Udacity 合作開的這一個課程,蠻建議大家可以看一下。除了是免費之外,更加許多文件裡面沒有提供的詳細資訊跟用法講得很清楚。 想要更了解每一個 API 該如何使用,可以考慮看看。

這邊快速講一下課程大綱,然後帶幾個我覺得很重要的概念:

課程大綱

  • Introduction to LLMs and Gemini
    • 基本概念補充。
  • Introduction to prompting in Google AI Studio
    • 主要都是 AI Studio 的操作說明。
  • Developing with the Gemini API
    • 建議開發者都要看這個,大多是 API 使用細節。
  • Advanced Applications
    • 課程整理,還有相關小專案給學員練習。

幾個重點整理:

如何算產出 token

token_n_model = genai.GenerativeModel(model_name, generation_config={"temperature": 0.0})
poem_prompt = "Write me a poem about Berkeley's campus"

prompt_token_count = token_n_model.count_tokens(poem_prompt)
output_token_count = token_n_model.count_tokens(response.text)
print(f'Tokens in prompt: {prompt_token_count} \n Estimated tokens in output {output_token_count}')

透過

  • prompt_token_count: 輸入的 token 數字。
  • output_token_count: 產出的 token 數字。

Safety Setting

由於 Gemini 有著嚴格的管控,許多時候一些資料會被以安全因素而拒絕回覆。這時候你需要做一些處理:

在進行此演示之前,請記住要負責任地處理 AI 並遵循道德準則。

安全性是 Gemini 的一個重要內建功能。讓我們來了解更多它的功能:

如何檢查您的提示是否被安全過濾器阻擋

  • 哪些安全過濾器導致了阻擋
  • 如何調整設置以解除阻擋

檢查提示是否被阻擋

假設我們選擇了以下提示,在當前的安全設置下,您可以預期您的回應會被阻擋:

model = genai.GenerativeModel("gemini-1.5-flash", generation_config={"temperature": 0})

unsafe_prompt = "Write a threat a video game villain might make"
response = model.generate_content(unsafe_prompt)
print(response.text)

輸出:ValueError: 無效操作:response.text 快速訪問器需要回應包含有效的 Part,但沒有返回任何內容。請檢查 candidate.safety_ratings 以確定回應是否被阻擋。

現在,您可以印出 response.candidates[0].finish_reason 以進一步調查。

  • 如果 finish_reasonFinishReason.STOP,則表示您的生成請求成功運行。
  • 如果 finish_reasonFinishReason.SAFETY,則表示您的生成請求因安全原因被阻擋,因此 response.text 結構將為空。

檢查安全過濾器

印出 response.candidates[0].safety_ratings 將顯示評級結構。我們可能會看到如下內容:

[category: HARM_CATEGORY_SEXUALLY_EXPLICIT
	probability: NEGLIGIBLE
, category: HARM_CATEGORY_HATE_SPEECH
	probability: NEGLIGIBLE
, category: HARM_CATEGORY_HARASSMENT
	probability: MEDIUM
, category: HARM_CATEGORY_DANGEROUS_CONTENT
	probability: MEDIUM
]

在這裡,我們的提示觸發了 HARM_CATEGORY_HARASSMENTHARM_CATEGORY_DANGEROUS_CONTENT 類別,概率為中等,這就是為什麼我們被阻擋無法看到輸出。

如何移除過濾器

response = model.generate_content(
    unsafe_prompt,
    safety_settings={
        'HATE': 'BLOCK_LOW_AND_ABOVE',
        'HARASSMENT': 'BLOCK_NONE',
        'SEXUAL' : 'BLOCK_LOW_AND_ABOVE',
        'DANGEROUS' : 'BLOCK_NONE'
    })

這樣即便要產生一些具有髒話或是攻擊性文字也是被允許的。

透過 code execution 可以讓幻覺更少

可以讓 Gemini 幫你產生 Python code 並且實際執行它 (範例),對於一些數學(或是難以計算的數字)可以透過執行程式碼的方式來實際運算。 主要原因,因為如果你直接問 Gemini 可能因為幻覺造成計算出錯誤的數學結果,這時候務必要使用 code execution 來計算。

import os
import google.generativeai as genai

genai.configure(api_key=os.environ['API_KEY'])

model = genai.GenerativeModel(
    model_name='gemini-1.5-pro',
    tools='code_execution')

response = model.generate_content((
    'What is the sum of the first 50 prime numbers? '
    'Generate and run code for the calculation, and make sure you get all 50.'))

print(response.text)

透過 response_mime_type 強制回覆 JSON

雖然使用 prompting 可以要求 Gemini 回覆 JSON,但是為了確保回覆的資料格式,可以使用 response_mime_type 來強至指定回覆格式。

model = genai.GenerativeModel('gemini-1.5-flash',
                              generation_config={"response_mime_type": "application/json"})

prompt = """
  List 5 popular cookie recipes.

  Using this JSON schema:

    Recipe = {"recipe_name": str}

  Return a `list[Recipe]`
  """

response = model.generate_content(prompt)
print(response.text)

response_schema更可以限制回傳的資料格式,可以是 list or map 。

result = model.generate_content(
  "List 5 popular cookie recipes",
  generation_config=genai.GenerationConfig(response_mime_type="application/json",
                                           response_schema = list[Recipe]))

print(result.text)

[Google Cloud/Firebase] 關於 Python Firebase Admin 認證方式

前提

將 Python Firebase 的套件改成官方的 FirebaseAdmin ,以下有兩種認證方式。

透過 GOOGLE_CREDENTIALS

  • 將 services_account.json 放在環境變數 GOOGLE_CREDENTIALS
  • 透過以下程式碼啟動
  • 這個方式可以在本地端,遠端連線去 firebase 測試。
# 从环境变量中读取服务账户密钥 JSON 内容
service_account_info = json.loads(os.environ['GOOGLE_CREDENTIALS'])
# 使用服务账户密钥 JSON 内容初始化 Firebase Admin SDK
cred = credentials.Certificate(service_account_info)

# 啟動 firebase realtime database (透過 firebase_url )
firebase_admin.initialize_app(cred, {'databaseURL': firebase_url})

透過 GCP 系統啟動

  • 如果服務是部署在 Cloud Function 或是 Cloud Run
  • 其實可以透過預設的 Services Account 來取得相關權限
    • My Project 可以取得 My Project 在 firebase 的權限。
  • 這個設定方式如法在本地端連接到 Firebase 測試
# 直接取得 Google Cloud 的參數
cred = credentials.ApplicationDefault()

# 啟動 firebase realtime database (透過 firebase_url )
firebase_admin.initialize_app(cred, {'databaseURL': firebase_url})

增加 Firebase 相關安全性設定 (Firebase Realtime Database Security Rules)

{
  "rules": {
    ".read": "auth != null && auth.token.admin === true",
    ".write": "auth != null && auth.token.admin === true"
  }
}

這樣就可以了。

相關程式碼

放一些基本常用到的

查詢全部

def get_all_cards(u_id):
    try:
        # 引用 "namecard" 路径
        ref = db.reference(f'{namecard_path}/{u_id}')

        # 获取数据
        namecard_data = ref.get()
        if namecard_data:
            for key, value in namecard_data.items():
                print(f'{key}: {value}')
            return namecard_data
    except Exception as e:
        print(f"Error fetching namecards: {e}")

新增資料

def add_namecard(namecard_obj, u_id):
    """
    将名片数据添加到 Firebase Realtime Database 的 "namecard" 路径下。

    :param namecard_obj: 包含名片信息的字典对象
    """
    try:
        # 引用 "namecard" 路径
        ref = db.reference(f'{namecard_path}/{u_id}')

        # 推送新的名片数据
        new_ref = ref.push(namecard_obj)

        print(f'Namecard added with key: {new_ref.key}')
    except Exception as e:
        print(f'Error adding namecard: {e}')

移除重複資料

def remove_redundant_data(u_id):
    """
    删除 "namecard" 路径下具有相同电子邮件地址的冗余数据。
    """
    try:
        # 引用 "namecard" 路径
        ref = db.reference(f'{namecard_path}/{u_id}')

        # 获取所有名片数据
        namecard_data = ref.get()

        if namecard_data:
            email_map = {}
            for key, value in namecard_data.items():
                email = value.get('email')
                if email:
                    if email in email_map:
                        # 如果电子邮件已经存在于 email_map 中,则删除该名片数据
                        ref.child(key).delete()
                        print(f'Deleted redundant namecard with key: {key}')
                    else:
                        # 如果电子邮件不存在于 email_map 中,则添加到 email_map
                        email_map[email] = key
        else:
            print('No data found in "namecard"')
    except Exception as e:
        print(f'Error removing redundant data: {e}')

查詢某個資料是否已經存在

def check_if_card_exists(namecard_obj, u_id):
    """
    检查名片数据是否已经存在于 "namecard" 路径下。

    :param namecard_obj: 包含名片信息的字典对象
    :return: 如果名片存在返回 True, 否则返回 False
    """
    try:
        # 获取名片对象中的电子邮件地址
        email = namecard_obj.get('email')
        if not email:
            print('No email provided in the namecard object.')
            return False

        # 引用 "namecard" 路径
        ref = db.reference(f'{namecard_path}/{u_id}')

        # 获取所有名片数据
        namecard_data = ref.get()

        if namecard_data:
            for key, value in namecard_data.items():
                if value.get('email') == email:
                    print(
                        f'Namecard with email {email} already exists: {key}')
                    return True
        print(f'Namecard with email {email} does not exist.')
        return False
    except Exception as e:
        print(f'Error checking if namecard exists: {e}')
        return False

[Google Gemma2/PaliGemma] Gemma2/PaliGemma 學習筆記,可以應用範圍

Google AI Dev - Gemma2 && PaliGemma

img

這張圖稍微解釋了 Gemma 家族的兩個主要產品:

  • Gemma 2:也就是第二代的 Gemma
  • PaliGemma:是第一代的 VLM (視覺語言模型)

PaliGemma 相關資源:

  • 這邊有 paligemma 的 demo code (在 HuggingFace 上面)

    image-20240711212906507

    Google Chrome 2024-07-11 15.46.00

    可以看出來,由於是 Gemma 2B 加上 SigLIP 他對於語言的處理比較簡單。 可以做一些簡單的資訊處理,但是複雜問題就不行,比如說:

    • 產生 JSON 回覆 (X)
    • 一次回答兩個問題以上 (X)

    但是可以達到:

    • 用中文問問題(但是只會回答英文)
    • 可以做簡單的 OCR ,或是 Object Detection 。

    根據以下討論 PaliGemma 的影片, Google 團隊建議直接使用 Mix 版本的模型。他可以 Vision + Object Detection 。

image-20240711223813438

以上是 PaliGemma model 的相關 Benchmark ,可以看出來。

對比的相關測試數據跟方法,都可以得到不錯的準確率。

在 GCP 上面直接部署 PaliGemma

https://console.cloud.google.com/vertex-ai/publishers/google/model-garden/paligemma

另外一方面 Gemma 2 也可以: https://console.cloud.google.com/vertex-ai/publishers/google/model-garden/gemma2

image-20240712105925552

Gemma 可以適用的相關內容

透過 Gemma 可以讓 token 數字有大幅度的減少,有以下幾種方向可以考慮:

個人隱私的偵測

讓一些可能有個人隱私的部分可以獲得比較有效的篩選。

以前做法:

個人資料的偵測跟去除一直是一個很難的技術,需要有許多 regular expression 來做控管。即便是如此,還是有可能會有遺漏的地方。針對個人資料偵測這一段,其實在 LLM 是可以使用的。 但是在資安法規上,直接將用戶的個人資料傳到第三方,這樣是不符合規範的。所以這一段可以透過 Gemma 來施行。

如何用 Gemma (on-device LLM) 處理

查看以下內容是否包含個人資料,地址,身份字號,銀行帳號,回覆我 是 或是 否
------
我想找台北的房子

如何用 PaliGemma 處理?

Check if the image content contains personal information, address, identity number, or bank account number, and reply with Yes or No.

實地測試 - Gemma2 / PaliGemma

文字測試 Gemma2-9B

iTerm2 2024-07-12 11.49.58

改成 「某人」跟 「配偶」,並且可以有效地去除身份字號跟銀行帳號。

圖片測試 PaliGemma

Google Chrome 2024-07-12 11.10.02

image-20240712111911951

判定是否需要 「大型」LLM 的介入

將聊天機器人放入群組之中,最害怕的就是怕「 Token」爆掉。因為每一句話都需要判斷是否需要 LLM 的介入。這時候就可以透過 Gemma 可以有效的處理。

以前做法

有看過一些人做法是: 設定前綴字 "@" "!" 才會呼叫 LLM

這些做法沒有錯誤,只是這樣往往讓聊天室裡面的文字不好理解。

如何用 Gemma (on-device LLM) 處理

可以透過簡單的判斷 Prompt 讓

查看以下文字是否需要客服人員的協助。回答 yes/no
------
我今天早上吃了蛋餅

實體測試 Gemma

image-20240712122131249

未來展望

所謂的「小模型」或者是「Open Model」 不僅僅是在 on-device 的應用才有用。 放眼在 Cloud Services 的概念上,其實也是可以透過 on-devices LLM model 來做相關應用。 也歡迎大家一起來發想,如何透過比較隱密的 on-device model 來做出更多符合法規與讓成本更加優化的的應用。

[Google Gemma] Gemma2 bootcamp 公開資源紀錄

image-20240708123810509

懶人包:

懶人包: Gemma2 目前還是屬於偏大的參數(27B) 小模型還在訓練中,可以先看看 Gemma 1.1 。

相關內容

概論

Gemma Cookbook 資料分享

在 AI Studio 試試看 Gemma2

image-20240708125437847

Model Card

新增: Gemma2 on Groq (沒有很好顯卡,可以用這個範例)

新增: Gemma2 相關中文模型

image-20240708124404765

Q&A

  • Q: Gemma2 - Fine-Tunning 經驗?
    • HuggingFace 上面有註解,如果要 Fine-Tune 需要把 Attention 改成 Egar
  • Q: Gemma2 是否有 Embedding Model?
    • 目前還沒有。
  • Q: 有方式透過雲端方式直接使用 Gemma 嗎?不需要本地端部署 GPU?

[iThome Cloud Summit Lab][Python] 透過 Cloud Function (Cloud Run) + Firebase 與 Gemini Pro Vision 打造一個旅遊小幫手 LINE ChatBot

image-20240702204105183

LINE 2024-07-02 23.42.02

前言:

本篇文章主要是 iThome Cloud Summit 2024 Lab 的課程內容

這裡可以看一下投影片內容,在緊接著來看 Lab 實作的流程教學:

課程目標

這個工作坊適合對 ChatBot 開發、雲端服務或機器學習有興趣的開發者、學生或任何技術愛好者。無論你是想擴展你的技能集,還是對打造智能旅遊助手有獨特的想法,這個工作坊都將為你提供實踐經驗和深入知識。

課程綱要

第一部分:了解基礎

Cloud Function 和 Firebase 簡介:學習這些平台的基本概念以及它們如何協同工作來支持應用程式的後端。

LINE ChatBot 的運作原理:深入了解 LINE ChatBot 的架構和 API,以及如何與用戶進行互動。

第二部分:動手實作

設置 Firebase 環境:實際操作,建立 Firebase 專案並配置所需的服務。

開發 Cloud Function:學習如何編寫和部署 Cloud Function 來處理 ChatBot 的邏輯和資料存取。

整合 Gemini Pro Vision API:探索如何使用 Gemini Pro Vision 的 API 進行影像識別,並將其應用於收據管理。

第三部分:ChatBot 功能開發

旅遊資訊查詢:實現一個功能,讓用戶可以透過 ChatBot 查詢旅遊相關資訊。

收據上傳與識別:開發一個系統,讓用戶能夠上傳收據圖片,並利用 Gemini Pro Vision 的技術自動識別和整理收據資訊。

第四部分:部署與監控

ChatBot 的部署:學習如何將 ChatBot 部署到生產環境中,讓真實用戶開始使用。

監控與維護:介紹如何監控 ChatBot 的運行狀況,並進行必要的維護。

學員自備裝置

1.可連接網路筆電

2.Google Cloud 帳號

3.LINE 帳號

學員基礎能力需求

Python

Cloud Deployment

事前準備:

  • LINE Developer Account: 你只需要有 LINE 帳號就可以申請開發者帳號。
  • Google Cloud Functions: Python 程式碼的部署平台,生成供 LINEBot 使用的 webhook address。
  • Firebase:建立Realtime database,LINE Bot 可以記得你之前的對話,甚至可以回答許多有趣的問題。
  • Google AI Studio:可以透過這裡取得 Gemini Key 。

關於 Gemini API Price

根據官方網站: https://ai.google.dev/pricing?hl=zh-tw

image-20240410164827279

申請 Gemini API Key

  • 到 Google AI Studio https://aistudio.google.com/
  • Click “Get API Key”
  • 選擇你已經有綁定信用卡的付費帳號,來取得 API Keyimage-20240412195805278

申請一個 LINE 聊天機器人 (Messaging API)

image-20240410165008871

  • LINE Developer Console )並且登入 image-20240410165104899
  • 在挑選 Channel 的時候,如果要申請 LINE Chatbot (官方帳號),就要申請 Messaging API image-20240410170120876
  • 相關資料填寫上:
    • Cmpany or owner’s country or region:
    • Channel Name: 也就是你的 LINE Bot 名稱。
    • Channel description: 相關敘述來描述你 LINE Bot 做什麼。
    • 其他都可以隨便填寫即可。
  • 接下來要到 Messaging API Tab 執行以下設定:
    • Auto-reply messages: 關閉它 image-20240410170924360
  • 接下來要取得兩個重要的參數:
    • Basic Setting Tab 下方的 Channel secret image-20240410171544805
    • Messaging API Tab 下方的 Channel access token (long-lived) image-20240410171731815
  • 目前先到這邊,稍後還會回來設定相關 Webhook 。

建立一個 Cloud Run 服務

image-20240702213018935

  • 選擇好 Source Repository (應該是你自己的名字)

image-20240702213127188

  • 透過 Dockerfile 來啟動

image-20240702213157101

  • 機器設定可以挑選任何區域,但是 Authentication 要挑選 Allow unauthenticated invocations

Google Chrome 2024-07-02 21.32.25

  • Container(s), Volumes, Networking, Security 相關設定,需要將環境參數寫進去。
    • ChannelSecret: Your LINE channel secret.
    • ChannelAccessToken: Your LINE channel access token.
    • GEMINI_API_KEY: Your Gemini API key for AI processing.

image-20240703010240455

第一階段成果 - Gemini Pro 小幫手

image

第二階段: 讓我們來加上 Firebase Realtime Database

申請 Firebase Database 服務

  • 記得到 Firebase Console,直接選取你現在有的專案。(可能叫做 My First Project?)

  • 建立一個 Firebase Realtime Database 等等會用到

    image-20240413212830827

  • 地區選美國

    image-20240413212903957

  • Start in “lock mode”

    img

  • 為了開發方便,到 “Rules”設定成可以寫跟讀取,千萬注意:

    • 這是為了測試,請勿用在對外環境
    • 這是為了測試,請勿用在對外環境
    • 這是為了測試,請勿用在對外環境

image-20240413213202354

  • 記住哪個 URL (注意!之後要正式上線,需要改回權限),並且加上一個項目: “BwAI

image-20240413213802313

建立一個 Cloud Run 服務

image-20240702213018935

  • 選擇好 Source Repository (應該是你自己的名字)

image-20240702213127188

  • 透過 Dockerfile 來啟動

image-20240702213157101

  • 機器設定可以挑選任何區域,但是 Authentication 要挑選 Allow unauthenticated invocations

Google Chrome 2024-07-02 21.32.25

  • Container(s), Volumes, Networking, Security 相關設定,需要將環境參數寫進去。
    • ChannelSecret: Your LINE channel secret.
    • ChannelAccessToken: Your LINE channel access token.
    • GEMINI_API_KEY: Your Gemini API key for AI processing.
    • FIREBASE_URL: Your Firebase database URL.

image-20240702213433321

LINE Bot 完成最後設定

  • 到 “Messaging API” Tab
  • 填入 “Webhook URL” 數值,將剛剛得「觸發網址填上去」
  • 更新(update)後,使用 “Verify” 看看有沒有設定錯誤。
  • 如果沒有問題,可以打開「Use webhook」

image-20240412214745544

需要注意事項:

1. 發生 Error “Cloud Build trigger creation failed. Required role roles/iam.service/run.admin, roles/iam.services/iam.serciceAccloutUser”

image-20240703134145163

第一次建立 Google Cloud 專案之後,如果馬上使用 Cloud Run 就會發生這樣的錯誤。 主要是因為預設的 Compute Engine default service account 的權限不足。 修改方式如下:

  • IAM 的設定畫面
  • 修改 Compute Engine default service account 權限
  • 確定增加兩個權限
    • Cloud Run Admin
    • Service Account User

參考以下圖片:

Google Chrome 2024-07-03 13.51.05

2. 要注意一下 Cloud Function / Cloud Run Instance 開的伺服器夠不夠大

  • 如果 Firebase 資料放太多,要小心記憶體可能會不夠。記得 Cloud Function (Cloud Run) 記憶體要開得夠大。
  • 有使用到圖像處理,因為要把圖像整個讀取到記憶體中。也會有相關的考量。

3. 記得定期清理 Artifact Registry 空間 - 透過 Artifact Registry 直接設定 House Keeping 策略

  • Artifact Registry

    image-20240502234018634

  • 點選 size 最大的吧,然後選取上方 Edit Repository

  • 在最下方,選曲 Cleanup Policies

  • 選擇 “Keep most Recent versions”

  • “Keep count” 選 1 (也可以是 2)

image-20240502234314012

如果怕刪除太多,可以用 Dry run 看看結果。

完整原始碼

你可以在這裡找到相關的開源程式碼:

衍伸應用

透過 Cloud Run / Cloud Function 可以很快速部署服務到 Google Cloud 並且很快的讓你的 LINE Bot 可以上線。以下有相關應用可以去參考一下:

[好書分享] 成熟大人回嘴的藝術:有人酸你、挖苦、打壓、諷刺你時,與其默默承受,你要走到對方面前這樣說……

成熟大人回嘴的藝術
有人酸你、挖苦、打壓、諷刺你時,與其默默承受,你要走到對方面前這樣說……
賢く「言い返す」技術
作者: 片田珠美  
譯者: 郭凡嘉  
出版社:大是文化 
出版日期: 2016/07/27 

買書推薦網址:

前言:

這是 2024 年第 5 本讀完的書。 當初看到這一本,就是在想說很多人常常喜歡酸來酸去,該如何正面且有效的回嘴勒?

內容摘要:

你是否曾在工作、生活中,被人這樣「挖苦」過……
◎公司前輩:「你都出社會幾年啦?連這種事都不知道!」
◎長輩鄰居一碰面就問:「怎麼還不生小孩啊?」
◎主管老愛想當年:「到現在為止,還沒有人可以超越我的紀錄。」
◎朋友愛吐槽漏我氣:「你那個身材穿這樣不好看啦,我穿好看多了……」
◎媽媽:「我說這些都是為了你好,你當我喜歡囉嗦啊……」
◎婆婆:「妳做的菜跟我們家味道都不太一樣……」
◎丈夫:「家庭主婦還真是輕鬆!」


◎回嘴的最高指導原則,就是「不搏鬥」,讓對方的襲擊落空:
•面對激動的、大聲的言語攻擊,你的回嘴口氣更必須顯得不痛不癢,
讓對方知道這樣說下去於事無補。
•言語攻擊者都想看到對方受傷,你悖離他的期待,就能使攻擊毫無價值。

心得:

這一本書根據一些心理狀態的頗析出發,開始去分析為什麼會有人想要透過「言語來霸凌」別人,為什麼想要在口頭上欺負別人?再來去思考你應該要有哪一些的心理建設與應對想法。 讓每一個人都能知道,你乖乖地並不一定能夠讓對方罷休。有些時候可以透過,轉移話題,正面拒絕,甚至是反嘴回去的一些方式來讓對方知道你不是好欺負的。