N番煎じでShisa-7BをDatabricksで動かす

久しぶりのN番煎じシリーズです。
モデルは割と早いうちにダウンロードしていたのですが、試すのが遅くなってしまいました。

# 導入

新たな日英対応のLLMが登場しました。

https://huggingface.co/augmxnt/shisa-7b-v1

> Shisa 7Bは、日本語と英語のバイリンガル(JA/EN)汎用チャットモデルで、合成データ駆動型のアプローチにより、堅牢な英語機能を維持しながら、強力な日本語パフォーマンスを実現することを目的としています。

Mistral-7Bベースではありますが、日本語に最適化したTokenizerを採用したりなど、多くの工夫が為されているようです。

既に大先生が記事にされております。

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

N番煎じではありますが、Databricks上でこちらを試してみます。

※　余談ですが、マスコットキャラクターの名前はシーちゃんとサーちゃんらしいです。可愛い。

# やり方

今回は以下の記事で行ったExLlamaV2を使う方法で試してみます。
ExLlamaV2の使用に関する詳細は下記記事を参照ください。

https://qiita.com/isanakamishiro2/items/c1856c94d4c0227a0d9e

モデルは、以下のGPTQ量子化モデルを利用します。

https://huggingface.co/TheBloke/shisa-7B-v1-GPTQ

# Step1. 準備

まずは必要なパッケージをインストール。

```python
%pip install -U -qq transformers accelerate exllamav2 langchain

dbutils.library.restartPython()
```

次にモデルをロード。
モデルは事前にダウンロードしておいたものを利用しています。

Tokenizerの設定で、force_jsonというパラメータをTrueにしてTokenizerを作成しています。
ExLlamaV2では、指定のフォルダ内にtokenzier.modelというファイルがあるとそのモデルをファイルを使ってTokenizerを作成しようとします。
しかし、Shisaはtokenizer.modelを使ってなさそうなので、これを使わないように指定しています。

```python
from transformers import AutoModelForCausalLM, AutoTokenizer
from exllamav2_chat import ChatExllamaV2Model

model_path = "/Volumes/training/llm/model_snapshots/models--TheBloke--shisa-7B-v1-GPTQ"
chat_model = ChatExllamaV2Model.from_model_dir(
    model_path,
    system_message_template="
 
\n{}\n
",
    human_message_template="{}
",
    ai_message_template="{}",
    temperature=0,
    max_new_tokens=1024,
    repetition_penalty = 1.25,
    tokenizer_force_json=True,
)
```

langchainでプロンプトテンプレートを準備。

```python
from langchain.prompts import ChatPromptTemplate
from langchain.prompts.chat import (
    SystemMessagePromptTemplate,
    AIMessagePromptTemplate,
    HumanMessagePromptTemplate,
)

prompt = ChatPromptTemplate.from_messages(
    [
        SystemMessagePromptTemplate.from_template("You are a helpful assitant."),
        HumanMessagePromptTemplate.from_template("{query}"),
    ]
)
```

最後にChainを作成。

```python
# Importing necessary modules
from langchain.schema.output_parser import StrOutputParser
from langchain.schema.runnable import RunnablePassthrough, RunnableLambda

# Defining the pipeline which passes the user's message through a prompt, generates a response using the chat_model, and parses the output to a string.
chain = ({"query": RunnablePassthrough()} 
         | prompt 
         | chat_model
         | StrOutputParser())
```


# Step2. 推論

では、推論してみます。

まずは先生のマネで。

```python
query = "まどか☆マギカでは誰が一番かわいい?"

async for s in chain.astream(query):
    print(s, end="", flush=True)
```

```:出力
まどかのファンが多いですが、各キャラクターに独自の魅力があるので、誰が一番可愛いという意見は人それぞれです。
```

他にも聞いてみます。

```python
query = "Databricksとは何ですか？"

async for s in chain.astream(query):
    print(s, end="", flush=True)
```

```:出力
Databricksは、データ分析と機械学習のためのクラウドベースのプラットフォームです。Python、Scala、Javaなどのプログラミング言語で実行されるApache Sparkクラスタを基盤とし、AIモデルのトレーニングや予測モデリングなど、複雑なデータの処理に役立ちます。
```

破綻なく日本語文章が出力されます。
日本語能力の低い多言語モデルだと漢字が破綻したりするのですが、そういうのはなさそうですね。

では、質問以外をさせてみましょう。


