想要自建 ChatGPT 服務嗎?
要訂閱 OpenAI ChatGPT Plus 一個月一個人費用需要 20 美元, 隨著一年內 Azure OpenAI 服務已經陸陸續續對齊提供了, 我想也是時候要把 ChatGPT Plus 退訂換成自己用 Azure OpenAI 架的 ChatGPT 服務起來自用了, 同時也觀察一下成本節約的狀況, 經過適當設計下, 單純自用的話, 還蠻出乎意料的便宜, 一個月還不到 1 美元
只需要 3 + 1 個必要材料
- 選擇 ChatGPT WebUI Project
- 申請 Azure OpenAI Service
- 部署 Azure Container App
- (Optional) 設定 Custom Domain Name
就能誕生出下面的服務喔~
部署流程重點提示
因為正常沒人會想要看一個動作一個截圖, 所以下面的流程只截重要部分, 輔以文字說明, 大家可以自行試試
1. 選擇 ChatGPT WebUI Project
這邊建議可以從 GitHub Toptics - chatgpt-ui 上找到一個你喜歡且有支援 Azure OpenAI Service 的專案, 我個人選擇採用 ChatGPTNextWeb/ChatGPT-Next-Web 這個專案, 也用了一段時間了, 支援的功能也相當多樣, 可以透過該網站看一下展示 app.nextchat.dev
另外選擇專案的時候, 要注意那個 Endpoint 和 Key 是不是要每一個 User 自己填進去, 建議還是放到 Backend 塞到環境變數處理比較好, 不要讓 User 自己填, 因為光金鑰管理就會有一堆問題
當然還有一些類似的專案也可以做到一樣的事情
- mckaywrigley/chatbot-ui: 這個從保哥那邊看到的, 看起來也可參考
- blrchen/chatgpt-lite: 這專案印象沒錯的話, 應該是微軟同事寫的, 也可以用
2. 申請 Azure OpenAI Service
首先, 你得要先申請到 Azure OpenAI 的服務, 無論是 gpt-35 還是 gpt-4 都可以, 因為最近我才拿到 gpt-4-32k
的額度, 所以就趁升級系統的時候順便寫了此篇文章
這邊要注意的是部署名稱 (Deployment Name)
和模型名稱 (Model Name)
的差異, 我個人習慣會把命名做區隔的話, 不然混再一起很難判斷是誰有問題, 如前者為 deploymnet-gpt-4-32k
, 後者為 gpt-4-32k
根據 Azure OpenAI Service REST API reference, 那你要輸入 AZURE_URL
的變數則會變成下列格式, 而不需使用到 Model Name
, 這點應該是大部分從 OpenAI 轉換到 Azure OpenAI 的人都會撞到的第一個問題
# POST https://YOUR_RESOURCE_NAME.openai.azure.com/openai/deployments/YOUR_DEPLOYMENT_NAME/
https://pichuang.openai.azure.com/openai/deployments/deploymnet-gpt-4-32k
啊如果你有看到網址後面接 Model Name
的話, 那個是一個誤會, 因為設定的人 Deployment Name
取跟 Model Name
一樣的名字, 如圖的 gpt-35-turbo-16k
# POST https://YOUR_RESOURCE_NAME.openai.azure.com/openai/deployments/YOUR_DEPLOYMENT_NAME/
https://pichuang.openai.azure.com/openai/deployments/gpt-35-turbo-16k
3. 新增 Azure Container App
3.1 Basic
關於 3
, 選擇鄰近區域, 這個有 2 個選擇, 一個是離 End user 近, 另一個是選離 Azure OpenAI Endpoint 的點近, 我個人是選擇離 End user 近的, 因為我個人相信 Microsoft Backbone (MSBB) 的能力, 精確的數字可以參考此文 Azure network round-trip latency statistics
關於 4
, 裡面有相當多可以選的地方, 強烈建議參考 Azure Container Apps environments 進行選擇, 簡單分類就是自己上班用選 Consumption only
, 預期一堆人要用得選 Workload profile
或者是你可以考慮換成 Azure Kuberenetes Service 架構
3.2 Container
關於 3 ~ 6
, 因為我使用的 ChatGPT WebUI 專案是用 ChatGPTNextWeb/ChatGPT-Next-Web, 而他的 Container Images 是位於 docker.io/yidadaa/chatgpt-next-web:latest
, 如果是個人用則把該填寫的欄位填進去即可, 但如果是企業用或者是一堆人用的話, 畢竟還是有安全疑慮需要處理, 建議另外拉去 Azure Container Registry 用 Microsoft Defender for Container 掃一掃後再拉下來用
關於 container image tag latest
, 因為個人懶得盯著版本號, 所以才用 latest
, 如果是企業用或者是給一堆人用的話, 建議還是用版本號, 和建立 Dev 環境, 確保升級不會有問題
關於 Image Tags 可以去 Docker Hub 查看, 或者是可以使用 skopeo
指令的方式來看
$ skopeo inspect docker://docker.io/yidadaa/chatgpt-next-web:latest --override-os linux --override-arch amd64 | jq '.RepoTags'
[
"1.7.2",
"latest",
"v1.5",
"v1.6",
...
若把 8~9
也放進去參考的話, 以 Kubernetes 表示方式來看, 下面的設定會等價於畫面上所需的設定
3.3 Ingress
關於 2
, 因為本文會把服務放在 Internet 之上, 所以 Ingress Traffic
的選項選擇 "Accepting traffic from anywhere", 如果你不要讓這個服務放在外網的話, 則需要回到第一頁的 Container Apps Environment
要進行網路修改為 Internal
和綁上特定的 Virtual Network
關於 3
, ChatGPTNextWeb/ChatGPT-Next-Web 服務是 HTTP 為主的, 所以選擇 HTTP
即可
關於 6
, 建議關掉 Insecure connections
這個選項, 這樣可以確保連線都是走 HTTPs 為主
關於 7
, Target Port
需要填寫的是會被 Expose 出來的 Port, 通常可以從 Dockefile 上找到答案, 或者是看 docker-compose 上的 ports 也可以
4. 設定 Azure OpenAI Key 和 Next Chat 通關密語
若要在 Azure Container App 上設定 Secrets, 如設定 Azure OpenAI Key 和通關密語等, 需要等建立起來後才能設定
4.1 Add Secrets
這邊建議會設定 2 個 Secrets, 名字可以先亂取, 分別是:
- azure-api-key: 目的連接 Azure OpenAI Service 時需要使用的金鑰
- entry-code: 通關密語, 如果不設定或者是不使用 Authentication and authorization in Azure Container Apps, 則會有任何人都可以直接去摸到這個網站, 導致 GPT Token 會被快速消耗, 詳細設定可參考 ChatGPT-Next-Web - CODE
這個畫面的設定效果, 跟在 Kubernetes 上建立 secret 設定 Opaque Secrets 的動作是等價的, 如下面表示:
$ kubectl create secret generic secret-continaer-app \
--from-literal=azure-api-key=YOUR_AZURE_OPENAI_KEY \
--from-literal=entry-code=YOUR_ENTRY_CODE
4.2 Add Environment Variables
接下來需要把 4.1 Add Secrets
所建立的密鑰, 放到 Environment Variables
裡面, 這樣才能讓 Container App 使用到這幾個參數, 如果用 Kubernetes 表示方式來看, 下面的設定會等價於畫面上所需的設定:
5. (Optional) Add Custom Domain Name
為了讓大家方便好存取, 建議都會放自己的 Domain 上去, 這樣可以讓大家更容易記住, Domain 的來源不一定是要從 Azure 上買, 或者是註冊到 Azure Public DNS Zone 的服務, 你只要確保該 Domain 是由你控制的即可
我還是很推薦 Domain 或 Sub-domain 委派 (Delegation) 給 Azure Public DNS 管理, 要放對外服務的時候, 便宜方便還安全, 還是唯一一個 SLA 100% 的服務
5.1 Setting Up DNS
關於 4
, 基於 Custom domain names and free managed certificates in Azure Container Apps (preview), Azure Container App 會免費提供一張受 Azure 控管的 SSL 憑證
關於 5
, 這邊需要決定你的網站名稱要叫什麼, 如 helloworld.pichuang.com.tw
, 之後要使用該服務的話則會需要使用 https://helloworld.pichuang.com.tw
來存取
關於 7~8
, 這個是你需要去你管理的 Domain 那邊, 分別把 CNAME 和 TXT 加進去到 Zone File 內, 然後等待 DNS 的更新後, 再按 Validate 才會生效
5.2 Check DNS validation
整體生效時間大概約略 15 分鐘, 正確運作的話你應該會看到上面的畫面, 這樣就可以用 https://helloworld.pichuang.com.tw
來存取你的 ChatGPT 服務了
Q&A
Q1: 既然是 Container 服務, 為何不要用 Azure Red Hat OpenShift 或 Azure Kubernetes Service?
技術上兩者皆可以, 但我這個服務是設計成獨立服務使用, 不需要使用到 Kubernetes API 或 Ingress 相關的能力, 所以不選 Azure Kubernetes Serivce 或 Azure Red Hat OpenShift. 另一個理由就是公司沒發給我這麼多額度可以用, 超過會直接封帳號...因為我 2023/12/31 被封了一次
Q2: 我沒有自己的 Domain Name, 還可以用這個做法嗎?
可以, Azure Container App 會提供給你 http://<projectname>.<我也不知道是什麼意思的域名>.<區域>.azurecontainerapps.io
的網址, 你可以直接用這個網址來使用你的 ChatGPT. 順便一提, 他有包含 SSL 憑證, 所以你的連線是安全的
倒是這年頭買一個自己的 Domain 很便宜呀, 找 Gandi 還是哪家買一個, 然後 nameserver 指到 Azure Public DNS 上, 大部分 Azure 服務有 Custom Domain 的能力, 有需要 TLS 的話, 都會順便幫你用 DigiCert 簽上去, 推薦買一個放上去或者是切一個 subdomain ns 指上去也可以
Q3: 我覺得 NextChatGPT 的通關密語太弱了, 有沒有更好的做法?
基於 Authentication and authorization in Azure Container Apps, 你可以掛 Microsoft Entra ID 的認證方式上去, 這樣就可以用公司的帳號密碼才能登入, 這樣就不用擔心密碼太弱的問題了
Q4: 如果我不用 NexChatGPT 這個專案, 想換成別的專案, 有什麼需要注意的地方嗎?
一般來說, 除了要先知道該專案是否有支援 Azure OpenAI 以外, 其次還會找看有沒有 docker-compose.yaml
可以看, 所有啟動所需要的資訊都會寫在裡面, 如 Environment Variables, port, volume 等, 再不行的話, 就是要分析 Dockerfile 和他的環境變數, 然後評估是不是有些變數過於敏感, 如 API Key 等, 需要放在 Azure Container App 的 Secret 或採用 Azure Key Vault 來存放, 提升安全性
Q5: 費用很貴嗎?
我用量不是很大的那種, 不是天天都在研究 OpenAI 的使用技術, 所以每個月整體用量很少, 如果你跟我有一樣的行為模式, 可以參考下面 2 個 2024/01 的實際費用, 以美金計價
Azure Container App
Azure OpenAI Service
文後廢言
過年來了, 這幾年的過年考題從 "女友呢?", "老婆在哪裡", "小朋友在哪裡?" 變成 "小朋友先有, 其他後面補沒關係 (疑?)", 真萬萬沒想到少子化問題已經高過一切了
因為報導者之前有出過一篇 【收養為何那麼難】一年半的等待、單身和年齡潛規則,收養層層關卡的情與理 的報導, 才發現收養這還真的是不容易
References
- ChatGPTNextWeb/ChatGPT-Next-Web
- Authentication and authorization in Azure Container Apps
- GitHub - ChatGPT