日本語LLMを使って生成AI用のOpenAI互換のAPIサーバーを構築する手順

日本語LLMを使って生成AI用のOpenAI互換のAPIサーバーを構築する手順

この資料は、2023年11月現在のものです。

この資料では、日本語LLMを使って、OpenAI互換の生成AIのAPIサーバーをパソコン上に構築し、トンネルサービスのngrokでインターネット上に一時的に公開するまでを説明しています。

動作確認に用いたパソコン環境

  • 100文字程度の文章を生成するまでにかかる時間として、数分かかる(だいたい3~5分くらい)

    • Windows 10

      • 第7世代 Core i5 , 2コア4スレッド対応

      • メモリ 8GB

      • SSD搭載

      • 中古として買うと、1万円台後半から2万台前半くらい。

  • 100文字程度の文章を生成するまでにかかる時間として、数十秒かかる(200文字前後だと2分弱くらい)

    • Windows 10/11

      • 第10世代 Core i5 , 4コア8スレッド対応

      • メモリ 16GB

      • SSD搭載

      • 中古として買うと、3万円台~4万円台。

      • 新品として買うと、第10世代のIntel CPUは古いため、より高性能なAMD Ryzen 7000番台搭載のラップトップ(ノートパソコン)が、6万円台くらいから買えるので、余裕があれば新品の方が望ましい。第13世代 Intel Core i5 搭載だと、7万円台前半から買える。

    • Mac

      • Intel版 MacBook Pro , メモリ16GB搭載 , 2020年に発売されたもの : MWP72J/A (Mid 2020) , 中古で買うと、7万円台くらいから買える。

      • M1 iMac , メモリ16GB搭載 , MGTF3J/A (Mid 2021) , 新品で17万円くらいで買える。

LLMの選択

本資料は、生成AI機能を持つAPIサーバーを構築するにあたり、LLMとして「ELYZA-japanese-Llama-2-7b」を選んでいます。

LLMを用いるために、「llama-cpp-python」を使います。「llama-cpp-python」でLLMを用いるには、「gguf」形式である必要があり、「gguf」形式で配布されている「ELYZA-japanese-Llama-2-7b-fast-instruct-gguf」を用います。

この資料により実現できること

100文字で説明せよと指示したものの、実際は260文字程度出力された。

生成AIのAPIサーバーの準備

Linuxをお使いの場合 ( Windows 10/11でWSL2を含む)

前提

Ubuntu 22.04 を前提とします。Ubutnu 22.04 は、2023年10月現在、2027年4月までのサポートが約束されており、かつ無料で使えるLinuxディストリビューションとして使い易いです。

sudoが使用可能か作業用ユーザーを用意してください。WSL2上でUbuntu22.04を動かす場合は、特にすることはありません。

WSL2を使って、Linux(Ubuntu)環境を用意する際の注意点(WSL2を使っていない場合は省略)

Microsoft Storeから、Ubuntu 22.04 をインストールする前に、「Visual Studio Build Tools 2022」をインストールしましょう。「Visual Studio Build Tools 2022」はC++対応のビルドツールがあり、WSL2上のUbuntuでllama-cpp-pythonがインストールエラーになることを防ぎます。

  1. https://visualstudio.microsoft.com/ja/downloads/ にアクセスし、「Tools for Visual Studio」>>Build Tools for Visual Studio 2022の「ダウンロード」をクリックします。

  2. 「vs_BuildTools .exe」をダウンロードします。

  3. ダウンロードした「vs_BuildTools.exe」をダブルクリックし、画面指示に従って進めます。

  4. 「C++ によるデスクトップ開発」をクリックし、右下の「インストール」をクリックします。

  5. 「Visual Studio Build Tools 2022」がインストールされます。

  6. Microsoft Storeから、Ubuntu 22.04 をインストールします。

  7. Ubuntu 22.04 をWindowsのスタートメニューから起動します。

Python用仮想環境の用意

次のコマンドを実行します。

sudo apt update -y && sudo apt upgrade -y sudo apt install -y python3-pip python3-venv python3-dev

