Databricks から Amazon Bedrock を使ってみた

# はじめに
株式会社NTTデータ [デザイン＆テクノロジーコンサルティング事業本部](https://enterprise-aiiot.nttdata.com/) の [nttd-saitouyun](https://qiita.com/nttd-saitouyun) です。

先月、Amazon Bedrock が東京リージョンでGAされ、AWS環境での生成AIの活用がより活発になっています。今回は、**Databricks から Amazon Bedrock を使用する方法をクイックに検証してみました。**


Amazon Bedrock については、以下の記事をご覧ください。

https://qiita.com/nttd-kashiwabaray/items/8ff6b84ad3570c36e8e6




# アーキテクチャ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118781/7d60c912-0873-3635-a269-5cbb55a901a3.png)

アーキテクチャは上記のようになります。
今回は**既存のDatabricksの環境から Amazon Bedrock への接続経路を新規に作りました。**
具体的なステップは以下のとおりです。

- Amazon Bedrock の設定（モデルアクセスの有効化や利用申請など）
- Databricks のデータプレーン用の VPC（※補足参照） に Amazon Bedrock 接続用のサブネットを作成
- 作ったサブネットに、Amazon Bedrock 用のエンドポイントを作成
- Databricks Cluster が作成されるサブネットからのルートやセキュリティグループの設定

### 補足：Databricks ワークスペースと対応するVPCの見つけ方
Databricks を使っていると、どのVPCがどのワークスペースに割り当てられているか分からなくなるケースがあります。その場合は、ワークスペースのURLの「?o=」以下の文字列でVPCを検索するとすぐに見つかります。

例：
ワークスペースURLが、`https://dbc-ab12c3de-45f.cloud.databricks.com/?o=1234567891234567#`の場合は`1234567891234567`がワークスペースIDに該当し、VPCの名前にこのIDが含まれているので検索すると見つけることができます。


# とりあえず、Databricks から Amazon Bedrock につないでみる

### 準備
Databricksクラスタにboto3はデフォルトでインストールされていますが、Amazon Bedrock に対応していないバージョンである可能性があるため、まずはアップグレードを行います。
```python
%pip install --upgrade boto3
dbutils.library.restartPython()
```

<br>

クライアントを作成します。今回は簡単な検証のため、アクセスキーとシークレットキーを使っています。
**商用で利用する場合は、Amazon Bedrock の最小権限を付与したIAMロールを作成し、クラスターに割り当ててください。**



```python
import json
import boto3

bedrock_runtime = boto3.client("bedrock-runtime", 
                               region_name="ap-northeast-1",
                               aws_access_key_id='XXXXXX', 
                               aws_secret_access_key='XXXXXX'
                               )
```
<br>

### Amazon Bedrock を使ってみる
今回は、データの概要を Amazon Bedrock を使って生成してみようと思います。

```python
# Databricksのサンプルデータを読み込み
taxi_df = spark.read.table("samples.nyctaxi.trips")

# データのスキーマを取得
df_schema = taxi_df.schema

# スキーマからテーブルの概要を質問するプロンプトを作成
prompt = f"""
Human: 次のスキーマ構造を持つテーブルの説明をしてください。
{df_schema}

Assistant:
"""
```

<br>
それでは、問い合わせしてみます。

```python
body = json.dumps(
 { 
  "prompt": prompt,
  "max_tokens_to_sample": 1000,
 }
)

# Amazon Bedrock に問い合わせ
res = bedrock_runtime.invoke_model(
    modelId="anthropic.claude-instant-v1",
    body=body,
    contentType="application/json",
    accept="application/json",
)

answer = res["body"].read().decode()
print(json.loads(answer)["completion"])
```

<br>
すると、以下のような回答が返ってきました。

>このスキーマはタクシー利用データのテーブルを表しています。
>
>- tpep_pickup_datetime: 乗車日時
>- tpep_dropoff_datetime: 降車日時  
>- trip_distance: 通常の走行距離(マイル)
>- fare_amount: 乗車料金の合計額
>- pickup_zip: 乗車地の郵便番号
>- dropoff_zip: 降車地の郵便番号
>
>主な属性はTimestampType()で表される日時属性と、DoubleType()の距離や料金、IntegerType()の郵便番号属性から構成されています。
>
>これは1件分のタクシー利用データ(1回の乗車)を表すレコードを1行として格納するテーブルのス>キーマだと考えられます。利用データの分析などに使用されるでしょう。
<br>
なかなか分かりやすくまとまってますね！

これをデータカタログのメタデータとして登録するところまで自動化すれば、一気にデータが見つけやすくなるのではないでしょうか。**データエンジニアリングやデータサイエンスも生成AIを活用して効率化する時代になってきましたね。**

<br>
<br>
それでは、本題です。

# English SDK for Apache Spark で Amazon Bedrock を活用する
OpenAI で English SDK for Apache Spark を使う記事はそこそこありますが、Amazon Bedrock を使ったパターンはほぼなかったので、やってみました！

### English SDK for Apache Spark とは？
Apache Spark によるデータ処理を「母国語」で行うことができるライブラリです。**Englishとありますが、日本語も使えます。**
プログラミングが苦手な方でも Apache Spark のデータ操作が簡単にできてしまいます。

６月末の [DATA + AI Summit 2023](https://www.databricks.com/dataaisummit/)のキーノートで「*The hottest new programming language is English*」という言葉とともに発表されたときは衝撃的でした！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118781/9903704a-aaf5-3fa7-9d9b-177c92ec405d.png)

詳しく知りたい方は以下もご覧ください。

- [English SDK for Apache Spark](https://pyspark.ai/)
- [Data + AI Summit Keynote, Thursday Part 2 - What's New with Apache Spark](https://www.youtube.com/watch?v=yj7XlTB1Jvc&t=622s
)


<br>

### English SDK for Apache Spark を Amazon Bedrock で動かす

### 準備
先ほどと同じですが、今回はEnglish SDK for Apache Spark（pyspark-ai）もインストールします。
```Python
%pip install pyspark-ai
%pip install --upgrade boto3
dbutils.library.restartPython()
```
<br>

こちらもほぼ同じです。
```Python
import boto3
from boto3.session import Session
from langchain.chat_models import BedrockChat

bedrock_runtime = boto3.client("bedrock-runtime", 
                               region_name="ap-northeast-1",
                               aws_access_key_id='XXXXXX', 
                               aws_secret_access_key='XXXXXX'
                               )

chat_model = BedrockChat(
    client=bedrock_runtime,
    model_id="anthropic.claude-instant-v1",
    model_kwargs={"temperature":0.0, "max_tokens_to_sample": 1000}
)
```
LangChain の`chat_model`オブジェクトを作成します。`model_id`の指定を変えると他のLLMも利用可能です。指定できる値は以下のページを参照してください。

https://docs.aws.amazon.com/bedrock/latest/userguide/model-ids-arns.html

<br>

English SDK for Apache Spark を使う準備をします。
```Python
from pyspark_ai import SparkAI

spark_ai = SparkAI(llm=chat_model)
spark_ai.activate()
```

### English SDK for Apache Spark を使って日本語でデータエンジニアリングを行う

いよいよ動かしてみます。
```Python
# サンプルデータを読み込み
taxi_df = spark.read.table("samples.nyctaxi.trips")

# LLMを使ってデータ処理
answer_df = spark_ai.transform_df(taxi_df, "いつからいつまでのデータがありますか？")
display(answer_df)
```

ふわっとした質問でしたが、以下の結果が得られました。乗車時間の最小と下車時間の最大を計算しているので合ってますね！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118781/748bfd3b-80ef-e163-d665-cfb796b95f2b.png)

<br>
<br>
続いて、もう少し細かい集計をしてみます。

```python
answer_df = spark_ai.transform_df(taxi_df, "乗車料金の合計を週ごとに計算してください。")
display(answer_df)
```

以下の結果となりました。計算できてますね。
ちなみに、English SDK for Apache Spark では自然言語から生成されたSQLも出力されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118781/139d415e-e8b2-6dbb-c0fc-25c62a128f0d.png)

さらに、可視化を行うこともできます。先ほどのデータを棒グラフにしてみます。

```python
answer_df.ai.plot("データを棒グラフにまとめてください。")
```

ちゃんとグラフ化されました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118781/8eea3344-e277-fc75-88a5-a66fa990cd4f.png)

