Llama-2-13b-chatをAmazon Bedrockで使う

2023/11/13にAmazon Bedrockで「Llama-2-13b-chat」が利用可能になりましたね!

https://aws.amazon.com/jp/about-aws/whats-new/2023/11/llama-2-chat-13b-model-meta-amazon-bedrock/

「US East (N. Virginia)」「US West (Oregon)」で利用可能とあり、残念ながら東京リージョンは入っていないようです。

以下のページ(英語で見てください、日本語にすると「近日公開予定」になってしまいます)も書き換わっています。70Bが「comming soon」とあり、楽しみです。

https://aws.amazon.com/bedrock/llama-2/?nc1=h_ls

ローカルPCでLlama-2-13b-chatなどのLLMを動かしていたときは、VRAMの関係でGGUF版しか動かせなかったため、やっとLlama-2-13b-chatの本気が見れそうです。

そんなこんなでAmazon BedrockでLlama-2-13b-chatを動かしてみた、です。

Llama-2-13b-chatを有効化する

バージニア北部リージョンでアクセスできるように(ここでは「有効化」と呼びます)します。

Amazon Bedrockにアクセスし、ナビゲーションメニューから「Model access」開きます。

「Manage model access」ボタンを押すとチェックボックスが表示されます。

「Llama 2 Chat 13B」を選択し、「Request model access」をボタンを押します。

押した直後は、「in Progress」状態になります。

「Claude Instant」を有効化した時の同じくらいの待ち時間(3分程度)で「Access granted」になりました。基盤モデル毎に違いはあまりないようですね。

このタイミングでは、まだ課金されません。基盤モデルにプロンプトを投げたらスタートです。

そういえば、「Claude Instant」を有効化する時には利用目的などを書いたので、Llama-2-13b-chatの手続きは非常に簡単でした。「Claude Instant」だけ特殊だったのかな?

playgroundによる試し実行

Chat

ナビゲーションメニューから[playground] – [Chat]を選択し、「Meta」と「Llama 2 Chat 13B」を選びます。

画面下部にあるチャット入力欄にプロンプトを入力し、「Run」ボタン押下でチャット開始です。

そして、恒例のOne-Shotプロンプトを。

応答はStreaming出力(文字が少しずつ表示)され、高速応答でした。ChatGPT 3.5と同じくらいかな。

ただ、「?」のような置き換え文字が出ており、一部読めない箇所がありました。5回同じプロンプトを実行しましたが、4回とも同じ事象(起きなかった1回は全部英語で出力)でした。日本語ではかなりの高確率で発生します。

では、英語にしてみると、

置き換え文字はでません。こちらも5回実行してみましたが発生しませんでした。日本語などのマルチバイト文字起因で発生するようです。

ナビゲーションメニューから「Providers」を開き、Llama-2-13B-Chatの情報を見ると、「English」とだけあるので、英語での動作しか保証していないのかも。本家と同じですね。。

置き換え文字は「Streaming」が悪さをしている

「Streaming」のチェックを外して実行した場合、置き換え文字は出力されませんでした。

5回実行して全て問題なしでした。1回は英語混じりでしたが。

Streaming処理にバグがあるのか、Llama-2-13b-chatが変な位置で切れたチャンクを返してくるのか。日本語出力ありの場合には、Streamingは今のところは使わない方がよさそうです

システムプロンプトをどこで打つ?

Llama系はシステムプロンプトによって応答の精度が大きく変わります。しかし、Chat画面には入力欄は見当たりませんでした。

試しに、下記のプロンプト(システムプロンプト入り)をチャットに入力してみました。

[INST] <<SYS>>
You are Assistant, a helpful, respectful, honest and highly intelligent assistant
<</SYS>>
日本で最も標高が高い山の名前を教えてください[/INST]

結果は以下の通り。

応答が変わりました。「Konnichiwa!」や先頭の文が特徴的です。先のシステムプロンプトだとこの文言がよく出てくるので、システムプロンプトとして認識されている気がします。

日本語で出したいな

何度やっても英語で出てくるので、日本語にしてとシステムプロンプトに書いてみます。

[INST] <<SYS>>
あなたはアシスタントであり、親切で、尊敬に値する、正直で、非常に知的なアシスタントです。私は日本人で英語を全く読むことができないため、必ず回答を日本語で返してください。日本語で返すことは非常に重要なタスクです。
<</SYS>>
日本で最も標高が高い山の名前を教えてください[/INST]

