首页 > 其他分享 >基于ChatTTS与zhipuai虚拟聊天助手(demo)

基于ChatTTS与zhipuai虚拟聊天助手(demo)

时间:2024-09-03 12:49:52浏览次数:12  
标签:ChatTTS zhipuai demo st session role chat text import

        demo采用的是streamlit,首先可以是能进行文字沟通,然后ai能够返回语音。正好streamlit中有streamlit.audio可以播放语音。所以剩下的就是如何将输入输出串起来,能够被streamlit.write。虚拟聊天助手的具体思路可以参考上篇文章baseline基于ChatTTS与zhipuai虚拟聊天助手(baseline)-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/2301_81587902/article/details/141643805?spm=1001.2014.3001.5501

        首先建立TTs.py调用ChatTTS 

import torchaudio
import torch
from ChatTTS import ChatTTS
import soundfile
from IPython.display import Audio
chat = ChatTTS.Chat()
chat.load_models(compile=False)


class Tts():
    def __init__(self):
        pass

    # 语音模型
    def chat_sound(self, texts, infer_code):
        # refine_text = chat.infer(texts, refine_text_only=True)
        wavs = chat.infer(texts, params_infer_code=infer_code)
        return wavs

    # 输出与下载
    def tts_response(self, answer, infer_code):
        wavs = self.chat_sound(answer, infer_code)
        print("___"*10)
        torchaudio.save("output/output_d1.wav", torch.from_numpy(wavs[0]), 24000)
        return wavs

         然后建立获取collect的函数命名为collect_role.py因为采用streamlit的text_input作为输入所以可以直接输入目标角色和角色关系以及特点性格,所以这里不采用ai进行收集。

        也可以采用ai收集,但是个人认为繁琐了点。

import streamlit as st
import os
from dataclasses import dataclass, asdict
from sqlalchemy import insert
from sqlalchemy import Table, Column, Integer, String, DateTime, Text, MetaData, SmallInteger
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
import sqlite3

# 收集角色信息
@dataclass
class ChatSession:
    role: str
    role_name: str
    role_personality: str

class role_collect():
    def __init__(self):
        pass

    def role_prompt(self, role, role_name, role_personality):
        all_role = ChatSession(role, role_name, role_personality)
        print("角色信息:", role_name)
        self.store(all_role)


    def store(self,all_role: ChatSession):

        with SessionLocal.begin() as sess:
            q = insert(
                chat_session_table
            ).values(
                [asdict(all_role)]
            )
            sess.execute(q)


db_file = "chatbot.db"

if os.path.exists(db_file):
    os.remove(db_file)
engine = create_engine(f"sqlite:///{db_file}")
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
metadata_obj = MetaData()
chat_session_table = Table(
    "chat_session_table",
    metadata_obj,
    Column("role", String(16)),
    Column("role_name", String(32)),
    Column("role_personality", String(32)),

)

metadata_obj.create_all(engine, checkfirst=True)
print("数据库创建成功!")

        之后就是获取保存好多sql数据可以命名为use_sql.py

# 将collect收集的信息导出
import sqlite3


def query_table(table: str):
    con = sqlite3.connect("chatbot.db")
    cur = con.cursor()
    q = cur.execute(f"SELECT * FROM {table}")
    return q.fetchall()


def query_chat_session():
    sql = query_table("chat_session_table")
    print("finish query chat session")
    return sql


if __name__ == ' __main__':
    
    sql = query_chat_session()

        接下来就是将收集的内容构建成prompt,并且根据角色的关系放回需要下载的语音包(目前只有设计男女两种不同的语音),所以将包命名成get_prompt.py

import streamlit as st
from TTs_down import download_speaker
from decide import ManWoman

manwoman = ManWoman()
# 调用模型


def get_sql(inputs_text=""):
    # 默认为空
    if inputs_text == "":
        inputs = "no"
    else:
        inputs = inputs_text
    # 输入no时直接对信息
    if inputs == "no":
        from use_sql import query_chat_session
        query_chat = query_chat_session()
        print("no")
        return query_chat
    # 输入为yes时重新读信息
    elif inputs == "yes":
        from use_sql import query_chat_session
        query_chat = query_chat_session()
        print("yes")
        return query_chat
    else:
        st.error("输入错误,请重新输入")


