Welcome to ROSMASTER M3 repository
3. AI large model voice interaction
3. AI Large Model Voice Interaction
3. AI Large Model Voice Interaction1. Concept Introduction1.1 What is "AI Large Model Voice Interaction"?1.2 Implementation Principle Overview2. Code AnalysisKey Code1. Speech Input Node (largemodel/largemodel/asr.py)2. AI service and voice output node (largemodel/largemodel/model_service.py)Code Analysis3. Practical Operation3.1 Configuring Offline Voice Interaction3.2 Launching and Testing the Feature
Note: Due to performance limitations, Raspberry Pi 5 2GB, 4GB, RDK X5 4GB, and Jetson Orin Nano 4GB versions cannot run offline. Please refer to online large model tutorials.
1. Concept Introduction
1.1 What is "AI Large Model Voice Interaction"?
In the largemodel project, AI Large Model Voice Interaction connects the previously introduced offline ASR and offline TTS with the core of the Large Language Model (LLM), forming a complete dialogue system that can hear, speak, and think.
This is no longer an isolated function, but a prototype of a true voice assistant. Users can engage in natural language conversations with the robot via voice, and the robot can understand questions, think about answers, and respond with voice. The entire process is completed locally, without a network.
The core of this function is the model_service ROS2 node. It acts as the brain and central nervous system, subscribing to the ASR recognition results, calling the LLM for processing, and then publishing the LLM's text response to the TTS node for speech synthesis.
1.2 Implementation Principle Overview
The implementation principle of this function is a classic data flow pipeline:
- Audio -> Text (ASR): The
asrnode continuously listens to ambient sound. Once it detects that a user has finished speaking a sentence, it converts it into text and publishes it to the/asr_texttopic. - Text -> Processing -> Text (LLM): The
model_servicenode subscribes to the/asr_texttopic. When it receives the text from the ASR, it sends it as a prompt to the locally deployed large language model (such asQwenrunning viaOllama). The LLM generates a response text based on the context. - Text -> Audio (TTS): After receiving the LLM's response, the
model_servicenode publishes it to the/tts_texttopic. - Audio Playback: The
tts_onlynode subscribes to the/tts_texttopic. Upon receiving the text, it immediately calls the offline TTS model to synthesize it into audio and plays it through the speaker.
This process forms a complete closed loop of speech input -> text processing -> text output -> speech output.
2. Code Analysis
Key Code
1. Speech Input Node (largemodel/largemodel/asr.py)
xxxxxxxxxx# From largemodel/largemodel/asr.pyclass ASRNode(Node): def __init__(self): # ... self.asr_pub = self.create_publisher(String, "asr", 5) # ... def kws_handler(self)->None: if self.listen_for_speech(self.mic_index): asr_text = self.ASR_conversion(self.user_speechdir) if asr_text != 'error': self.asr_pub_result(asr_text) def asr_pub_result(self,asr_result:str)->None: msg=String(data=asr_result) self.asr_pub.publish(msg)2. AI service and voice output node (largemodel/largemodel/model_service.py)
xxxxxxxxxx# From largemodel/largemodel/model_service.pyclass LargeModelService(Node): def __init__(self): # ... self.asrsub = self.create_subscription(String,'asr', self.asr_callback,1) # ... def asr_callback(self,msg): """Callback function for handling ASR messages.""" # ... result = self.model_client.infer_with_text(msg.data, message=messages_to_use) self.process_model_result(result) def process_model_result(self, result, from_seewhat=False): """Process the result returned by the model. """ # ... user_friendly_response = response_json.get("response", "我正在处理...") # ... self._safe_play_audio(user_friendly_response) # ... self.execute_tools(tools_list) def _safe_play_audio(self, text_to_speak: str): """ Synthesizes and plays all non-empty messages only in non-text chat mode. """ if not self.text_chat_mode and text_to_speak: try: self.model_client.voice_synthesis(text_to_speak, self.tts_out_path) self.play_audio_async(self.tts_out_path) except Exception as e: self.get_logger().error(f"Safe audio playback failed: {e}")Code Analysis
The voice interaction functionality of the large AI model is implemented by two independent ROS nodes, asr.py and model_service.py, which communicate via the ROS topic /asr, forming a complete processing loop.
Voice Input and Publishing (
asr.py):- The
ASRNodenode processes voice input. In thekws_handlerfunction, it performs audio recording and text conversion. - After successful conversion, the
asr_pub_resultfunction is called. This function places the resulting text string into astd_msgs.msg.Stringmessage and then publishes it to the/asrtopic via theself.asr_pubpublisher.
- The
Subscription and Response (
model_service.py):- During initialization, the
LargeModelServicenode subscribes to the/asrtopic using thecreate_subscriptionmethod and specifiesasr_callbackas its callback function. - When
ASRNodepublishes a message on the/asrtopic, the ROS system automatically calls theasr_callbackfunction ofLargeModelService, passing the message as themsgparameter.
- During initialization, the
Interaction Loop:
- After receiving the message, the
asr_callbackfunction extracts the text data (msg.data) and passes it to the large model for inference (self.model_client.infer_with_text). - After inference is complete, the
process_model_resultfunction is called. This function extracts the reply text from the model result. - Next, the
_safe_play_audiofunction is called, which uses the TTS function (self.model_client.voice_synthesis) to synthesize the reply text into audio and play it back. - At this point, a complete interaction loop from "receiving user voice" to "responding to the user with voice" is completed. The two nodes are decoupled using ROS's publish-subscribe model.
asr.pyhandles input, whilemodel_service.pyhandles processing and output.
- After receiving the message, the
3. Practical Operation
3.1 Configuring Offline Voice Interaction
To implement a fully offline voice interaction system, you need to ensure that ASR, TTS, and LLM are all configured in offline mode.
Raspberry Pi 5 requires entering a Docker container; RDK X5 and Orin controllers do not require this:
xxxxxxxxxx./ros2_docker.sh
If you need to enter the same Docker container later and run other commands, simply enter ./ros2_docker.sh again in the host terminal.
Open the main configuration file
yahboom.yaml:xxxxxxxxxxvim ~/yahboom_ws/src/largemodel/config/yahboom.yamlModify/confirm the following key configurations:
xxxxxxxxxxasrros__parametersuse_oline_asrFalse # Key: Set to False to enable offline ASRregional_setting "China"model_serviceros__parametersuseolinettsFalse # Key: Set to False to enable offline TTSllm_platform'ollama' # Key: Set to 'ollama' to enable offline LLMregional_setting "China"Open the model interface configuration file
large_model_interface.yaml:xxxxxxxxxxvim ~/yahboom_ws/src/largemodel/config/large_model_interface.yamlConfirm that all offline model paths are correct:
- Raspberry Pi 5
xxxxxxxxxx# large_model_interface.yaml## Offline large modelollama_model"qwen2.5:7b" # Make sure the model has been downloaded via ollama pull## Offline speech recognitionlocal_asr_model"/path/to/your/SenseVoiceSmall" # Ensure the ASR model path is correct## Offline speech synthesiszh_tts_model"/path/to/your/zh_CN-huayan-medium.onnx" # 确保TTS模型路径正确# ...- RDK X5
xxxxxxxxxx# large_model_interface.yaml## Offline large modelollama_model"qwen2.5:7b" # Make sure the model has been downloaded via ollama pull## Offline speech recognitionlocal_asr_model"~/yahboom_ws/src/largemodel/MODELS/asr/SenseVoiceSmall" # Ensure the ASR model path is correct##Offline speech synthesis (Offline TTS)# Chinese TTS modelzh_tts_model"/home/sunrise/yahboom_ws/src/largemodel/MODELS/tts/zh/zh_CN-huayan-medium.onnx"zh_tts_json"/home/sunrise/yahboom_ws/src/largemodel/MODELS/tts/zh/zh_CN-huayan-medium.onnx.json"