4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ようやく試せた Amazon Bedrock の Latency Optimize

Last updated at Posted at 2024-12-27

tl;dr

latency optimize は実験の条件下(※)において

input : 176 tokens/msec -> 301 tokens/msec (x1.71 高速)
output : 58 tokens/msec -> 109 tokens/msec (x1.88 高速)

という高速化を実現しています。

(※input token 109, output token 301, Claude 3.5 haiku)

今年も終わりですね。

仕事が一段落したので、ようやく少し遊ぶ時間が出来ました。

Latency optimizeが出たので、試してみます。

Latency Optimize?

Latency Optimize はいろいろ最適化して速くなったよ!以上のことがブログには書かれていません。

re:Invent のキーノートで発表が合った時は Trainium(trn2)で推論することで速くなったよ、という解説がありました。
私見ではありますが、GPU は Graphic Processing Unit であり、機械学習専用に作ったコンピューティングリソースを利用すればそりゃ速くなるし、推論はトレーニングからバックプロパゲーションだけを抜いた行為なのだからその高速化された環境でやるのもそりゃ速いですよね、というところです。

image.png

そして claude 3.5 haiku も対応しているよ、とのことです。

image.png

Latency Optimize を試してみよう

さて、Latency Optimize を試してみましょう。

ドキュメントによると、Claude 3.5 haiku と Llama 3.1 70b/405b で以下の引数を設定すれば使えるよ、とのことです。

"performanceConfig" : {
    "latency" : "optimized"
}

また注意として以下があります。

Latency optimized inference is available for Meta’s Llama 3.1 70B and 405B, as well as Anthropic’s Claude 3.5 Haiku in the US East (Ohio) Region via cross-region inference. For more information about pricing, visit the pricing page.

Latency optimized inference for Llama 3.1 405B currently supports requests with total input and output token count up to 11K. For larger token count requests, we will fall back to the standard mode.

  • Ohio でクロスリージョンしなさい
  • 入出力トークンの上限(11k)があるよ

とのことです。

まずは標準で時間計測

早速やってみましょう。

今回は boto3 から converse API を使ってみることとします。

import boto3

brt = boto3.client( # Ohio を指定しましょう
    service_name='bedrock-runtime',
    region_name='us-east-2'
)

model_id = 'us.anthropic.claude-3-5-haiku-20241022-v1:0'
prompt = '''あなたは大学受験生です。
問題として円周率が 3.05 以上であることの証明を求められました。
円に内接する正八角形の面積を求めることで円周率が 3.05 以上であることを実際に計算して証明してください。
私は TeX の表記を読むことができるので TeX で表現してください。'''

301 tokens 出力

速度差を出すために出力を長くなるようなプロンプトを用意してみました。(2003年の東大の問題)
使用するモデルは 3.5 haiku sonnet です。
このプロンプトのレスポンスはだいたい 400-500 output tokens でした。今回の目的は出力内容はどうでもいいので、 maxTokens を 301 で cut off して 3 回計測します。
そして、まずは Latency Optimize されていない(=たぶん GPU)状態で計測してみます。

response = brt.converse(
    modelId = model_id,
    messages = [
        {
            'role':'user',
            'content':[
                {'text':prompt}
            ]
        }
    ],
    inferenceConfig={
        'maxTokens':301,
        'temperature':0,
    }
)
print(response)

1 回目 5641 msec

出力
{(前略)
 'output': {'message': {'role': 'assistant',
   'content': [{'text': '以下に、円周率が3.05以上であることを正八角形の面積を用いて証明します。\n\n証明:\n\n1) 半径 $r = 1$ の円を考える。\n\n2) 正八角形の内接円の面積を計算する。\n\n3) 正八角形の各頂点の座標は以下のように表せる:\n   $(\\cos(\\frac{k\\pi}{4}), \\sin(\\frac{k\\pi}{4}))$ where $k = 0, 1, 2, ..., 7$\n\n4) 正八角形の面積 $A_8$ は:\n   $A_8 = 2r^2 \\sin(\\frac{\\pi}{4}) \\cdot 8 = 2 \\sin(\\frac{\\pi}{4}) = 2 \\cdot \\frac{\\sqrt{2}}{2} = \\sqrt{2}$\n\n5) 円の面積は $\\pi r^2 = \\pi$\n\n6) $\\frac{A_8}{\\pi} = \\frac{\\sqrt{2}}{\\pi} \\approx 0.9$\n\n7) したがって、$\\pi'}]}},
 'stopReason': 'max_tokens',
 'usage': {'inputTokens': 109, 'outputTokens': 301, 'totalTokens': 410},
 'metrics': {'latencyMs': 5641}}