作業用ディレクトリの作成

次のコマンドを実行します。

mkdir -p llmtest cd llmtest/

日本語LLMのモデルダウンロード

日本語LLMのモデルをなんらかの取り組みや講義でダウンロードしている場合は、ダウンロード済みのモデルを作業用ディレクトリに移動してください。

日本語LLMのモデルをダウンロードしていない場合は、作業用ディレクトリで、次のコマンドを実行します。

Linux環境では、wgetコマンドを用います。「ELYZA-japanese-Llama-2-7b-fast-instruct-q8_0.gguf」と「ELYZA-japanese-Llama-2-7b-fast-instruct-q2_K.gguf」、どちらかをダウンロードします。

2023年11月現在、「ELYZA-japanese-Llama-2-7b-fast-instruct-q8_0.gguf」としました。7GB近く(2023年11月現在、6.8GB)あるため、ダウンロードに数十分から数時間かかります。

wget https://huggingface.co/mmnga/ELYZA-japanese-Llama-2-7b-fast-instruct-gguf/resolve/main/ELYZA-japanese-Llama-2-7b-fast-instruct-q8_0.gguf

7GB近くのダウンロードを待つ時間がない場合は、性能が落ちますが、半分以下の3GB近くのモデルをダウンロードする手もあります。「ELYZA-japanese-Llama-2-7b-fast-instruct-q2_K.gguf」

wget https://huggingface.co/mmnga/ELYZA-japanese-Llama-2-7b-fast-instruct-gguf/resolve/main/ELYZA-japanese-Llama-2-7b-fast-instruct-q2_K.gguf

Python用仮想環境を作ります

次のコマンドを実行します。ここでは、myvenvという名前にします。

python3 -m venv myvenv source myvenv/bin/activate

llama-cpp-pythonをインストールします

次のコマンドを実行します。

pip install llama-cpp-python

インストール成功のメッセージ(インストール作業を行った時期により、表示されるバージョン番号が異なるので注意)

Successfully installed diskcache-5.6.3 llama-cpp-python-0.2.18 numpy-1.26.2 typing-extensions-4.8.0

OpenAI互換のAPIサーバー機能の追加

次のコマンドを実行します。

pip install llama-cpp-python[server]

インストール成功のメッセージ(インストール作業を行った時期により、表示されるバージョン番号が異なるので注意)

Successfully installed annotated-types-0.6.0 anyio-3.7.1 click-8.1.7 exceptiongroup-1.1.3 fastapi-0.104.1 h11-0.14.0 idna-3.4 pydantic-2.5.1 pydantic-core-2.14.3 pydantic-settings-2.1.0 python-dotenv-1.0.0 sniffio-1.3.0 sse-starlette-1.6.5 starlette-0.27.0 starlette-context-0.3.6 uvicorn-0.24.0.post1

APIサーバーの起動

モデルを指定して起動

「ELYZA-japanese-Llama-2-7b-fast-instruct-q8_0.gguf」と「ELYZA-japanese-Llama-2-7b-fast-instruct-q2_K.gguf」のどちらか一方、ダウンロードしてある方で、APIサーバーを起動します。

ELYZA-japanese-Llama-2-7b-fast-instruct-q8_0.gguf の場合

localhost以外からでも、IPアドレスでも利用できるように、--host 0.0.0.0 を指定し、次のコマンドを実行します。

python3 -m llama_cpp.server --host 0.0.0.0 --model ELYZA-japanese-Llama-2-7b-fast-instruct-q8_0.gguf
ELYZA-japanese-Llama-2-7b-fast-instruct-q2_K.gguf の場合

localhost以外からでも、IPアドレスでも利用できるように、--host 0.0.0.0 を指定し、次のコマンドを実行します。

python3 -m llama_cpp.server --host 0.0.0.0 --model ELYZA-japanese-Llama-2-7b-fast-instruct-q2_K.gguf

実行結果 ( 膨大なので、重要な最後の方を表示 )

