商用無料、完全オープンソースの 大規模言語モデル open_llama_7b_preview_300bt が凄そうなので試してみた

# 概要

LLMかいわいは、毎月、毎週のように目を引くアップデートがありますね。

今日は、2023年GW中に登場した **商用利用** もできそうな LLaMA 互換言語モデル [open_llama_7b_preview_300bt](https://huggingface.co/openlm-research/open_llama_7b_preview_300bt) を味見してみました。

## 最近の LLaMA モデルのめぐる経緯

Meta 社がリリースした強力な LLM(大規模言語モデル) である [LLaMA](https://github.com/facebookresearch/llama) は一大ブームを引き起こしています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170905/98039cf8-f375-c220-893a-07d825d06cc2.png)


[Alpaca](https://crfm.stanford.edu/2023/03/13/alpaca.html) や [Vicuna](https://github.com/lm-sys/FastChat) といったラマ🦙の近縁種の名前がついたモデルたちも人気がありますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170905/4573f84a-2236-4cca-65a4-ede760002109.png)

ここでポイントですが、LLaMA のトレーニングデータや学習済の重みデータは **学術目的の利用に限られて** いました

こうした中、最近、トレーニングデータや学習済の重みデータのライセンスをオープンにしようという流れが起こりつつあります。

（20年前のオープンソース論争のように、オープンにすることのベネフィットとリスクが AI の世界でも活発に[議論](https://venturebeat.com/ai/redpajama-replicates-llama-to-build-open-source-state-of-the-art-llms/)されはじめています。大事なことだとおもいます）

さて、オープンソース化を進める動きとして、まず2023年4月に LLaMA のトレーニングデータのオープンソース版として 颯爽と登場したのが [Together](https://github.com/togethercomputer) の **[RedPajama](https://github.com/togethercomputer/RedPajama-Data)** というデータセットです。このデータセットは LLaMA のトレーニングデータセット相当を目指しており、ライセンスは Apache 2.0 となっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170905/f091f998-ccdc-51a0-0498-a927979c5820.png)


さらに、つい先日の 2023年5月3日に、この **RedPajama** データセットをつかって学習をした学習済重みデータが [open_llama_7b_preview_300bt](https://huggingface.co/openlm-research/open_llama_7b_preview_300bt) が公開されました。この学習済重みデータのライセンスも Apache 2.0　です。

つまり、論理的には、この学習済データを使えば、 LLaMA ベースの言語モデルが商用利用できる　ということになりそうです。

さっそく試してみました。



## open_llama_7b_preview_300bt とは

- RedPajama の 3000億トークンでトレーニングされた　70億パラメータのモデル(チェックポイント)
- まだプレビュー段階だそう
- 先行して 2000億トークンのモデルもリリースされている。こちらは、入力トークンに BOS を付加しないと結果がイマイチらしい。3000億トークンは BOS 入れなくてもいい感じなので、そっちがオススメとのこと。

# お試し手順

## 試した環境

- OS: Ubuntu 20.04 
- CUDA: 11.7
- GPU: RTX 3090

**(遅いけどCPUでも動作します)**

## パッケージのインストール

```
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu117
pip install accelerate transformers
pip install SentencePiece
```

## ソースコード

お試し用に作ったソースコードは以下となります。

```
git clone https://github.com/riversun/open_llama_7b_hands_on.git
python main.py
```

一般的な HuggingFace Transformer をつかった LLM 処理のソースコードですが、いくつかハマったポイントがあったので、ハマった部分を中心に説明していきます。


## 試したときの様子

こんな感じで動きました

- 文章生成は動作している模様
- かなり軽快に動作する

<iframe width="1268" height="713" src="https://www.youtube.com/embed/R5dlEuG7FDc" title="First look at &quot;open_llama_7b_preview_300bt&quot; model" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

## いろいろハマったところ

### ポイントその１ HuggingFace 用の Transformer モデルが一段深いところにある

モデルはHuggingFace のココ→ https://huggingface.co/openlm-research/open_llama_7b_preview_300bt にあるので、モデル名を軽いノリで "openlm-research/open_llama_7b_preview_300bt" と指定するとうまくいかない。


```python:失敗例
model_name="openlm-research/open_llama_7b_preview_300bt"

tokenizer = LlamaTokenizer.from_pretrained(model_name, add_eos_token=True)

model = LlamaForCausalLM.from_pretrained(
        model_name, low_cpu_mem_usage=True, **kwargs
    )
```

上記のようにやってもうまくいかないので、いったんローカルに落としてから使うことにした

```
git clone https://huggingface.co/openlm-research/open_llama_7b_preview_300bt
```

```python:成功例
model_path ="/home/user/sandbox/open_llama_7b_preview_300bt/open_llama_7b_preview_300bt_transformers_weights"


tokenizer = LlamaTokenizer.from_pretrained(model_path, add_eos_token=True)

model = LlamaForCausalLM.from_pretrained(
        model_path, low_cpu_mem_usage=True, **kwargs
    )
```

### ポイントその２ LLaMa 用のモデルローダー、トークナイザーを使おう

モデルのロード、トークナイザは Llama 用のもの(LlamaTokenizer,LlamaForCausalLM)を使うのが吉

### ポイントその３ BOS と EOS を正しくセットしよう

BOS = Begin Of Sentence、 EOS = End Of Sentence のトークンIDを手動セットする。

EOS で文章生成を停止させようとしていたが、生成トークン数を増やしても、ダラダラと文章を生成しつづけるので、どうしてかなーとおもったら `tokenizer.bos_token_id` と `tokenizer.eos_token_id` がセットされていなかった。（というか、0にセットされていた)

LLaMa のお作法にあわせて、 `tokenizer.bos_token_id=1  tokenizer.eos_token_id=2` とした。

### ポイントその４ open_llama_7b_preview_200bt は入力トークンの先頭 BOS を忘れずに

[open_llama_7b_preview_200bt
](https://huggingface.co/openlm-research/open_llama_7b_preview_200bt) を使うときは、入力トークン列の先頭にBOSトークンをはさむと、いい感じになる。

```
input_ids = [tokenizer.bos_token_id] + tokenizer(prompt).input_ids
```

### ポイントその５ tokenizer.eos_token_id=2 とすると生成結果があやしくなる

ポイントその３で説明したばかりだが、 `tokenizer.eos_token_id=2` のように強制セットするのはダメかもしれない。停止条件として EOS トークンを使いたいだけなら、生成中に 生成された トークンID が　EOSかを判定するだけで十分

```python
            stop_token_ids=[2]
# 中略
            if token_id in stop_token_ids:
                stopped = True
            else:
                stopped = False
```

### ポイントその６　単純な入力プロンプトだと、同じようなセンテンスを生成しつづける

これはこのモデルに限ったことじゃないが、それを抑制するために、
トップKサンプリングを導入した。上位K位のトークンを選択し、その中からランダムに1つを選ぶ。
このほうがいい感じの生成結果につながった。

以下のトップKの関数は ChatGPT に作ってもらった :)

```python:トップK
            def top_k_sampling(logits, k=top_k_value):
                top_k = torch.topk(logits, k)
                top_k_indices = top_k.indices
                top_k_values = top_k.values
                probabilities = torch.softmax(top_k_values, dim=-1)
                choice = torch.multinomial(probabilities, num_samples=1)
                token_id = int(top_k_indices[choice])
                return token_id
```

# まだ、ハマってるところ

今回ためしたのは、いわゆる **text continuation** (与えられたテキストの続きを生成する) だったが、今まだうまくいっていないのが、二者間のチャット。USER と ASSISTANT にわかれてチャットをするような ChatGPT 的な機能。

LLama で実績のある[初期プロンプト](https://github.com/facebookresearch/llama/issues/162) を食わせると、コンテクストも維持しつつなんとなく６割くらい動いているが、途中からズレてくる。ヒューリスティックにトークナイズする手もあるけど、もうすこし要スタディ。

<iframe width="793" height="446" src="https://www.youtube.com/embed/e5e5y1ygea0" title="Try to chat with open_llama_7b_preview_300bt" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

# まとめ

- リリースされたばかりの **open_llama_7b_preview_300bt** をお試しして、ファーストルックをご紹介しました。
    - いくつかハマりポイントはあったものの、一応うごくというレベルまでお試ししました。
    - ChatGPTのような二者間チャットは、まだ道半ばな感じなので初期プロンプトの与え方やトークナイズをスタディしていきたいとおもいます。

- ちなみに、 RedPajama リリース元の Together 自身もRedPajamaデータセットをトレーニング中だそうですが、まだ 2023/05/05 時点で、学習済の重みはリリースされていません。データセットが公開されたら本家よりも先に[ちらほら](https://huggingface.co/mosaicml/mpt-1b-redpajama-200b) 学習済モデルがリリースされるあたり、本当に、この分野は活発ですね。
- 先日 [Dolly V2 をお試し](https://qiita.com/riversun/items/7c45580f1a098b041528) しましたが、 Dolly V2 も商用無料なオープンソースとしてかなり話題となりました。今後、制約の緩いオープンソース系LLMが席巻するのか、あくまで最先端のものは Gated なリリースが続くのかどちらの流れになっていくのか注目しています。