2 回目 5613 msec

出力
{(前略)
 'output': {'message': {'role': 'assistant',
   'content': [{'text': '以下に、円周率が3.05以上であることを正八角形の面積を用いて証明します。\n\n証明:\n\n1) 半径 $r = 1$ の円を考える。\n\n2) 正八角形の内接円の面積を計算する。\n\n3) 正八角形の各頂点の座標は以下のように表せる:\n   $(\\cos(\\frac{k\\pi}{4}), \\sin(\\frac{k\\pi}{4}))$ where $k = 0, 1, 2, ..., 7$\n\n4) 正八角形の面積 $A_8$ は:\n   $A_8 = 2r^2 \\sin(\\frac{\\pi}{4}) \\cdot 8 = 2 \\sin(\\frac{\\pi}{4}) = 2 \\cdot \\frac{\\sqrt{2}}{2} = \\sqrt{2}$\n\n5) 円の面積は $\\pi r^2 = \\pi$\n\n6) $\\frac{A_8}{\\pi} = \\frac{\\sqrt{2}}{\\pi} \\approx 0.9$\n\n7) したがって、$\\pi'}]}},
 'stopReason': 'max_tokens',
 'usage': {'inputTokens': 109, 'outputTokens': 301, 'totalTokens': 410},
 'metrics': {'latencyMs': 5613}}

3 回目 5961 msec

