【STT+LLM+TTS】如何使用语音转文字模型+大预言模型+语音生成模型完成一个类人的语音交互机器人


1. Introduction

  • 通过对各种大模型部署框架以及一些语音模型的研究及调研可以使用ollama框架实现对大预言模型(llama3,moondream,phi)和 多模态模型(llava)的部署 ollama-api documents

  • 基于Chat-TTS开源工程能够将llm给出的文字结果通过语音的形式给与反馈 chat-tts github project

  • whisper 提供了一个很好的离线框架用于STT过程. 所以, 我们可以基于以下方式将整个推理过程进行联动给出结果, 完成一个可用于人类情感对话的语音机器人.

voice
text request
request
text response
actionbyHomeAssisstant
voice
User speaches
whisper
LLM
texts/pictures
Chat-TTS
hardware
Earphone or Audio
  • 基于HomeAssistant的智能设备交互指令

  • 基于Openglass项目的基础上,进一步完善整个交互流程, 对XIAO ESP32各种模块的使用如ble(bluetooth low energy), microphone, camera等

  • 使用python Robyn作为整个后端, 发布交互服务. 包括:

    • 语音身份验证
    • 语音(voice wave)+图片(image)输入, 语音(voice wave)输出
    • 生成用于控制智能设备的控制指令
    • 数据库
  • 使用web或者ISO应用进行信息检索与交互

2. Description

2.1. Dependencies

  • Chat-TTS: 用于生成类人文字转语音模型: pip install the requirements of Chat-TTS project or directly pip install Chat-TSS
  • 用于保存音频: pip install torchaudio[all]; jupyter前端可使用Audio
  • 用于保存wav格式的音频:sudo apt-get install sox libsox-dev ffmpeg
  • ollama: 可以参考ollama工程进行ollama镜像的部署, 用于提供大语言或者多模态模型的交互
  • robyn: pip install robyn
  • whisper: pip install whisper

2.2. Codes

2.2.1. 产文本切分

  1. import re
  2. def split_long_text(text, max_length=100):
  3. # 使用正则表达式匹配中文“。”和英文“.”作为分隔符
  4. segments = re.split(r'(?<=[。\.])', text)
  5. result = []
  6. current_segment = ""
  7. for segment in segments:
  8. if len(current_segment) + len(segment) <= max_length:
  9. current_segment += segment
  10. else:
  11. if current_segment:
  12. result.append(current_segment)
  13. current_segment = segment
  14. if current_segment:
  15. result.append(current_segment)
  16. return result
  17. text = "这是一个非常长的字符串。它包含了很多句子,每个句子都可能非常长。你可以用它来测试分割功能。Make sure it works with English sentences as well. The text can be long enough to test the function."
  18. result = split_long_text(text, max_length=100)
  19. for i, segment in enumerate(result):
  20. print(f"Segment {i+1}: {segment}")
  1. # output
  2. Segment 1: 这是一个非常长的字符串。它包含了很多句子,每个句子都可能非常长。你可以用它来测试分割功能。Make sure it works with English sentences as well.
  3. Segment 2: The text can be long enough to test the function.

