Databricks 端點讓你少猜
我拆 Databricks 自訂模型服務端點的權限、Registry、流量與部署模板,整理成可直接照抄的實作清單。

這篇把 Databricks 自訂模型服務端點的權限、Registry、流量與部署模板整理成可直接照抄的版本。
我用 Databricks 模型服務一陣子了,越用越覺得它不是不行,是很會把人搞到懷疑自己。端點建起來看起來很順,結果一更新就冒出 PERMISSION_DENIED;明明模型有掛上去,卻因為建立者身份、Unity Catalog 權限、還有那個會依模型所在位置變來變去的表單,整個流程卡得像老電腦。我本來以為這只是 UI 難用,後來才發現根本不是。它是在逼你把「誰建立、誰擁有、誰能更新」這三件事先講清楚,不然就等著踩雷。
這次我拆的是 Databricks 官方文件 Create custom model serving endpoints,搭配 Model Serving 總覽、權限說明,還有 Databricks Python SDK。文件本身有寫,但真正會害你出事的,通常不是功能,而是那些看起來像細節、其實是地雷的地方。官方沒給觀看數或星數,我就不亂掰了。
先別急著建端點,先搞清楚誰在背鍋
訂閱 AI 趨勢週報
每週精選模型發布、工具應用與深度分析,直送信箱。不定期,不騷擾。
不會寄垃圾信,隨時可取消。
當你建立端點時,Databricks 會把呼叫者身分記成端點建立者。這個身分通常是 service principal,之後會代表端點去存取 Unity Catalog 資源,而且建立後不能改。
白話就是:你以為你是在建一個端點,Databricks 其實是在記錄「這個端點以後算誰的」。這個人不是備註欄位,不是裝飾,是之後更新、查權限、碰 UC 資源時會被拿來驗證的身分。你如果用某個工程師的個人帳號去建,三天後他離開團隊,端點就會開始用最難看的方式提醒你:當初不該偷懶。

我之前就遇過一個很煩的案例。團隊趕著上線,直接用值班同仁的帳號把端點建起來,當下都正常。結果那位同仁調組後,某次更新直接炸掉,錯誤就是 PERMISSION_DENIED。那時候大家還以為是模型版本壞掉,查半天才發現是建立者身分已經不在 workspace 裡了。這種問題最討厭的地方不是難修,是它看起來像隨機故障。
實操寫法很簡單:建立端點時,優先用 service principal,不要拿人類帳號硬上。然後把這個 service principal 當成長期資產管理,確保它還留在 workspace、還有需要的權限、還能碰得到 Unity Catalog。要是你已經用錯身分建了,別幻想可以局部補救,官方的做法就是刪掉重建,讓正確的身分重新成為建立者。
- 建立端點的人,最好固定是 service principal。
- 這個身分要保留 workspace membership。
- 更新前先假設建立者權限會被重新檢查。
表單不是在問好玩,它是在分流你的模型來源
點進 Entity 欄位後,選取要服務的實體表單。依照模型註冊位置,選擇 My models - Unity Catalog 或 My models - Model Registry。表單會依你的選擇動態更新。
這段很容易被忽略,因為 UI 看起來像只是多問你一個選項,但它其實是在先問:你的模型到底放哪裡。放在 Unity Catalog,還是放在 Workspace Model Registry,後面整套路徑、權限、版本解析都不一樣。你如果心裡沒先定義清楚,後面就會一直在那邊猜,猜到最後只是在跟錯誤訊息對話。
我現在會把這件事當成第一個決策點,不是最後一步。原因很簡單,因為 Databricks 並不是用同一套邏輯處理兩種 Registry。Unity Catalog 要的是完整的 catalog.schema.model_name,workspace registry 則走另一條路。你如果把這兩個世界混在一起,端點看似建立成功,實際上只是把未來的自己推去撞牆。
實操寫法:先決定模型歸屬,再去填端點。模型在 Unity Catalog,就老老實實用完整名稱;模型在 Workspace Model Registry,就在 UI 選對來源,不要硬把兩邊的命名習慣混用。這不是格式潔癖,這是避免你之後在權限與版本上來回試錯。
- Unity Catalog 模型:用完整路徑
catalog.schema.model_name。 - Workspace Model Registry:先選對來源,再填版本。
- 建立前先確認你要的是哪一版模型,不要靠印象。
權限不是一次檢查完就沒事,它會在兩個時間點咬你
我覺得 Databricks 最值得記住的地方,就是它把權限分成兩種時機在檢查。第一種是建立或更新端點時,第二種是實際有流量打進來時。很多人只看前者,然後在 production 被後者補刀,還一頭霧水。