<br>
<br>

プロンプトを詳細に記載すれば、細かい計算も可能です。

乗車時間という言葉は「車に乗った時間」と「車中に滞在した時間」の両方の意味があるため、LLMにうまく解釈がされませんでした（日本語難しい）。
以下のように計算手順を記載することで計算してくれました。
```python
answer_df = spark_ai.transform_df(taxi_df, "tpep_pickup_datetimeとtpep_dropoff_datetimeから乗車時間を分で計算したカラムを追加してください。")
display(answer_df)
```

結果は以下のとおりです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118781/93e9e934-f0b3-57ca-0208-778219b92b23.png)

続けて、乗車時間の最大と最小を見てみます。
```python
answer_df2 = spark_ai.transform_df(answer_df, "最大の乗車時間と最小の乗車時間を計算してください。")
display(answer_df2)
```

以下のようになりました。1分も乗らないこともあるんですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118781/340435de-00d0-97c4-37e1-6bf07ff3e5eb.png)

どのくらいの乗車時間が多いのか可視化してみます。
```python
answer_df.ai.plot("乗車時間を10分単位で集計し、ヒストグラムにまとめてください。")
```

指数関数的に数が減っていくきれいなグラフが書けました。わかりやすいですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118781/f08fd923-5624-bc2a-59c5-f646f69253d8.png)