2.2.2. 多余字符和表情清理

  1. def clean_no_need_text(text):
  2. # 去掉 \n 和多余的空白字符
  3. text = text.replace('\n', ' ').strip()
  4. # 使用正则表达式去除 emoji 和特殊符号
  5. # 这里的正则表达式匹配所有的 emoji 表情和特殊符号
  6. emoji_pattern = re.compile(
  7. "["
  8. "\U0001F600-\U0001F64F" # Emoticons
  9. "\U0001F300-\U0001F5FF" # Symbols & Pictographs
  10. "\U0001F680-\U0001F6FF" # Transport & Map Symbols
  11. "\U0001F1E0-\U0001F1FF" # Flags (iOS)
  12. "\U00002700-\U000027BF" # Dingbats
  13. "\U0001F900-\U0001F9FF" # Supplemental Symbols and Pictographs
  14. "\U0001FA70-\U0001FAFF" # Symbols and Pictographs Extended-A
  15. "\U00002500-\U00002BEF" # Chinese characters
  16. "\U0001F600-\U0001F64F"
  17. "\U0001F680-\U0001F6FF"
  18. "]+", flags=re.UNICODE
  19. )
  20. cleaned_text = emoji_pattern.sub(r'', text)
  21. return cleaned_text
  22. # 示例文本
  23. texts = ['😊\n\n如果我需要推薦一個關於投資理財的書籍,我會推薦《The Intelligent Investor》(聰明投資者)作者為 Benjamin Graham。\n\n這本書出版於1949年,但它仍然是投資界的一個經典作品。Graham 是 Wall Street 的一位大師級人物,他在《The Intelligent Investor》中提出了一個基于基本分析的投資策略,這種策略可以幫助投資者避免損失,並獲取長期的投資回報。\n\n這本書的優點是,它不僅提供了基本的金融知識和概念,還教會讀者如何應對市場的變化、管理風險、評估投資 opportunity 等等。Graham 的投資哲學是基于長期持有、低成本、高獲利的理念,這種策略可以幫助投資者避免泡沫和 market crash。\n\n如果你是一個投資新手或經驗豐富的投資者,《The Intelligent Investor》都是值得閱讀的一本書籍。它可以幫助你建立自己的投資哲學,並讓你更好地理解金融市場和投資理財。 💸\n\n總的來說,《The Intelligent Investor》是一本有價值、實用的投資指南,對任何想投資的人都是非常有益的! 📚']
  24. # 清理文本
  25. cleaned_texts = [clean_text(text) for text in texts]
  26. # 输出清理后的文本
  27. for i, cleaned_text in enumerate(cleaned_texts):
  28. print(f"Cleaned Text {i+1}: {cleaned_text}")
  1. # output
  2. Cleaned Text 1: 如果你想了解投资理财,我强烈建议你阅读《A Random Walk Down Wall Street》(《随机游走 WALL STREET》) written by Burton G. Malkiel。这本书是一本经典的投资著作,首次出版于1973年。 Malkiel 是一位知名金融学家和经济学家,他在这本书中对投资理财进行了深入的分析和解释。书中的主要内容包括:1. 投资的基本原则:Malkiel 论述了投资的基本原则,例如投资组合、风险管理和投资策略。2. 股票市场的行为学:他详细探讨了股票市场的行为学,包括市场趋势、波动性和效率等方面。3. 投资工具和技术:Malkiel 对各种投资工具和技术进行了分析,例如期货、options ETF 等。我认为,这本书对投资理财非常有帮助。 Malkiel 的写作风格轻松 yet informative,易于理解,且对读者的投资经验没有特殊要求。同时,这本书的知识架构完整,涵盖了投资的各个方面。总之,《A Random Walk Down Wall Street》是一本经典的投资著作,对投资理财有很大的帮助。我建议你阅读这本书,如果你想了解更多关于投资和股票市场的信息。