出力
{(前略)
 'output': {'message': {'role': 'assistant',
   'content': 
 'output': {'message': {'role': 'assistant',
   'content': [{'text': '以下に、円周率が3.05以上であることを正八角形の面積を用いて証明します。\n\n証明:\n\n1) 半径 $r = 1$ の円を考える。\n\n2) 正八角形の内接円の面積を計算する。\n\n3) 正八角形の各頂点の座標は以下のように表せる:\n   $(\\cos(\\frac{k\\pi}{4}), \\sin(\\frac{k\\pi}{4}))$ where $k = 0, 1, 2, ..., 7$\n\n4) 正八角形の面積 $A_8$ は:\n   $A_8 = 2r^2 \\sin(\\frac{\\pi}{4}) \\cdot 8 = 2 \\sin(\\frac{\\pi}{4}) = 2 \\cdot \\frac{\\sqrt{2}}{2} = \\sqrt{2}$\n\n5) 円の面積は $\\pi r^2 = \\pi$\n\n6) $\\frac{A_8}{\\pi} = \\frac{\\sqrt{2}}{\\pi} \\approx 0.9$\n\n7) したがって、$\\pi'}]}},
 'stopReason': 'max_tokens',
 'usage': {'inputTokens': 109, 'outputTokens': 301, 'totalTokens': 410},
 'metrics': {'latencyMs': 5961}}

latencyMs は 5641 msec, 5613 msec, 5961 msec でした。
これは API 側が出力しているメトリクスなので、リクエストを受け取ってから返すまでの時間のはずです。

1 tokens 出力

ここに対して、maxTokens:1 の LatencyMs を計測することで、ほぼ GPU (だと思われる) に token を載せる時間を得て、301 token 出力するのにかかった時間から引き算することで、output token の時間を計測できるはずです。同様に 3 回計測してみましょう。

response = brt.converse(
    modelId = model_id,
    messages = [
        {
            'role':'user',
            'content':[
                {'text':prompt}
            ]
        }
    ],
    inferenceConfig={
        'maxTokens':1,
        'temperature':1,
    }
)

1 回目 730 msec

出力
{(前略)
 'output': {'message': {'role': 'assistant',
   'content': 
 'output': {'message': {'role': 'assistant', 'content': []}},
 'stopReason': 'max_tokens',
 'usage': {'inputTokens': 109, 'outputTokens': 1, 'totalTokens': 110},
 'metrics': {'latencyMs': 730}}

2 回目 514 msec

出力
{(前略)
 'output': {'message': {'role': 'assistant',
   'content': 
 'output': {'message': {'role': 'assistant', 'content': []}},
 'stopReason': 'max_tokens',
 'usage': {'inputTokens': 109, 'outputTokens': 1, 'totalTokens': 110},
 'metrics': {'latencyMs': 514}}

3 回目 621 msec

出力
{(前略)
 'output': {'message': {'role': 'assistant',
   'content': 
 'output': {'message': {'role': 'assistant', 'content': []}},
 'stopReason': 'max_tokens',
 'usage': {'inputTokens': 109, 'outputTokens': 1, 'totalTokens': 110},
 'metrics': {'latencyMs': 621}}

たった 3 回の計測ですが、雑に平均を取ってから計算してみましょう。

    109 tokens req して 301 token を得るまでの平均時間 : (5641+5613+5961)/3 = 5738 msec

-)  109 tokens req して   1 token を得るまでの平均時間 : (730+514+621)/3    =  622 msec
--------------------------------------------------------------------------------------
                                                                          5116 msec
109 /  622 * 1000 = 176 tokens/sec(input)
300 / 5116 * 1000 =  58 tokens/sec(output)

input に 176 tokens/sec, output に 58 tokens/sec かかりました。(条件や token 長さによって変わることに注意)

Latency Optimize で試す

同じことを latency Optimize でやってみましょう。

301 tokens 出力

converse API で引数に performanceConfig={'latency': 'optimized'} を設定するだけです。簡単ですね。

response = brt.converse(
    modelId = model_id,
    messages = [
        {
            'role':'user',
            'content':[
                {'text':prompt}
            ]
        }
    ],
    inferenceConfig={
        'maxTokens':301,
        'temperature':0,
    },
    performanceConfig={
        'latency': 'optimized'
    }
)
print(response)

1 回目 : 3184 msec

出力
{(前略)
 'output': {'message': {'role': 'assistant',
   'content': [{'text': '以下に、円周率が3.05以上であることを正八角形の面積を用いて証明します。\n\n\\begin{proof}\n半径 $r = 1$ の円を考える。\n\n正八角形の内接円の面積を計算する手順:\n\n1. 正八角形の一辺の長さ $a$ を求める\n   $a = 2r \\sin(\\frac{\\pi}{8}) = 2 \\sin(\\frac{\\pi}{8})$\n\n2. 正八角形の面積 $S$ を計算\n   $S = 8 \\cdot \\frac{1}{2} a^2 \\cot(\\frac{\\pi}{8})$\n\n3. 計算\n   $S = 8 \\cdot \\frac{1}{2} (2 \\sin(\\frac{\\pi}{8}))^2 \\cot(\\frac{\\pi}{8})$\n   $= 8 \\sin^2(\\frac{\\pi}{8}) \\cot(\\frac{\\pi}{8})$\n\n4. 数値計算\n   $S \\approx 3.0615$\n\n5. 円の面積 $\\pi r^'}]}},
 'stopReason': 'max_tokens',
 'usage': {'inputTokens': 109, 'outputTokens': 301, 'totalTokens': 410},
 'metrics': {'latencyMs': 3184},
 'performanceConfig': {'latency': 'optimized'}}

2 回目 : 3129 msec

出力
{(前略)
 'output': {'message': {'role': 'assistant',
   'content': [{'text': '以下に、円周率が3.05以上であることを正八角形の面積を用いて証明します。\n\n\\begin{proof}\n半径 $r = 1$ の円を考える。\n\n正八角形の内接円の面積を計算する手順:\n\n1. 正八角形の一辺の長さ $a$ を求める\n   $a = 2r \\sin(\\frac{\\pi}{8}) = 2 \\sin(\\frac{\\pi}{8})$\n\n2. 正八角形の面積 $S$ を計算\n   $S = 8 \\cdot \\frac{1}{2} a^2 \\cot(\\frac{\\pi}{8})$\n\n3. 計算\n   $S = 8 \\cdot \\frac{1}{2} (2 \\sin(\\frac{\\pi}{8}))^2 \\cot(\\frac{\\pi}{8})$\n   $= 8 \\sin^2(\\frac{\\pi}{8}) \\cot(\\frac{\\pi}{8})$\n\n4. 数値計算\n   $S \\approx 3.0615$\n\n5. 円の面積 $\\pi r^'}]}},
 'stopReason': 'max_tokens',
 'usage': {'inputTokens': 109, 'outputTokens': 301, 'totalTokens': 410},
 'metrics': {'latencyMs': 3129},
 'performanceConfig': {'latency': 'optimized'}}

3 回目 : 3035 msec

出力
{(前略)
 'output': {'message': {'role': 'assistant',
   'content': [{'text': '以下に、円周率が3.05以上であることを正八角形の面積を用いて証明します。\n\n\\begin{proof}\n半径 $r = 1$ の円を考える。\n\n正八角形の内接円の面積を計算する手順:\n\n1. 正八角形の一辺の長さ $a$ を求める\n   $a = 2r \\sin(\\frac{\\pi}{8}) = 2 \\sin(\\frac{\\pi}{8})$\n\n2. 正八角形の面積 $S$ を計算\n   $S = 8 \\cdot \\frac{1}{2} a^2 \\cot(\\frac{\\pi}{8})$\n\n3. 計算\n   $S = 8 \\cdot \\frac{1}{2} (2 \\sin(\\frac{\\pi}{8}))^2 \\cot(\\frac{\\pi}{8})$\n   $= 8 \\sin^2(\\frac{\\pi}{8}) \\cot(\\frac{\\pi}{8})$\n\n4. 数値計算\n   $S \\approx 3.0615$\n\n5. 円の面積 $\\pi r^'}]}},
 'stopReason': 'max_tokens',
 'usage': {'inputTokens': 109, 'outputTokens': 301, 'totalTokens': 410},
 'metrics': {'latencyMs': 3035},
 'performanceConfig': {'latency': 'optimized'}}

5 秒後半だったのが 3 秒前半 と 2.5 秒くらい速くなりましたね。

1 tokens 出力

先ほど同様、maxTokens を 1 にして input の計測をしてみましょう。

response = brt.converse(
   modelId = model_id,
   messages = [
       {
           'role':'user',
           'content':[
               {'text':prompt}
           ]
       }
   ],
   inferenceConfig={
       'maxTokens':1,
       'temperature':0,
   },
   performanceConfig={
       'latency': 'optimized'
   }
)

1 回目: 312 msec

出力
{(前略)
 'output': {'message': {'role': 'assistant', 'content': []}},
 'stopReason': 'max_tokens',
 'usage': {'inputTokens': 109, 'outputTokens': 1, 'totalTokens': 110},
 'metrics': {'latencyMs': 312},
 'performanceConfig': {'latency': 'optimized'}}

2 回目 : 362 msec

出力
{(前略)
 'output': {'message': {'role': 'assistant', 'content': []}},
 'stopReason': 'max_tokens',
 'usage': {'inputTokens': 109, 'outputTokens': 1, 'totalTokens': 110},
 'metrics': {'latencyMs': 362},
 'performanceConfig': {'latency': 'optimized'}}

3 回目 : 411 msec

出力
{(前略)
 'output': {'message': {'role': 'assistant', 'content': []}},
 'stopReason': 'max_tokens',
 'usage': {'inputTokens': 109, 'outputTokens': 1, 'totalTokens': 110},
 'metrics': {'latencyMs': 411},
 'performanceConfig': {'latency': 'optimized'}}
    109 tokens req して 301 token を得るまでの平均時間 : (3184+3129+3035)/3 = 3116 msec

-)  109 tokens req して   1 token を得るまでの平均時間 : (312+362+411)/3    =  362 msec
--------------------------------------------------------------------------------------
                                                                          2754 msec
109 /  362 * 1000 = 301 tokens/sec(input)
300 / 2754 * 1000 = 109 tokens/sec(output)

input : 176 tokens/msec -> 301 (x1.71 高速)
output : 58 tokens/msec -> 109 (x1.88 高速)

in/out 共に 1.7 倍以上高速化していますね。また出力を全部確認したわけではないですが、書き出しを見る限り latency optimize も標準と変わっていません。精度を維持したまま高速化したい、という要望にはお金で解決する、というオプションが加わったと考えることができます。

おわりに

Amazon Bedrock はモデルだけじゃなく周辺の機能(Agents, KnowlesgeBases, Guardrails, etc...)が豊富でエンタープライズ用途で使いやすいところが売りでしたが、そこに新しいオプションが加わって嬉しい!(小並感)
1.25 倍のお金を払うと 1.8 倍くらい速いよ、というのは UX を売りにしているサービスだと嬉しいケースがありそうです。

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?