1. 项目概述当机器人“开口”思考最近在折腾一个挺有意思的项目让我的Reachy Mini机器人通过它自带的麦克风“听见”我说话然后直接在它“大脑”——也就是那块reComputer Mini开发板上——运行一个语言大模型LLM来理解我的意图并生成回应最后再通过扬声器“说”出来。简单说就是给它装上一个完全本地的、能听会说的“大脑”。这听起来像是科幻电影里的场景但实现起来核心就是本地语音LLM部署。为什么非要本地部署原因很直接实时性、隐私性和成本。想象一下你让机器人去拿杯水如果每次指令都要上传到云端处理再等结果返回这个延迟在交互体验上是致命的。更别提语音数据本身非常敏感本地处理能彻底杜绝隐私泄露的风险。对于像Reachy Mini这样的教育或研究型机器人频繁的云端API调用也是一笔不小的开销。reComputer Mini是NVIDIA Jetson系列中的一员通常搭载Jetson Orin Nano或NX模块它体积小巧但算力不俗尤其擅长边缘AI推理。而Reachy Mini是一个开源的、模块化的桌面级机械臂设计初衷就是用于AI和机器人学研究。这个项目的目标就是把这两者结合起来探索在资源受限的边缘设备上实现复杂AI任务语音交互的可行性。它适合谁呢如果你是机器人爱好者、AI应用开发者、嵌入式系统工程师或者单纯对“让机器更智能地交互”感兴趣那么这个从硬件选型、环境配置到模型优化的完整实践会给你带来不少启发。2. 核心思路与方案选型这个项目的核心链路可以拆解为三个环环相扣的模块语音输入ASR - 语言理解与生成LLM - 语音输出TTS。在reComputer Mini上实现它就像是在一台性能尚可但资源有限的“迷你电脑”上同时运行三个吃资源的AI服务并且还要保证它们能流畅地协同工作。因此方案选型的每一个决策都围绕着“如何在有限的算力和内存下达到可用的性能”这个核心矛盾展开。2.1 语音转文本ASR模块选型ASR是交互的入口它的准确度和延迟直接影响第一印象。在边缘设备上我们主要有两个方向离线模型和调用本地服务的API。离线轻量级模型例如Vosk、Coqui STT的Tiny版本。它们的好处是完全离线隐私性最佳启动快。但缺点也很明显中文等非英语语言的模型精度通常较云端大模型有差距尤其是面对专业术语或嘈杂环境时并且模型本身仍需要占用一定的内存和CPU资源。本地服务化模型例如部署Faster-Whisper。这是OpenAI Whisper模型的一个高效实现支持多种尺寸tiny, base, small。我们可以将其用FastAPI或Flask封装成一个本地HTTP服务。这样做的好处是ASR模型作为一个独立进程运行与主程序解耦稳定性更好并且可以选用精度更高的small模型识别效果远超大多数离线模型。虽然它比离线模型更耗资源但在Jetson Orin Nano8GB/16GB上运行small版本是可行的。我的选择是后者部署 Faster-Whisper 作为本地服务。理由如下对于机器人交互场景语音指令的准确理解至关重要。一个误识别比如把“打开灯”听成“打开等”可能导致完全错误的操作。牺牲一些内存和CPU资源换取显著提升的识别率这个交换是值得的。而且服务化的方式更利于后期维护和升级。2.2 大语言模型LLM选型与优化这是项目的核心也是最大的挑战。在Jetson设备上运行LLM我们必须直面内存RAM和显存VRAM的硬约束。模型家族选择考虑到社区支持、工具链成熟度和性能我优先考虑Llama系列包括其衍生的中文优化版如Chinese-Llama或Qwen系列。Qwen对中文的支持原生就很好且提供了丰富的量化版本。Gemma等模型也可选但生态相对较新。模型尺寸与量化这是关键中的关键。动辄7B、13B参数的原始模型根本无法放入边缘设备的内存。量化Quantization是唯一的出路。我们需要将模型权重从高精度如FP16转换为低精度如INT8, INT4甚至更低。量化会轻微损失模型能力但能极大地减少内存占用。GGUF格式这是目前社区在CPU/边缘设备上运行LLM的事实标准。它利用llama.cpp项目进行高效的推理。我们可以直接下载现成的GGUF量化模型文件如qwen1.5-1.8b-chat-q4_k_m.gguf。q4_k_m表示一种4位量化方法在精度和速度间取得了很好的平衡。TensorRT-LLM这是NVIDIA官方的LLM推理优化框架能为Jetson平台带来极致的性能。但它需要将模型编译成特定的引擎文件过程稍复杂且对模型的支持列表有限。对于初次尝试GGUF方案更简单快捷。推理后端选择llama.cpp配合GGUF模型这是最通用、最简单的方案。它纯用CPU推理但优化得很好。对于1.8B或3B级别的模型在Jetson Orin Nano的CPU上也能达到数token/秒的速度对于简单的对话交互足够。Ollama一个非常流行的本地大模型管理运行工具。它底层也支持llama.cpp但提供了更友好的API类似OpenAI API和模型管理功能。如果你的交互逻辑用Python写调用Ollama的API比直接操作llama.cpp更简洁。我的方案是使用Ollama拉取并运行一个量化后的轻量级模型例如qwen:1.8bOllama会自动下载适配平台的最佳版本。这样我可以用一个统一的HTTP API来与LLM交互简化了开发流程。2.3 文本转语音TTS模块选型TTS的要求是自然、延迟低、资源占用小。同样有离线和服务化两种思路。离线轻量级库如pyttsx3调用系统语音引擎或edge-tts离线效果一般。它们的好处是集成简单无依赖。本地TTS模型服务如ChatTTS、StyleTTS2或Coqui TTS。这些模型能生成质量高得多的语音但同样需要GPU资源部署复杂度高。折中方案系统TTS引擎Linux系统通常内置了如espeak、festival或pico2wave等语音合成引擎。虽然声音机械但胜在零延迟、零额外资源消耗且非常稳定。考虑到机器人交互的实时性要求以及前两个模块ASR, LLM已经占用了大量资源我选择了最轻量的方案使用pico2wave如果系统已安装或pyttsx3调用系统默认引擎。我们的首要目标是完成“听-思-说”的闭环语音质量可以在后续优化。实际上这种略带机械感的语音反而有一种“机器人”的独特味道。2.4 整体架构设计最终的架构如下图所示此处用文字描述主控程序Python运行在reComputer Mini上作为大脑的“总指挥”。语音采集线程持续监听Reachy Mini的麦克风当检测到语音活动VAD后录制音频。ASR客户端将录制的音频发送给本地运行的Faster-Whisper HTTP服务获取识别出的文本。LLM客户端将文本作为提示词发送给本地运行的Ollama服务内部运行Qwen 1.8B GGUF模型获取生成的回复文本。TTS调用将回复文本交给系统TTS引擎通过Reachy Mini的扬声器播放。逻辑控制主程序可以解析LLM的回复。如果回复是结构化指令如{action: wave, duration: 2}则可以调用Reachy Mini的SDK来控制机械臂做出相应动作实现真正的“听懂并执行”。这个架构清晰地将计算密集型任务ASR, LLM服务化主程序逻辑轻量通过HTTP进行通信提高了系统的稳定性和可维护性。3. 环境准备与依赖安装在reComputer Mini假设系统为JetPack 5.1.2 Ubuntu 20.04上开始实操。第一步是搭建一个稳定、互不干扰的Python环境并安装所有必要的依赖。3.1 创建并激活Python虚拟环境强烈建议使用虚拟环境来管理项目依赖避免污染系统Python环境。# 更新系统包列表 sudo apt update # 安装python3-venv如果未安装 sudo apt install python3.8-venv -y # 为项目创建一个目录 mkdir ~/reachy_voice_llm cd ~/reachy_voice_llm # 创建虚拟环境使用python3.8 python3.8 -m venv venv # 激活虚拟环境 source venv/bin/activate激活后命令行提示符前会出现(venv)字样。3.2 安装PyTorch与相关库由于Faster-Whisper和许多AI库依赖PyTorch我们需要安装与JetPack版本和CUDA版本匹配的PyTorch。访问 PyTorch官网 获取对应版本的安装命令。对于JetPack 5.1.2 (CUDA 11.4)命令可能如下pip install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu114安装后可以在Python中验证import torch print(torch.__version__) # 应显示版本号 print(torch.cuda.is_available()) # 应返回 True表示GPU可用3.3 安装核心项目依赖在虚拟环境中安装我们项目所需的Python包。# 安装音频处理库 pip install pyaudio wave sounddevice # 安装Web框架用于后续可能的简单控制界面 pip install fastapi uvicorn # 安装HTTP客户端 pip install requests # 安装语音活动检测库 pip install webrtcvad # 安装一个轻量级TTS库备用 pip install pyttsx33.4 部署Faster-Whisper本地服务Faster-Whisper使用CTranslate2作为推理后端效率很高。我们将其部署为一个独立的服务。安装Faster-Whisperpip install faster-whisper创建ASR服务脚本在项目目录下创建asr_server.py。# asr_server.py from fastapi import FastAPI, File, UploadFile from faster_whisper import WhisperModel import numpy as np import soundfile as sf import io import logging import torch # 配置日志 logging.basicConfig(levellogging.INFO) logger logging.getLogger(__name__) app FastAPI() # 指定模型尺寸这里用 small精度和速度平衡较好 # 首次运行会自动从Hugging Face下载模型 model_size small # 指定在GPU上运行如果显存不够可改为 cpu device cuda if torch.cuda.is_available() else cpu compute_type float16 if device cuda else int8 logger.info(f正在加载Whisper模型 {model_size} 在 {device} 上计算类型 {compute_type}...) model WhisperModel(model_size, devicedevice, compute_typecompute_type) logger.info(模型加载完毕。) app.post(/transcribe/) async def transcribe_audio(file: UploadFile File(...)): 接收音频文件WAV格式返回识别文本。 try: # 读取上传的音频文件 contents await file.read() audio_data, sample_rate sf.read(io.BytesIO(contents)) # 确保是单声道faster-whisper需要 if len(audio_data.shape) 1: audio_data audio_data.mean(axis1) # 执行语音识别 segments, info model.transcribe(audio_data, beam_size5, languagezh) text .join([segment.text for segment in segments]) logger.info(f识别结果: {text}) return {text: text, language: info.language} except Exception as e: logger.error(f识别失败: {e}) return {error: str(e)} if __name__ __main__: import uvicorn # 服务运行在 8001 端口避免冲突 uvicorn.run(app, host0.0.0.0, port8001)运行ASR服务在终端新建一个窗口激活虚拟环境后运行。cd ~/reachy_voice_llm source venv/bin/activate python asr_server.py首次运行会下载small模型需要一定时间和网络。看到“模型加载完毕”和“Uvicorn running on...”的日志即表示服务启动成功。3.5 部署Ollama与LLM模型Ollama的安装非常简便它提供了Linux ARM64的安装包正好适配Jetson。安装Ollama# 使用一键安装脚本 curl -fsSL https://ollama.com/install.sh | sh # 安装完成后启动Ollama服务 sudo systemctl start ollama # 设置开机自启 sudo systemctl enable ollama拉取并运行轻量级LLM模型# 拉取Qwen 1.8B模型Ollama会自动选择适合本机的最佳版本很可能是量化版 ollama pull qwen:1.8b # 运行模型默认API服务在11434端口 ollama run qwen:1.8b在ollama run交互界面里你可以简单测试一下模型是否工作正常。输入“你好”看它能否用中文回复。测试完成后按CtrlC退出交互界面但Ollama服务仍在后台运行。你也可以直接让模型在后台以服务模式运行# 后台运行指定模型 ollama serve # 或者使用nohup nohup ollama run qwen:1.8b Ollama的REST API默认在http://localhost:11434提供。我们可以通过发送POST请求到/api/generate端点来与模型交互。3.6 系统TTS引擎安装确保系统有可用的TTS引擎。pico2wave是一个轻量级选择。# 安装pico2wave及其中文语音包 sudo apt install libttspico-utils libttspico-data -y # 测试TTS生成一个WAV文件 pico2wave -l zh-CN -w test.wav 你好我是Reachy Mini aplay test.wav如果听到语音说明TTS工作正常。也可以使用pyttsx3它会自动调用系统默认引擎。4. 核心交互程序实现现在我们将三个模块串联起来编写主交互程序。这个程序需要完成监听麦克风、调用ASR服务、调用LLM服务、调用TTS播放。4.1 语音监听与VAD检测持续监听麦克风会产生大量音频数据我们需要使用**语音活动检测VAD**来只在有人说话时进行录制和处理以节省资源。# voice_llm_main.py 部分代码 import pyaudio import wave import numpy as np import webrtcvad import threading import queue import time import requests import json import subprocess import pyttsx3 class VoiceLLMAgent: def __init__(self, asr_server_urlhttp://localhost:8001, ollama_urlhttp://localhost:11434): self.asr_url asr_server_url /transcribe/ self.ollama_url ollama_url /api/generate self.audio_format pyaudio.paInt16 self.channels 1 self.rate 16000 # Whisper模型通常使用16kHz self.chunk_duration_ms 30 # VAD处理帧长 self.chunk_size int(self.rate * self.chunk_duration_ms / 1000) self.vad webrtcvad.Vad(2) # 设置VAD敏感度0-3越大越激进 self.audio_queue queue.Queue() self.is_recording False self.frames [] # 初始化TTS引擎 self.tts_engine pyttsx3.init() # 设置语速和音量可选 self.tts_engine.setProperty(rate, 150) self.tts_engine.setProperty(volume, 0.9) def vad_collect_audio(self, threshold0.5, silence_limit1.0): 使用VAD监听麦克风检测到语音后开始录制静音超过阈值后停止。 p pyaudio.PyAudio() stream p.open(formatself.audio_format, channelsself.channels, rateself.rate, inputTrue, frames_per_bufferself.chunk_size) print(开始监听...请说话) num_silent_chunks 0 audio_data [] triggered False while True: chunk stream.read(self.chunk_size, exception_on_overflowFalse) # VAD检测需要16kHz16bit mono is_speech self.vad.is_speech(chunk, self.rate) if not triggered: # 等待语音触发 if is_speech: triggered True print(检测到语音开始录制...) audio_data.append(chunk) else: audio_data.append(chunk) if not is_speech: num_silent_chunks 1 else: num_silent_chunks 0 # 如果静音持续时间超过限制则认为一句话结束 if num_silent_chunks (silence_limit * 1000 / self.chunk_duration_ms): print(检测到静音停止录制。) break # 也可以设置最长录音时间防止意外 if len(audio_data) (10 * 1000 / self.chunk_duration_ms): # 最长10秒 print(达到最大录音长度。) break stream.stop_stream() stream.close() p.terminate() # 将音频数据转换为字节流 audio_buffer b.join(audio_data) return audio_buffer4.2 调用ASR服务进行转录将录制好的音频字节流发送给我们之前启动的Faster-Whisper服务。def transcribe_audio(self, audio_bytes): 将音频数据发送给ASR服务返回识别文本。 try: # 需要将音频字节包装成文件对象上传 files {file: (audio.wav, audio_bytes, audio/wav)} response requests.post(self.asr_url, filesfiles, timeout10) if response.status_code 200: result response.json() return result.get(text, ).strip() else: print(fASR服务请求失败: {response.status_code}) return None except requests.exceptions.RequestException as e: print(f连接ASR服务失败: {e}) return None4.3 调用Ollama LLM生成回复将识别出的文本作为提示词发送给Ollama获取模型的回复。这里需要构造一个符合Ollama API格式的请求。def ask_llm(self, prompt): 向Ollama服务的LLM提问返回生成的回复。 # 可以设计一个系统提示词让模型以机器人的口吻回复 system_prompt 你是一个名为Reachy Mini的桌面机器人助手。你的回复应该简洁、友好、直接尽量用口语化的短句。如果用户要求你执行动作请在你的回复中明确表示你将执行并以JSON格式在最后输出动作指令例如{action: wave, param: 2}。 full_prompt f{system_prompt}\n\n用户说{prompt}\n机器人回复 payload { model: qwen:1.8b, # 与运行的模型名一致 prompt: full_prompt, stream: False, # 非流式一次性返回完整结果 options: { temperature: 0.7, # 创造性0-1越高越随机 top_p: 0.9, num_predict: 150 # 最大生成token数 } } try: response requests.post(self.ollama_url, jsonpayload, timeout30) # LLM推理需要更长时间 if response.status_code 200: result response.json() return result[response].strip() else: print(fLLM服务请求失败: {response.status_code}) return 抱歉我现在有点困惑。 except requests.exceptions.RequestException as e: print(f连接LLM服务失败: {e}) return 网络好像出了点问题。4.4 文本转语音与播放获取LLM的回复文本后通过TTS引擎播放出来。def speak_text(self, text): 使用pyttsx3将文本转换为语音并播放。 if not text: return print(f机器人说{text}) # 使用pyttsx3同步播放会阻塞直到播放完成 self.tts_engine.say(text) self.tts_engine.runAndWait() # 或者使用pico2wave异步不阻塞主线程 def speak_text_pico(self, text): 使用pico2wave生成WAV文件并用aplay播放 import tempfile import os with tempfile.NamedTemporaryFile(suffix.wav, deleteFalse) as f: wav_file f.name # 生成wav文件 subprocess.run([pico2wave, -l, zh-CN, -w, wav_file, text], checkTrue) # 异步播放不阻塞 subprocess.Popen([aplay, -q, wav_file], stdoutsubprocess.DEVNULL, stderrsubprocess.DEVNULL) # 可选播放后删除临时文件 time.sleep(0.5) # 稍等片刻再删除 os.unlink(wav_file)4.5 主循环与集成最后我们将所有功能集成到一个主循环中。def main_loop(self): 主交互循环。 print(Reachy Mini 本地语音LLM助手已启动) print(*50) while True: try: # 1. 监听并录制语音 print(\n请说话...说完后保持安静1秒) audio_data self.vad_collect_audio(silence_limit1.0) if len(audio_data) self.chunk_size * 5: # 过滤掉过短的噪音 print(录音太短忽略。) continue # 2. 语音转文本 print(正在识别语音...) user_text self.transcribe_audio(audio_data) if not user_text: print(未识别到有效内容。) continue print(f你说{user_text}) # 3. 大模型生成回复 print(思考中...) bot_response self.ask_llm(user_text) # 4. 文本转语音并播放 self.speak_text(bot_response) # 或者使用 pico2wave # self.speak_text_pico(bot_response) # 5. 可选解析回复中的动作指令控制Reachy Mini # self.parse_and_execute_action(bot_response) except KeyboardInterrupt: print(\n程序退出。) break except Exception as e: print(f主循环发生错误: {e}) time.sleep(1) if __name__ __main__: agent VoiceLLMAgent() agent.main_loop()运行这个主程序你就拥有了一个能听、能思考、能说的本地机器人助手核心了。5. 性能优化与资源管理实战在reComputer Mini上同时运行多个AI服务资源管理是成败的关键。以下是我在实测中总结的优化经验。5.1 内存与显存监控与调优Jetson设备的内存是共享的即CPU和GPU共用同一块物理内存。你需要密切关注整体内存使用情况。监控命令# 查看整体内存和显存使用 sudo tegrastats这个命令会持续输出详细的系统状态关注RAM和GR3D(GPU) 的使用率。Ollama模型参数调优在启动Ollama或调用API时可以通过options参数限制资源使用。{ model: qwen:1.8b, prompt: ..., options: { num_ctx: 1024, // 减小上下文长度默认可能是2048 num_thread: 4 // 限制CPU线程数避免占满所有核心 } }在~/.ollama/config.json中也可以进行全局配置。Faster-Whisper模型选择如果发现内存紧张可以将small模型降级为base甚至tiny。在asr_server.py中修改model_size变量即可。tiny模型速度极快内存占用极小但中文精度有所下降。5.2 使用系统服务管理后台进程为了让ASR服务和Ollama服务在开机后自动运行并方便管理最好将它们配置为系统服务。创建Ollama服务文件通常安装脚本已完成检查/etc/systemd/system/ollama.service是否存在。创建Faster-Whisper ASR服务文件sudo nano /etc/systemd/system/faster-whisper.service写入以下内容根据你的实际路径修改[Unit] DescriptionFaster-Whisper ASR Server Afternetwork.target [Service] Typesimple User你的用户名 WorkingDirectory/home/你的用户名/reachy_voice_llm EnvironmentPATH/home/你的用户名/reachy_voice_llm/venv/bin ExecStart/home/你的用户名/reachy_voice_llm/venv/bin/python /home/你的用户名/reachy_voice_llm/asr_server.py Restarton-failure RestartSec5s [Install] WantedBymulti-user.target启用并启动服务sudo systemctl daemon-reload sudo systemctl enable faster-whisper.service sudo systemctl start faster-whisper.service # 查看状态 sudo systemctl status faster-whisper.service5.3 降低延迟的实用技巧交互延迟是体验的杀手。除了选用更快的模型还可以从流程上优化。预热模型在服务启动后主动发送一个简短的测试音频给ASR服务发送一个简单查询给Ollama让它们完成模型的初始加载和缓存。这能避免第一次交互时的长延迟。流水线操作在主循环中当TTS正在播放上一句回复时就可以开始下一轮的VAD监听实现“边说边听下一句”减少用户等待感。优化VAD参数调整webrtcvad.Vad()的敏感度等级和silence_limit参数。更低的敏感度如等级1和更短的静音判断时间能更快地结束录音但也可能切掉话尾。需要根据实际环境噪音情况调整。使用更轻量的TTSpico2waveaplay的方案比pyttsx3的延迟通常更低因为它是直接调用系统底层库。6. 常见问题与故障排查在部署和运行过程中你几乎一定会遇到下面这些问题。这里是我的排查实录。6.1 音频采集相关问题问题PyAudio报错 “No default input device found” 或无法打开麦克风。排查首先用arecord -l命令查看音频设备列表确认reComputer Mini的麦克风已被识别通常是hw:0,0。解决在pyaudio.PyAudio().open()中指定设备索引。import pyaudio p pyaudio.PyAudio() # 打印所有设备信息找到麦克风设备的索引 for i in range(p.get_device_count()): info p.get_device_info_by_index(i) if info[maxInputChannels] 0: print(fInput Device {i}: {info[name]}) # 假设麦克风设备索引是2 stream p.open(..., input_device_index2, ...)权限问题确保当前用户有访问音频设备的权限。可以将用户加入audio组sudo usermod -a -G audio $USER然后注销重新登录。问题VAD检测不灵敏总是无法触发或过早结束。排查webrtcvad要求音频必须是16kHz采样率、16位深、单声道。检查pyaudio打开的流参数是否匹配。解决确保rate16000,formatpyaudio.paInt16,channels1。调整Vad()的敏感度等级0-3。在嘈杂环境中可能需要先进行简单的噪声抑制如使用noisereduce库或使用更复杂的端点检测算法。6.2 ASR服务相关问题问题Faster-Whisper服务启动时下载模型失败或速度极慢。解决可以考虑手动下载模型。首先在能高速访问网络的环境从Hugging Face下载openai/whisper-small模型文件注意是CTranslate2格式的或者用transformers格式再转换。然后在WhisperModel初始化时指定本地路径model WhisperModel(/path/to/your/local/model)。问题识别结果为空或全是乱码。排查检查发送的音频格式。faster-whisper和原始Whisper一样支持多种音频格式但最保险的是发送单声道、16kHz的WAV/PCM数据。确保你在服务端和客户端使用了相同的采样率。解决在客户端录制音频后可以先用soundfile或librosa库重采样到16kHz并确保是单声道。也可以在服务端加载模型时指定语言languagezh强制进行中文识别避免自动检测出错。6.3 Ollama与LLM相关问题问题Ollama拉取模型失败或速度慢。解决Ollama默认使用国外镜像。可以配置环境变量使用国内镜像加速如果可用。例如在运行ollama pull前设置export OLLAMA_HOST镜像地址需自行寻找可用镜像。更可靠的方法同样是先在网络好的机器上下载好模型文件位于~/.ollama/models/然后拷贝到reComputer Mini的对应目录下。问题LLM响应速度非常慢或者回复不完整。排查首先检查系统资源。运行tegrastats看是否内存已满导致交换swapping这会极大拖慢速度。解决减少上下文长度在API请求的options中设置num_ctx: 512。换用更小的量化版本如果用的是qwen:1.8b可以尝试寻找或自己量化一个q2_k或q3_k的GGUF版本然后用ollama create自定义一个模型。关闭无关进程关掉不需要的桌面环境、浏览器等为LLM推理腾出最大内存。问题LLM的回复不符合预期总是胡言乱语。解决这通常是提示词Prompt工程问题。我们的场景是简单的指令-回复不需要太复杂的上下文。尝试简化系统提示词并明确指令格式。例如“你是一个机器人。直接回答用户的问题如果问题是指令回复‘好的我将执行XX动作’。不要解释不要添加额外信息。” 多迭代几次提示词对输出结果影响巨大。6.4 系统集成与稳定性问题问题长时间运行后程序崩溃或服务无响应。排查可能是内存泄漏。Python的requests库如果频繁创建会话而不关闭可能会积累问题。也可能是某个子进程僵死。解决使用with requests.Session()来管理HTTP连接。为主循环添加异常捕获和日志记录记录崩溃前的状态。为系统服务faster-whisper.service配置Restarton-failure让它崩溃后能自动重启。编写一个简单的监控脚本定期检查服务端口如8001, 11434是否存活如果死掉就尝试重启。问题TTS播放有杂音或断断续续。解决这可能是音频系统冲突或资源占用过高。尝试关闭其他可能使用音频的程序。使用aplay直接播放一个WAV文件测试硬件是否正常。如果使用pyttsx3尝试换用不同的底层引擎如espeak。在播放TTS时暂时降低LLM推理的线程数减少CPU争抢。这个项目就像是在一块有限的画布上作一幅复杂的画每一个环节都需要权衡和优化。从麦克风里传来的声音到机械臂最终挥动的轨迹中间每一步的延迟和可靠性都至关重要。我个人的体会是在边缘设备上部署AI应用“可用性”优先于“最优性”。先追求整个链路能稳定跑通哪怕TTS声音机械一点LLM反应慢一点。然后再像挤牙膏一样从模型量化、代码优化、流程设计等各个角度去一点点提升体验。当你第一次对着Reachy Mini说“挥挥手”并看到它经过“思考”后真的开始运动时那种将前沿AI模型塞进一个小盒子里并让它活过来的成就感是单纯调用云端API无法比拟的。