聊天分为听、思考、读,简单的通过ASR、LLM、TTS三类模型的组合可以实现,最近openai推出支持多模态的GPT-4o模型,可以把三个模型真正融合成在一起。 现在市面上的模型百花齐放,各有所长。要实现可落地的方案,需要结合业务,验证模型效果,同时也要考虑方案的可行性,有些模型在国内能用,有些在国内不能用。
模型的选择过程
- 选择候选模型
- 准备测试数据集
- 使用模型生成测试结果
- 结果打分
聊天协议的选择
完整的聊天交互是,用户说完话,通过ASR识别出来用户说的内容,发送给聊天模型,模型生成内容后转出语音内容,发送给用户。 客户端与服务端通信的协议推荐用websocket,它在需要频繁交互的场景比http更适合。http每次请求都需要握手,还会带上很多header,降低了整体的传输效率;另一方面,websocket支持全双工,服务端可以主动推送消息给客户端。 websocket作为TCP协议的简单包装,支持文本和二进制数据,协议格式十分精简,保证了传输的性能。这也是一把双刃剑,就需要业务根据需要自己定义传输数据的协议。自定义协议的好坏直接影响到后续的扩展。子协议我们推荐使用stomp协议,它是参考了http的设计理念,由command、header和body构成,也支持ack/nack、断线重连等功能。它是轻量级的协议,不像http那样适用大多数的web场景,它只适用于一部分场景。stomp预定义了可用的command,客户端和服务端能使用的command也不一样。 所以,最终的聊天协议选择是websocket+stomp的组合。
模型的接入
ASR模型
以微软为例,ASR模型的输入是音频流,输出是文本,输出的形式包含流式和完整输出。这输出完整的内容之前,会跟进完整音频做一次校准,所以内容可能会跟流式输出的有差异。 对接的方式,如果在客户端接入模型,只需引入微软的SDK,SDK会自动获取设备的音频流。另外,微软的服务在国外,从国内调用需要经过防火墙,对响应时间有影响。首个文字返回的时间在1.5~2.7秒之间,平均1.6秒左右(杭州访问微软东亚节点)。 如果在服务端接入模型,就需要客户端将音频数据,先传给服务端,服务音频内容不断追加到模型的输入流里。首个文字返回的时间在1.6~2.3秒之间,平均1.9秒左右(杭州访问香港服务器,转发到微软东亚节点)。
LLM模型
拿到ASR识别的完整的内容后,交给LLM模型生成待回复内容。LLM模型考虑智力水平的话,首选的是GPT系列,包括GPT-3.5、GPT-4、GPT-4o,还有Claude3系列。考虑聊天效果的话,考虑使用国内的豆包、MiniMax系列的模型,聊天内容跟自然。 接入模型的方式比较简单,以接入openai为例,申请到token后,调用它的聊天接口就可以。接入豆包会复杂些,需要先创建连接点(模型实例),再生成对应待过期时间的token(最长30天)。 另外,接模型从零开始,有一些现成的框架。java工程推荐使用spring-ai框架,它更新迭代比较快,能快速支持openai新的接口格式。另外还有4.6k个star的TheoKanning/openai-java,不过已经5个月没更新了。 openai的聊天接口支持流式和完整返回,流式的协议是SSE,完整返回是JSON格式。要按场景选择返回的格式,实时聊天推荐是流式,因为完整返回时间比较慢。以输出10个英文单词为例,完整返回的时间GPT-3.5要700ms,GPT-4要2s,GPT-4o要1s。另外,内容返回给用户之前,还要做敏感词检测,所以边输出边检测效率会更高。
TTS模型
LLM生成的文本,要通过TTS转出语音后才会输出给用户。与ASR相反,TTS模型输入是文本,输出是音频。对TTS模型的要求是多语言的支持、音色的丰富程度和个性化。微软TTS对多语言支持最好,也有丰富的音色。通过SSML的描述方式,还能控制语速和情感。openai的TTS能根据文本推断出相应的情感,不需要在输入端做额外标记,但它只对英语支持较好,中文发音像是老外说中文。 以微软TTS为例,在服务端接入,如果是linux服务器,需要安装微软的语音库。之后项目里引入对应版本的SDK,就可以直接获取转换后的音频二进制数组。10个文字左右的延迟在400ms左右(香港调用微软东亚节点)。 另外,微软TTS调用前需要初始化客户端,会有点耗时,可以先预初始化,提高请求响应速度。
模型切换
各模型厂商都在快速的迭代模型,效果、性能都在提升,成本也在下降。这决定了我们要有快速接入和切换模型的能力。可能是单个模型的替换,也可能是多个模型换成一个多模态的模型,例如GPT-4o就是多模态的。 要支持这种能力,在模型调用上,我们需要先跟具体的模型厂商解耦,单独抽象出一套请求接口规范。 幸运的是spring ai项目正在做这件事,它定义了和模型交互的流程,也已经支持一部分国外的模型,包括openai的大部分模型。但它没有支持国内的模型,这就需要我们做扩展。 在开发框架上支持多模型后,还剩一个最大的问题,就是服务部署地区。海外的模型,只能在非大陆地区调用。不然从国内去访问会有很大的延迟(防火墙),并且可能被限制访问,如openai限制了大陆地区使用模型。国内的模型,最好在国内调用,网络状况会更好。如何部署调用的服务,不仅仅是技术问题,还需要考虑业务发展。在极端的情况下,也能考虑将功能拆成多个服务,分地域部署。这样维护和扩展都成本都会提高。折中的方案是,部署在亚太附近,例如:东京、首尔、香港等。
模型测试
对于不同版本和厂商的模型,我们在使用前和使用中都需要持续的观测它们的表现。这就需要有一套流程和工具去持续测试模型的性能和效果。
ASR模型
关注识别的准确度,准备一批语音,将模型输出的文字和标准文本进行相似度匹配,判断整体的准确度。需要考虑的因素有,发音的准确度、背景音、口音等。
LLM模型
关注回答内容的准确度,如果输出格式是json,可以直接判断json的内容。如果输出是开放到文本,就需要人工介入检查。或者通过prompt来提取文本的信息,返回结构化内容,再进行判断。例如,问数字人的名字,它回答“我叫Leo”。我们就可以用提取名字的prompt获得名字信息,再跟答案比较。
TTS模型
关注生成语音的准确度,可以将生成内容用ASR转成文本,再和原文进行比较。这样可能有点一定的误差,但是能减少人工的检查成本。