<br>
<br>
という感じで、プログラミングをほぼせずにデータエンジニアリングしてみました。

グラフ化など想像していたより簡単にできて驚きました。**どのようなグラフにまとめようか試行錯誤する際には役に立ちそうです。**


一方で、プログラミングが不要な分、**プロンプトエンジニアリングに気を使わないといけないので別の難しさも感じました。** 使い分けが重要だと思います。



# おわりに
話題の Amazon Bedrock と Databricks を組み合わせて使ってみました。

Amazon Bedrock は、生成AIをAWS環境で閉域で簡単に利用できるサービスです。
**Amazon Bedrock で提供されている Anthropic の Claude は日本語でも高精度の回答を得られ、Databricks と組み合わせるとデータエンジニアリングやデータサイエンスが効率化できます。**

Claude 以外の LLM も Amazon Bedrock では提供されていますし、今後はOSSのLLMをファインチューニングして自社や業界特化のLLMを開発するケースも出てきます。そのため、**今後は複数のLLMを使い分けながら活用する時代になると思います。**

Databricks には、OpenAI、Amazon Bedrock、OSSから開発する特化型LLMなど、**複数のLLMを包括的に管理する機能もある**ので今後はそれらの機能検証も進めてみようと思います！


# 仲間募集
NTTデータ テクノロジーコンサルティング事業本部 では、以下の職種を募集しています。

<details><summary> 1. クラウド技術を活用したデータ分析プラットフォームの開発・構築(ITアーキテクト/クラウドエンジニア) </summary>
クラウド／プラットフォーム技術の知見に基づき、DWH、BI、ETL領域におけるソリューション開発を推進します。

https://enterprise-aiiot.nttdata.com/recruitment/career_sp/cloud_engineer

</details>

<details><summary> 2. データサイエンス領域（データサイエンティスト／データアナリスト） </summary>
データ活用／情報処理／AI／BI／統計学などの情報科学を活用し、よりデータサイエンスの観点から、データ分析プロジェクトのリーダーとしてお客様のDX／デジタルサクセスを推進します。

https://enterprise-aiiot.nttdata.com/recruitment/career_sp/datascientist

</details>

<details><summary> 3.お客様のAI活用の成功を推進するAIサクセスマネージャー </summary>
DataRobotをはじめとしたAIソリューションやサービスを使って、
お客様のAIプロジェクトを成功させ、ビジネス価値を創出するための活動を実施し、
お客様内でのAI活用を拡大、NTTデータが提供するAIソリューションの利用継続を推進していただく人材を募集しています。

https://nttdata.jposting.net/u/job.phtml?job_code=804

</details>

<details><summary> 4.DX／デジタルサクセスを推進するデータサイエンティスト《管理職/管理職候補》 </summary>
データ分析プロジェクトのリーダとして、正確な課題の把握、適切な評価指標の設定、分析計画策定や適切な分析手法や技術の評価・選定といったデータ活用の具現化、高度化を行い分析結果の見える化・お客様の納得感醸成を行うことで、ビジネス成果・価値を出すアクションへとつなげることができるデータサイエンティスト人材を募集しています。

https://nttdata.jposting.net/u/job.phtml?job_code=898

</details>

# ソリューション紹介
<details><summary> Trusted Data Foundationについて </summary>
～データ資産を分析活用するための環境をオールインワンで提供するソリューション～

https://enterprise-aiiot.nttdata.com/tdf/
最新のクラウド技術を採用して弊社が独自に設計したリファレンスアーキテクチャ（Datalake+DWH+AI/BI）を顧客要件に合わせてカスタマイズして提供します。
可視化、機械学習、DeepLearningなどデータ資産を分析活用するための環境がオールインワンで用意されており、これまでとは別次元の量と質のデータを用いてアジリティ高くDX推進を実現できます。