如果你服務的是 Unity Catalog 模型,建立者至少要有 USE CATALOG、USE SCHEMA、EXECUTE 這幾個權限。模型如果還依賴其他函式,連上游函式的 EXECUTE 也要一併有。少一個,建立或更新就可能直接失敗。這裡不是「最好有」,是「沒給就別想過」。
我以前最常看到的錯誤,就是大家只去補模型本身的權限,忘了 schema。結果 endpoint 建不過,還以為是 UI 壞掉。其實不是,Databricks 只是照規則檢查而已。只是這規則很不客氣,錯了就直接拒絕,不會幫你猜。
實操寫法:先做一份建立者權限清單,包含 catalog、schema、model、上游函式。你可以把它當成部署前檢查表,先確認再動手。然後記得,端點建立成功不代表萬事大吉,query-time 的權限還是可能在實際請求時失敗,所以要把「能建立」跟「能穩定服務」分開看。
- 先檢查建立者是不是 workspace 成員。
- 再檢查 UC 權限鏈。
- 建立成功後,還要另外測實際查詢。
流量分配跟併發,才是你真正要算的帳
Databricks 提供 traffic split 和 compute sizing,這其實就是在叫你別再憑感覺配資源。你可以把流量切到不同 served entity,也可以依照模型吞吐量去選擇併發規模。官方甚至直接丟了一個很實在的估算方式:併發數大概抓 QPS x model run time。
這句我很買單,因為它把很多人愛講的「先開小一點看看」直接打回去。你如果知道 QPS,知道單次推論時間,就可以開始算了,不用靠運氣。像一個請求 200 毫秒、每秒 20 個請求的模型,跟一個每次要 3 秒的模型,資源需求根本不是同一個量級。你不先算,最後就是 latency 跟成本一起爆。
實際上我看過不少團隊把 endpoint 開得很小,測試時都沒事,正式流量一進來就開始抖。問題不是模型不行,是你根本沒用真實負載去配。Databricks 有 Small、Medium、Large 這些範圍,API 和 SDK 也能設自訂併發;如果你要用自訂值,記得要是 4 的倍數,這種小規則不先記起來,就很容易卡在奇怪的地方。
實操寫法:先用觀察到的 QPS 和平均推論時間算出大概需要的併發,再選最小但不會卡住的配置。如果你要同時跑多個版本,就明確切 traffic split,不要把版本混成一團。要做自動化,就用 REST API 或 SDK,不要每次都靠 UI 手動改,久了只會漂移。
- Small:適合 0 到 4 個請求。
- Medium:適合 8 到 16 個請求。
- Large:適合 16 到 64 個請求。
Scale to zero 很省錢,但 production 會記恨你
官方對這件事講得很直接:scale to zero 不建議拿來做 production endpoint,因為冷啟動時不保證容量,流量回來時你會先吃到延遲。這不是理論問題,是使用者真的會感受到的問題。
我不反對 scale to zero,我自己也會拿來做 demo、測試環境,或那種偶爾才會被打到的端點。但如果這條端點是產品流程的一部分,我就不想賭。因為第一個請求慢,不只是慢而已,它會讓整個體驗看起來很不穩。你省下來的錢,常常是拿使用者耐心去換的。
實操寫法:低風險、低頻率的 workload 可以留著 scale to zero;正式上線、重視回應時間的路徑就關掉。你如果很在意首請求延遲,別省那點錢。這不是道德選擇,是成本跟體驗的取捨。
同一件事有四種入口,方便,但也很容易抄錯
Databricks 讓你可以用 Serving UI、REST API、MLflow Deployments SDK,或 Databricks Workspace Client SDK 來建立端點。這種彈性我承認很方便,但也很容易讓人把不同情境的範例混著抄,最後配置語法對不上。
我自己的做法是,正式自動化只選一條路走到底。UI 適合第一次摸、快速驗證;REST API 比較像基礎設施操作,配置明確;SDK 則適合 Python 腳本化部署。每條路都能做同一件事,但你最好只挑一條當主線,不然之後排查差異會很痛苦。
實操寫法:如果你要做 production,先決定團隊標準是 API 還是 SDK,然後把範例固化。不要今天 UI 建、明天 API 改、後天又手動補設定。那種做法短期看起來快,長期就是 config drift 的溫床。
- UI:適合人工檢查與快速試錯。
- REST API:適合明確可追蹤的部署設定。
- MLflow Deployments SDK / Workspace Client SDK:適合 Python 自動化。
GPU 不是勾一下就好,版本不對一樣白搭
如果你要走 GPU serving,Databricks 不是只給你一個勾選框而已,它還會看你套件版本合不合。官方列得很清楚:PyTorch 1.13.0 到 2.0.1、TensorFlow 2.5.0 到 2.13.0、MLflow 2.4.0 以上。版本不在範圍內,別幻想只是小問題。
這點我很有感,因為很多模型在本機或訓練環境跑得好好的,一搬到服務端就開始出現相依性問題。GPU endpoint 需要對應的 workload type,像 GPU_SMALL 這種設定也不是裝飾。你如果只看到 GPU 兩個字就衝,很容易在上線前才發現 runtime 不合。
實操寫法:先盤點模型使用的套件版本,再決定要不要上 GPU。版本在支援範圍邊緣的,先升級或固定版本,別邊跑邊賭。接著再把 workload type、workload size 一起設好,最後用真實請求把整條路測過一次,不要只驗 artifact 能不能載入。
我也順手把常用參考放這裡:MLflow Deployments、Databricks Workspace Client SDK、Model Serving 總覽、權限說明。這些連結我自己也會留著,因為單看一頁常常會漏掉上下文。
可抄的模板
# Databricks 自訂模型服務端點檢查表
## 建立前先確認
- 先決定模型是在 Unity Catalog,還是在 Workspace Model Registry。
- 端點建立者請固定用 service principal。
- 確認這個身分還在 workspace,且有 workspace-access entitlement。
- 如果是 Unity Catalog 模型,請先確認:
- catalog 上有 USE CATALOG
- schema 上有 USE SCHEMA
- model 上有 EXECUTE
- 若有上游函式,也要有 EXECUTE
## UI 建立流程
1. 打開 Databricks 側邊欄的 Serving。
2. 點 Create serving endpoint。
3. 輸入端點名稱。
4. 在 Entity 欄位選擇:
- My models - Unity Catalog,或
- My models - Model Registry
5. 選模型與版本。
6. 設定 traffic percentage。
7. 選 CPU 或 GPU compute。
8. 設定 compute scale-out:
- Small:0-4 requests
- Medium:8-16 requests
- Large:16-64 requests
9. 產品環境不要開 scale to zero。
10. 視需要加上:
- served entity 重新命名
- instance profile
- environment variables
- inference table logging
11. 需要多版本就再加 served entities。
12. 流量高就開 route optimization。
13. 需要的話再配 AI Gateway。
14. 按 Create。
## REST API 範例
POST /api/2.0/serving-endpoints
{
"name": "uc-model-endpoint",
"config": {
"served_entities": [
{
"name": "ads-entity",
"entity_name": "catalog.schema.my-ads-model",
"entity_version": "3",
"min_provisioned_concurrency": 4,
"max_provisioned_concurrency": 12,
"scale_to_zero_enabled": false
}
]
}
}
## MLflow Deployments 範例
import mlflow
from mlflow.deployments import get_deploy_client
mlflow.set_registry_uri("databricks-uc")
client = get_deploy_client("databricks")
endpoint = client.create_endpoint(
name="unity-catalog-model-endpoint",
config={
"served_entities": [
{
"name": "ads-entity",
"entity_name": "catalog.schema.my-ads-model",
"entity_version": "3",
"min_provisioned_concurrency": 4,
"max_provisioned_concurrency": 12,
"scale_to_zero_enabled": False,
}
]
},
)
## Workspace Client SDK 範例
from databricks.sdk import WorkspaceClient
from databricks.sdk.service.serving import EndpointCoreConfigInput, ServedEntityInput
w = WorkspaceClient()
w.serving_endpoints.create(
name="uc-model-endpoint",
config=EndpointCoreConfigInput(
served_entities=[
ServedEntityInput(
name="ads-entity",
entity_name="catalog.schema.my-ads-model",
entity_version="3",
workload_size="Small",
scale_to_zero_enabled=False,
)
]
),
)
## GPU 端點範例
POST /api/2.0/serving-endpoints
{
"name": "gpu-model-endpoint",
"config": {
"served_entities": [
{
"entity_name": "catalog.schema.my-gpu-model",
"entity_version": "1",
"workload_type": "GPU_SMALL",
"workload_size": "Small",
"scale_to_zero_enabled": false
}
]
}
}
## 營運規則
- 同一個團隊盡量固定一條部署路徑。
- 端點建立者身分要穩定。
- 若建立者失去 workspace membership,更新很可能失敗。
- scale to zero 當成成本選項,不要當 production 預設。
- 每次改端點設定,都重查權限。
- 建立成功不代表查詢一定成功,查詢權限要另外測。這份模板就是我把官方文件拆完後,留下來真的能用的版本。你可以直接拿去當部署前檢查表,至少不會再把「誰建立的」和「誰能更新」這兩件事搞混。
來源主要來自 Databricks 官方文件 Create custom model serving endpoints。我這篇的重點整理、風險提醒、與可抄模板是我自己重新整理的,原始規則與介面說明則以官方文件為準。