2.2.3. 正则化文本,将一些无法生成音频的文字剔除或替换

  1. def normalize_text(text):
  2. # 删除换行符和多余的空格,将所有空白字符替换为单一空格
  3. text = re.sub(r'\s+', ' ', text).strip()
  4. # 替换标点符号
  5. text = re.sub(r'[…?!;]', '。', text) # 替换省略号、问号、感叹号、分号为句号
  6. text = re.sub(r'[?!;]', '.', text) # 替换英文问号、感叹号、分号为句号
  7. text = re.sub(r'[:、]', ',', text)
  8. text = re.sub(r'[:]', ',', text)
  9. # # 删除特殊字符
  10. text = re.sub(r'[《》【】()“”’‘——¥]', '', text) # 删除中文特殊字符
  11. text = re.sub(r'[<>\"\'\[\]\{\}\(\)\_\-\—+=*&%$#@]', '', text) # 删除英文特殊字符
  12. # 将多个句号或逗号合并为一个
  13. text = re.sub(r'。+', '。', text)
  14. text = re.sub(r',+', ',', text)
  15. text = re.sub(r'\.+', '.', text)
  16. return text
  17. # 示例文本
  18. cleaned_texts = [
  19. """
  20. 如果你想了解投资理财,我强烈建议你阅读《A Random Walk Down Wall Street》(《随机游走 WALL STREET》)
  21. written by Burton G. Malkiel。这本书是一本经典的投资著作,首次出版于1973年。 Malkiel 是一位知名金融学家和经济学家,
  22. 他在这本书中对投资理财进行了深入的分析和解释。书中的主要内容包括:1. 投资的基本原则:Malkiel 论述了投资的基本原则,例如投资组合、
  23. 风险管理和投资策略。2. 股票市场的行为学:他详细探讨了股票市场的行为学,包括市场趋势、波动性和效率等方面。3. 投资工具和技术:
  24. Malkiel 对各种投资工具和技术进行了分析,例如期货、options 和 ETF 等。我认为,这本书对投资理财非常有帮助。
  25. Malkiel 的写作风格轻松 yet informative,易于理解,且对读者的投资经验没有特殊要求。同时,这本书的知识架构完整,
  26. 涵盖了投资的各个方面。总之,《A Random Walk Down Wall Street》是一本经典的投资著作,对投资理财有很大的帮助。
  27. 我建议你阅读这本书,如果你想了解更多关于投资和股票市场的信息。
  28. """
  29. ]
  30. # 清理文本
  31. normalize_texts = [normalize_text(text) for text in cleaned_texts]
  32. # 输出清理后的文本
  33. for i, normalized_text in enumerate(normalize_texts):
  34. print(f"Normalized Text {i+1}: {normalized_text}")
  1. # output
  2. Normalized Text 1: 如果你想了解投资理财,我强烈建议你阅读A Random Walk Down Wall Street随机游走 WALL STREET written by Burton G. Malkiel。这本书是一本经典的投资著作,首次出版于1973年。 Malkiel 是一位知名金融学家和经济学家, 他在这本书中对投资理财进行了深入的分析和解释。书中的主要内容包括,1. 投资的基本原则,Malkiel 论述了投资的基本原则,例如投资组合, 风险管理和投资策略。2. 股票市场的行为学,他详细探讨了股票市场的行为学,包括市场趋势,波动性和效率等方面。3. 投资工具和技术, Malkiel 对各种投资工具和技术进行了分析,例如期货,options ETF 等。我认为,这本书对投资理财非常有帮助。 Malkiel 的写作风格轻松 yet informative,易于理解,且对读者的投资经验没有特殊要求。同时,这本书的知识架构完整, 涵盖了投资的各个方面。总之,A Random Walk Down Wall Street是一本经典的投资著作,对投资理财有很大的帮助。 我建议你阅读这本书,如果你想了解更多关于投资和股票市场的信息。

2.2.4. 配置cudnn参数, 加载ChatTTS模型, 设置问答payload, 发送请求

  1. import torch
  2. # set the parameters of cudnn
  3. torch._dynamo.config.cache_size_limit = 64
  4. torch._dynamo.config.suppress_errors = True
  5. torch.set_float32_matmul_precision('high')
  6. torch.backends.cudnn.enabled = False
  7. import ChatTTS
  8. from IPython.display import Audio
  9. # create the object of chat tts
  10. chat = ChatTTS.Chat()
  11. # load the model of chat tts
  12. chat.load_models()
  13. import requests
  14. import json
  15. # API URL
  16. url = "http://xxxxxxxxxxxx/api/generate"
  17. # request payload
  18. payload = {
  19. "model": "llama3",
  20. "prompt": "如果希望你推荐给我一般关于投资理财的书籍,那会是哪一本,为什么?另外请用中文回答我",
  21. "stream": False
  22. }
  23. # POST Request
  24. response = requests.post(url, data=json.dumps(payload), headers={"Content-Type": "application/json"})