llm_load_print_meta: n_yarn_orig_ctx = 4096 llm_load_print_meta: rope_finetuned = unknown llm_load_print_meta: model type = 7B llm_load_print_meta: model ftype = mostly Q8_0 llm_load_print_meta: model params = 6.85 B llm_load_print_meta: model size = 6.77 GiB (8.50 BPW) llm_load_print_meta: general.name = ELYZA-japanese-Llama-2-7b-fast-instruct llm_load_print_meta: BOS token = 1 '<s>' llm_load_print_meta: EOS token = 2 '</s>' llm_load_print_meta: UNK token = 0 '<unk>' llm_load_print_meta: LF token = 13 '<0x0A>' llm_load_tensors: ggml ctx size = 0.11 MiB llm_load_tensors: mem required = 6937.01 MiB ................................................................................................. llama_new_context_with_model: n_ctx = 2048 llama_new_context_with_model: freq_base = 10000.0 llama_new_context_with_model: freq_scale = 1 llama_new_context_with_model: kv self size = 1024.00 MiB llama_build_graph: non-view tensors processed: 740/740 llama_new_context_with_model: compute buffer total size = 159.07 MiB AVX = 1 | AVX2 = 1 | AVX512 = 1 | AVX512_VBMI = 1 | AVX512_VNNI = 1 | FMA = 1 | NEON = 0 | ARM_FMA = 0 | F16C = 1 | FP16_VA = 0 | WASM_SIMD = 0 | BLAS = 1 | SSE3 = 1 | SSSE3 = 1 | VSX = 0 | INFO: Started server process [14436] INFO: Waiting for application startup. INFO: Application startup complete. INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)

Macをお使いの場合 ( Intel Mac / Apple シリコン Mシリーズ )

日本語LLMのモデルダウンロード

下記の日本語LLMのモデルをダウンロードします。日本語LLMのモデルをなんらかの取り組みや講義でダウンロードしている場合は、スキップして次の「ターミナルアプリを起動」に進んでください。

SafariやGoogle Chrome等のWebブラウザで、下記にアクセスすればダウンロードが始まります。

2023年11月現在、「ELYZA-japanese-Llama-2-7b-fast-instruct-q8_0.gguf」としました。7GB近く(2023年11月現在、6.8GB)あるため、ダウンロードに数十分から数時間かかります。

https://huggingface.co/mmnga/ELYZA-japanese-Llama-2-7b-fast-instruct-gguf/resolve/main/ELYZA-japanese-Llama-2-7b-fast-instruct-q8_0.gguf

7GB近くのダウンロードを待つ時間がない場合は、性能が落ちますが、半分以下の3GB近くのモデルをダウンロードする手もあります。「ELYZA-japanese-Llama-2-7b-fast-instruct-q2_K.gguf」

wget https://huggingface.co/mmnga/ELYZA-japanese-Llama-2-7b-fast-instruct-gguf/resolve/main/ELYZA-japanese-Llama-2-7b-fast-instruct-q2_K.gguf

お使いのMacのダウンロードフォルダに保存します。どこにダウンロードされたかは、ご自分のMacなのですから把握しておきましょう。

ターミナルアプリを起動

ターミナルアプリを起動します。アプリケーションフォルダ内のユーティリティフォルダに格納されています。Macを使って、プログラミングする人は1度は使ったことがあるはず。

Pythonのインストール

昔は別として、現在のMacには標準でPythonが入っていないため、自分でPythonをインストールする必要があります。既にPython3系で3.8以上が入っている場合は、飛ばしてください。

定番のHomebrewを使います。以下を参考に、HomebrewによるPythonのインストールを行ってください。

MacにHomebrewを使ってPythonをインストール

作業用ディレクトリの作成

次のコマンドを実行します。

mkdir -p llmtest

LLMを作業用ディレクトリにコピー

次のコマンドを実行し、作成した作業用ディレクトリに、ダウンロードしておいたLLMをコピーします。

LLMは、ダウンロードフォルダにダウンロードした前提にしています。

ダウンロードした場所が異なる場合は、Downloads/ を適切なパスに読み替えてください。

ELYZA-japanese-Llama-2-7b-fast-instruct-q8_0.gguf の場合