def get_prompt():
    query_chat = get_sql()
    req = []
    for i in range(len(query_chat[0])):
        if i <= 2:
            inx = -1 * (i + 1)
            # print(query_chat[0][inx])
            req.append(query_chat[0][inx])
        else:
            break
    role = req[2]  # 男/女角色
    role_name = req[1]
    role_personality = req[0]
    prompt = f'''我与你的【任何对话】都必须严格执行以下角色要求。你叫{role_name},
    我与你的对话必须严格遵守以下角色要求,你将扮演我的【{role}】,我的【{role}】必须严格遵守以下角色要求:
    姓名:{role_name}。性格:{role_personality}。
    记住你不是AI,请你完全沉浸在{role}的角色里,我们的任何对话都要用{role_name}的口吻回答我,
            回答不能超过50字,根据聊天话题延展你自己的想法。
            不能有解释类型的逻辑,表达要带有角色的性格特点。
    '''
    print("finish prompt")
    w_m = manwoman.similarity(role)
    print(w_m)
    info = download_speaker(w_m)
    return prompt, info

        因此需要有判断是男性或者是女性的包,命名为decide.py

from zhipuai import ZhipuAI
import os
from dotenv import load_dotenv, find_dotenv
from sklearn.metrics.pairwise import cosine_similarity
_ = load_dotenv(find_dotenv())
client = ZhipuAI(api_key=os.getenv("ZhipuAI_API_KEY"))


class ManWoman:
    def __init__(self):
        pass

    def embedding_man(self, text):
        emb = client.embeddings.create(
            model="embedding-2",
            input=text,
        )
        return emb.data[0].embedding

    # 通过相似度来对比角色是男性还是女性
    def similarity(self, role):
        text = self.embedding_man(role)
        man = self.embedding_man("男性")
        woman = self.embedding_man("女性")
        if cosine_similarity([text], [man])[0][0] > cosine_similarity([text], [woman])[0][0]:
            return "男性"
        else:
            return "女性"


if __name__ == '__main__':
    WM = ManWoman()
    print(WM.similarity("汪星人"))

        既然判断完男女就需要下载对应的信息命名为TTs_down.py

import torch


def download_speaker(text):
    if text == "男性":
        speaker = torch.load('speakers/b1hou.pth')
    elif text == "女性":
        speaker = torch.load('speakers/g1.pth')
    else:
        print("err")
    infer_code = {
        "spk_emb": speaker,
        # 'prompt': '[speed_10]',
        'temperature': 0.1,
        'top_P': 0.7,
        'top_K': 20,
        # "custom_voice": 3000,
        }
    print("finish download")
    return infer_code

        所有的内容都构建完了就到main.py,将大部分的内容串起来,有一部分需要用demo.py才能连接

import os
import streamlit as st
from dotenv import load_dotenv, find_dotenv
from zhipuai import ZhipuAI
from get_prompt import get_prompt
from TTs import Tts
from decide import ManWoman
# 调用模型
tts = Tts()
manwoman = ManWoman()

_ = load_dotenv(find_dotenv())
client = ZhipuAI(api_key=os.getenv("ZhipuAI_API_KEY"))


class ChatGlm():
    def __init__(self):

        self.prompt, self.info = get_prompt()
        self.msg = [{"role": "user", "content": self.prompt}]

    def reponse(self, msg):
        response = client.chat.completions.create(
            model="glm-4",
            messages=msg,
            temperature=0.7,
        )
        return response.choices[0].message.content

    def check_over(self, inpt):
        if "再见" in inpt or "拜拜" in inpt or "结束" in inpt:
            return True

    def chat(self, ):
        while True:
            outp = self.reponse(self.msg)
            inpt = input()
            self.msg += [
                {"role": "assistant", "content": outp},
                {"role": "user", "content": inpt},
            ]
            answer = self.reponse(self.msg)
            if self.check_over(inpt):
                break
            print(answer)

        最后demo.py

from main import ChatGlm
from TTs import Tts
import streamlit as st
from get_prompt import get_sql

