N番煎じでLLM-jp-3 13B InstructをDatabricks Mosaic AI Model Serving上で試す

今週はGoogleがGemini 1.5proを出すわLLM-jp-3が出るわMeta Llama3.2が出るわ、モリモリですね。

# 導入

大規模言語モデル研究開発センター（LLMC）様がLLM-jpの新バージョンを公開しました。

https://llmc.nii.ac.jp/topics/post-707/

パラメータサイズや指示チューニングモデルなど、複数のバリエーションが公開されており、各モデルは日本語・英語・ソースコードを重点的に学習しているようです。ライセンスはApache 2.0。

以下のように既に多くの方が試されていますが、遅ればせながら触ってみたいと思います。

https://note.com/npaka/n/n56bf8d787805

検証はDatabricks on AWS、DBRは15.4MLです。
Databricks Mosaic AI Model Serving上にデプロイしてからクエリを実行してみます。

# Step1. パッケージインストール

ノートブックを作成して、transformersとmlflowを最新化。

```python
%pip install -U transformers
%pip install "mlflow-skinny[databricks]>=2.16.2"

dbutils.library.restartPython()
```

また、この先の処理に利用するパラメータを変数に格納。
```python
model_path='/Volumes/training/llm/model_snapshots/models--llm-jp--llm-jp-3-13b-instruct/'

catalog='training'
schema='llm'
registered_model_name='training.llm.lm-jp-3-13b-instruct'
endpoint_name='lm-jp-3-13b-instruct-endpoint'
endpoint_scale_to_zero_enabled='true'
```


# Step2. モデルのロギング