cp Downloads/ELYZA-japanese-Llama-2-7b-fast-instruct-q8_0.gguf llmtest/

ELYZA-japanese-Llama-2-7b-fast-instruct-q2_K.gguf の場合

cp Downloads/ELYZA-japanese-Llama-2-7b-fast-instruct-q2_K.gguf llmtest/

Python用仮想環境の作成

次のコマンドを実行します。作成済みの作業用ディレクトリに移動し、myvenvという名称の仮想環境を作ります。

cd llmtest/ python3 -m venv myvenv source myvenv/bin/activate

pipをアップグレード

次のコマンドを実行します。

pip install --upgrade pip

アップグレード成功のメッセージ ( 2023年11月現在 )

Successfully installed pip-23.3.1

llama-cpp-pythonをインストール

次のコマンドを実行します。

pip install llama-cpp-python

インストール成功のメッセージ(インストール作業を行った時期により、表示されるバージョン番号が異なるので注意)

Successfully built llama-cpp-python Installing collected packages: typing-extensions, numpy, diskcache, llama-cpp-python Successfully installed diskcache-5.6.3 llama-cpp-python-0.2.19 numpy-1.26.2 typing-extensions-4.8.0

OpenAI互換のAPIサーバー機能の追加

次のコマンドを実行します。

pip install 'llama-cpp-python[server]'

インストール成功のメッセージ(インストール作業を行った時期により、表示されるバージョン番号が異なるので注意)

Successfully installed annotated-types-0.6.0 anyio-3.7.1 click-8.1.7 fastapi-0.104.1 h11-0.14.0 idna-3.4 pydantic-2.5.2 pydantic-core-2.14.5 pydantic-settings-2.1.0 python-dotenv-1.0.0 sniffio-1.3.0 sse-starlette-1.8.1 starlette-0.27.0 starlette-context-0.3.6 uvicorn-0.24.0.post1

APIサーバーの起動

モデルを指定して起動

「ELYZA-japanese-Llama-2-7b-fast-instruct-q8_0.gguf」と「ELYZA-japanese-Llama-2-7b-fast-instruct-q2_K.gguf」のどちらか一方、ダウンロードしてある方で、APIサーバーを起動します。

ELYZA-japanese-Llama-2-7b-fast-instruct-q8_0.gguf の場合

localhost以外からでも、IPアドレスでも利用できるように、--host 0.0.0.0 を指定し、次のコマンドを実行します。

python3 -m llama_cpp.server --host 0.0.0.0 --model ELYZA-japanese-Llama-2-7b-fast-instruct-q8_0.gguf
ELYZA-japanese-Llama-2-7b-fast-instruct-q2_K.gguf の場合

localhost以外からでも、IPアドレスでも利用できるように、--host 0.0.0.0 を指定し、次のコマンドを実行します。

python3 -m llama_cpp.server --host 0.0.0.0 --model ELYZA-japanese-Llama-2-7b-fast-instruct-q2_K.gguf

実行結果 ( 膨大なので、重要な最後の方を表示 )

llm_load_print_meta: n_yarn_orig_ctx = 4096 llm_load_print_meta: rope_finetuned = unknown llm_load_print_meta: model type = 7B llm_load_print_meta: model ftype = mostly Q8_0 llm_load_print_meta: model params = 6.85 B llm_load_print_meta: model size = 6.77 GiB (8.50 BPW) llm_load_print_meta: general.name = ELYZA-japanese-Llama-2-7b-fast-instruct llm_load_print_meta: BOS token = 1 '<s>' llm_load_print_meta: EOS token = 2 '</s>' llm_load_print_meta: UNK token = 0 '<unk>' llm_load_print_meta: LF token = 13 '<0x0A>' llm_load_tensors: ggml ctx size = 0.11 MiB llm_load_tensors: mem required = 6937.01 MiB ................................................................................................. llama_new_context_with_model: n_ctx = 2048 llama_new_context_with_model: freq_base = 10000.0 llama_new_context_with_model: freq_scale = 1 llama_new_context_with_model: kv self size = 1024.00 MiB llama_build_graph: non-view tensors processed: 740/740 llama_new_context_with_model: compute buffer total size = 159.07 MiB AVX = 1 | AVX2 = 1 | AVX512 = 1 | AVX512_VBMI = 1 | AVX512_VNNI = 1 | FMA = 1 | NEON = 0 | ARM_FMA = 0 | F16C = 1 | FP16_VA = 0 | WASM_SIMD = 0 | BLAS = 1 | SSE3 = 1 | SSSE3 = 1 | VSX = 0 | INFO: Started server process [14436] INFO: Waiting for application startup. INFO: Application startup complete. INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)

