N番煎じでMeta社のLlama3 8B Instructを試す

流行りに乗ります。正しくｎ番煎じ。

# 導入

Meta社が新たなLLMとして[Llama3](https://ai.meta.com/blog/meta-llama-3/)を公開しました。

https://ai.meta.com/blog/meta-llama-3/

Llama3は幅広い業界ベンチマークで最先端のパフォーマンスを実証し、推論の改善などの新機能を提供します。
現時点で8Bと70Bのボリュームと、それぞれベースモデル・指示チューニングされたモデルが公開されており、それぞれベンチマークにおいて高いスコアを記録しています。
また、400B超の大型モデルも現在学習中とのことで、より高性能なモデルもやがて公開される予定のようです。
ライセンス形態はLlama2ライセンスを拡張したLlama3ライセンスとなります。

今後、パートナー各社のサービスとしても提供される予定であり、例えばDatabricks社からも公式Blogでアナウンスされていました。

https://www.databricks.com/blog/building-enterprise-genai-apps-meta-llama-3-databricks

その他、同時に[Llama Guard 2](https://llama.meta.com/trust-and-safety/)などの信頼性を高めるためのツール・モデルも公開されています。

なお、Llama3はhuggingface chat等で試すこともできます。

https://huggingface.co/chat/models/meta-llama/Meta-Llama-3-70B-instruct

<br>

界隈でも大きく盛り上がっており、既に以下のような方々が試され、記事化されております。

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

https://qiita.com/taka_yayoi/items/3454f1d94e2e4a1ea7bb

先達に倣って、こちらも試してみます。

今回は、以下の8B Instructモデルについて、EXL2形式に8bitで量子化したもので推論してみます。
利用にあたってはポリシーへの同意が必要です。

https://huggingface.co/meta-llama/Meta-Llama-3-8B-Instruct

検証はDatabricks on AWSを利用しました。
DBRは14.3ML、クラスタタイプはg5.xlargeです。
推論エンジンにはExLlamaV2を利用します。

:::note warn
量子化したモデルを利用していますので、本来のモデルとは出力結果が異なるであろうことに注意ください。
:::


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

いつものように推論に必要なパッケージをインストール。

```python
%pip install torch==2.2.2 --index-url https://download.pytorch.org/whl/cu118
%pip install ninja
%pip install -U flash-attn --no-build-isolation

%pip install https://github.com/turboderp/exllamav2/releases/download/v0.0.18/exllamav2-0.0.18+cu118-cp310-cp310-linux_x86_64.whl

dbutils.library.restartPython()
```

# Step2. モデルのロード

事前に以下のEXL2量子化モデルをダウンロードしておき、そのモデルをロードします。
今回は8.0bpwで量子化されたモデルを利用しました。

https://huggingface.co/bartowski/Meta-Llama-3-8B-Instruct-special-tokens-exl2

```python
from exllamav2 import (
    ExLlamaV2,
    ExLlamaV2Config,
    ExLlamaV2Cache_Q4,
    ExLlamaV2Tokenizer,
)

from exllamav2.generator import ExLlamaV2BaseGenerator, ExLlamaV2Sampler


batch_size = 1
cache_max_seq_len = 4096

model_directory = "/Volumes/training/llm/model_snapshots/models--bartowski--Meta-Llama-3-8B-Instruct-special-tokens-exl2--8_0/"

config = ExLlamaV2Config(model_directory)

model = ExLlamaV2(config)
print("Loading model: " + model_directory)

cache = ExLlamaV2Cache_Q4(
    model,
    lazy=True,
    batch_size=batch_size,
    max_seq_len=cache_max_seq_len,
) 
model.load_autosplit(cache)

tokenizer = ExLlamaV2Tokenizer(config)
generator = ExLlamaV2BaseGenerator(model, cache, tokenizer)

# サンプリングの設定
settings = ExLlamaV2Sampler.Settings()
settings.temperature = 0.0
settings.top_k = 50
settings.top_p = 0.9
settings.token_repetition_penalty = 1.05

max_new_tokens = 512
```

# Step3. バッチ推論

[以前、DBRX Instructを試した](https://qiita.com/isanakamishiro2/items/0ce0fc9917f749d96f2f)ときと同じ内容の問題を解かせてみます。

システムプロンプトはかなり適当です。
また、ストップトークンをTokenizerの設定に記載されているeos_tokenではなく、別のトークン（
）に置き換えています。公式リポジトリでもこのあたり触れられています。

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

# パディングを最小化するために文字列サイズでソート
s_prompts = sorted(prompts, key=len)

# プロンプトを整形
def format_prompt(sp, p):
    return f"
system
\n\n{sp}

user
\n\n{p}

assistant
\n\n"

# 日本語で返すようにシステムプロンプトを設定
system_prompt = "あなたは日本語を話すAIアシスタントです。"

f_prompts = [format_prompt(system_prompt, p) for p in s_prompts]

# 生計済みプロンプトをバッチに分割
batches = [f_prompts[i : i + batch_size] for i in range(0, len(prompts), batch_size)]

collected_outputs = []
for b, batch in enumerate(batches):

    print(f"Batch {b + 1} of {len(batches)}...")

    outputs = generator.generate_simple(
        batch,
        settings,
        max_new_tokens,
        seed=1234,
        add_bos=True,
        completion_only=True,
        stop_token=tokenizer.encode("
").item(),
    )
    collected_outputs += outputs

# 結果出力
for q, a in zip(s_prompts, collected_outputs):
    print("---------------------------------------")
    print("Q: " + q)
    print("A: " + a.strip())
```

````:出力
Batch 1 of 6...
Batch 2 of 6...
Batch 3 of 6...
Batch 4 of 6...
Batch 5 of 6...
Batch 6 of 6...
---------------------------------------
Q: 現在の日本の首相は誰？
A: 2021年10月現在、 日本の内閣総理大臣（首相）は、岸田文雄（Kishida Fumio）です。
---------------------------------------
Q: まどか☆マギカでは誰が一番かわいい?
A: 😊

まどか☆マギカのキャラクターたちはみなかわいいですが、人気投票ではソウルジェネレーターとして登場するキュゥべえが一番かわいいと評判されています！ 🐰💕

しかし、ファンの個々の好みは異なりますから、実際には各キャラクターに愛着を持つ人も多いと思います。まどか、ミサカ、サヤカ、キュゥべえ、Homuraなど、各キャラクターの魅力的な面が多くありますから、誰が一番かわいいかは結局、個人の好み次第です！ 😊
---------------------------------------
Q: Hello, what is your name?
A: Konnichiwa My name is AI Assistant, but you can call me "AI" for short. I'm a Japanese-speaking AI assistant, and I'm here to help you with any questions or tasks you may have. Ogenki desu ka? (How are you?)
---------------------------------------
Q: Databricksとは何ですか？詳細に教えてください。
A: Databricksは、Apache Sparkを基盤としたデータエンジニアリングプラットフォームです。2013年に設立されたDatabricksは、Sparkの創始者であるMatei ZahariaとIon Stoicaによって創業されました。Databricksは、Sparkを基盤としたクラウドベースのデータプラットフォームを提供しています。

Databricksの主要な機能は以下の通りです。

1. **Apache Spark**: Databricksは、Apache Sparkを基盤としています。Sparkは、高速でスケーラブルなデータ処理を実現するためのオープンソースのデータ処理フレームワークです。
2. **Cloud-based**: Databricksは、クラウドベースのプラットフォームを提供しています。ユーザーは、AWS、Azure、GCPなどのクラウドプロバイダーを通じてDatabricksにアクセスできます。
3. **Unified Analytics Platform**: Databricksは、統合された分析プラットフォームを提供しています。ユーザーは、データのインポート、変換、分析、ビジュアライゼーションなど、複数のタスクを一つのプラットフォーム上で実行できます。
4. **Collaboration**: Databricksは、チームでの協力的な開発を可能にします。ユーザーは、共同でプロジェクトを開発し、コードを共有、レビュー、メンテナンスすることができます。
5. **Security**: Databricksは、セキュリティーを重視しています。ユーザーは、暗号化されたストレージ、IAMロール、RBACなど、多くのセキュリティー機能を使用して、データを保護できます。
6. **Scalability**: Databricksは、スケーラブルな設計をしています。ユーザーは、大量のデータを処理するために、自動的にスケールアップやスケールダウンを行うことができます。
7. **Integration**: Databricksは、多くのデータソースと統合されています。ユーザーは、S3、HDFS、Azure Blob Storage、Google Cloud Storageなど、多くのデータソースにアクセスできます。

Databricksは、データエンジニアリング、データサイエンス、ビジネスインテリジェ
---------------------------------------
Q: あなたはマラソンをしています。今3位の人を抜きました。あなたの今の順位は何位ですか?
A: やった！3位の人を抜きました！これで、2位になりました！
---------------------------------------
Q: ランダムな10個の要素からなるリストを作成してソートするコードをPythonで書いてください。
A: 以下は、ランダムな10個の要素からなるリストを作成し、そのリストをソートするPythonのコードです。
```python
import random

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

# ソート
sorted_list = sorted(random_list)
print("Sorted list:", sorted_list)
```
このコードでは、`random.randint(1, 100)` を使用して、ランダムな整数を生成し、リストに追加しています。`sorted()` 関数を使用して、リストをソートしています。

実行結果例：
```
Original list: [43, 91, 13, 67, 25, 82, 31, 58, 46, 19]
Sorted list: [13, 19, 25, 31, 42, 46, 58, 67, 82, 91]
```
Note: `random.randint(1, 100)` は、1以上100以下のランダムな整数を生成します。必要な範囲を指定する場合は、`random.randint(a, b)` のように、aとbを指定してください。
````

ハルシネーションは当然存在しますが、このサイズで非常にきちんとした日本語での応答をしてくれます。
（あと、割と絵文字を出力してくる）
70Bサイズも別途試してみたいと思います。

# まとめ

Llama2の登場からまだ1年足らずなんですよね。その時と比べても大きく進化してきているなという印象です。

というか、この1週間で試したいモデルがどんどん出てきていて、追い付かない状態。
Llama3をベースモデルとしたカスタムモデルもこれから大量に出てくるでしょうし、この界隈は益々盛り上がっていくように思います。