IBM TechXchange Conference Japan 2023 での TJBot zero + watson.x 連携したメモです。
経緯
#TJBot ブースでライブコーディングして、TJBot くんに機能追加します! #IBMTechXchange #IBMChampion pic.twitter.com/lkwVZNmpCB
— Tanaka Seigo (@1ft_seabass) October 31, 2023
IBM の watson.x に詳しい方々にもその場でアドバイスをいただき、TJBot zero くんに実際に watson.x から来た答えを話してもらうることができるようになりました。
#TJBot で #watsonai つながるにはつながりましたー!ただし良い返事には、プロンプト頑張る必要はありそうー。
ともあれ一旦ライブコーディング完了! #IBMTechXchange pic.twitter.com/TT4QoSyjl5— Tanaka Seigo (@1ft_seabass) October 31, 2023
とはいえ、まだまだブラッシュアップしていきたい点はあるので、途中経過としてまとめときます。
加えた部分はどこか
現在 TJBot zero くんで標準で動いているフローの場合は、Watson Assistant で「あなたは誰?」とか「手を振って」といった特定の言葉を理解して動作をさせています。
今回の設計では、Watson Assistant で特定の言葉ではないときに例外の分岐とそてきたメッセージを watson.x ノードに伝えて、そこから回答をもらう方針で行いました。
このように例外の言葉、たとえば「 IBM を説明してください」というメッセージを watson.x ノードに伝えて帰ってきたものを Text to Speech でしゃべらせます。
今回うまくいった改修
当初は IBM watsonx.ai のカスタムノードを公開しました : まだプログラマーですが何か? の記事をそのまま使っていたため、mpt-7b-instruct2 のモデルを使って作っていたのですが、どうも回答が思い通りに返ってきませんでした。
そこで、前述のとおり、IBM の watson.x に詳しい方々にもその場でアドバイスをいただいて、質問に対して答えるタイプで、いい感じのモデルは「meta-llama/llama-2-70b-chat」が現状では良いそうです。
プロンプトは以下となりました。
こちらは、あとで 一般的なタスクのためのサンプルファウンデーション・モデル・プロンプト で復習してみたところ [INST][/INST]
や <<SYS>><</SYS>>
は、llama-2-70b-chat 特有のプロンプト命令のようです。INST で囲むとその中はプロンプト扱いになり SYS は OpenAI 社の ChatGPT で system 値と呼ばれる、回答への前提の定義に使われるものに類似した機能です。
このあたり、復習できてよかったです。
というわけで、切り出したフロー
ということで、こちらで TJBot zero 内で、みなさんのナレッジを反映しつつ、一旦つくったフローを切り出したフローがこちらです。
フロー JSON は以下です。
[{"id":"548ff3bd88ff5cc3","type":"watsonx.ai","z":"44d82f8472281117","name":"","apikey":"","project_id":"","model_id":"meta-llama/llama-2-70b-chat","only_firstline":false,"x":670,"y":700,"wires":[["45b896c00d03ca9f"]]},{"id":"ecc5a66666ef5bf2","type":"inject","z":"44d82f8472281117","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"IBM について教えてください。","payloadType":"str","x":270,"y":700,"wires":[["f92aa3cb3964e020"]]},{"id":"45b896c00d03ca9f","type":"debug","z":"44d82f8472281117","name":"debug 5","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":820,"y":700,"wires":[]},{"id":"f92aa3cb3964e020","type":"template","z":"44d82f8472281117","name":"プロンプト","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"[INST]\n<<SYS>>\n質問は対して日本語だけで回答してください。\n英語では絶対に回答しないでください。\n<</SYS>>\n### 質問 : {{payload}}\n\n### 回答 : (日本語だけでお願いします。)\n[/INST]","output":"str","x":510,"y":700,"wires":[["548ff3bd88ff5cc3"]]}]
こちらを inject ノードのボタンをクリックして動かします。
このように、ちゃんと「IBM について教えてください。」という日本語の質問に対して、日本語で回答してくれるようになりました。
今後よくしたいところ
これだけでも TJBot zero くんが watson.x と連携できて感動ものなのですが、とはいえ、展示などで気軽に話しかけてもらって、うまく動くまでにはいろいろ気になるところがあるので、試しつつブラッシュアップしていくことがあるのでメモしておきます。
- 「meta-llama/llama-2-70b-chat」モデルは現状だと最適だが、モデル内で英語データが多く日本語データがかなり少ないため、そもそも英語で返しやすく、近々、日本語特化のモデルが来年でてくるようなの、それに切り替えるとよりやりやすそうなので試してみたい
- 「IBM について教えてください。」はよかったけれど「雨について教えて。」だと冒頭に英語が混ざったりするので、プロンプトはもっと日本語で返すように但し書きが必要かもしれない。いろいろな文言で回答を試す必要がありそう。
- 先ほどの「IBM について教えてください。」の回答も返ってきてはいるはいるが、日本語のトークン数が多いのか途中で文字が切れてしまっているので watsonx ノード内の max_new_tokens が 100 で抑えめなあたりを調整する必要があるかもしれない(ちなみに英語での回答だともう少し多めに出てくれる)
- そのほか「temperature を 0.1 くらいにする TOP_P 0.5 TOP_K 5 にする」というパラメータ値のアドバイスもいただけたが watsonx ノードだとパラメータの細かな調整は、まだできないので http request ノードで API 挙動を作ってパラメータを試すのもありかもしれない
- node-red-contrib-dotnsf-watsonxai/node.js at main · dotnsf/node-red-contrib-dotnsf-watsonxai を参考に、getAccessToken → generateText の流れを http request ノードで作ってやればパラメータ渡せそう
このあたりです。
TJBot zero としても watson.x 連携のナレッジはまだまだ始まったばかりですし、watsonx ノードも今後アップデートされていくでしょうし、IBM 的にも AI モデルや watsonx の仕組みがよりよくなっていくので、あくまで現時点でのスナップショットにはなりますが、 TJBot zero コミュニティのみなさんと、ワイワイしつつ良くしていけたら楽しいなと思っております!