首页 > 其他分享 >语音助手Antenna(长期更新)

语音助手Antenna(长期更新)

时间:2024-10-03 19:22:09浏览次数:5  
标签:Antenna kimi 助手 command 语音 query print import

【目标】
制作一个个人的语音助手随时能聊天,核心要求是能够了解我,包括能够认识我周围的人,知晓我的生活经历,同时也能够连接网络搜索内容,为我提供知识。强调一个私人性,得知道我的个人信息并能聊起来。按照现在大模型的发展速度,肯定已经、或即将有这种东西了,但是一是不想付费,二是自己搞的过程中也学学东西。害本来是玩嵌入式的,现在演化到这个项目了。这个助手的名字就叫Antenna好了,原意“天线”,这里致敬/来源于Halo里的Cortana。

【实现思路】
该助手需要长期开机收集我的个人生活信息,目前主要是语音内容,有针对性的定期finetune。因此软件层面,需要基于一个预训练的大语言模型进行语言交互,一个语音识别模型将语音转换为文字;硬件层面需要录音和相应的控制设备、大模型的部署设备和与大模型通信的设备。

【基本方案】

饭得一口一口吃,初步设想先不动硬件,软件包括云和本地两个部分。使用本地设备收集我的语音内容,整理成适配大模型的数据集格式,定期上传云平台进行大模型finetune,然后定期下载finetune后的模型至本地进行merge;本地运行大模型平时交互的inference。

我手里算力最强、同时也是用的最多的本地设备是一台2021年的MacBook Pro,搭载Apple M1 Pro芯片组,8+2核CPU,16G内存,16核GPU,驱动架构为苹果自己的Metal 3,目前系统为Sequoia 15.0. 另有一台实验室的Intel台式机,无GPU,唯一优点是windows系统,且存储几个T...

嵌入式设备方面,算力最强的是意法半导体的STM32MP157,目前只是一块来自正点原子的核心板,主频800MHz,内置GPU(但不会用),板载1G内存和8G存储eMMC和千兆PHY,感觉有可能带的动简单的模型。。

另看上了基于RK3566的泰山派卡片电脑,主频1.8GHz,搭载NPU和支持OpenGL的GPU,2G内存,价格也挺友好,考虑入手。

【测试-学习大模型使用】

kimi广告做的多,用起来也不错,而且免费,API也很完善,但是不开源没法finetune。但是先做点能跑的玩意儿出来鼓舞下士气还是很有必要滴。先用python基于kimi做了一个仅inference的语音对话demo在Mac上跑着玩一下,主要包括三部分:(1)调用Mac麦克风录音后转文字;(2)文字输入给kimi并获得回答文本;(3)文本转语音播放。步骤(1)最广泛的包是在线识别的GoogleSpeech,免费、准确度高、中英通吃,但是得联网,有时候略慢;另一个不联网方案是vosk,不设计特殊名词和英文时准确度不错,且本地跑速度很快,调包大法用起来都很简单,我都是直接用kimi生成的code改一改就用了。步骤(2)用的kimi的API,教程很详细,且内置了网络搜索功能,很nice,直接copy过来。步骤(3)用的pyttsx3,中文语音只有Tingting,很不好听,不过用起来倒也简单,速度快且完全本地,先凑合着。代码全文如下:

点击查看代码
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sat Sep 28 19:13:28 2024