以下のリポジトリからモデルをダウンロードしておき、mlflowにロギングします。
llm-jp-3はLlama2アーキテクチャを採用しているぽいので、Databricks　Mosaic AI Model Servingで[プロビジョニングされたスループットの基盤モデルAPI](https://docs.databricks.com/ja/machine-learning/foundation-models/deploy-prov-throughput-foundation-model-apis.html)が利用できるため、それを使える設定にしています。

https://huggingface.co/llm-jp/llm-jp-3-13b-instruct

```python
import mlflow
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
import numpy as np

mlflow.set_registry_uri('databricks-uc')

model = AutoModelForCausalLM.from_pretrained(
    model_path,
    torch_dtype=torch.bfloat16,
)
tokenizer = AutoTokenizer.from_pretrained(model_path)
input_example = {
    "messages": [
        {"role": "system", "content": "以下は、タスクを説明する指示です。要求を適切に満たす応答を書きなさい。"},
        {"role": "user", "content": "自然言語処理とは何か"},
    ],
    "max_tokens": 100,
    "stream": False,
}

with mlflow.start_run():
    components = {
        "model": model,
        "tokenizer": tokenizer,
    }
    mlflow.transformers.log_model(
        transformers_model=components,
        artifact_path="model",
        task="llm/v1/chat",
        input_example=input_example,
        registered_model_name=registered_model_name,
        save_pretrained=False,
    )
```

# Step3. モデルのデプロイ

登録したモデルをDatabricks Mosaic AI Model Serving上のエンドポイントとして公開します。

```python
import requests
import json
import mlflow
from mlflow import MlflowClient

# Get the API endpoint and token for the current notebook context
API_ROOT = (
    dbutils.notebook.entry_point.getDbutils().notebook().getContext().apiUrl().get()
)
API_TOKEN = (
    dbutils.notebook.entry_point.getDbutils().notebook().getContext().apiToken().get()
)

# 登録済みモデルの最新バージョンを取得
mlflow.set_registry_uri("databricks-uc")
client = MlflowClient()
versions = [
    mv.version for mv in client.search_model_versions(f"name='{registered_model_name}'")
]
model_version = versions[0]

# プロビジョニング(略 APIに対応しているかどうかのチェック
headers = {"Context-Type": "text/json", "Authorization": f"Bearer {API_TOKEN}"}

optimizable_info = requests.get(
  url=f"{API_ROOT}/api/2.0/serving-endpoints/get-model-optimization-info/{registered_model_name}/{model_version}",
  headers=headers).json()

if 'optimizable' not in optimizable_info or not optimizable_info['optimizable']:
  raise ValueError("Model is not eligible for provisioned throughput")

# スループット設定
chunk_size = optimizable_info['throughput_chunk_size']
min_provisioned_throughput = 0 if endpoint_scale_to_zero_enabled else chunk_size
max_provisioned_throughput = chunk_size

# エンドポイント作成
data = {
  "name": endpoint_name,
  "config": {
    "served_entities": [
      {
        "entity_name": registered_model_name,
        "entity_version": model_version,
        "min_provisioned_throughput": min_provisioned_throughput,
        "max_provisioned_throughput": max_provisioned_throughput,
        "scale_to_zero_enabled": endpoint_scale_to_zero_enabled,        
      }
    ]
  },
}

response = requests.post(
  url=f"{API_ROOT}/api/2.0/serving-endpoints", json=data, headers=headers
)

# print(json.dumps(response.json(), indent=4))
```

ここまでで準備編完了。

# Step4. 推論

デプロイしたエンドポイントを使って簡単な推論を実行してみます。
ノートブックを新たに作成し、以下を実行。

```python
%pip install -U -qq langchain_core langchain-databricks
%pip install -U "mlflow-skinny[databricks]>=2.16.2"

dbutils.library.restartPython()
```

```python

import time
from langchain_databricks import ChatDatabricks

prompts = [
    "Hello, what is your name?",
    "Databricksとは何ですか？詳細に教えてください。",
    "まどか☆マギカでは誰が一番かわいい?",
    "ランダムな10個の要素からなるリストを作成してソートするコードをPythonで書いてください。",
    "現在の日本の首相は誰？",
    "あなたはマラソンをしています。今3位の人を抜きました。あなたの今の順位は何位ですか?ステップバイステップで考えてください。",
]

system_prompt = """あなたは親切なAIアシスタントです。日本語で回答してください。"""

messages = [[("system", system_prompt), ("user", p)] for p in prompts]

chat_model = ChatDatabricks(endpoint=endpoint_name)

start_time = time.time()
outputs = chat_model.batch(messages, temperature=0.0, max_tokens=512)
end_time = time.time()

processing_time = end_time - start_time
total_tokens = 0
for p in zip(prompts, outputs):

    total_tokens += p[1].response_metadata["total_tokens"]

    print("Q:", p[0])
    print("A:", p[1].content)
    print("-"*100)

print("processing_time:", processing_time)
print("total_tokens:", total_tokens)
print("avg. tokens per sec.:", total_tokens / processing_time)

```

````md:出力
Q: Hello, what is your name?
A: こんにちは！私はAIアシスタントです。あなたのお名前を教えていただけますか？
----------------------------------------------------------------------------------------------------
Q: Databricksとは何ですか？詳細に教えてください。
A: Databricksは、データサイエンスと機械学習のための統合プラットフォームです。このプラットフォームは、データの準備、分析、および機械学習モデルの構築を容易にするためのツールと機能を提供します。以下に、Databricksの詳細について説明します。

### 1. 概要
Databricksは、Apache Sparkを基盤としたクラウドネイティブなプラットフォームで、データサイエンティストやエンジニアがデータ処理、分析、機械学習モデルの構築を効率的に行うためのツールを提供します。

### 2. 主な機能
#### a. データの準備
- データ統合: 様々なデータソース（データベース、ファイルシステム、APIなど）からデータを統合し、一元管理できます。
- データクリーニング: 欠損値の処理、異常値の検出、データの正規化などを行います。
- データ変換: データの形式変換、エンコーディング、フォーマット変換などを行います。

#### b. データ分析
- データ探索: データの探索と可視化を行い、データの理解を深めます。
- ダッシュボード: インタラクティブなダッシュボードを作成し、データの可視化を行います。
- 機械学習: 様々な機械学習アルゴリズムを使用して、予測モデルや分類モデルを構築します。

#### c. コラボレーション
- チームコラボレーション: 複数のユーザーが同時にデータ分析やモデル構築を行うことができます。
- バージョン管理: コードのバージョン管理と履歴管理が可能です。
- 通知とアラート: 重要なイベントや変更があった際に通知を受け取ることができます。

### 3. 利点
- スケーラビリティ: Apache Sparkの分散処理能力により、大規模なデータセットでも高速に処理が可能です。
- オープンソース: Apache Sparkを基盤としているため、オープンソースコミュニティからのサポートが受けられます。
- クラウドネイティブ: AWS、Google Cloud、Azureなどのクラウドプロバイダーと統合されており、クラウド環境での利用が容易です。

### 4. 利用シナリオ
- ETLプロセス: データの抽出、変換、ロード（ETL）プロセスを効率化します。
- データウェアハウス: データウェアハウスの構築と管理を支援します。
- 機械学習: 機械学習モデルのトレーニングとデプロイを支援します。
- リアルタイム分析: リアルタイムでのデータ分析とインサイトの提供を行います。

### 5. 導入方法
- クラウドプロバイダーのサービス: AWS、Google Cloud、Azureなどのクラウドプロバイダーが提供するDatabricksサービスを利用します。
- オンプレミス: 自社のインフラにDatabricksをインストールして利用することも可能です。


----------------------------------------------------------------------------------------------------
Q: まどか☆マギカでは誰が一番かわいい?
A: 「魔法少女まどか☆マギカ」（通称：まどマギ）は、2011年に放送されたシャフト制作のテレビアニメで、魔法少女をテーマにしたダークファンタジー作品です。この作品には魅力的なキャラクターが多く登場し、それぞれが異なる魅力を持っています。

まず、鹿目まどかについて説明します。彼女は物語の主人公であり、非常に優しい性格と強い正義感を持っています。彼女の純粋な心と成長する姿は、多くの視聴者に感動を与えました。

次に、暁美ほむらについて触れます。彼女は時間操作の能力を持つ魔法少女で、まどかを守るために何度も時間を遡る姿が印象的です。彼女の強い意志と忠誠心は、多くのファンに支持されています。

続いて、巴マミについて説明します。彼女は「魔法少女まどか☆マギカ」の初期メンバーの一人で、頼れる先輩魔法少女として描かれています。彼女の優雅さと強さは、多くの視聴者に安心感を与えました。

さらに、美樹さやかについても触れておきます。彼女はまどかの親友であり、正義感が強く、仲間思いの性格です。彼女の成長と悲劇的な結末は、物語の中で重要な役割を果たしています。

最後に、佐倉杏子について説明します。彼女は「魔法少女まどか☆マギカ」のもう一人の初期メンバーで、孤高の魔法少女として描かれています。彼女の強さと人間味あふれる性格は、多くのファンに愛されています。

結論として、「魔法少女まどか☆マギカ」には多くの魅力的なキャラクターが存在し、それぞれが異なる魅力を持っています。そのため、誰が一番かわいいかは視聴者の好みによるところが大きいです。しかし、鹿目まどか、暁美ほむら、巴マミ、美樹さやか、佐倉杏子のいずれもが非常に魅力的なキャラクターであり、それぞれが異なる理由で多くのファンに愛されています。
----------------------------------------------------------------------------------------------------
Q: ランダムな10個の要素からなるリストを作成してソートするコードをPythonで書いてください。
A: ```python
import random

# ランダムな10個の要素からなるリストを作成
random_list = [random.randint(1, 100) for _ in range(10)]

# リストをソート
random_list.sort()

# ソートされたリストを出力
print(random_list)
```

このコードでは、`random`モジュールを使用してランダムな整数を生成し、リスト内包表記を使って10個の要素からなるリストを作成しています。その後、`sort()`メソッドを使ってリストをソートし、最後にソートされたリストを出力しています。
----------------------------------------------------------------------------------------------------
Q: 現在の日本の首相は誰？
A: 2023年10月時点での日本の首相は、岸田文雄（きしだ ふみお）です。彼は2021年10月に首相に就任し、現在もその職にあります。
----------------------------------------------------------------------------------------------------
Q: あなたはマラソンをしています。今3位の人を抜きました。あなたの今の順位は何位ですか?ステップバイステップで考えてください。
A: マラソンの順位を考えるとき、現在の順位を「X」とすると、以下のように考えることができます。

1. 最初に1位の人を抜きます。このとき、あなたの順位は2位になります。
2. 次に2位の人を抜きます。このとき、あなたの順位は1位になります。
3. そして3位の人を抜きます。このとき、あなたの順位は2位になります。

しかし、最初に2位の人を抜いた時点であなたの順位は1位になっているので、3位の人を抜いたとしても順位は変わりません。したがって、あなたの今の順位は1位です。
----------------------------------------------------------------------------------------------------
processing_time: 11.222462892532349
total_tokens: 1454
avg. tokens per sec.: 129.56157787498861
````

推論能力は改善の余地がありますが、日本語知識は十分に備えていますね！

# まとめ

LLM-jp-3 13B instructを試してみました。
このレベルのモデルが国内でもどんどん出てきているところが本当にすごい。
学習データセットやプロセスも公開されているため、これをベースとして継続事前学習やFine-tuningなどを行って独自のLLMを開発する人・組織も増えていくのではないでしょうか。（そうなっていって欲しい）

そしてDatabricks使うと本当に手軽にLLMのAPIサーバを作れるなあ。
プロビジョ(略　APIは基盤モデルの対応範囲がもっと広がるとありがたい。。。

どんどん楽しい世界になっていくといいな！