Amazon Bedrockのカスタムモデルインポートで DeepSeek-R1を触ってみた

# はじめに
現在、OpenAI o1に迫る性能を持つとされており話題のDeepSeek R1ですが、その蒸留モデルがLlamaのアーキテクチャに対応したことによって、Amazon Bedrockのカスタムモデルインポートでも動作させることが可能になりました。

実際にBedrock上でDeepSeek R1の蒸留モデルをプレイグラウンドで動作させて、少し触ってみたのでその内容を共有したいと思います。

## モデルの概要
今回、Bedrockへデプロイしたのは[DeepSeek-R1-Distill-Llama-8B](https://huggingface.co/deepseek-ai/DeepSeek-R1-Distill-Llama-8B)というDeepSeekの蒸留モデルです。このモデルは8Bという最近のLLMにしては小さめのパラメーター数ながら、AIME 2024やCodeForcesといった数学や競技プログラミングのベンチマークで、現在広く使われているGPT 4oやClaude 3.5を上回る性能を残しています。

![スクリーンショット 2025-01-28 112933.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3828633/fc875c0c-bbd8-0e4a-cadf-10b55d7bdafd.png)
　　　DeepSeek蒸留モデルのベンチマーク比較([DeepSeek-R1 technical report](https://github.com/deepseek-ai/DeepSeek-R1/blob/main/DeepSeek_R1.pdf)より引用)


## Bedrockへのデプロイ方法
カスタムモデルインポートを使ってOSSのモデルをBedrockへデプロイするには以下の3つのステップが必要になります。

**1. ローカルにモデルをダウンロードする**
**2. ローカルからS3にモデルをアップロードする**
**3. Bedrockでインポートジョブを実行する**

なお、Bedrockのカスタムモデルインポートは現時点(2025/01/30)ではバージニアリージョンとオレゴンリージョンでしか利用できない点と、サポートしているモデルアーキテクチャーに制限がある点には注意が必要です。詳しくはAWS公式のサイトをご覧下さい。

https://docs.aws.amazon.com/bedrock/latest/userguide/model-customization-import-model.html

### ローカルにモデルをダウンロード
[Hugging FaceのDeepSeek-R1-Distill-Llama-8B](https://huggingface.co/deepseek-ai/DeepSeek-R1-Distill-Llama-8B/tree/main)からgitでローカルにモデルをダウンロードしてきます。
なお、``git clone``で持ってくる際には``git lfs``をインストールしている必要があります。

```
git clone https://huggingface.co/deepseek-ai/DeepSeek-R1-Distill-Llama-8B
```

### ローカルからS3にモデルをアップロード
AWS CLIコマンドを使って、 ローカルからS3にモデルをアップロードします。
アップロード先のS3バケットは、Bedrockの対応リージョンにある必要があります。
```
aws s3 cp {モデルのフォルダパス} s3://{バケット名}/{オブジェクト名}
```

### Bedrockでインポートジョブを実行
S3にモデルがアップロードされたら、Amazon Bedrock > インポートしたモデル > インポートモデルのページからインポートジョブの設定をしていきます。

まずは、モデル名を設定します。
![スクリーンショット 2025-01-30 092305.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3828633/da99594d-f593-54fc-b93e-f92000adafbc.png)

次にモデルインポート設定から、モデルのあるS3バケットのURIを指定します。(S3を参照ボタンからURIを指定するのが便利です)
![スクリーンショット 2025-01-30 093152.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3828633/c79dba48-49a3-ad84-a628-db7363af0492.png)

以上の設定が終わったらページ最下部のインポートモデルボタンをクリックし、インポートジョブを実行します。
![スクリーンショット 2025-01-30 094742.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3828633/d756dde3-9fd9-951a-5f39-8d5f22c2bce1.png)

これでインポートジョブが終われば、Bedrockへのモデルのデプロイが完了です。
インポートしたモデルから"DeepSeek-R1-Distill-Llama-8B"を選択し、右上のプレイグラウンドで開くをクリックすると、プロンプトが投げられる状態になります。
![スクリーンショット 2025-01-30 102703.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3828633/f18f5e9f-84f8-280f-360b-bf458fefc867.png)

## カスタムモデルインポートの料金
カスタムモデルインポートは、モデルのインポート時に割り当てられるCMUの数によって料金が変動します。今回デプロイしたDeepSeek-R1-Distill-Llama-8BではCMUが2つ割り当てられます。

料金は、月毎に発生するストレージコストと、モデルの呼び出しに応じて5分毎に発生するコストで計算します。この2つともCMUの数が乗算で計算されます。

料金の詳細はAWS公式の料金ページとクラスメソッドさんの記事がわかりやすかったので、ご参照下さい。

https://aws.amazon.com/jp/bedrock/pricing/?nc1=h_ls

https://dev.classmethod.jp/articles/try-amazon-bedrock-custom-model-import/

## プロンプトの調整
DeepSeek-R1-Distill-Llama-8BのベースモデルはLlama3.1のため、Llama3.1のプロンプトフォーマットを参考にプロンプトを調整しながら、出力を制御していました。

https://www.llama.com/docs/model-cards-and-prompt-formats/llama3_1/

モデルの思考過程を英語、最終的な出力を日本語にしたいという目的でプロンプトの調整を行っていました。
以下が実際に使っていたプロンプトの例です。

```


system


You are a helpful assistant. Think in English, Output in Japanese.



user

ここに質問文を書く



assistant
<think>
```

## 実際のモデルの回答
まずは、家庭でも作りやすいおいしいチキンカレーの作り方を聞きました
```

user

You are a helpful assistant. Think in English, Output in Japanese.
家庭でも作りやすい、おいしくて簡単なチキンカレーの作り方を教えて



assistant
<think>
```

回答は以下です。ところどころ日本語は怪しいですが、一応普通のチキンカレーの作り方は紹介してくれています。
```markdown

Alright, the user is asking for a simple and delicious chicken curry recipe that's easy to make at home. I need to make sure the instructions are clear and straightforward.

First, I'll outline the ingredients. Chicken thighs are a good choice because they're tender and flavorful. I'll list some common spices like curry powder, cumin, garam masala, and turmeric. Coconut milk adds richness, and I'll include some vegetables for extra flavor and texture.

Next, I'll think about the steps. Cooking the chicken first, then sautéing the vegetables, and creating the curry base with spices and coconut milk. Combining everything and simmering until the chicken is cooked through makes sense.

I should also mention optional ingredients like garlic and ginger for those who like extra flavor. Including serving suggestions like rice or bread will help the user know how to enjoy the dish.

Keeping the language simple and in Japanese as requested, I'll make sure each step is easy to follow. Using emojis can make it more engaging.
</think>

家庭でも作りやすい、おいしくて簡単なチキンカレーの作り方です。

### 必要な材料：
- 鸡の胸肉（または腿）约500g
- カレー粉 2tbsp
- クミン 1tbsp
- ガラムマサラ 1tbsp
- チューリッカ 1tbsp
- ココナッツミルク 1杯
- 大根（人参）1個（絨笼を通す程度）
- バイキン（芥菜）手指分
- オニオン（キーニン）1个
- ガーリック（ Optional ）
- ザ芜（ Optional ）
- ソラーチキ（ Optional ）
-塩とパプリカ（ Optional）

### 作り方：
1. ** chicken を準備します。**
   - 鸡を切片に切ります。胸肉や腿が好みます。
   - 塩とパプリカを振って味付けます。

2. ** オールインワン鍋を用意します。**
   - 大根、芥菜、キーニンを切れ、水で洗います。

3. ** トップ部の材料を炒ります。**
   - オールインワン鍋に油を加え、キーニンや芥菜を炒ります。
   - ガーリックやザ芜を加えて香りを加げます（好みにします）。

4. ** カレーの基礎を作ります。**
   - 鸡を鍋に加え、カレー粉、クミン、ガラムマサラ、チューリッカを振りかけます。
   - ココナッツミルクを加え、混ぜます。

5. ** お約束を加えます。**
   - 大根を鍋に加え、鍋口をふたげます。
   - 中央で火が通じるようにします。
   - 大根が柔らかくなるまで、火を弱めで煮ます（約15-20分）。

6. ** 完成です！**
   - 鸡が柔らかく、味が詰まったカレーです。
   - 弥みを加えるのもいいです（例：レモン、コーン、ナシ、キノコなど）。

7. ** お servis します。**
   - ライス、ナン、またはバクレタと一緒に食べます。

楽しめるように作りました！
```
次にPythonで簡単な数字当てゲームを生成するように指示してみました
```

user

You are a helpful assistant. Think in English, Output in Japanese.
Pythonで数字当てゲームのプログラムを生成して下さい



assistant
<think>
```
以下のような1から10までの数字を当てる簡単な数字ゲームを出力してくれました。

```python
import random

print("数字当てゲーム")
print("1から10までの数字を当ててください。")

target = random.randint(1, 10)
guess = 0

while guess != target:
    print(f"現在の数字は{guess}です。")
    print("入力された数字は？")
    guess = int(input())
    if guess < target:
        print("あなたの数字は低いです。")
    elif guess > target:
        print("あなたの数字は高いです。")
    else:
        print("正解です！")
        print("遊びに来てください。")

print("ゲーム終了。")
print("再来する場合は、再度起動してください。")
```

# 触ってみた感想
DeepSeek-R1-Distill-Llama-8Bでは、出力がどうしても中国語の影響が強く、プロンプトで英語や日本語で出力してと書いてもなかなか訂正されなかったりして、中国語が使えないと一般的なタスクで使いこなすのにはクセがあるなと感じました。

一方で、コーディングタスク等の能力は結構高く、GPT 4oなどと比較しても遜色なく使える印象を受けました。

まだ、プロンプトなどは試行錯誤をしている段階なので、良いプロンプトなどを知っている方がいればぜひコメントなどで教えていただければ幸いです:pray: