N番煎じで量子化したQwen2を試す on Databricks

# 導入

Alibaba社が大規模言語モデルQwenシリーズの新モデルであるQwen2を公開しました。

https://qwenlm.github.io/blog/qwen2/

Qwen2では、Mixture-of-Expertsモデルを含む、0.5から72BパラメータのLLMを公開しています。
詳細は上記Blog等を参照いただきたいのですが、128kのコンテキスト長を備え、72BモデルにおいてはMeta社のLlama3-70Bを超える性能をうたっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168727/09730ce5-5e12-49b8-93c5-a79f4658fe8e.png)

また、72Bモデル以外はApache 2.0ライセンスで公開されています。

Qwenは日本語性能が高い一方で中国語がちょくちょく混ざる問題を感じていたのですが、Qwen2ではかなり改善されたようです。

というわけでいつも通り試してみます。
今回は7B-instructモデルと72B-instructモデルの2種を試します。

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

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


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

いつものように推論に必要なパッケージをインストール。
推論エンジンは```exllamav2```を利用します。

```python
%pip install torch==2.3.0 --index-url https://download.pytorch.org/whl/cu121

%pip install -U flash-attn --no-build-isolation
%pip install https://github.com/turboderp/exllamav2/releases/download/v0.1.4/exllamav2-0.1.4+cu121.torch2.3.0-cp311-cp311-linux_x86_64.whl

dbutils.library.restartPython()
```

# Step2. モデルのロード

事前に以下のEXL2量子化モデルをダウンロードしておき、そのモデルをロードします。

7Bモデル(6.5bpwで量子化)、72Bモデル(4.65bpwで量子化)それぞれ以下のものを利用しました。

https://huggingface.co/bartowski/Qwen2-7B-Instruct-exl2

https://huggingface.co/LoneStriker/Qwen2-72B-Instruct-4.65bpw-h6-exl2

```python
from exllamav2 import (
    ExLlamaV2,
    ExLlamaV2Config,
    ExLlamaV2Cache,
    ExLlamaV2Cache_Q4,
    ExLlamaV2Tokenizer,
    Timer,
)
from exllamav2.generator import (
    ExLlamaV2DynamicGenerator,
    ExLlamaV2DynamicJob,
    ExLlamaV2Sampler,
)
import exllamav2.tokenizer

total_context = 32768
max_chunk_size = 4096
paged = True
max_batch_size = 20 if paged else 1

# 7Bの場合
model_dir = "/Volumes/training/llm/model_snapshots/models--bartowski--Qwen2-7B-Instruct-exl2--6_5/"

# 72Bの場合
# model_dir = "/Volumes/training/llm/model_snapshots/models--LoneStriker--Qwen2-72B-Instruct-4.65bpw-h6-exl2/"


config = ExLlamaV2Config(model_dir)
config.max_input_len = max_chunk_size
config.max_attention_size = max_chunk_size**2

model = ExLlamaV2(config)
cache = ExLlamaV2Cache_Q4(model, max_seq_len=total_context, lazy=True)
model.load_autosplit(cache, progress=True)

tokenizer = ExLlamaV2Tokenizer(config)

generator = ExLlamaV2DynamicGenerator(
    model=model,
    cache=cache,
    tokenizer=tokenizer,
    max_batch_size=max_batch_size,
    max_chunk_size=max_chunk_size,
    paged=paged,
)
generator.warmup()

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

max_new_tokens = 400
```

# Step3. バッチ推論

いくつかの質問をバッチ推論してみます。(7B/72B共通)

```python
def format_prompt(sp, p):
    return f"
system\n{sp}
\n
user\n{p}
\n
assistant"

# 今回推論する内容
prompts = [
    "Databricksとは何ですか？詳細に教えてください。",
    "まどか☆マギカでは誰が一番かわいい?",
    "ランダムな10個の要素からなるリストを作成してソートするコードをPythonで書いてください。",
    "現在の日本の首相は誰？",
    "あなたはマラソンをしています。今3位の人を抜きました。あなたの今の順位は何位ですか?",
    "大阪の観光名所を3カ所、その特徴と合わせて教えてください。",
    "日本で２番目に高い山は何？",
]

system_prompt = "あなたは日本語を話すAIアシスタントです。"
f_prompts = [format_prompt(system_prompt, p) for p in prompts]

with Timer() as t:
    outputs = generator.generate(
        prompt=f_prompts,
        max_new_tokens=max_new_tokens,
        add_bos=True,
        gen_settings=settings,
        completion_only=True,
        stop_conditions=[tokenizer.eos_token_id, tokenizer.single_id("
")],
    )

total_num_tokens = 0
for idx, output in enumerate(zip(prompts, outputs)):
    print(f"--- Batched completion #{idx + 1} ---")
    print("Q: ", output[0])
    print("A: ", output[1])
    print()
    total_num_tokens += tokenizer.num_tokens(output[1])

print("--------------------------------------------------------------------------")
print(f"generated {total_num_tokens} tokens")
print(f"speed, bsz {len(prompts)}: {total_num_tokens / t.interval:.2f} tokens/second")
```

7B/72B各モデルの推論結果は以下のようになりました。

### 7Bの場合

````:7B 出力
--- Batched completion #1 ---
Q:  Databricksとは何ですか？詳細に教えてください。
A:  : Databricksは、クラウードデータ分析と機械dbe学習を効率的に実行うべるための、クラウドベースのプラットフォームです。Apache Spark、ML、Mlibなど、オープンソーストのテクノロジを基盤に構成されていて、データエンジニア、データサイエンスト、マス科学者などに対して利用が可能です。

以下に主なな��能について詳しくに説べます：

1. **高速なデータ処理**: Apache Sparkを使用して、非常に高速かつ効率的なデータ処理を行うことができます。これは大量のデータを効率的に処理することが必要となる大規模なビジネスインテリビューややリアルタイムアナリティなどに適しています。

2. **機械学習**: Databricksは、Python、Scala、Rを使って機械学習のアルツを実行できます。これにより、データサイエンツやデータサイエンリストが、自身のスキルセットを利用して機械学習モデルを作成し、テストすることができるようになります。

3. **統合されたワークスペース**: Jupyter、Python、またはRのセルを含む統合されたワークスペースが提供されています。これにより、データサイイツ、エンジニア、データサイエンツが協力し、コードを共有し、レビューすることができます。

4. **クラウドベースのデプロ**: AWS、Azure、Google Cloudなど、主要なクラウドサービスと統合でき、任意のクラウド上で稼動させることが可能で、スケールやデプロ環境の管理を簡単化します。

5. **セキュリティ**: デデータは常に暗号化され、アクセスは権認定された quindi安全に扱理されます。また、Databricksは高度な監視と警備システム

--- Batched completion #2 ---
Q:  まどか☆マギカでは誰が一番かわいい?
A:  
「まどか☆マギカ」楽し�楽し�のキャラクターたち全員がとても魅力的で、それぞれが素晴らしいのキャラクタです。それぞれがユニーな個性と成長のストーリーンを通じて愛されるべきキャラクタアリです。一番かわわいいというものは主観の感想ですので、他のの者が選ぶることは必ず一様なとなります。

それでも多くの人々から高い人気を誇るキャラクターと言えば、可能ならびんの「小面向（さくら）」や「鹿目三千院（かのめ さんせんいんん）」などが挙りえられます。どちらも独特のキャラクタアであり、愛される理由は様々だと思います。

--- Batched completion #3 ---
Q:  ランダムな10個の要素からなるリストを作成してソートするコードをPythonで書いてください。
A:  
もちろん、Pythonの標準ライブラリを使用して以下のコードを作成します。

このコードでは、リストにランダムな10個の要素を挿加し、それらをソートします。

```python
import random

# ラランダムな10個の要素を挿りつ加える
lista = [random.randint(0, 100) for _ in range(10)]

# ソートを行う
lista.sort()

# リリストを出力
print(lista)
```

このプログラムを実行すると、10個のランダムな整数が作成され、それらをソートしたリストが出力されます。ただしる、毎毎ごとに異なる結果を得るでしょう。

--- Batched completion #4 ---
Q:  現在の日本の首相は誰？
A:  
現在の日本の首相は菅义偉（かん）と答える、阁僚楽し�です。更新日時：2年b月dd日。ただし、政治の領域は変动性が高く、速やかにご確認ください。

--- Batched completion #5 ---
Q:  あなたはマラソンをしています。今3位の人を抜きました。あなたの今の順位は何位ですか?
A:   updatedAt楽し�、あなたがマラソンをしていますし、その結果として3位の人を抜いたとします。そのことから-followする、あなたの現在の順位は3位です。

--- Batched completion #6 ---
Q:  大阪の観光名所を3カ所、その特徴と合わせて教えてください。
A:  : .ToShort答えるなら、以下が大阪の観光スポット4カ所です。

1. 大阪城: この歴は日本の歴史的な建築物で、特に天守閣は有名です。周囲には大黒公園があり、美しい眺めが楽しめます。また、毎年1月に行われるの大黒祭りは非常に賑にぎます。

2. ��本屋大[]={: このエリアは「小説の町」とも呼ばれ、多くのレストランやショッピングショップが並んでいます。和食から洋食まで様々なメニューがあるので、観観な人々が訪れます。また、毎は日本の伝統的な文化を楽しめる場所でもあります。

3. 必空港ビルディング: このビルは、大阪空港のシンボルとして知bdb。夜景は特に美しいとされ、観光客にとって絶対のスポットとなっています。また、ビル内の観店やも見ごたいです。

4. ��浪堂: ��浪堂は、大阪の象徴で、特に焼酎作りが有名です。焼酎博物館があり、その歴史と製造方法について詳しく学ぶことができます。また、自らの焼酎を集めも楽しむことができます。

以上が大阪の観光名所の一部ですが、それぞれの場所には独自の魅力が詰め込まれており、訪れる人に合った楽しみが見つついています。

--- Batched completion #7 ---
Q:  日本で２番目に高い山は何？
A:  : 日本で２番目に高い山は富士山です。ただし、質問の文脈から推測すると、富士山が二番目最高の山是不是という理解是在下为您查询的是。日本の最高峰である富士山の次に高い山は桐生山（あきゅうさん）で、標高は2,91m被誉为存在。

--------------------------------------------------------------------------
generated 1222 tokens
speed, bsz 7: 86.68 tokens/second
````

### 72Bの場合

````:72B 出力
--- Batched completion #1 ---
Q:  Databricksとは何ですか？詳細に教えてください。
A:  
Databricksは、Apache Sparkの共同創設者によって作成されたデータ分析プラットフォームです。このプラットフォームは、データエンジニア、データサイエンティスト、データアナリストが協力してデータを処理し、分析し、機械学習モデルを作成するためのツールを提供します。

以下にDatabricksの主な特徴をいくつか挙げてみましょう：

1. **スケーラビリティ**：Databricksはクラウドベースのサービスであり、データ量やユーザー数が増えてもスムーズに対応できます。

2. **統合されたワークスペース**：Databricksは、データの準備、変換、視覚化、共有、そして機械学習モデルの作成と展開を行うための統合された環境を提供します。

3. **Apache Sparkのパワフルな��能**：DatabricksはApache Sparkを利用しており、これにより高速で効率的なデータ処理が可能になります。

4. **セキュリティと管理**：Databricksは企業レベルのセキュリティと管理��能を備えており、データのプライバシーとコンプライアンスを確保します。

5. **MLflowとDelta Lake**：Databricksは、機械学習プロジェクトのライフサイクル全体を追跡し、管理するためのMLflowというツールと、高性能でスケーラブルなデータレイクとして��能するDelta Lakeを含んでいます。

これらの特性により、Databricksは大規模なデータセットに対する高度な分析と機械学習のニーズを満たす強力なツールとなっています。

--- Batched completion #2 ---
Q:  まどか☆マギカでは誰が一番かわいい?
A:  
その質問の答えは個々の好みによるところが大きいですが、多くのファンから高い人気を博しているのは鹿目まどかや暁美ほむら、そして美樹さばきなどです。特に、まどかは物語の中心的なキャラクターであり、その純粋さと強さで多くの人々に愛されています。しかし、それぞれのキャラクターには独自の魅力があり、誰が一番可愛いのかは視聴者の感性によります。

--- Batched completion #3 ---
Q:  ランダムな10個の要素からなるリストを作成してソートするコードをPythonで書いてください。
A:  
もちろんです、以下にPythonを使ってランダムな整数のリストを作成し、それをソートするコードを示します。

```python
import random

# ランダムな10個の要素を持つリストを作成
list_random = [random.randint(0, 100) for _ in range(10)]
print("Unsorted List: ", list_random)

# リストをソート
list_sorted = sorted(list_random)
print("Sorted List: ", list_sorted)
```

このコードでは、`random.randint(0, 100)`を使用して0から100までのランダムな整数を生成しています。そして、`sorted()`関数を使用してリストをソートしています。

--- Batched completion #4 ---
Q:  現在の日本の首相は誰？
A:  : 2021年現在、日本の首相は菅義偉（よしひろ）です。ただし、これは変動する情報ですので、最新の情報を確認するためには信頼できるニュースソースをご覧ください。 (2023年以降の情報については、私が更新されていない場合もありますのでご注意ください。) 

最新の情報によれば、2021年9月から日本の首相は岸田文雄（ふみお）です。

--- Batched completion #5 ---
Q:  あなたはマラソンをしています。今3位の人を抜きました。あなたの今の順位は何位ですか?
A:  
あなたは今3位です。先ほどまで3位だったランナーを抜いたので、そのランナーの位置、つまり3位を引き継いだことになります。

--- Batched completion #6 ---
Q:  大阪の観光名所を3カ所、その特徴と合わせて教えてください。
A:  
もちろんです、大阪には多くの魅力的な観光地がありますが、以下に3つをご紹介します。

1. 「大阪城」: 大阪の象徴とも言えるこの城は、豊臣秀吉によって16世紀に建設されました。現在の天守閣は再建されたものですが、内部は博物館になっており、豊臣秀吉やその時代について学ぶことができます。また、周囲の大公園では四季折々の自然を楽しむことができます。

2. 「通天閣」：新世界エリアにあるこの塔は、大阪の下剋上精神を象徴する存在です。展望台からは大阪の街並みを一望できます。また、周辺には美味しい串カツや焼鳥の店がたくさんあります。

3. 「ユニバーサル・スタジオ・ジャパン」：映画やテレビの世界を体験できるテーマパークで、ハリーポッターやミニオン、ジュラシックパークなど、人気の映画の世界が再現されています。大人から子供まで楽しめるスポットです。

これらの場所はそれぞれ異なる魅力を持ち、訪れる人々に楽しい時間を提供しています。

--- Batched completion #7 ---
Q:  日本で２番目に高い山は何？
A:  
日本で2番目に高い山は、北アルプスにある「北岳」です。標高は3,192メートルです。ただし、測量の方法や基準点により、キレトリアンコウ（剣山）や焼岳などが2位とも言われることがあります。最も一般的に言われるのは北岳です。

--------------------------------------------------------------------------
generated 1121 tokens
speed, bsz 7: 24.25 tokens/second
````

7Bはおそらく量子化の影響かプロンプトの問題で回答が壊れてしまっているものが結構あります。
72Bは非常に素晴らしい結果です。部分的におかしな文字や微妙なハルシネーションがありますが、かなり賢く推論されています。

72Bはライセンスの制約や、実行環境の用意が大変だったりしますが、性能面では非常に魅力的な選択肢かと思いました。

# まとめ

Qwen2を少し試してみました。
量子化せずにTransformersやvLLMで動作をさせるとおそらく性能面ではもっとよい結果を得られると思います。
最近はライセンスもApache-2.0やMITで提供されるLLMも増えてきており、商用的にも利用しやすくなってきました。
オープンLLMの盛り上がりはまだまだ続きそうです。