結果は以下の通り。

完全勝利UC!!と思いきや、英語混じりでした。その後、何度か実行するも英語の頻度が高いです。

じゃあ、ということで翻訳をChatでお願いしてみましたが、余計な言葉が随所に入るので実用的ではなさそうです。

応答を確実に日本語にしたければ、「Claude2」「Claude Instant」のようなマルチ言語タイプのLLMを使った方がよいでしょう。

Text

TextだとAPIに投げている様子が見えるので、システムプロンプト入りで投げてみました。

「View Request API」ボタンを押してAPIを確認します。

aws bedrock-runtime invoke-model \
--model-id meta.llama2-13b-chat-v1 \
--body "{\"prompt\":\"[INST] <<SYS>>\\nあなたはアシスタントであり、親切で、尊敬に値する、正直で、非常に知的なアシスタントです。私は日本人で英語を全く読むことができないため、必ず回答を日本語で返してください。日本語で返すことは非常に重要なタスクです。\\n<</SYS>>\\n日本で最も標高が高い山の名前を教えてください[/INST]\",\"max_gen_len\":512,\"temperature\":0.5,\"top_p\":0.9}" \
--cli-binary-format raw-in-base64-out \
--region us-east-1 \
invoke-model-output.txt

ちゃんと、システムプロンプト付きで投げてくれているようです。

応答が英語になること、「Streaming」がONの時に置換文字が出てくるのは「Chat」と同じでした。

チューニングできる設定が少ない

「Claude Instant」と比べて、チューニングできる設定が少ない(Top K、Stop sequencesがない)ようです。

APIによるアクセスのための準備

ローカルPC(WSL2なしのWindowsネイティブ)で実行します。

IAMユーザ、IAMポリシー、アクセスキー、プロファイル名は、下記の「Cloude2 Instant」をAmazon Bedrock経由で使った時と同じものを使用しました。

AWS CLI更新

使えるかどうか確認せずにAWS CLIを更新しました(条件反射でつい)。
そのため更新せずに利用可能だったかどうかは不明です。ただし、過去に一度もAmazon Bedrockを使ったことがなければ、AWS CLIを更新します。

インストーラー(AWSCLIV2.msi)をダウンロードしてインストールします。https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html

モデル一覧を取得

利用可能なモデル一覧をAWS CLIで取得します。
コマンドライン中の「bedrock_prof」はプロファイル名として私が設定したものです。適当に読み替えてください。

> aws --profile bedrock_prof --region us-east-1 bedrock list-foundation-models
{
    "modelSummaries": [
        ・・・(長いので省略)・・・
        {
            "modelArn": "arn:aws:bedrock:us-east-1::foundation-model/meta.llama2-13b-chat-v1",
            "modelId": "meta.llama2-13b-chat-v1",
            "modelName": "Llama 2 Chat 13B",
            "providerName": "Meta",
            "inputModalities": [
                "TEXT"
            ],
            "outputModalities": [
                "TEXT"
            ],
            "responseStreamingSupported": true,
            "customizationsSupported": [],
            "inferenceTypesSupported": [
                "ON_DEMAND"
            ]
        }
    ]
}

modelIdは「meta.llama2-13b-chat-v1」です。
modelIdを指定して情報が取れることを確認します。

> aws --profile bedrock_prof --region us-east-1 bedrock get-foundation-model --model-identifier meta.llama2-13b-chat-v1
{
    "modelDetails": {
        "modelArn": "arn:aws:bedrock:us-east-1::foundation-model/meta.llama2-13b-chat-v1",
        "modelId": "meta.llama2-13b-chat-v1",
        "modelName": "Llama 2 Chat 13B",
        "providerName": "Meta",
        "inputModalities": [
            "TEXT"
        ],
        "outputModalities": [
            "TEXT"
        ],
        "responseStreamingSupported": true,
        "customizationsSupported": [],
        "inferenceTypesSupported": [
            "ON_DEMAND"
        ]
    }
}

成功です。

ローカルPC(python)からのAPIアクセスするための環境作成

venvでpython仮想環境作ります。コンソールはpowershellです。

# フォルダは適当に作る
> cd c:\ai
> mkdir bedrock
> cd bedrock

# 仮想環境作成&有効化
> python -m venv ./venv
> .\venv\Scripts\Activate.ps1