2.2.5. 校验请求结果并进行后处理

  1. texts = ''
  2. # 检查请求是否成功
  3. if response.status_code == 200:
  4. # print("Response JSON:", response.json()['response'])
  5. texts = [response.json()['response']][0]
  6. print("raw:", texts)
  7. texts = clean_no_need_text(texts)
  8. print("clean:", texts)
  9. texts = normalize_text(texts)
  10. print("normalize:", texts)
  11. texts = split_long_text(texts, 100)
  12. print("split:", texts)
  13. else:
  14. print(f"Request failed with status code: {response.status_code}, Response text: {response.text}")
  1. # output
  2. raw: 😊
  3. 如果您想学习投资理财,我强烈建议您读《The Intelligent Investor》(有智慧的投资者)。这是一本经典的投资著作,作者Charles Ellis认为这是投资领域的“圣经”。
  4. 为什么我会推荐这本书?因为:
  5. 1. **基础知识**:这本书提供了投资的基本概念和原则,对于投资新手来说是一个非常好的起点。
  6. 2. **长期投资观念**:《The Intelligent Investor》强调投资的长期视角,鼓励您避免短期的投机行为,而是采取长期持有策略,这样可以减少风险和提高回报率。
  7. 3. **市场无常性**:作者 Ellis 强调市场的无常性,即使您拥有很好的投资计划,但市场仍然会对您的投资产生影响。因此,您需要具有足够的风险承受能力和投资智慧。
  8. 4. **避免情感投资**:这本书还提醒您不要根据个人情感进行投资决策,而是基于科学分析和明确的投资目标。
  9. 总之,《The Intelligent Investor》是一本非常实用的投资著作,能够帮助您建立投资的正确观念和策略。即使您已经有了一定的投资经验,也值得您重新回顾和学习这本书中的知识。 😊
  10. clean: 如果您想学习投资理财,我强烈建议您读《The Intelligent Investor》(有智慧的投资者)。这是一本经典的投资著作,作者Charles Ellis认为这是投资领域的“圣经”。 为什么我会推荐这本书?因为: 1. **基础知识**:这本书提供了投资的基本概念和原则,对于投资新手来说是一个非常好的起点。 2. **长期投资观念**:《The Intelligent Investor》强调投资的长期视角,鼓励您避免短期的投机行为,而是采取长期持有策略,这样可以减少风险和提高回报率。 3. **市场无常性**:作者 Ellis 强调市场的无常性,即使您拥有很好的投资计划,但市场仍然会对您的投资产生影响。因此,您需要具有足够的风险承受能力和投资智慧。 4. **避免情感投资**:这本书还提醒您不要根据个人情感进行投资决策,而是基于科学分析和明确的投资目标。 总之,《The Intelligent Investor》是一本非常实用的投资著作,能够帮助您建立投资的正确观念和策略。即使您已经有了一定的投资经验,也值得您重新回顾和学习这本书中的知识。
  11. normalize: 如果您想学习投资理财,我强烈建议您读The Intelligent Investor有智慧的投资者。这是一本经典的投资著作,作者Charles Ellis认为这是投资领域的圣经。 为什么我会推荐这本书。因为, 1. 基础知识,这本书提供了投资的基本概念和原则,对于投资新手来说是一个非常好的起点。 2. 长期投资观念,The Intelligent Investor强调投资的长期视角,鼓励您避免短期的投机行为,而是采取长期持有策略,这样可以减少风险和提高回报率。 3. 市场无常性,作者 Ellis 强调市场的无常性,即使您拥有很好的投资计划,但市场仍然会对您的投资产生影响。因此,您需要具有足够的风险承受能力和投资智慧。 4. 避免情感投资,这本书还提醒您不要根据个人情感进行投资决策,而是基于科学分析和明确的投资目标。 总之,The Intelligent Investor是一本非常实用的投资著作,能够帮助您建立投资的正确观念和策略。即使您已经有了一定的投资经验,也值得您重新回顾和学习这本书中的知识。
  12. split: ['如果您想学习投资理财,我强烈建议您读The Intelligent Investor有智慧的投资者。这是一本经典的投资著作,作者Charles Ellis认为这是投资领域的圣经。', ' 为什么我会推荐这本书。因为, 1. 基础知识,这本书提供了投资的基本概念和原则,对于投资新手来说是一个非常好的起点。 2.', ' 长期投资观念,The Intelligent Investor强调投资的长期视角,鼓励您避免短期的投机行为,而是采取长期持有策略,这样可以减少风险和提高回报率。 3.', ' 市场无常性,作者 Ellis 强调市场的无常性,即使您拥有很好的投资计划,但市场仍然会对您的投资产生影响。因此,您需要具有足够的风险承受能力和投资智慧。 4.', ' 避免情感投资,这本书还提醒您不要根据个人情感进行投资决策,而是基于科学分析和明确的投资目标。', ' 总之,The Intelligent Investor是一本非常实用的投资著作,能够帮助您建立投资的正确观念和策略。即使您已经有了一定的投资经验,也值得您重新回顾和学习这本书中的知识。']

