Metaより
Llama 2の提供が開始されました。動かすには沢山のリソースが必要なのだろうなと思っていたら、以下の記事を見つけました。
CPUでも動くとのことで、以前に作成したOracle Cloudの無料枠のAmpere A1のインスタンス(4OCPU、24GB)で動かしてみました。
OpenAI Whisperを使った文字起こしアプリの作成(3) - Flaskを使ったAPIサーバーHuggingFaceより
TheBloke/Llama-2-13B-chat-GGMLの
llama-2-13b-chat.ggmlv3.q8_0.binをダウンロードして使用しています。Provided filesのUse caseには、リソース使用量が多く遅いと記載されていますが、メモリについては24GBあるので足りそうですし、動作させてみるのが目的なのでaccuracyが高そうなモデルを選んでいます。
Ampere A1のインスタンスにAPIサーバーを作成し、フロントエンドをAPEXで作成します。
作成したアプリケーションに、プロンプトとして以下を与えました。
User: Who was the Japanese prime minister during Reagan's administration?
Assistant:
応答は以下です。
Assistant: The Japanese Prime Minister during Ronald Reagan's administration (1981-1989) was Yasuhiro Nakasone. He served as Prime Minister from 1982 to 1987.
応答が得られるまでに1分程度かかりました。
プロンプトに日本語を入力してみました。
User: 現在のアメリカの大統領は誰ですか?
Assistant:
応答は以下です。
Assistant: The current President of the United States is Joe Biden. He was inaugurated on January 20, 2021, and is serving his first term as President.
応答は英語でしたが、正しく解釈されています。
日本に関する質問をしてみました。
User: 現在の日本の首相は誰ですか?
Assistant:
日本語で学習していると応答が日本語になることがあるのかもしれません。しかし、3年前の情報です。
これから行った作業について説明します。
Llama.cppのPythonバインディングをインストールします。
pip install llama-cpp-pythonubuntu@mywhisper2:~$ pip install llama-cpp-python
Collecting llama-cpp-python
Downloading llama_cpp_python-0.1.73.tar.gz (1.6 MB)
|████████████████████████████████| 1.6 MB 27.6 MB/s
Installing build dependencies ... done
Getting requirements to build wheel ... done
Preparing wheel metadata ... done
Collecting diskcache>=5.6.1
Downloading diskcache-5.6.1-py3-none-any.whl (45 kB)
|████████████████████████████████| 45 kB 4.3 MB/s
Collecting typing-extensions>=4.5.0
Downloading typing_extensions-4.7.1-py3-none-any.whl (33 kB)
Requirement already satisfied: numpy>=1.20.0 in /usr/local/lib/python3.8/dist-packages (from llama-cpp-python) (1.23.5)
Building wheels for collected packages: llama-cpp-python
Building wheel for llama-cpp-python (PEP 517) ... done
Created wheel for llama-cpp-python: filename=llama_cpp_python-0.1.73-cp38-cp38-linux_aarch64.whl size=250785 sha256=292028cdc30da399c4dfc90d3a465b46a0834d377b1956de529377a79b1e0942
Stored in directory: /home/ubuntu/.cache/pip/wheels/0e/b1/1c/924b1420d220bbb77b4b7c5e533f23b2cf683d28ad20ee5b62
Successfully built llama-cpp-python
ERROR: tensorflow-cpu-aws 2.13.0 has requirement typing-extensions<4.6.0,>=3.6.6, but you'll have typing-extensions 4.7.1 which is incompatible.
Installing collected packages: diskcache, typing-extensions, llama-cpp-python
Successfully installed diskcache-5.6.1 llama-cpp-python-0.1.73 typing-extensions-4.7.1
ubuntu@mywhisper2:~$
使用するモデルのダウンロード・リンクを取得し、wgetでファイルをダウンロードします。
APIサーバーをllama2-server.pyとして作成します。コードは以下になります。
pythonで実行します。
python llama2-server.py
ubuntu@mywhisper2:~$ python llama2-server.py
llama.cpp: loading model from /home/ubuntu/llama-2-13b-chat.ggmlv3.q8_0.bin
llama_model_load_internal: format = ggjt v3 (latest)
llama_model_load_internal: n_vocab = 32000
llama_model_load_internal: n_ctx = 512
llama_model_load_internal: n_embd = 5120
llama_model_load_internal: n_mult = 256
llama_model_load_internal: n_head = 40
llama_model_load_internal: n_layer = 40
llama_model_load_internal: n_rot = 128
llama_model_load_internal: freq_base = 10000.0
llama_model_load_internal: freq_scale = 1
llama_model_load_internal: ftype = 7 (mostly Q8_0)
llama_model_load_internal: n_ff = 13824
llama_model_load_internal: model size = 13B
llama_model_load_internal: ggml ctx size = 0.09 MB
llama_model_load_internal: mem required = 15025.96 MB (+ 1608.00 MB per state)
llama_new_context_with_model: kv self size = 400.00 MB
AVX = 0 | AVX2 = 0 | AVX512 = 0 | AVX512_VBMI = 0 | AVX512_VNNI = 0 | FMA = 0 | NEON = 1 | ARM_FMA = 1 | F16C = 0 | FP16_VA = 1 | WASM_SIMD = 0 | BLAS = 0 | SSE3 = 0 | VSX = 0 |
* Serving Flask app 'llama2-server'
* Debug mode: on
INFO:werkzeug:WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on all addresses (0.0.0.0)
* Running on https://127.0.0.1:8443
* Running on https://10.0.0.131:8443
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on all addresses (0.0.0.0)
* Running on https://127.0.0.1:8443
* Running on https://10.0.0.131:8443
INFO:werkzeug:Press CTRL+C to quit
Press CTRL+C to quit
INFO:werkzeug: * Restarting with stat
* Restarting with stat
llama.cpp: loading model from /home/ubuntu/llama-2-13b-chat.ggmlv3.q8_0.bin
llama_model_load_internal: format = ggjt v3 (latest)
llama_model_load_internal: n_vocab = 32000
llama_model_load_internal: n_ctx = 512
llama_model_load_internal: n_embd = 5120
llama_model_load_internal: n_mult = 256
llama_model_load_internal: n_head = 40
llama_model_load_internal: n_layer = 40
llama_model_load_internal: n_rot = 128
llama_model_load_internal: freq_base = 10000.0
llama_model_load_internal: freq_scale = 1
llama_model_load_internal: ftype = 7 (mostly Q8_0)
llama_model_load_internal: n_ff = 13824
llama_model_load_internal: model size = 13B
llama_model_load_internal: ggml ctx size = 0.09 MB
llama_model_load_internal: mem required = 15025.96 MB (+ 1608.00 MB per state)
llama_new_context_with_model: kv self size = 400.00 MB
AVX = 0 | AVX2 = 0 | AVX512 = 0 | AVX512_VBMI = 0 | AVX512_VNNI = 0 | FMA = 0 | NEON = 1 | ARM_FMA = 1 | F16C = 0 | FP16_VA = 1 | WASM_SIMD = 0 | BLAS = 0 | SSE3 = 0 | VSX = 0 |
WARNING:werkzeug: * Debugger is active!
* Debugger is active!
INFO:werkzeug: * Debugger PIN: 610-498-273
* Debugger PIN: 610-498-273
これから、このAPIサーバーを呼び出すAPEXアプリケーションを作成します。
アプリケーション作成ウィザードを起動し、空のアプリケーションを作成します。ユーザー・インターフェースはすべてデフォルトで作成されるホーム・ページに実装します。
名前はLlama2 UIとし、アプリケーションの作成を実行します。
RESTデータ・ソースを作成して、APIサーバーへの呼び出しを行います。
共有コンポーネントのRESTデータ・ソースを開きます。
作成済みのRESTデータ・ソースが一覧されます。作成をクリックします。
RESTデータ・ソースの作成に最初からを選択します。
次へ進みます。
RESTデータ・ソース・タイプとして
簡易HTTPを選択します。
名前は
Llama2とします。
URLエンドポイントは、Amere A1で動作しているAPIサーバーを呼び出すURLになります。以下のような形式になります。
https://インスタンスのホスト名/chat
次へ進みます。
リモート・サーバー、ベースURL、サービスURLパスが認識されます。
通常は変更不要なので、値を確認して次へ進みます。
ページ区切りなしです。
次へ進みます。
認証が必要ですは
オフです。
今回作成するRESTデータ・ソースは特殊なため、自動検出はできません。RESTソースの手動作成を実施します。
RESTデータ・ソース
Llama2が作成されます。ただし、ほとんど構成されていません。
RESTデータ・ソースを編集するために開きます。
操作はデータベース・アクションの行のフェッチだけを残し、他を削除します。
データベース・アクションが行のフェッチである操作の鉛筆アイコンをクリックして開きます。
HTTPメソッドをGETからPOSTに変更します。変更するとリクエスト本文テンプレートの項目が現れるので、以下を記述します。
{
"max_tokens": #MAX_TOKENS#,
"query": "#PROMPT#"
}
上記を入力後、生成をクリックします。
操作パラメータに本文との同期というボタンが現れます。これをクリックすると、リクエスト本文に含まれる置換文字列が操作パラメータとして追加されます。
今回は操作パラメータとしてMAX_TOKENSとPROMPTが追加されます。
操作パラメータの
MAX_TOKENSは、
必須を
オンにし、
デフォルト値として
64を設定します。
操作パラメータPROMPTについては、後で必須をオンにします。サンプル・データを使ってデータ・プロファイルを検出する際に、デフォルト値の無い必須パラメータがあるとエラーが発生します。そのため、データ・プロファイルの検出ができなくなります。
パラメータの追加をクリックし、Content-TypeヘッダーとAcceptヘッダーを追加します。両方ともに、値はapplication/jsonです。
パラメータのタイプはHTTPヘッダー、名前はContent-Type、目的は入力です。デフォルト値としてapplication/jsonを指定します。静的をオンにすることにより、つねにデフォルト値が送信されます。
同様にパラメータとしてAcceptヘッダーを追加します。
以上で操作の設定は完了です。
変更の適用をクリックします。
続いてデータ・プロファイルの編集を行います。
データ・プロファイルを編集するにあたって、サンプルとなるレスポンスをファイルに落とします。
curlコマンドを使ってAPIサーバーを呼び出します。APIサーバーの応答がsample.jsonに書き込まれます。
curl -X POST -H "Content-Type: application/json" -d '{ "max_tokens": 64, "query": "User: Why is sky blue?\nAssistant:" }' -o sample.json https://ホスト名/chat
sample.jsonは以下のような内容になります。
{
"id": "cmpl-2293b348-82a9-44f9-b270-e04df749473a",
"object": "text_completion",
"created": 1689824214,
"model": "/home/ubuntu/llama-2-13b-chat.ggmlv3.q8_0.bin",
"choices": [
{
"text": "User: Why is sky blue?\nAssistant: That's a great question! The reason the sky appears blue is because of a phenomenon called Rayleigh scattering. When sunlight enters Earth's atmosphere, it encounters tiny molecules of gases such as nitrogen and oxygen. These molecules scatter the light in all directions,",
"index": 0,
"logprobs": null,
"finish_reason": "length"
}
],
"usage": {
"prompt_tokens": 12,
"completion_tokens": 64,
"total_tokens": 76
}
}
データ・プロファイルの編集をクリックします。
データ・プロファイルの
行セレクタとして
choicesを指定します。
再検出の
サンプル・レスポンスとしてcurlを実行して出力した
sample.jsonを指定します。
上記で、データ・プロファイルの再検出をクリックします。
新規列としてTEXT、INDEX_などが検出されます。
データ・プロファイルの置換をクリックします。
列としてTEXT、INDEX_などが追加されていることを確認し、変更の適用をクリックします。
操作パラメータ
PROMPTの編集画面を再度開き、
必須を
オンにします。
以上でRESTデータ・ソースは完成です。
変更の適用をクリックします。
Llama2のAPIサーバーへの問い合わせを行なう画面を作成します。
ページ・デザイナでホーム・ページを開きます。
出力のトークン数を指定するページ・アイテムP1_MAX_TOKENSを作成します。タイプは数値フィールド、ラベルはMax Tokensです。デフォルトのタイプに静的値を選び、静的値として64を設定します。
Llama2に渡すプロンプトを入力するページ・アイテムP1_PROMPTを作成します。タイプはテキスト領域、ラベルはPromptとします。
APIサーバーへの問い合わせを発行するボタン
QUERYを作成します。
ラベルは
Query、
動作の
アクションとして
動的アクションで定義を選択します。必ずしも必要ではありませんが、
テンプレート・オプションの
Widthを
Strechに変更し、ボタンの幅をページ幅まで広げます。
動的アクションは、対話モード・レポートのリージョンを作成したのちに作成します。
対話モード・レポートのリージョンResponseを作成します。ソースの位置としてRESTソースを選択し、RESTソースとしてLlama2を選びます。送信するページ・アイテムにP1_MAX_TOKENSとP1_PROMPTを含めます。
RESTデータ・ソースLlama2のパラメータMAX_TOKENSには、アイテムP1_MAX_TOKENSが割り当たります。
パラメータPROMPTには、アイテムP1_PROMPTが割り当たります。
列
TEXTがLlama2によって生成された文字列です。改行が適切に表示されるよう、
タイプを
リッチ・テキストに変更し、
設定の
書式を
マークダウンにします。
ボタン
QUERYに
動的アクションを作成します。
リージョンResponseのRESTデータ・ソースが行のフェッチを行なうときにAPIリクエストが発行され、そのレスポンスが対話モード・レポートに表示されます。つまり、リージョンResponseをリフレッシュするだけで新しくAPIリクエストが発行され、対話モード・レポートの表示が更新されます。
動的アクションの識別の名前はonClick Refreshとします。タイミングはボタンのデフォルトから変更せず、イベントがクリック、選択タイプがボタン、ボタンがQUERYです。
TRUEアクションとしてリフレッシュを選択します。影響を受ける要素の選択タイプはリージョン、リージョンとしてResponseを選択します。クライアントの条件のタイプとしてアイテムはnullではないを選択し、アイテムにP1_PROMPTを選択します。
ページ・アイテムP1_PROMPTに値がないときにリージョンResponseのリフレッシュはしない、つまりAPI呼び出しも行いません。
以上でアプリケーションは完成です。
今回作成したAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/llama2-ui-test.zip
Flaskのサーバーが応答するのに時間がかかるし、応答を返す前に新たなリクエストを受け付けると、Llamaのレスポンスが##################になったりしますが、Llama2のお試しにはなるでしょう。
また、Oracle APEXでノーコードでREST APIを扱うサンプルにもなっています。
Oracle APEXのアプリケーション作成の参考になれば幸いです。
完