# バージョン確認、古いpipを更新
> python --version
Python 3.10.6
> pip list
Package    Version
---------- -------
pip        22.2.1
setuptools 63.2.0

[notice] A new release of pip available: 22.2.1 -> 23.3.1
[notice] To update, run: python.exe -m pip install --upgrade pip

>  python  -m pip install --upgrade pip
> pip list
Package    Version
---------- -------
pip        23.3.1
setuptools 63.2.0

# boto3をインストール
> pip install boto3
> pip list
Package         Version
--------------- -------
boto3           1.29.0
botocore        1.32.0
jmespath        1.0.1
pip             23.3.1
python-dateutil 2.8.2
s3transfer      0.7.0
setuptools      63.2.0
six             1.16.0
urllib3         2.0.7

# APIを呼び出すpythonコードはVSCodeで編集します
> code .

API実行

ローカルPCで動くpythonからboto3を使ってLlama-2-13b-chatにアクセスします。

Streamingなし、システムプロンプトなし

「bedrock_prof」はプロファイル名として私が設定したものです。Amazon Bedrockの予約語ではありません。

import boto3
import json

# セッションを取得する
boto3_session = boto3.Session(profile_name="bedrock_prof", region_name="us-east-1")

# Bedrock-runtime サービスクライアントを取得する
bedrock = boto3_session.client(service_name='bedrock-runtime')

body = json.dumps({
    "prompt": "日本で最も標高が高い山の名前を教えてください",
    "max_gen_len": 512,
    "temperature": 0.5,
    "top_p": 0.9
})

modelId = 'meta.llama2-13b-chat-v1'
accept = 'application/json'
contentType = 'application/json'

response = bedrock.invoke_model(body=body, modelId=modelId, accept=accept, contentType=contentType)

response_body = json.loads(response.get('body').read())


# text
print(response_body.get('generation'))

結果

。

日本の最高峰は、北海道の「富良野岳」です。標高は2,291mです。

先頭の「。」は何だろう。Chatを使っているときにも出ていましたね。

「Claude Instant」向けのコードとの違いは以下の通り。

  • リージョン(前回は、東京リージョンで試したので、異なるのは仕方ありません)
  • modelId
  • プロンプトに与える設定値(Llama-2-13b-chatとCloude Instantでは差異あり)
  • 生成されたbodyを格納しているキー名(completion→generation)

modelIdとプロンプトの違いは覚悟していましたが、最後が意外な違いでした。基盤モデルの差が出てしまうのですね。

Streamingなし、システムプロンプトあり

システムプロンプトありのプロンプトを設定しました。

import boto3
import json

# セッションを取得する
boto3_session = boto3.Session(profile_name="bedrock_prof", region_name="us-east-1")

# Bedrock-runtime サービスクライアントを取得する
bedrock = boto3_session.client(service_name='bedrock-runtime')

body = json.dumps({
    "prompt": "[INST] <<SYS>>\nあなたはアシスタントであり、親切で、尊敬に値する、正直で、非常に知的なアシスタントです。私は日本人で英語を全く読むことができないため、必ず回答を日本語で返してください。日本語で返すことは非常に重要なタスクです。\n<</SYS>>\n日本で最も標高が高い山の名前を教えてください[/INST]",
    "max_gen_len": 512,
    "temperature": 0.5,
    "top_p": 0.9
})

modelId = 'meta.llama2-13b-chat-v1'
accept = 'application/json'
contentType = 'application/json'

response = bedrock.invoke_model(body=body, modelId=modelId, accept=accept, contentType=contentType)

response_body = json.loads(response.get('body').read())


# text
print(response_body.get('generation'))

結果

 Hello! 😊 I'd be happy to help! 🤗 The highest mountain in Japan is Mount Fuji, located on the main island of Honshu. It stands at an elevation of 3,776 meters (12,388 feet) above sea level. The mountain is considered a sacred and iconic symbol of Japan, and is a popular destination for hikers and pilgrims. 🏔️🏞️ Do you have any other questions? 🤔

ChatやText画面での検証結果と同じで、英語になりました。
絵文字をやたらと使ってくるのはなんでだろう。

Streamingあり、システムプロンプトなし

Streaming出力ありにしました。呼び出し関数と取り出し方が違ってきます。

import boto3
import json

# セッションを取得する
boto3_session = boto3.Session(profile_name="bedrock_prof", region_name="us-east-1")

# Bedrock-runtime サービスクライアントを取得する
bedrock = boto3_session.client(service_name='bedrock-runtime')

