DatabricksマーケットプレイスからWhisper V3 Modelを試してみる

久々にマーケットプレイスを覗いたらモデルが増えてました。Whisper V3 Modelとな。

https://marketplace.databricks.com/details/1eceaa77-6b60-42f0-9809-ceccf1b237f5/Databricks_Whisper-V3-Model

音声テキスト変換のモデルなんですね。

https://huggingface.co/openai/whisper-large-v3

# モデルとノートブックの取得

![Screenshot 2023-12-12 at 11.41.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/f2dd3b9f-28cd-26f0-41ca-1fdd356d36fe.png)

**即時アクセス権を取得**をクリックして、**その他のオプション**を展開します。モデルは新規の共有カタログ配下に格納されるので、カタログ名を変更します。
![Screenshot 2023-12-12 at 11.41.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/9cb2d4cc-4d0e-5f42-0e65-b9934115d77d.png)
![Screenshot 2023-12-12 at 11.45.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/9d0bb657-aee3-d0b2-342a-be3cd12cf5fc.png)

カタログエクスプローラでモデルにアクセスできます。
![Screenshot 2023-12-12 at 11.46.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/02a82877-4bb0-1c77-0efd-ed62e75ff396.png)

サンプルノートブックもインポートします。
![Screenshot 2023-12-12 at 11.43.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/15b60ee9-5972-1283-b8cf-ce2c797f3831.png)

# ノートブックのウォークスルー

ノートブックの実行自体はCPUクラスターで問題ありません。Databricks SDKをインストールします。

```py
# Upgrade to use the newest Databricks SDK
%pip install --upgrade databricks-sdk
dbutils.library.restartPython()
```

```py
# Select the model from the dropdown list
model_names = ['whisper_large_v3']
dbutils.widgets.dropdown("model_name", model_names[0], model_names)
```

カタログ名は上で設定したものに変更します。必要に応じてモデルサービングエンドポイント名を変更します。
```py
# Default catalog name when installing the model from Databricks Marketplace.
# Replace with the name of the catalog containing this model
# You can also specify a different model version to load for inference
catalog_name = "databricks_whisper_v3_model_taka"
version = "1"
model_name = dbutils.widgets.get("model_name")
model_uc_path = f"{catalog_name}.models.{model_name}"
endpoint_name = f'{model_name}_marketplace_taka'
```

モデルのサービングにはGPUが必要となります。

```py
# Choose the right workload types based on the model size
workload_type = "GPU_MEDIUM"
```

SDKでモデルサービングエンドポイントをデプロイします。30分くらいかかります。

```py
import datetime

from databricks.sdk import WorkspaceClient
from databricks.sdk.service.serving import EndpointCoreConfigInput
w = WorkspaceClient()

config = EndpointCoreConfigInput.from_dict({
    "served_models": [
        {
            "name": endpoint_name,
            "model_name": model_uc_path,
            "model_version": version,
            "workload_type": workload_type,
            "workload_size": "Small",
            "scale_to_zero_enabled": "False",
        }
    ]
})
model_details = w.serving_endpoints.create(name=endpoint_name, config=config)
model_details.result(timeout=datetime.timedelta(minutes=30))
```

![Screenshot 2023-12-12 at 13.27.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/6cb963a5-0360-5ac2-56ba-53a0ff80a27f.png)


音声ファイル自体にはこちらからアクセスできます。

https://huggingface.co/datasets/Nexdata/accented_english

2つの音声ファイルがあります。聞いてみるとバイデン首相に関するニュース記事のようです。

データセットとしてロードしてモデルサービングエンドポイントにリクエストします。
```py
from datasets import load_dataset
import pandas as pd
import base64
import json

from databricks.sdk import WorkspaceClient

dataset = load_dataset("Nexdata/accented_english", split="train")
sample_path = dataset[0]["audio"]["path"]

# Change it to your own input file name
with open(sample_path, 'rb') as audio_file:
    audio_bytes = audio_file.read()
    audio_b64 = base64.b64encode(audio_bytes).decode('ascii')

dataframe_records = [audio_b64]

w = WorkspaceClient()
response = w.serving_endpoints.query(
    name=endpoint_name,
    dataframe_records=dataframe_records,
)
print(response.predictions)
```

```py
["The news forced the state to move immediately from planning the site's operational processes to building software, Baden said."]
```

(私の英語力では)合っています。

SparkのUDF(ユーザー定義関数)でモデルをラッピングすることで、バッチ推論で活用する小tゴアできます。

```py
import mlflow
mlflow.set_registry_uri("databricks-uc")

catalog_name = "databricks_whisper_v3_models_taka"
transcribe = mlflow.pyfunc.spark_udf(spark, f"models:/{model_uc_path}/{version}", "string")
```

```py
import pandas as pd
from datasets import load_dataset
import base64
import json

dataset = load_dataset("Nexdata/accented_english", split="train")
sample_path = dataset[0]["audio"]["path"]

with open(sample_path, 'rb') as audio_file:
    audio_bytes = audio_file.read()
    dataset = pd.DataFrame(pd.Series([audio_bytes]))

df = spark.createDataFrame(dataset)

# You can use the UDF directly on a text column
transcribed_df = df.select(transcribe(df["0"]).alias('transcription'))

display(transcribed_df)
```

データフレームに格納されている音声データからテキストに起こしてくれます。
![Screenshot 2023-12-12 at 13.24.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/6920f80c-55f4-fe2e-2eff-193262d21b82.png)

複数行であっても同じように処理してくれます。

```py
dataset = load_dataset("Nexdata/accented_english", split="train")

sample_path_1 = dataset[0]["audio"]["path"]
sample_path_2 = dataset[1]["audio"]["path"]

with open(sample_path_1, 'rb') as audio_file_1:
    audio_bytes_1 = audio_file_1.read()

with open(sample_path_2, 'rb') as audio_file_2:
    audio_bytes_2 = audio_file_2.read()

dataset = pd.DataFrame(pd.Series([audio_bytes_1, audio_bytes_2]))

df = spark.createDataFrame(dataset)

# You can use the UDF directly on a text column
transcribed_df = df.select(transcribe(df["0"]).alias('transcription'))

display(transcribed_df)
```

これはこれで夢が広がりますね。
![Screenshot 2023-12-12 at 13.25.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/18a6346c-1c10-8585-da18-2fe096d1761d.png)


### Databricksクイックスタートガイド

[Databricksクイックスタートガイド](https://www.amazon.co.jp/dp/B09V1YXFVQ/)


### Databricks無料トライアル

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