途中、下図のような警告メッセージが表示されますので、「許可」をクリックします。

Macが使っているIPアドレスの確認

Macの「システム設定」画面の「ネットワーク」で、IPアドレスを確認します。「Wi-Fi」を使っている場合で、接続しているネットワーク(例 iPhone)の「詳細」をクリックすることで、Macに割り当てられているIPアドレスがわかります。

表示されたIPアドレス

Webブラウザで、生成AIのAPIサーバーにアクセス

LinuxまたはMacのIPアドレスを使い、次のURLにアクセスします。http:// <IPアドレス> :8000/docs (例 http://172.20.10.7:8000/docs , またはhttp://127.0.0.1:8000/docs)

APIサーバーのUIが表示されます。APIサーバー内に記載されている方法で処理することで、文章生成を行う生成AIとして機能します。

Chat風のテキスト生成は、「Create Chat Completion」で、「POST」のメソッドを選びます。「Try it out」をクリックします。「Try it out」は、動作確認の意があります。

「Request body」に、下記のように生成AIに対する質問文(プロンプト)をJSON形式で入力します。

{ "messages": [ { "content": "あなたは私を助けてくれる優秀なアシスタントです。.", "role": "system" }, { "content": "SNSでAIについて投稿したいので、120文字くらいで最新のAIの話題の原稿を、知恵を絞って作ってください。", "role": "user" } ] }

「Execute」をクリックします。

今回は100文字前後なので、数秒でレスポンスがありました。指定した文字数や質問内容次第では、数十秒以上かかることもあります。

レスポンス画面の最初は、リクエスト内容を「Curl」で実施した場合について表示されます。その下に「Request URL」が表示されます。

「Request URL」の下に、JSON形式で「Response body」表示されます。「JSON」形式ですから、パースすることで、さまざまなAPIに抽出した文章を渡すことができます。

「Response body」の下に、「Response headers」が表示されます。

今回は、パソコン上のLinux環境やMacで動かしていますが、実際にLinuxやMacのサーバーで実行すれば、より多くのAPIと連携できることは想像に難くありません。

ローコード開発ツール Node-REDから、呼び出してみよう

Node-REDとローカル生成AIの連携

APIサーバーをたてたら、次はAPI連携によるサービス開発に取り組みましょう。

パソコン上の生成AIのAPIサーバーをインターネット向けに公開する方法

パソコン上で動くAPIサーバーをインターネットから利用できるようにするにはトンネルサービスの「ngrok」を使います。ngrokは、ローカル環境(今回はパソコン)上で動くサービス(今回はAPIサーバー)をインターネットに向け公開することができるトンネルサービスです。使い方は、下記をご覧ください。

ngrokによるローカル環境の公開手順

ngrokを使うことで、起動したAPIサーバーをインターネットに公開できるので、様々なインターネットサービスと、自分で用意した生成AI環境を連携させるための開発や検証に役立ちます。

APIサーバーの使用停止と再利用時

使用停止方法

APIサーバーを終了するには、ターミナル画面に戻り、Ctrl + c キーを押します。これで、APIサーバーが停止します。

その後、Python仮想環境の使用を終えるために、次のコマンドを実行します。

deactivate

これで、開発・検証環境が停止します。

停止したAPIサーバーを起動する場合

作業用ディレクトリで、作成済みのPython仮想環境を立ち上げるため、次のコマンドを実行します。

source myvenv/bin/activate

その後、APIサーバー起動コマンドを実行します。