Databricks Model Serving 연결
Unity Catalog에 등록하여 Databricks Model Serving에 배포한 표 모델을 Foundry 외부 모델로 연결합니다. Model Adapter Library에 어댑터를 게시하고 태그를 만든 뒤 모델 연결을 구성합니다. 예제의 기준 패키지는 Python 3.11.11, databricks-sdk 0.55.0과 pandas 2.2.3입니다.
여기서는 와인이 고품질인지 분류하는 모델을 사용합니다. 11개 원천 특성은 CSV에서 문자열로 읽고 is_red는 0.0 또는 1.0 수치로 추가한 학습 계약에 맞춥니다. 출력 predictions는 Boolean 분류 결과입니다. 다른 모델은 실제 배포한 모델의 입력 및 출력 시그니처로 바꿉니다.
클라이언트 설정
| 위치와 키 | 값 |
|---|---|
| Connection Configuration의 host | HTTPS를 포함한 Databricks 작업 공간 기본 URL입니다. 모델별 호출 경로는 붙이지 않습니다. |
| Connection Configuration의 serving_endpoint_name | 호출할 Model Serving 엔드포인트 이름입니다. |
| Credentials Configuration의 token | 해당 엔드포인트에 접근할 권한이 있는 Databricks 개인 액세스 토큰입니다. |
이 어댑터는 connection_config의 host와 serving_endpoint_name을 사용하며 Foundry 모델의 별도 URL 필드는 읽지 않습니다. 따라서 그 URL 필드는 비워 둘 수 있습니다. SDK가 작업 공간 주소와 엔드포인트 이름으로 요청 경로를 구성합니다.
표 모델 어댑터
각 입력 행을 dataframe_records로 전달합니다. 응답의 predictions만 출력 표로 만들므로 선택적인 served-model-name 메타데이터가 없어도 그 필드를 삭제하려다 실패하지 않습니다. 실제 예측 필드가 없으면 잘못된 응답을 빈 결과로 대체하지 않고 오류를 전달합니다.
import logging
import pandas as pd
import palantir_models as pm
from databricks.sdk import WorkspaceClient
logger = logging.getLogger(__name__)
class DatabricksExternalModelAdapter(pm.ExternalModelAdapter):
TEXT_FEATURES = [
"fixed_acidity", "volatile_acidity", "citric_acid", "residual_sugar",
"chlorides", "free_sulfur_dioxide", "total_sulfur_dioxide", "density",
"pH", "sulphates", "alcohol",
]
def __init__(self, host, serving_endpoint_name, creds):
self.serving_endpoint_name = serving_endpoint_name
self.client = WorkspaceClient(host=host, token=creds["token"])
@classmethod
def init_external(cls, external_context):
return cls(
host=external_context.connection_config["host"],
serving_endpoint_name=external_context.connection_config["serving_endpoint_name"],
creds=external_context.resolved_credentials,
)
@classmethod
def api(cls):
columns = [(name, str) for name in cls.TEXT_FEATURES] + [("is_red", float)]
return (
{"df_in": pm.Pandas(columns=columns)},
{"df_out": pm.Pandas(columns=[("predictions", bool)])},
)
def predict(self, df_in):
columns = self.TEXT_FEATURES + ["is_red"]
try:
response = self.client.serving_endpoints.query(
name=self.serving_endpoint_name,
dataframe_records=df_in[columns].to_dict(orient="records"),
)
except Exception as error:
logger.error("Model serving endpoint query failed: %s", type(error).__name__)
raise
return pd.DataFrame({"predictions": response.as_dict()["predictions"]})
입력은 표여야 하고 원격 엔드포인트는 행별 예측을 표로 변환할 수 있는 응답으로 반환해야 합니다. SDK 질의 오류는 로그를 남긴 뒤 원래 예외로 전달합니다.
송신 정책과 연결 저장
실제 Databricks 작업 공간 또는 사용자 정의 도메인의 443 포트를 허용합니다. AWS 작업 공간 주소는 workspace-name.cloud.databricks.com 같은 형태입니다.
외부 모델 연결에서 게시한 어댑터를 선택합니다.
Connection Configuration에 host와 serving_endpoint_name을 입력합니다.
Credentials Configuration의 token에 개인 액세스 토큰을 저장합니다. 이 토큰은 모델이 사용할 호출 권한을 가져야 합니다.
온라인 배포
Modeling Objective의 온라인 배포에서 모델을 질의할 수 있습니다. 모델 접근 권한을 가진 사용자는 저장한 토큰의 권한으로 추론합니다. Modeling Objective의 배치 배포 및 자동 평가는 지원하지 않습니다.
Python 변환
송신 정책을 구성한 경량 변환에서도 사용할 수 있습니다. 아래 정책 RID와 리소스 경로는 실제 값으로 바꿉니다. 어댑터 라이브러리와 transforms-external-systems를 저장소에 추가합니다. 예시 입력은 같은 값을 가진 두 행이며 실제 예측 결과를 작성합니다.
import pandas as pd
from transforms.api import Output, transform, lightweight
from palantir_models.transforms import ModelInput
from transforms.external.systems import EgressPolicy, use_external_systems
DATABRICKS_EGRESS_POLICY_RID = "YOUR_DATABRICKS_EGRESS_POLICY_RID"
@lightweight
@use_external_systems(egress=EgressPolicy(DATABRICKS_EGRESS_POLICY_RID))
@transform(
out=Output("/Models/data/databricks_predictions"),
model=ModelInput("/Models/external/wine_quality"),
)
def compute(egress, out, model):
row = {
"fixed_acidity": "7.4", "volatile_acidity": "0.7", "citric_acid": "0.0",
"residual_sugar": "1.9", "chlorides": "0.076", "free_sulfur_dioxide": "11",
"total_sulfur_dioxide": "34", "density": "0.9978", "pH": "3.51",
"sulphates": "0.56", "alcohol": "9.4", "is_red": 1.0,
}
df_in = pd.DataFrame([row, row.copy()])
out.write_pandas(model.predict(df_in))
CBAC 환경에서는 출력 데이터셋을 미리 만듭니다. 실제 Foundry 데이터를 전송하는 변환은 해당 데이터의 수출 제어 및 송신 승인 조건도 외부 모델의 변환 설정에 맞춰 적용합니다.