M5Stack LLM モジュールとCoreS3 SEを使って、SerialTextAssistantを使ってチャットをやってみます。
Windows 側からメッセージを送って、それをM5Stack CoreS3 SE +LLM モジュール側で応答を予測するものです。
予測した内容を表示後、TTSで読み上げてみます。
●初期機種のGray でも動作しました。ボード情報はM5Core です。
M5Stack CoreS3 SE にアプリを展開します。
LLM モジュールはデフォルトの環境で使います。
元ネタはArduino IDE のM5ModuleLLMライブラリに付いてくるスケッチ例のSerialTextAssistantとMeloTTSです。
Arduino IDE のインストールなどはWindows 11からM5Stack LLM モジュール に触ってみる(2)環境設定とアプリケーションの環境設定1をご参照ください。
初期画面です。
まず、Arduino IDE のシリアルモニタの初期設定をしてから、「Who are you ?」という質問を投げてみます。
初回はnullが出力されます。
ハードウェアリセットをかけてLLM を再起動しておきます。
例えばPower Key を6秒ほど長押ししてシャットダウンした後、再度押して起動させます。
同様なメッセージを送ると、予測された内容が表示されます。
自分はAIでありAlibaba Cloud で作成されたもので、Qwen という名前なのだそうです。
年齢を尋ねてみると、自分はAIであって実体としての身体がない、したがって年齢もないそうです。至極まっとうな回答です。
これは通常のクラウド型のLLM でも同様な回答を出しています。
また、算数をさせてみると普通に回答してくれます。
独立した数値演算の能力も持っています。
表示後、文章をMeloTTS で読み上げさせてみます。
コード
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
/* * SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD * * SPDX-License-Identifier: MIT */ #include <Arduino.h> #include <M5Unified.h> #include <M5ModuleLLM.h> #define CommSerialPort Serial M5ModuleLLM module_llm; String llm_work_id; String received_question; bool question_ok; String melotts_work_id; String language; String text; void setup() { M5.begin(); M5.Display.setTextSize(2); M5.Display.setTextScroll(true); // M5.Display.setFont(&fonts::efontCN_12); // Support Chinese display /* Init usb serial */ CommSerialPort.begin(115200); // language = "en_US"; /* Init module serial port */ // int rxd = 16, txd = 17; // Basic // int rxd = 13, txd = 14; // Core2 // int rxd = 18, txd = 17; // CoreS3 int rxd = M5.getPin(m5::pin_name_t::port_c_rxd); int txd = M5.getPin(m5::pin_name_t::port_c_txd); Serial2.begin(115200, SERIAL_8N1, rxd, txd); /* Init module */ module_llm.begin(&Serial2); /* Make sure module is connected */ M5.Display.printf(">> Check ModuleLLM connection..\n"); while (1) { if (module_llm.checkConnection()) { break; } } /* Reset ModuleLLM */ M5.Display.printf(">> Reset ModuleLLM..\n"); module_llm.sys.reset(); //MeloTTS /* Setup Audio module */ M5.Display.printf(">> Setup audio..\n"); module_llm.audio.setup(); /* Setup MeloTTS module and save returned work id */ M5.Display.printf(">> Setup melotts..\n\n"); m5_module_llm::ApiMelottsSetupConfig_t melotts_config; melotts_work_id = module_llm.melotts.setup(melotts_config, "melotts_setup", language); /* Setup LLM module and save returned work id */ M5.Display.printf(">> Setup llm..\n"); m5_module_llm::ApiLlmSetupConfig_t llm_config; llm_config.max_token_len = 1023; llm_work_id = module_llm.llm.setup(llm_config); M5.Display.printf(">> Setup finish\n"); M5.Display.printf(">> Try send your question via usb serial port\n"); M5.Display.setTextColor(TFT_GREEN); M5.Display.printf("e.g. \nHi, What's your name?\n"); M5.Display.printf("(end with CRLF \\r\\n)\n\n"); } void tts_speak() { //MeloTTS module_llm.tts.inference(melotts_work_id, text.c_str(), 10000); } void loop() { /* for Gray if pressed A button ,repeat result. */ /* M5.update(); if(M5.BtnA.wasPressed()) { String dummy = "repeat"; M5.Display.printf("||%s\n", dummy.c_str()); tts_speak(); } */ /* Check comm serial port and get received question */ question_ok = false; if (CommSerialPort.available()) { while (CommSerialPort.available()) { char in_char = (char)CommSerialPort.read(); received_question += in_char; /* Check if question finish */ if (received_question.endsWith("\r\n")) { received_question.remove(received_question.length() - 2); question_ok = true; break; } } } /* If question is ready */ if (question_ok) { text = ""; M5.Display.setTextColor(TFT_GREEN); M5.Display.printf("<< %s\n", received_question.c_str()); M5.Display.setTextColor(TFT_YELLOW); M5.Display.printf(">> "); CommSerialPort.printf("<< \"%s\"\n", received_question.c_str()); CommSerialPort.print(">> "); /* Push question to LLM module and wait inference result */ module_llm.llm.inferenceAndWaitResult(llm_work_id, received_question.c_str(), [](String& result) { /* Show result on screen and usb serial */ M5.Display.printf("%s", result.c_str()); CommSerialPort.print(result); //add text += result; }); tts_speak(); /* Clear for next question */ received_question.clear(); M5.Display.println(); CommSerialPort.println(); } delay(20); } |
初期画面
地球の半径を尋ねてみました。
こういうのは知識としてちゃんと持っているのですね。
正解です。
注:
Gray などの3つボタンがある機種の場合、loopの最初にあるコメントアウトを外せばAボタンを押すことで結果を再生して聞き直すことができます(^^)。
Appendix
その他のシリアルモニタについては
Windows11からM5Stack LLM モジュール に触ってみる(3)アプリケーション(TTS)
のAppendixをご参照ください。
関連ページ
Windows 11からM5Stack LLM モジュール に触ってみる(1)アクセス編
Windows 11からM5Stack LLM モジュール に触ってみる(2)環境設定とアプリケーション
Windows11からM5Stack LLM モジュール に触ってみる(3)アプリケーション(TTS)
Windows11からM5Stack LLM モジュール に触ってみる(4)アプリケーション(SerialTextAssistant + TTS)
LLM モジュール のSerialTextAssistant + TTS のシリアルモニタにPythonを使ってみる










Leave a Reply