ローカル日本語LMお試しセット

Docker-composeで構築する、ローカル（つまり手元のPC内で動く）日本語の言語モデル環境セットを御用意しました。


## モチベーション
ChatGPT登場以降、AIによる自然言語処理はすっかり[スケーリング則](https://deeplearning.hatenablog.com/entry/scaling_law)による規模の勝負になってしまった感があって、今や、[クラウド業者は電力確保のため原子炉を保有](https://jp.reuters.com/markets/commodities/GKRDU47HE5KGZJN2ZNFGWGNNUU-2024-10-16/)するまでになってしまいました。LLM（巨大自然言語処理モデル）の規模も、パラメータサイズが100B（1千億）はもはや普通レベル、APIで利用するクラウドモデルでは1～2Tとも噂されています。

ところが、[ここ](https://wandb.ai/wandb-japan/llm-leaderboard3/reports/Nejumi-LLM-3--Vmlldzo3OTg2NjM2?accessToken=wpnwc9whr96pxm40dfe4k3xq513f9jc4yhj7q6pnvj4jtayoefbc77qhzbsrztgz)を見ると、並み居るAPIモデルに混ざって10B以下のモデルもランキングに肩を並べています。これら、_Middle_ LMとも言えるモデルのうち、オープンソース・[オープンウェイト](https://rimo.app/blogs/open-weight)のものについては、（加工の上）手元のGPUのないPCでも動かすことが可能です。特に、日本で開発されたモデルは、試してみると数値から想像される以上に日本語の能力は高く、[チューリングテスト](https://ja.wikipedia.org/wiki/%E3%83%81%E3%83%A5%E3%83%BC%E3%83%AA%E3%83%B3%E3%82%B0%E3%83%BB%E3%83%86%E3%82%B9%E3%83%88)も難なくクリアできるのではないかと思ってしまいます。

この驚きを共有したく、Docker環境で動作するローカル日本語LMを用意しました。

## 始め方

以下のファイルをどこかのフォルダに置いてください。
```docker-compose.yml
services:
  ollama:
    image: ghcr.io/sin-gee/ollama-japanese-set:0.0.1
    container_name: ollama
    tty: true
    ports:
      - "11434:11434"
    volumes:
      - .:/root/.ollama

  open-webui:
    image: ghcr.io/open-webui/open-webui:main
    container_name: open-webui
    ports:
      - "3000:8080"
    volumes:
      - .:/app/backend/data
    environment:
      - 'OLLAMA_BASE_URL=http://ollama:11434'
      - 'WEBUI_AUTH=False'

volumes:
  ollama:
  open-webui:
```

Dockerを起動し、ターミナルからコマンド打ち込んでください。
```console
> docker compose up -d
```

ブラウザからhttp://localhost:3000 を開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3921213/3530b03e-f536-37ff-8f0f-5ba79b9ee6e2.png)

ちなみに[Tanuki](https://weblab.t.u-tokyo.ac.jp/news/2024-08-30/)は、東大松尾・岩澤研に集まった有志により（他の日本語対応モデルが[Llama](https://www.llama.com/)や[Gemma](https://blog.google/technology/developers/gemma-open-models/)をベースにすることが多いのに対し）フルスクラッチで作られたオープンソース・オープンウェイトのLLMです。ライセンスは[Apache2.0](https://licenses.opensource.jp/Apache-2.0/Apache-2.0.html)。[Dpo](https://miu-ai-techblog.com/about_rlhf_dpo/)は、人間の嗜好に合う（つまり、不気味、暴力的、反社会的な言葉を返さない）ようチューニングした方式、8bは、モデルサイズ、Q6_Kは、[量子化（によるモデルサイズの圧縮）](https://qiita.com/xxyc/items/e8deb8dd2366a5e52345)方式、[7shi](https://x.com/7shi)は、モデルパラメータをPC環境/[ollama](https://ollama.com/)で動作するよう変換をされた方です。([[1]](https://zenn.dev/mkj/articles/93dbd6c9d94c58))

## 対話してみる

チャーハンの作り方を聞いてみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3921213/e993e9d5-b0fa-b073-d377-2de0ce45f26f.png)

>おいしいチャーハンを作るためには、まず新鮮な食材と基本的な調味料が重要です。以下にステップバイステップで美味しいチャーハンの作り方をご紹介します。
>
>材料の準備
> 1.米（白米または短粒種）: 2杯分
> 2.鶏肉またはエビ: 100g（細かく切る）
> 3.豚バラ肉または牛肉: 50g（細切り）
> 4.にんじん: 1/2本（千切り）
> 5.ピーマン: 1個（細切り）
> 6.玉ねぎ: 1/2個（薄切り）
> 7.しょうゆ: 大さじ2
> 8.みりん: 大さじ1
> 9.酒: 大さじ1
>10.塩: 小さじ1
>11.こしょう: 少々
>12.ごま油: 大さじ1
>13.青ねぎ（飾り用）: 適量
>手順
>１. 下準備
>・米をよく洗い、水気を切ります。
>・鶏肉や豚肉、にんじん、ピーマン、玉ねぎを一口大に切ります。
>２. 炒める
>1.フライパンにごま油を熱し、中火で温めます。
>2.まず、鶏肉またはエビを加えて表面がカリッとするまで炒めます。
>3.次に、豚肉や牛肉を加え、さらに数分間炒めます。
>4.野菜（にんじん、ピーマン、玉ねぎ）を加え、軽く炒めます。
>5.しょうゆ、みりん、酒、塩、こしょうを加えて混ぜ合わせます。
>6.ご飯をフライパンに加え、全体が均一になるように炒めます。
>３. 火加減と仕上げ
>・ご飯がパラリとしたら、一度火を弱めてさらに数分炒めます。
>・ご飯がほぼ混ざり合い、香ばしい香りが立ったら完成です。
>４. 盛り付け
>・お皿にチャーハンを盛った後、青ねぎやパクチーなどのフレッシュなハーブを添えると見た目も美しくなります。
>・最後に軽く塩とこしょうで味を整えます。
>ポイント
>・ご飯は冷やご飯よりも常温ご飯の方がパラリとして扱いやすいです。
>・調味料は好みに応じて調整してください。特にしょうゆやみりんの量は好みによって変えてみてください。
>・最後に軽く炒めることで、ご飯に香ばしさが加わります。
>これで美味しいチャーハンが完成です！ぜひお試しください！

味つけが濃いような気がしますが、日本語に破綻はなさそうです。欲を言えば何人前かは教えてほしかったところではありますが。「 <font color=#00FF00>安くて</font> おいしい 」と注書きを入れると、エビや牛肉は省いてくれるでしょうか。どなたか[プロンプトエンジニアリング](https://www.nri.com/jp/knowledge/glossary/lst/ha/prompt_engineering)を試してみませんか？
<font color=#a0a0a0> ちなみに、別のモデルに聞いたところ「チャーハンのもとを水に溶かす」と指示されたことがあります。 </font>

## 他のモデルを追加してみる
Dockerコンテナの中に入ることで、他の言語モデルを追加することができます。
例えば、[ELYZA,inc](https://elyza.ai/)が開発した *ELYZA*（[参考](https://ja.wikipedia.org/wiki/ELIZA)）の場合は、次のとおりです。
```console:
> docker compose exec ollama /bin/bash
# ollama pull hf.co/elyza/Llama-3-ELYZA-JP-8B-GGUF
pulling manifest
pulling 91553c45080b... 100% ▕████████████████████████████████████████████████████████▏ 4.9 GB
pulling 475211637354... 100% ▕████████████████████████████████████████████████████████▏ 7.8 KB
pulling eef4a93c7add... 100% ▕████████████████████████████████████████████████████████▏  193 B
verifying sha256 digest
writing manifest
success
# ollama ls
NAME                                           ID              SIZE      MODIFIED
hf.co/elyza/Llama-3-ELYZA-JP-8B-GGUF:latest    4d9f57e24956    4.9 GB    48 seconds ago
7shi/tanuki-dpo-v1.0:8b-q6_K                   2801dfe6d142    6.2 GB    2 days ago
# exit
>
```
画面左上をプルダウンすることでモデルが追加されていることを確認できます。
ここでモデルの切り替えを行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3921213/13934620-eabd-6c71-3443-4e5e48ff2fd9.png)


なお、ELYZA以外のモデルについては、[[2](https://zenn.dev/hellorusk/books/e56548029b391f)]を参照してみてください。

コンテナサイズが心配な方は、次のようにしてモデルの削除を行うことができます。
```console:
> docker compose exec ollama /bin/bash
# ollama rm hf.co/elyza/Llama-3-ELYZA-JP-8B-GGUF
deleted 'hf.co/elyza/Llama-3-ELYZA-JP-8B-GGUF'
# exit
>
```


## 後片付け
Docke環境を元に戻したい方は、以下のコマンドでコンテナ、イメージ、ボリュームをまとめて削除することができます。
```console
> docker compose down --rmi all --volumes
```

## クロージング
企業によっては、インターネットを含めて外部に企業内の情報が流れることを嫌いますし、そうでなくても技術情報については[輸出管理の対象](https://www.meti.go.jp/policy/anpo/qanda25.html)となることから、外部に情報を持ち出すことのないローカル（オンプレミス）で動作するLLMの需要は一定以上あるものと想像されます。
一方で、日本語は、単語と単語の間にスペースを入れない数少ない言語のひとつであり、加えて使用する文字数が多いこともあって、海外発のLLMを（サイズにかかわらず、）そのまま適用することは難しくて、大なり小なり専用に開発を行う必要があるのではないか、と思います。
日本語LLMの開発に携わる技術者の皆様のこれまでの努力をしのびつつ今後の活躍を願っています。
<br/>
では、最後にtanukiからのメッセージをどうぞ。

>こんにちは、皆さん。今日は私のことについての記事を読んでいただき、本当にありがとうございます。この記事を通じて、少しでも私のことを知っていただけたこと、そして興味を持っていただけたことに感謝しています。
>
>クリスマスは特別な時期であり、家族や友人と過ごす時間が増える素晴らしい機会ですね。今年はどんな風に過ごされる予定ですか？もし何か特別な計画や思い出があれば、ぜひ教えてください。私もあなたたちと一緒にこの素晴らしい季節を楽しむことができることを心から願っています。
>
>クリスマスは思いやりと愛を分かち合う大切な時間です。どうか皆さんが心温まる瞬間を過ごせますように。そして、健康で幸せな日々が続くことを祈っています。
>
>最後に、メリークリスマス！素晴らしいホリデーシーズンをお過ごしください。


***
参考にさせていただいたサイト
[1] [Tanuki-8BとOllamaとDifyを使って日本語ローカルRAG構築](https://zenn.dev/mkj/articles/93dbd6c9d94c58)
[2] [Ollamaで体験する国産LLM入門](https://zenn.dev/hellorusk/books/e56548029b391f)
and more