body = json.dumps({
    "prompt": "日本で最も標高が高い山の名前を教えてください",
    "max_gen_len": 512,
    "temperature": 0.5,
    "top_p": 0.9
})

modelId = 'meta.llama2-13b-chat-v1'
accept = 'application/json'
contentType = 'application/json'

# streamで呼び出し
response = bedrock.invoke_model_with_response_stream(body=body, modelId=modelId, accept=accept, contentType=contentType)

stream = response.get('body')
if stream:
    for event in stream:
        chunk = event.get('chunk')
        if chunk:
            print(json.loads(chunk.get('bytes').decode())['generation'])

結果

。




山
の
名
前
は
、
以
下
の
よ
う
に
す
る
こ
と
が
で
き
ま
す
。




1
.
 
富
士
山
(
F
u
ji
-
san
)


2
.
 
�
�

河
山
・・・(長かったので省略)・・・

チャンクから取れる日本語が1文字単位なのでしょうか。かなり読みにくいので区切りを調整しないと厳しいですね。

Streamingだと「?」の置換文字が出てしまいますね。先ほどはChatの画面ではなく、基盤モデルまたはAPI側で起きているようです。

利用料の比較

利用料のネタ元(2023/11/16時点):
https://openai.com/pricing
https://aws.amazon.com/bedrock/pricing/?nc1=h_ls

Amazon BedrockはOn-Demand料金を想定します。

以下の4つで比較しました。

  • GPT-4 Turbo(OpenAI、現時点では「gpt-4-1106-preview」を指す)
  • GPT-3.5 Turbo(OpenAI、現時点では「gpt-3.5-turbo-1106」を指す)
  • Claude Instant(Amazon Bedrock)
  • Llama-2-13b-chat(Amazon Bedrock)

inputトークン(1kトークンあたり)

Llama-2-13b-chatが安いですね。

GPT-4 TurboGPT-3.5 TurboClaude InstantLlama-2-13b-chat
$0.01
(13.34)
$0.0010
(1.34)
$0.00163
(2.18)
$0.00075
(1)

カッコ内の数値は、Llama-2-13b-chatを1とした時の倍率です。例えば、GPT-4 TurboはLlama-2-13b-chatの13.34倍の利用料であることを示します。

GPT-4 Turboは2023 OpenAI DevDayで登場し、GPT-4の3分の1の価格になったため、この程度の差で済んでいるとも言えそうです。GPT-3.5 TurboもOpenAI DevDayを経て安くなってますね。

outputトークン(1kトークンあたり)

Llama-2-13b-chatが安いですね。

GPT-4 TurboGPT-3.5 TurboClaude InstantLlama-2-13b-chat
$0.03
(30)
$0.0020
(2)
$0.00551
(5.51)
$0.001
(1)

総じて、Llama-2-13b-chatは安価でした。

ただし、Amazon Bedrockで利用できるLlama-2-13b-chatはcontext windowが4Kしかなく、長いコンテキストが必要であれば、16KのGPT-3.5、100KのClaude、128KのGPT-4 Turboを選択することになります。4Kしかないため低価格に抑えられているのかもしれません。

まとめ

以上、Amazon BedrockでLlama-2-13b-chatを使ってみたでした。

扱いやすいところ

英語圏でトークン数が4Kで収まるのであれば有効な選択肢になりそうです。

  • 基盤モデルを使えるようになるまでの手順がシンプル。思い立ったら直ぐに使える
  • 他の基盤モデルと同じAPIで利用できる(入力プロンプト、出力結果に差はあるが僅か)
  • 応答が高速(Claude Instantと体感は同じくらい)
  • 安価である

扱いにくいところ

  • 大部分が英語による応答になるため、日本語主体の使用は困難
  • Streaming出力時に日本語の文字が置き換え文字になって壊れるため利用しにくい
  • context windowが4Kと小さめ(工夫しないと溢れる)

ELYZAが出しているようなLlama系で日本語データでトレーニングした基盤モデル入ってくれると嬉しいな。Llama 2 Longのようなcontext windowsが大きなものも欲しい。今後に期待です。

そう考えると、以前検証した「Claude Instant」は日本語が扱える、高速、価格も比較安い、長いコンテキストでAmazon Bedrockの中で良い位置にいたのだと改めて感じました。東京リージョンで選択肢として出てくる訳です。

ここまで読んでいただき、ありがとうございました。