</details>

<details><summary> TDF-AM（Trusted Data Foundation - Analytics Managed Service）について </summary>
～データ活用基盤の段階的な拡張支援（Quick Start) と保守運用のマネジメント（Analytics Managed）をご提供することでお客様のDXを成功に導く、データ活用プラットフォームサービス～

https://enterprise-aiiot.nttdata.com/service/tdf/tdf_am
TDF-AMは、データ活用をQuickに始めることができ、データ活用の成熟度に応じて段階的に環境を拡張します。プラットフォームの保守運用はNTTデータが一括で実施し、お客様は成果創出に専念することが可能です。また、日々最新のテクノロジーをキャッチアップし、常に活用しやすい環境を提供します。なお、ご要望に応じて上流のコンサルティングフェーズからAI/BIなどのデータ活用支援に至るまで、End to Endで課題解決に向けて伴走することも可能です。

</details>

<details><summary> NTTデータとDatabricksについて </summary>
NTTデータは、お客様企業のデジタル変革・DXの成功に向けて、「databricks」のソリューションの提供に加え、情報活用戦略の立案から、AI技術の活用も含めたアナリティクス、分析基盤構築・運用、分析業務のアウトソースまで、ワンストップの支援を提供いたします。

 https://enterprise-aiiot.nttdata.com/service/databricks

</details>

</details>

<details><summary> NTTデータとSnowflakeについて </summary>
NTTデータでは、Snowflake Inc.とソリューションパートナー契約を締結し、クラウド・データプラットフォーム「Snowflake」の導入・構築、および活用支援を開始しています。
NTTデータではこれまでも、独自ノウハウに基づき、ビッグデータ・AIなど領域に係る市場競争力のあるさまざまなソリューションパートナーとともにエコシステムを形成し、お客さまのビジネス変革を導いてきました。
Snowflakeは、これら先端テクノロジーとのエコシステムの形成に強みがあり、NTTデータはこれらを組み合わせることでお客さまに最適なインテグレーションをご提供いたします。

https://enterprise-aiiot.nttdata.com/service/snowflake

</details>

</details>

<details><summary> NTTデータとInformaticaについて </summary>
データ連携や処理方式を専門領域として10年以上取り組んできたプロ集団であるNTTデータは、データマネジメント領域でグローバルでの高い評価を得ているInformatica社とパートナーシップを結び、サービス強化を推進しています。

https://enterprise-aiiot.nttdata.com/service/informatica

</details>

</details>

<details><summary> NTTデータとTableauについて </summary>
ビジュアル分析プラットフォームのTableauと2014年にパートナー契約を締結し、自社の経営ダッシュボード基盤への採用や独自のコンピテンシーセンターの設置などの取り組みを進めてきました。さらに2019年度にはSalesforceとワンストップでのサービスを提供開始するなど、積極的にビジネスを展開しています。

これまでPartner of the Year, Japanを4年連続で受賞しており、2021年にはアジア太平洋地域で最もビジネスに貢献したパートナーとして表彰されました。
また、2020年度からは、Tableauを活用したデータ活用促進のコンサルティングや導入サービスの他、AI活用やデータマネジメント整備など、お客さまの企業全体のデータ活用民主化を成功させるためのノウハウ・方法論を体系化した「デジタルサクセス」プログラムを提供開始しています。

https://enterprise-aiiot.nttdata.com/service/tableau

</details>

</details>

<details><summary> NTTデータとAlteryxについて </summary>
Alteryxは、業務ユーザーからIT部門まで誰でも使えるセルフサービス分析プラットフォームです。
Alteryx導入の豊富な実績を持つNTTデータは、最高位にあたるAlteryx Premiumパートナーとしてお客さまをご支援します。

導入時のプロフェッショナル支援など独自メニューを整備し、特定の業種によらない多くのお客さまに、Alteryxを活用したサービスの強化・拡充を提供します。

https://enterprise-aiiot.nttdata.com/service/alteryx

</details>

</details>

<details><summary> NTTデータとDataRobotについて </summary>
DataRobotは、包括的なAIライフサイクルプラットフォームです。
NTTデータはDataRobot社と戦略的資本業務提携を行い、経験豊富なデータサイエンティストがAI・データ活用を起点にお客様のビジネスにおける価値創出をご支援します。

https://enterprise-aiiot.nttdata.com/service/datarobot

</details>