项目简介
本项目基于行空板M10及其扩展板,结合本地开源大模型Vosk的语音识别与对话能力,构建一个面向小学学科的本地化知识答疑库系统。通过语音交互,学生可以快速获取语文、数学、英语等学科的知识解答,系统支持离线运行,保障隐私安全,同时降低对网络环境的依赖。项目整合了硬件控制、语音处理、自然语言理解等技术,为教育场景提供轻量级、低成本的智能辅助工具。
项目目标
功能实现
完成行空板与蓝牙音箱的无线连接,实现语音输入与输出的低延迟交互。
部署Vosk本地语音识别模型,支持中英文语音转文本。
构建小学学科知识库(如数学公式、古诗词解析、英语单词等),结合本地大模型生成精准答案。
设计交互逻辑,实现“提问-识别-检索-语音回答”的完整闭环。
教育价值
为小学生提供即时、准确的学科答疑服务,弥补传统教育资源的时空限制。
探索离线AI技术在教育硬件中的应用潜力,推动普惠型智能教育工具发展。
所需硬件
硬件名称 | 数量 | 用途说明 |
行空板M10 | 1块 | 主控设备,运行语音收集与反馈 |
配套扩展板 | 1套 | 提供接口扩展,连接外设 |
蓝牙音箱 | 1个 | 语音输出(需支持A2DP协议) |
笔记本电脑 | 1台 | 开发调试、知识库数据预处理,可做服务器 |
预期成果
可演示系统
用户通过蓝牙音箱提问(如“圆的面积公式是什么?”),行空板实时识别并返回语音答案。
知识库覆盖小学主要学科高频问题,回答准确率≥85%。
实施步骤
●行空板与蓝牙音箱互联
●通过thonny控制行空板编写客户端程序并进行调试
●笔记本安装ollama,编写服务端程序并进行调试
行空板与蓝牙音箱互联
通过行空板jupyter服务新建终端执行 bluetoothctl 命令,进入交互模式后依次输入:
power on # 开启蓝牙
agent on # 启用配对代理
scan on # 扫描设备(记录音箱MAC地址)
pair [MAC] # 配对
connect [MAC] # 连接
trust [MAC] # 设为信任设备
若以前连过多次则可以通过命令bluetoothctl paired-devices查看已连接过的蓝牙设备,然后直接使用命令connect [MAC]进行连接。
若对行空板连接蓝牙细节不太清楚可以看
行空板与蓝牙连接问题解决记录
行空板连接蓝牙音箱的补充说明
●通过thonny控制行空板编写客户端程序并进行调试
import json
import pyttsx3
import requests
import sounddevice as sd
import numpy as np
import wave
import io
ServerIP = '192.168.1.139' #服务端IP地址 根据实际情况可以有变动
ServerPort = '5000' #服务端使用端口 根据实际情况可以有变动
url = 'http://' + ServerIP + ':' + ServerPort
def record_audio(duration, samplerate=16000, channels=1):
# 记录音频
print(f"Recording for {duration} seconds...")
audio = sd.rec(int(samplerate * duration), samplerate=samplerate, channels=channels, dtype='float32')
sd.wait() # 等待录音完成
print("Recording complete.")
return audio
def save_wave_file(filename, data, samplerate):
# 保存音频为WAV文件
with wave.open(filename, 'wb') as wav_file:
wav_file.setnchannels(1)
wav_file.setsampwidth(2)
wav_file.setframerate(samplerate)
wav_file.writeframes((data * 32767).astype(np.int16).tobytes())
def send_audio(audio_data, samplerate):
# 将音频数据转换为WAV格式并发送到服务器
audio_bytes = io.BytesIO()
with wave.open(audio_bytes, 'wb') as wav_file:
wav_file.setnchannels(1)
wav_file.setsampwidth(2)
wav_file.setframerate(samplerate)
wav_file.writeframes((audio_data * 32767).astype(np.int16).tobytes())
audio_bytes.seek(0)
files = {'file': ('audio.wav', audio_bytes, 'audio/wav')}
# 发送请求并打印响应
response = requests.post(url+'/upload', files=files)
print("Status Code:", response.status_code)
print("Response Content:", response.content)
# 尝试解析 JSON 响应
try:
result = response.json()
except json.JSONDecodeError:
result = "JSON decode error"
return result
def inferMeaning(message):
data = {'message': message}
response = requests.post(url + '/chat', json=data)
#print("inferMeaning:",response)
res_con_text = response.content.decode('utf-8')
#print("response.content:",res_con_text)
con_pos_s = res_con_text.find("content=")
con_pos_e = res_con_text.find("', thinking=")
#print("con_pos_s:",con_pos_s)
#print("con_pos_e:",con_pos_e)
res_con_text = res_con_text[con_pos_s+len("content="):con_pos_e]
return res_con_text
if __name__ == '__main__':
while True:
try:
duration = 5 # 录音持续时间(秒)
audio_data = record_audio(duration)
result = send_audio(audio_data, 16000)
#print("__name__ Recognition Result:", result)
message_to_send = result['result'].replace('\n','').replace(' ','')
message = json.loads(message_to_send)['text']
#print("__name__ :",message)
#message = input("Please enter your message: ")
response = inferMeaning(message)
#print("response:",response)
if response is not None:
#print('Assistant response:', response)
engine = pyttsx3.init()
engine.say(response)
engine.runAndWait()
else:
print("服务端响应无效,请检查服务端是否正常工作。")
except:
pass
笔记本安装ollama,编写服务端程序并进行调试
服务端需要有较大的存储空间用来存放大模型数据,Vosk是由Alphabet的AI研究部门开发的一个开源语音识别库,它支持多种语言,包括中文、英文等,并能在多种平台上运行,如Raspberry Pi、Android、iOS等。Vosk的优势在于其高效的识别速度和良好的识别准确率,使得实时语音识别成为可能。
相关网址如下:
vosk官方网址
vosk github
ollama官方网址
服务端需要安装的包:
ollama、flask、vosk
import ollama
from flask import Flask, request, jsonify
import vosk
import json
model_path = "vosk-model-cn-0.22"
model = vosk.Model(model_path)
app = Flask(__name__)
def getresponse(content=None):
if content is None:
return 'Please enter your message'
res = ollama.chat(model="qwen2.5:0.5b", stream=False, messages=[{"role": "user", "content": content}], options={"temperature": 0})
return res
@app.route('/chat', methods=['POST'])
def receive_message():
data = request.json
message = data.get('message')
print(f"Received message: {message}")
response = getresponse(message)
#print("type(response):",type(response),response)
#print("True or False:",hasattr(response, 'to_dict'))
print("str(response):",str(response))
return str(response)
@app.route('/upload', methods=['POST'])
def upload_file():
if 'file' not in request.files:
return jsonify({'error': 'No file part'}), 400
file = request.files['file']
if file.filename == '':
return jsonify({'error': 'No selected file'}), 400
if file:
# 使用 vosk 处理音频文件
rec = vosk.KaldiRecognizer(model, 16000)
data = file.read()
if rec.AcceptWaveform(data):
result = rec.Result()
return jsonify({'result': result}), 200
else:
return jsonify({'error': 'Recognition failed'}), 500
return jsonify({'error': 'File upload failed'}), 500
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000) # 监听所有网络接口
项目感想
技术挑战:本地大模型在行空板上的性能优化(如内存占用、响应速度)是核心难点,需通过模型剪裁和量化解决。需要后期予以细节调试实现
教育意义:离线AI工具能有效保护学生隐私,避免数据云端传输风险,符合教育信息化安全趋势。
扩展性:未来可加入多模态交互(如屏幕显示图解),或对接学校教材数据库深化内容覆盖。
评论