tts = Tts()
# # 创建一个标题和一个副标题
st.title("

标签:ChatTTS,zhipuai,demo,st,session,role,chat,text,import
From: https://blog.csdn.net/2301_81587902/article/details/141822190

相关文章

  • 2024最新盗u授权版,有演示Demo,最全教程包教包会
    一、案例展示1.前端商品列表,这里可以选择很多商品,商品在后台自己随便配置2.选择抖音产品,下单。3.点击立即支付二、环境:Linux系统 进入宝塔依次安装:Nginx> MySQL>php> phpMyAdmin    1.修改数据库配置:/application/database.phpusethink\Env;return[......
  • MediatR实现高效信息传递,以.net8做demo演示
    MediatR是.NET下的一个实现消息传递的库,轻量级、简洁高效,用于实现进程内的消息传递机制。它基于中介者设计模式,支持请求/响应、命令、查询、通知和事件等多种消息传递模式。通过泛型支持,MediatR可以智能地调度不同类型的消息,非常适合用于领域事件处理。我们将定义一个命令、......
  • 【工程应用十二】Bayer图像格式中Hamilton-Adams及Zhang Wu 基于LMMSS算法的Demosaic
    Demosaic,中文直接发翻译为去马赛克,但是其本质上并不是去除马赛克,这让很多第一次接触这个名词或者概念的人总会想的更多。因此,一般传感器在采集信息时一个位置只采集RGB颜色中的一个通道,这样可以减少采集量,降低成本,由于人的视觉对绿色最为敏感,所以一般情况下,绿色分量会比红色......
  • ChatTTS 长音频合成和本地部署2种方式,让你的“儿童绘本”发声的实战教程(文末有福利)
    接上文(GLM-4-Flash大模型API免费了,手把手构建“儿童绘本”应用实战(附源码)),老牛同学通过GLM-4-Flash文生文和CogView-3文生图大模型,和大家一起编写了一个图文并茂的儿童绘本应用,并且以《黑神话·悟空》当前热门游戏为背景,做了一本名为《悟空探秘之旅》的儿童小绘本。绘本我......
  • Havoc的demon开发环境配置(使用vscode二开beacon)
    二开havoc需要看一下之前的几篇文章,感谢chatAI让我少吃了很多苦头,二开beacon(demon)环境终于搭建好了,之前想过使用ollvm编译demon,以便于源码级的混淆,但是试了以下,llvm能让人吃更多苦头,我没有测试过demon能不能使用llvm编译,因为llvm本身就很难编译成功,以至于我不想在llvm上花费任......
  • libwebsocket demo以及遇到的坑。
    借鉴的 https://blog.csdn.net/qq_19004627/article/details/88737411坑1:openssl报错:ipaddressmismatch(preverify_ok=0;err=64;depth=0),不确定是不是自己生成的证书在无网情况下是不是不可用(开发电脑无法连互联网),暂时屏蔽了openssl相关的代码。坑2:这个文章的client的代码中......
  • 基于springboot的grpc服务端demo
    1.Javamaven配置点击查看代码<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="h......
  • 【SQL练习】demo1
    为了适应技术发展的需求,SQL标准于2016年增加了以下JSON功能:JSON对象的存储与检索。将JSON对象表示成SQL数据。将SQL数据表示成JSON对象。如今,主流关系型数据库都增加了原生JSON数据类型和相关函数的支持,使得我们可以将SQL的强大功能与JSON文档存储的灵......
  • 【Python安全】demo1:模拟木马传播行为(谨慎使用)
    原创蓝胖子之家代码主要功能是将自身复制到系统目录,并将其写入注册表以实现开机启动。它还设置了一个定时器,用于定期执行一些操作。该程序还监听设备的插拔事件,并在可移动驱动器插入时将自身复制到驱动器上。具体来说,代码中的kill_process函数用于终止指定名称的进程。wnd_pr......
  • 【反沙箱系列】代码demo1
    一、判断CPU核心数dwNumberOfProcessors#include<iostream>#include<windows.h>intGetCPUCoreCount(){SYSTEM_INFOsysInfo;GetNativeSystemInfo(&sysInfo);returnsysInfo.dwNumberOfProcessors;}boolIsCPUCoreCountLessThanTwo(){......