2.2.6. 选择语音,并加载

  • 根据Chat-TTS核心代码可以使用sample_random_speaker接口随机一个speaker. 但是由于语音合成的难度,所以可以选择一个对于长文本和多段文本生成语音质量更可靠的声音,当然也可以使用自己的声音生成pt文件.关于音频的选择与使用可参考ChatTTS_Speaker. 我使用rank_multi进行排序,选择了一个评分高且相对较均衡的speaker, seed2155.
  1. # random speaker
  2. # rand_spk = chat.sample_random_speaker()
  3. # print(rand_spk)
  4. # chosen one with seed id https://modelscope.cn/studios/ttwwwaa/ChatTTS_Speaker/summary
  5. # seed_id rank_long rank_multi rank_single score gender age feature
  6. # seed_2155 90.99 91.57 91.34 0.4 男 54.66% 女 45.34% 青年 100.00%
  7. # rank_long: 长句文本的音色稳定性评分。
  8. # rank_multi: 多句文本的音色稳定性评分。
  9. # rank_single: 单句文本的音色稳定性评分。
  10. spk = torch.load("seed_2155_restored_emb.pt")
  11. # print(spk)

2.2.7. 配置语音合成参数

  1. params_infer_code = {
  2. 'spk_emb': spk, # add sampled speaker
  3. 'temperature': .3, # using custom temperature
  4. 'top_P': 0.7, # top P decode
  5. 'top_K': 20, # top K decode
  6. }
  7. ###################################
  8. # For sentence level manual control.
  9. # use oral_(0-9), laugh_(0-2), break_(0-7)
  10. # to generate special token in text to synthesize.
  11. params_refine_text = {
  12. 'prompt': '[oral_2][laugh_0][break_6]'
  13. }

2.2.8. 生成音频并保存

  1. print(texts)
  2. import torchaudio
  3. if len(texts) > 0:
  4. # wavs = chat.infer(texts)
  5. wavs = chat.infer(texts, skip_refine_text=True, params_refine_text=params_refine_text, params_infer_code=params_infer_code)
  6. waveforms = []
  7. for wav in wavs:
  8. waveforms.append(torch.from_numpy(wav))
  9. merged_waveform = torch.cat(waveforms, dim=1) # 在时间维度上拼接
  10. torchaudio.save("output.wav", merged_waveform, 24000, format="wav")
  11. else:
  12. print(f"No response")

  • 体验一下语音问答的快乐

  • Q: why the sky is blue?

  • Q: 如果希望你推荐给我一般关于投资理财的书籍,那会是哪一本,为什么?另外请用中文回答我?

2.2.9. Wav to Text STT

  1. import whisper
  2. model = whisper.load_model("large")
  3. result = model.transcribe("why_sky_is_blue.wav")
  4. print(result["text"])
  5. # output:
  6. # The color of the sky blue is a fascinating topic that has puzzled humans for centuries. So why is the sky blue? There are several reasons contributing to the sky's blueness. One, scattering when sunlight enters Earth's atmosphere, it encounters tiny molecules of gases like nitrogen, N2, and oxygen, O2. These molecules scatter the light in all directions, but they do so more efficiently for shorter wavelengths like blue and violet. This is known as Rayleigh scattering, named after the British physicist Lord Rayleigh II. Atmospheric particles, the atmosphere contains aerosols such as dust, pollen, smoke, and water vapor, which also scatter light. These particles have a different effect on longer wavelengths like red and orange, causing them to be absorbed or scattered in different ways. Three, Earth's curvature as you look at the sky, your line of sight is actually a curve that intersects with the Earth's surface at a certain angle. This means that the blue light from higher altitudes has a longer path to travel before reaching your eyes, which affects its apparent color. Four, atmospheric conditions, weather phenomena like clouds, haze, and pollution can alter the sky's color. For example, during sunrise and sunset, the sky often takes on hues of orange and red due to the scattering of shorter wavelengths by atmospheric particles. In summary, the blue color of the sky is primarily due to the scattering of sunlight by tiny particles. Many molecules in the atmosphere Rayleigh scattering. The combination of this effect with the presence of aerosols and the Earth's curvature contributes to the overall blueness we see in the sky. Now go enjoy that beautiful blue sky.

2.3. Additional

  • 如果想要使用多模态模型,可以使用ollama doc中的教程,进入ollama容器ollama pull llava
  • 将需要转换的图片可以离线进行 base64 图片转换,或使用python接口
  • 使用ollama提供的api进行测试

2.4. Backend Service API

[todo]

3. Open Issues

  • 模型初次初始化时,速度较慢,执行过程中单词交互的语音生成速度也比较慢,性能还没有具体分析
  • 当文字过长时,语音生成的质量下降比较明显。需要将文字部分进行拆分。

4. Annexe


dingfeng 2024年6月25日 16:13 2493 0 条评论 收藏文档
评论

暂无评论,我来发表第一篇评论!

发表评论