```python
query = "架空の生き物をデザインし、その特徴や能力について説明してください。"

async for s in chain.astream(query):
    print(s, end="", flush=True)

```
```:出力
 タイトル：The Unicorn of the Enchanted Forest: The Legendary Creature and its Abilities

はじめに：
このテキストでは、伝説の生き物であるユニコーンとその魔法の森における特異な能力を詳しく説明します。ユニコーンの起源、生態系での役割、そしてそのユニークな特性について学びます。また、これらの魅力的で魅力的な存在の潜在的な脅威についても考察し、それらがどのようにして私たちの世界と結びついているかを探ります。

1. ユニコーンの起源: 伝説によると、ユニコーンは古代ギリシャの神話に登場する魔法の獣です。彼らはしばしば「黄金の馬」と見なされ、彼らの美しさから神聖視されています。彼らは、人間の理解を超えた力を持つという神話上の動物であり、それらは多くの場合、神秘的な力を与えるとされる精霊とのつながりを持っています。

2. 生息地：ユニコーンは、主にヨーロッパ、特にイギリス、アイルランド、およびスコットランドの広大な森に生息しています。しかし、彼らが住む場所についての最も正確な情報はほとんどありません。なぜなら、彼らの自然の生態系の保護のために、そのような情報が知られていないからです。

3. 主な行動：ユニコーンは、その優雅さと美しさがよく知られているため、通常は穏やかで平和に暮らしていると考えられています。ただし、人間や他の生物に対する攻撃性があることもあります。

4. 身体的特徴：この驚くべき種には、大きく美しい角と、鮮やかな色調の毛皮で覆われた体があります。さらに、彼らは長い首を持ち、頭には特徴的な王冠のような冠をかぶっています。

5. 食餌：ユニコーンの食事は主に植物で構成されていますが、一部の報告では昆虫を食べることさえあるようです。

6. 社会構造：ユニコーンの集団生活に関する詳細は不明ですが、おそらく群れを形成するでしょう。これは、他の多くの哺乳類と同様に、生存のために不可欠かもしれません。

7. 特異性と関連性の可能性：ユニコーンは、私たちが知っているすべての動物のように、特定の遺伝子の変異によって形成された単一の系統に属していません。代わりに、それは異なる種類の霊または神格化された種族からのブレンドとして考えられている可能性があります。

8. 潜在的に危険な性質：ユニコーンは、非常に鋭敏で速く、鋭い爪を持っていることで知られるので、危険にさらされる可能性のある野生生物の1つと見なすことができます。

9. 文化的、歴史的および宗教的意義：ユニコーンは、西洋文学、音楽、映画などのさまざまなメディアで見られる象徴的なシンボルです。この種の多様性を反映して、様々な形で表現されており、特にファンタジーの世界で、彼らは魅惑的な要素となっています。

結論として、ユニコーンの謎に満ちた歴史を通じて、私たちは彼らの特別な外見と独自の特性を発見しました。これらはすべて、彼らの物語を語り、私たち自身の想像力の限界を押し広げるのに役立ってきました。
```

論文ぽいですね。

```python
query = "ランダムな10個の要素からなるリストを作成してソートするコードをPythonで書いてください。"

async for s in chain.astream(query):
    print(s, end="", flush=True)
```

```:出力
 以下は、指定された数のランダムな要素を含むリストの生成とソートを行う Python スクリプトです。

```python
import random
from collections import OrderedDict

def generate_list(n):
    return sorted([random.randint(1, 10) for _ in range(n)])

if __name__ == "__main__":
    num = int(input("リストのサイズを入力してください: "))
    print(f"生成されたリスト: {generate_list(num)}")
``
```

コードは実際に動くものなのですが、言葉の解釈を少し間違えていますね。

```python
query = "日本国内で観光に行きたいと思っています。東京、名古屋、大阪、京都、福岡の特徴を表にまとめてください。列名は「都道府県」「おすすめスポット」「おすすめグルメ」にしてください。"

async for s in chain.astream(query):
    print(s, end="", flush=True)
```

```:出力
| 都道府県 | おすすめの観光スポット | おすすめの食べ物 |
| 東京都 | 東京のシンボルであるスカイツリーや浅草寺。寿司と和食が有名な築地市場。 | 寿司、天ぷら、おでん
| 愛知県 | 日本の文化遺産を学べる博物館や、日本一の高さを誇る大観覧車がある名古屋市科学館。味噌カツが人気です。 | 唐揚げ、ラーメン、鍋料理（特におでん）|
| 兵庫県 | 神戸港に面した公園で、桜並木で有名な六甲山ロープウェイがあります。海鮮丼がおすすめです。 | 焼き魚、刺身定食
| 京都府 | 平安時代の歴史的な建物が多く、清水寺は全国的にも有名ですね。京都の伝統菓子「抹茶」が人気です。 | 抹茶ソフトクリーム、ごま豆腐、ほうじ茶ラテ
| 福岡県 | 博多駅周辺の商業施設は、ショッピングを楽しむことができる場所ですが、屋台も楽しめます。もつ煮込みがお勧めです。 | もつ煮込み、お好み焼
```

大阪が兵庫になっていたり、マークダウンの表をうまく閉じれなかったり、なんというか惜しい。

最後に翻訳。

```python
query = \
"""次の文章を英語に翻訳してください。

Databricksは、データ分析と機械学習のためのクラウドベースのプラットフォームです。Python、Scala、Javaなどのプログラミング言語で実行されるApache Sparkクラスタを基盤とし、AIモデルのトレーニングや予測モデリングなど、複雑なデータの処理に役立ちます。
"""

async for s in chain.astream(query):
    print(s, end="", flush=True)
```

```:出力
 Databricks is a cloud-based platform for data analysis and machine learning. It's based on Apache Spark clusters that run in Python, Scala, Java among others; it helps with complex data processing such as training AI models or predictive modeling.
```

正しく翻訳してくれます。


# まとめ

Shisa-7BをDatabricks上で試してみました。

体感、非常にきちんと日本語文章を出力してくれるモデルだと思いました。
ただ、何となく「おしい」感じもあります。量子化モデルを使っているせいもあると思いますが、得手不得手をもう少し調査する必要がありそうです。

とはいえ、期待が持てるLLMです。今後も使ってみたいと思います。