@author: jiaminghu
"""

from openai import OpenAI
import cv2
import sounddevice as sd
import numpy as np
from scipy.io.wavfile import write

import pyttsx3
import pyaudio
from vosk import Model, KaldiRecognizer
import json
import time

from typing import *
from openai.types.chat.chat_completion import Choice
import speech_recognition as sr

def listen_for_command():
    # 初始化识别器
    recognizer = sr.Recognizer()

    # 使用麦克风作为音频源
    with sr.Microphone() as source:
        print("Please speak command...")
        audio = recognizer.listen(source)

        try:
            # 使用Google的免费Web API进行语音识别
            command = recognizer.recognize_google(audio, language='zh-CN') #en-US'
            print("You said: " + command)
            
            # 在这里,你可以将command发送给Kimi搜索
            answer = kimi_search(command)
            
            # 将文本转换为语音并播放
            engine.say(answer)
            engine.runAndWait()

            # 在这里,你可以将command发送给Kimi搜索
            # 例如,你可以调用一个函数来处理搜索请求
            return command

        except sr.UnknownValueError:
            print("Google Speech Recognition could not understand audio")
            return None
        except sr.RequestError as e:
            print("Could not request results from Google Speech Recognition service; {0}".format(e))
            return None
        
        

def listen_for_command_localvosk():
    
    # 指定模型路径
    model_path = "./vosk-model-small-cn-0.22"
    model = Model(model_path)
    
    # 初始化识别器,采样率为16000Hz
    recognizer = KaldiRecognizer(model, 16000)
    
    # 定义音频流参数
    chunk = 1024
    format = pyaudio.paInt16
    channels = 1
    rate = 16000
    p = pyaudio.PyAudio()
    
    # 开启音频流
    stream = p.open(format=format, channels=channels, rate=rate, input=True, frames_per_buffer=chunk)
    
    print("开始说话,说'停止'以结束录音...")
    
    # 记录开始时间
    start_time = time.time()
    
    text = ''
    # 读取音频流
    while True:
        data = stream.read(chunk)
        if recognizer.AcceptWaveform(data):
            result = recognizer.Result()
            if result:
                result_json = json.loads(result)
                if 'text' in result_json:
                    if '停止' in result_json['text']:
                        print("停止录音")
                        break
                    print("识别结果:", result_json['text'])
                    text += result_json['text']
                    # 检查是否说出了“停止”
                    
        if time.time() - start_time > 20:  # 设置超时时间为10秒,也可以根据需要调整
            print("超时,自动停止录音")
            break
    
    # 关闭音频流
    stream.stop_stream()
    stream.close()
    p.terminate()
    
    command = text.strip()
    print("You said: " + command)
    
    # 在这里,你可以将command发送给Kimi搜索
    answer = kimi_search(command)
    
    # 将文本转换为语音并播放
    engine.say(answer)
    engine.runAndWait()

    return command



def kimi_search_offline(query):
    
    # 这里应该是调用Kimi搜索的代码
    query = '你好kimi, ' + query
    print("Searching Kimi for: " + query)
    client = OpenAI(
        api_key = "API_KEY", #得用自己的KEY哦
        base_url = "https://api.moonshot.cn/v1",
    )
     
    completion = client.chat.completions.create(
        model = "moonshot-v1-8k",
        messages = [
            {"role": "system", "content": system_query},
            {"role": "user", "content": query}
        ],
        temperature = 0.8,
    )
    
    print(completion.choices[0].message.content)
   

    # 要转换为语音的文本
    return completion.choices[0].message.content
    

    
def kimi_search(query):
    query = '你好kimi, ' + query
    print("Searching Kimi for: " + query)
    client = OpenAI(
        api_key = "sk-NZ9KYlSLrfCUEe3gvGMO6YSP99Lf7n5OVzoNer6xRtfHfbti",
        base_url = "https://api.moonshot.cn/v1",
    )
    
    messages = [
        {"role": "system", "content": system_query},
    ]
     
    # 初始提问
    messages.append({
        "role": "user",
        "content": query
    })
    

 
    # search 工具的具体实现,这里我们只需要返回参数即可
    def search_impl(arguments: Dict[str, Any]) -> Any:
        """
        在使用 Moonshot AI 提供的 search 工具的场合,只需要原封不动返回 arguments 即可,
        不需要额外的处理逻辑。
     
        但如果你想使用其他模型,并保留联网搜索的功能,那你只需要修改这里的实现(例如调用搜索
        和获取网页内容等),函数签名不变,依然是 work 的。
     
        这最大程度保证了兼容性,允许你在不同的模型间切换,并且不需要对代码有破坏性的修改。
        """
        return arguments
     
     
    def chat(messages) -> Choice:
        completion = client.chat.completions.create(
            model="moonshot-v1-128k",
            messages=messages,
            temperature=0.3,
            tools=[
                {
                    "type": "builtin_function",  # <-- 使用 builtin_function 声明 $web_search 函数,请在每次请求都完整地带上 tools 声明
                    "function": {
                        "name": "$web_search",
                    },
                }
            ]
        )
        return completion.choices[0]
     
    finish_reason = None
    while finish_reason is None or finish_reason == "tool_calls":
        choice = chat(messages)
        finish_reason = choice.finish_reason
        if finish_reason == "tool_calls":  # <-- 判断当前返回内容是否包含 tool_calls
            messages.append(choice.message)  # <-- 我们将 Kimi 大模型返回给我们的 assistant 消息也添加到上下文中,以便于下次请求时 Kimi 大模型能理解我们的诉求
            for tool_call in choice.message.tool_calls:  # <-- tool_calls 可能是多个,因此我们使用循环逐个执行
                tool_call_name = tool_call.function.name
                tool_call_arguments = json.loads(tool_call.function.arguments)  # <-- arguments 是序列化后的 JSON Object,我们需要使用 json.loads 反序列化一下
                if tool_call_name == "$web_search":
                    tool_result = search_impl(tool_call_arguments)
                else:
                    tool_result = f"Error: unable to find tool by name '{tool_call_name}'"
     
                # 使用函数执行结果构造一个 role=tool 的 message,以此来向模型展示工具调用的结果;
                # 注意,我们需要在 message 中提供 tool_call_id 和 name 字段,以便 Kimi 大模型
                # 能正确匹配到对应的 tool_call。
                messages.append({
                    "role": "tool",
                    "tool_call_id": tool_call.id,
                    "name": tool_call_name,
                    "content": json.dumps(tool_result),  # <-- 我们约定使用字符串格式向 Kimi 大模型提交工具调用结果,因此在这里使用 json.dumps 将执行结果序列化成字符串
                })
    
    print(choice.message.content)
    
    return choice.message.content  # <-- 在这里,我们才将模型生成的回复返回给用户

    

if __name__ == "__main__":
    system_query = "你是 Kimi,由 Moonshot AI 提供的人工智能助手,你更擅长中文和英文的对话。你之后收到的文字来源于语音识别,所以可能会有误差、重复和标点不全的情况,请按照一个人通常说话的习惯进行理解。"
    engine = pyttsx3.init()
    engine.setProperty('voice', 'com.apple.voice.compact.zh-CN.Tingting')
    engine.setProperty('rate', 220)
    
    command = listen_for_command()
    #command = listen_for_command_localvosk()

玩够了以后,继续测试大模型的finetine。优先考虑了阿里云的通义千问系列QWen,因为中英都支持的好,而且是开源里目前性能最好的嘛。inference很顺利,但是官方的finetune script不支持苹果的GPU架构Metal Performance Shaders(MPS),这让我手里唯一的GPU都用不起来了。好在MPS的生态做的不错,有一个专门的repo叫MLX,介绍说it is an array framework for machine learning research on Apple silicon(https://github.com/ml-explore) ,特别有llm的例子,就跟着一篇博客(https://apeatling.com/articles/part-3-fine-tuning-your-llm-using-the-mlx-framework/) 使用测试一下Mistral-7B-Instruct-v0.2,然后看看能不能搞QWen。

另一方面同步测试的是语音,一直用Tingting肯定也受不了。这个平台(https://fish.audio/zh-CN) 简单用了一下搞的不错,上传了对象的一段20s音频,很快就能学到语音模型,现在研究一下API和价格。

标签:Antenna,kimi,助手,command,语音,query,print,import
From: https://www.cnblogs.com/jiaming121/p/18445890

相关文章

  • 沃德校园助手系统V1.1.2
    为校园团队提供全套的技术系统及运营的方案(目前仅适配微信小程序),可以更好的帮助你打造自己的线上助手平台。成本低,见效快。各种场景都可以自主选择服务。V1.1.2小程序需要更新【优化】1.腾讯接口文本校验问题2.修复微信小程序添加申请校园接单员是否显示学号、学生证照片配置选否,小......
  • 超轻巧modbus调试助手使用说明
    一、使用说明1.1数据格式和其他的modbus采集工具一样,本组件也支持各种数据格式,其实就是高字节低字节的顺序。一般是2字节表示一个数据,后面又有4字节表示一个数据,目前好像还有8字节表示一个数据的设备。不同厂家的设备对应的字节顺序可能不同,要求可以自定义顺序,以便满足各种......
  • Go AI 编程助手的使用 Fitten Code
    GoAI编程助手FittenCode1、安装2、智能补全3、AI问答4、生成代码5、代码转换6.生成注释7、解释代码8、生成测试9、检查BUG11、优化代码12、对项目整项目分析GoAI编程助手的核心优势在于其能够显著提高编程效率,减少错误,并提供灵活的选择。‌这些工具通过自动......
  • 实时语音交互,打造更加智能便捷的应用
    随着人工智能和自然语言处理技术的进步,用户对智能化和便捷化应用的需求不断增加。语音交互技术以其直观的语音指令,革新了传统的手动输入方式,简化了用户操作,让应用变得更加易用和高效。通过语音交互,用户可以在不方便使用触屏操作例如驾驶、烹饪时通过语音指令进行操作;在需要输入大......
  • 实时语音交互中文基准首期测评出炉;美取消 SB-1047 法案,大模型厂商大难不死丨 RTE 开发
       开发者朋友们大家好: 这里是「RTE开发者日报」,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享RTE(Real-TimeEngagement)领域内「有话题的新闻」、「有态度的观点」、「有意思的数据」、「有思考的文章」、「有看点的会议」,但内容仅代表编......
  • GPT-SoVITS语音合成模型实践
    1.概述GPT-SoVITS是一款开源的语音合成模型,结合了深度学习和声学技术,能够实现高质量的语音生成。其独特之处在于支持使用参考音频进行零样本语音合成,即使没有直接的训练数据,模型仍能生成相似风格的语音。用户可以通过微调模型,进一步提升其性能,以适应特定的应用需求。2.内容2.1......
  • yy语音找不到qjpeg4.dll怎么办?YY语音qjpeg4.dll修复大全:多种方法总有一款适合你
    当YY语音找不到qjpeg4.dll文件时,这通常意味着系统或YY语音的安装目录中缺少了必要的动态链接库文件。以下是一些修复方法,你可以根据自己的情况选择适合的一种或多种方法尝试解决:1.重新安装YY语音步骤:卸载当前版本的YY语音。清除可能残留的旧文件或注册表项(可选步骤,如果卸......
  • 小咖批量剪辑助手款视频批量自动剪辑软件
    小咖批量剪辑助手是一款视频批量自动剪辑软件,具有智能化、批量化、操作简单等特点。该软件适用于自动化处理和生产视频,旨在帮助用户实现批量化生产产品推广视频的功能。三、安装与配置安装步骤:下载程序压缩包:访问官方网站或指定下载地址,下载小咖批量剪辑助手程序压缩包......
  • 小咖批量剪辑助手款视频批量自动剪辑软件
    小咖批量剪辑助手是一款视频批量自动剪辑软件,具有智能化、批量化、操作简单等特点。该软件适用于自动化处理和生产视频,旨在帮助用户实现批量化生产产品推广视频的功能。三、安装与配置安装步骤:下载程序压缩包:访问官方网站或指定下载地址,下载小咖批量剪辑助手程序压缩包......
  • 小咖批量剪辑助手款视频批量自动剪辑软件
    小咖批量剪辑助手是一款视频批量自动剪辑软件,具有智能化、批量化、操作简单等特点。该软件适用于自动化处理和生产视频,旨在帮助用户实现批量化生产产品推广视频的功能。三、安装与配置安装步骤:下载程序压缩包:访问官方网站或指定下载地址,下载小咖批量剪辑助手程序压缩包......