【AWS】Amazon BedrockのモデルをJupyter Notebook + VSCodeで呼び出す

## はじめに
**Amazon Bedrock**とは、生成AIの基盤モデルが利用できる、AWSのサービスです。

本記事では、VSCodeを用いて、[Jupyter Notebook](https://jupyter.org/)でBedrockが提供するLLMを呼び出します。
割と初心者向けです。

### 前提条件
- AWSのアカウントを作成済み
- 以下がインストール済み
    - AWS CLI
    - python 3系
    - VSCode

:::note warn
Bedrockによる生成AIの利用には、料金が発生します。詳しくは[こちら](https://aws.amazon.com/jp/bedrock/pricing/)。
:::

## 1. IAMユーザーに許可を追加
本記事の手順を行うために、Bedrockへのアクセス権限を持ったIAMユーザーが必要です。

AWSマネジメントコンソールなどで、任意のIAMユーザーに`AmazonBedrockFullAccess`というポリシーをアタッチします。（ユーザーがない場合は作成して下さい。）

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3946195/7bae6290-cce4-4fde-8407-e3f9ca21cb8b.png" width="600">


## 2. AWSの認証情報を設定
IAMユーザーの認証情報を、ローカルの環境に設定します。既に設定済みの場合は[3.](#3.-基盤モデルへのアクセスを有効化)の手順へ。

まず、IAMユーザーの**アクセスキー**を作成します。
- ユーザー詳細ページから作成可能です
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3946195/656ff073-18c2-493d-9428-bd546824b9e7.png" width="600">

    :::note warn
    シークレットアクセスキーは**最後のステップの確認画面でしか取得できません**。どこかにメモしておきましょう。

次に、以下のコマンドで認証情報を設定します。
```
aws configure
```
- [公式ドキュメント](https://docs.aws.amazon.com/ja_jp/cli/v1/userguide/cli-configure-files.html#cli-configure-files-methods)にあるように、ダイアログで先程作成したアクセスキーの値を入力します
    - リージョンや出力フォーマットの設定値はお好みでどうぞ
- `--profile`オプションでプロファイル名を指定して設定できます（指定しない場合は`default`）
- 設定ファイルが、`~/.aws/`または`C:\Users\USERNAME\.aws\`フォルダ内に作成されます

## 3. 基盤モデルへのアクセスを有効化
Bedrockでは、使用するモデルへのアクセスを予め有効化しておく必要があります。

1. マネジメントコンソールの「_Amazon Bedrock_」を開く[^1]
1. サイドメニューから「_モデルアクセス_」を選択
1. 「_特定のモデルを有効にする_」ボタンを押す
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3946195/40cdb62f-3f35-4260-921f-a52429947d62.png" width="600">
1. 有効化したいモデルにチェックを入れて、ページ下部の「_次へ_」ボタンを押す
    - 今回はAmazonの<strong>"Titan Text G1 - Express"</strong>を選択します[^2]
        <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3946195/3c46c1a2-fb3f-4a1a-ac1f-68829f979ad9.png" width="600">

    :::note warn
    リージョンによって選択できるモデルの種類が異なります
        :::
1. 確認画面で「_送信_」ボタンを押す

送信されたリクエストが通ると、モデルの「_アクセスのステータス_」が「_アクセスが付与されました_」になり、有効化が確認できます。

[^1]: 基盤モデルへのアクセスの変更は、マネジメントコンソール上でのみ可能（[参考](https://docs.aws.amazon.com/ja_jp/bedrock/latest/userguide/model-access.html?icmpid=docs_bedrock_help_panel_model_access)）
[^2]: Amazon Titanシリーズのモデルのアクセスは、一度許可すると**取り消しできません**
    (アクセス許可を削除するタイミングはないとは思いますが)

## 4. 実行ファイルの作成と環境構築
では、コードを実装するJupyter Notebookファイルの作成と、実行に必要な環境の設定をVSCodeで行います。

### ファイルの作成
適当なフォルダの配下に、Notebookファイルを作成します。
```
mkdir bedrock
cd bedrock
touch sample.ipynb
```
上記のフォルダをVSCodeで開きます。

### VSCodeの拡張機能のインストール
必要なVSCodeの拡張機能をインストールしましょう。

1. [Jupyter](https://marketplace.visualstudio.com/items?itemName=ms-toolsai.jupyter)
1. [Python](https://marketplace.visualstudio.com/items?itemName=ms-python.python)

以下の表示になるはずです。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3946195/59a5fb7d-2e9a-497a-bcd5-4cb0e7d0d2a5.png" width="600">

### 仮想環境の作成
Jupyter Notebookのコードを実行するには、**Jupyterカーネル**が必要です。今回は、現在のワークスペースにPythonの仮想環境を作成し、それをカーネルとして選択します。

1. Notebookファイルの右上にある「_カーネルの選択_」を押す
1. 表示されたポップアップで、次のように選択する
    - 「_Python環境_」>「_+ Python 環境の作成_」>「_Venv_」
        <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3946195/7f0a5da9-f3ee-48f2-ac61-abe5daa92e20.png" width="600">
1. すると、ローカルにインストールされているPythonの一覧が表示されるので、使用するバージョンのPythonを選択する

以上の手順が終わると、ワークスペースの中に`.venv`フォルダが作成され、その仮想環境がNotebookファイルのカーネルとして選択されています。
この方法ではワークスペースごとに仮想環境が用意されるため、プロジェクトごとに環境を分けることができます。

これで、Jupyter Notebookファイルを実行する準備が整いました。

## 5. LLMモデルを呼び出すコードの実装
上記手順で作成したNotebookファイルに、SDKを用いてBedrockのLLMを呼び出すコードを実装していきます。

まず、最初のセルを追加してSDK用のライブラリをインストールします。
```python:sample.ipynb
%pip install boto3
```

以下のコードで、BedrockのAPIを呼び出す用のクライアントを作成します。
```python:sample.ipynb
import boto3

bedrock_client = boto3.client('bedrock-runtime')
```
実行すると、AWSのデフォルトのプロファイルのリージョン設定が読み込まれます。

:::note warn
設定に失敗していると、`NoRegionError`もしくは、`InvalidRegionError`になります
:::

<details><summary><strong>デフォルト以外のプロファイル</strong>を指定したい場合</summary>

環境変数`AWS_PROFILE`に、プロファイル名を設定する必要があります。
Notebookファイルに環境変数を設定するには、pythonライブラリの[python-dotenv](https://pypi.org/project/python-dotenv/)を使うのが良いでしょう。

1. `.env`ファイルをルートフォルダに作成
    ```:.env
    AWS_PROFILE=your-profile    
    ```
    &#13;&#10;

1. Notebookファイルでライブラリのインストール
    ```python:sample.ipynb
    %pip install python-dotenv
    ```
    &#13;&#10;

1. コード内で`.env`ファイルを読み込む
    ```python:sample.ipynb
    import os
    
    %load_ext dotenv
    %dotenv

    # 環境変数を表示
    print(os.environ.get('AWS_PROFILE'))
    ```
    &#13;&#10;

1. 上記コードの後にクライアントを作成すれば、自動的に環境変数が読まれ、指定したプロファイルの情報が利用される

:::note
もちろん、セル内で直接環境変数を指定してもよい
:::

---
</details>

続いて、以下がBedrockのモデルの呼び出しに必要な引数の設定です。`input_text`がLLMに送られるユーザーの入力になります。
```python:sample.ipynb
import json

input_text = """
    AWSのSDKとは何ですか？
"""

body = json.dumps({
    "inputText": input_text, 
    "textGenerationConfig": {
        "maxTokenCount": 8192,
        "stopSequences": [],
        "temperature": 0,
        "topP": 1
    }
})

modelId = 'amazon.titan-text-express-v1'
accept = 'application/json'
contentType = 'application/json'
```

そして、`invoke_model`メソッドを用いてモデルに回答を生成させましょう。
```python:sample.ipynb
response = bedrock_client.invoke_model(
    body = body,
    modelId = modelId,
    accept = accept,
    contentType = contentType
)
```
AWSの認証情報の設定が間違っていると、上のコードの実行が失敗します。

成功したら、LLMモデルが生成した回答を表示してみましょう。
```python:sample.ipynb
response_body = json.loads(response.get('body').read())
outputText = response_body.get('results')[0].get('outputText')

print(outputText)
```
```:結果
AWSのSDKとは、AWSのサービスを簡単に利用できるようにするためのソフトウェア開発キットです。AWSのSDKには、さまざまな言語に対応したライブラリやツールが含まれており、これらのライブラリやツールを使用することで、AWSのサービスを簡単に利用することができます。AWSのSDKは、AWSのサービスをより効率的に利用するために開発されたものであり、開発者にとって非常に便利なツールです。
```

Bedrockのモデルを呼び出すことができました。

## おわり
本記事では、VSCodeを使ってJupyter Notebookの環境を作成し、Bedrockのモデルを呼び出すコードを実行してみました。
ぜひ入力する質問を変えてみたりして、生成AIで遊んでみて下さい。

## 参考リンク

https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-authentication-user.html

https://zenn.dev/oyamiya/articles/data-science-tips-jupyter