Databricksのサーバレスリアルタイム推論エンドポイントを使ってみる

Databricksでは前から[REST API経由で機械学習モデルを呼び出すことができるエンドポイント](https://qiita.com/taka_yayoi/items/b5a5f83beb4c532cf921)をサポートしていましたが、最近ではタイトルにある[サーバレスリアルタイム推論](https://qiita.com/taka_yayoi/items/32266655075795f5ab65)エンドポイント(serverless real time inference endpoint)をサポートする様になりました(パブリックプレビュー中です)。

サーバレスリアルタイム推論エンドポイントは、プロダクション用途を意図しており、秒間3000クエリー(QPS)までをサポートすることができます。サーバレスリアルタイム推論エンドポイントは、自動でスケールアップ・ダウンするので、エンドポイントはスコアリングのリクエストのボリュームに応じて自動で調整することを意味します。リクエストがない際にはノード数を0にまでスケールダウンすることも可能です。

# サーバレスリアルタイム推論エンドポイントの起動

ここでは、[ワイン品質予測モデル](https://qiita.com/taka_yayoi/items/f48ccd35e0452611d81b)をエンドポイントにデプロイします。

1. サービングタブをクリックします。
![Screen Shot 2022-11-17 at 16.10.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/24f23ee2-b123-b3b4-6df1-b872df7b479a.png)

1. 有効化ボタンをクリックします。従来のエンドポイントを使うには`クラシックタイプのモデルサービングも引き続き使用できます。有効にするには、こちらのリンクをクリックしてください。`のリンクをクリックします。
![Screen Shot 2022-11-17 at 16.13.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/554daacb-14bb-1e60-f45b-5666325a6069.png)

1. 少し待つとエンドポイントが起動し、モデルのデプロイがスタートします。
![Screen Shot 2022-11-17 at 16.28.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/609874b1-a09d-919b-7787-40788202384f.png)

1. モデルが**準備完了**となれば、エンドポイントからモデルを呼び出すことができます。
![Screen Shot 2022-11-17 at 16.31.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/fecf433d-ec52-2501-cea5-253efa21d064.png)


1. なお、上の**Compute Setting**でエンドポイントの計算リソースを設定することができます。**ゼロにスケーリング**をチェックすると、エンドポイントが使用されていない場合はノード数がゼロにまでスケールダウンします。
![Screen Shot 2022-11-17 at 16.28.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/a3d85c19-e60b-2b8a-7f80-93db7f7d68e9.png)

# エンドポイントの呼び出し

以下の様な関数を準備してエンドポイントにアクセスできる様にします。ここで注意しなくてはならないのは、関数`process_input`です。MLflow 2.0になってエンドポイントへの[リクエストフォーマットが変更](https://mlflow.org/docs/latest/models.html#deploy-mlflow-models)されています。旧来のMLflowを使う様に設定(Conda環境にMLflowのバージョンを指定)するか、フォーマットを変更する必要があります。この関数はMLflow 2.0にリクエストする際に必要なフォーマットにデータフレームを変換しています。

```py:Python
import os
import requests
import numpy as np
import pandas as pd

def create_tf_serving_json(data):
  return {'inputs': {name: data[name].tolist() for name in data.keys()} if isinstance(data, dict) else data.tolist()}

def process_input(dataset):
  if isinstance(dataset, pd.DataFrame):
    return {"dataframe_split": dataset.to_dict(orient='split') }
  elif isinstance(dataset, str):
    return dataset
  else:
    return create_tf_serving_json(dataset)

def score_model(dataset):
  
  #print(dataset)
  url = 'https://<エンドポイントのURL>'
  headers = {'Authorization': f'Bearer {os.environ.get("DATABRICKS_TOKEN")}'}
  data_json = process_input(dataset)
  
  print(data_json)
  
  response = requests.request(method='POST', headers=headers, url=url, json=data_json)
  if response.status_code != 200:
    raise Exception(f'Request failed with status {response.status_code}, {response.text}')
  return response.json()
```

- `https://<エンドポイントのURL>`はお使いのモデルに割り振られるURLで置き換える必要があります。
- `os.environ["DATABRICKS_TOKEN"]`には、以下の様なコードを用いてパーソナルアクセストークンを設定します。

```py:Python
import os

# 事前にCLIでシークレットにトークンを登録しておきます
token = dbutils.secrets.get("demo-token-takaaki.yayoi", "token")

os.environ["DATABRICKS_TOKEN"] = token
```

以下の様にデータを準備してエンドポイントを呼び出してスコアリングを行います。

```py:Python
# モデルサービングは、比較的小さいデータバッチにおいて低レーテンシーで予測するように設計されています。
num_predictions = 5
served_predictions = score_model(X_test[:num_predictions])
model_evaluations = model.predict(X_test[:num_predictions])

# トレーニングしたモデルとデプロイされたモデルの結果を比較します。
df1 = pd.DataFrame(model_evaluations)
df2 = pd.DataFrame(served_predictions)

df1.rename(columns={0: "Model Prediction"}, inplace=True)
df2.rename(columns={"predictions": "Served Model Prediction"}, inplace=True)

pd.concat([df1, df2], axis=1)
```
エンドポイントから結果が返されていることがわかります。
![Screen Shot 2022-11-17 at 16.42.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/0c665849-29fa-e038-674d-0bf99dba6ce6.png)

また、エンドポイントの画面にはモニタリングのためのメトリクスが表示されます。
![Screen Shot 2022-11-17 at 16.43.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/86be4657-9032-f550-1d99-e9818a260e8e.png)
![Screen Shot 2022-11-17 at 16.43.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/31252d30-c0a0-bcdf-5e09-051d711e4d7d.png)
![Screen Shot 2022-11-17 at 16.43.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/a30cd3fa-7636-f15b-48ae-4a651eb87393.png)

プロダクション用途でも活用できるサーバレスリアルタイム推論エンドポイント、ぜひ試してみてください！

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)