数字人解决方案——ER-NeRF实时对话数字人模型推理部署带UI交互界面

简介

这个是一个使用ER-NeRF来实现实时对话数字人、口播数字人的整体架构,其中包括了大语言回答模型、语音合成、成生视频流、背景替换等功能,项目对显存的要求很高,想要达到实时推理的效果,建议显存在24G以上。

实时对话数字人

讨论群企鹅:787501969

一、环境安装

#下载源码
git clone https://github.com/Fictionarry/ER-NeRF.git
cd ER-NeRF
#创建虚拟环境
conda create --name vrh python=3.10
activate vrh
#pytorch 要单独对应cuda进行安装,要不然训练时使用不了GPU
conda install pytorch==2.0.0 torchvision==0.15.0 torchaudio==2.0.0 pytorch-cuda=11.7 -c pytorch -c nvidia
conda install -c fvcore -c iopath -c conda-forge fvcore iopath
#安装所需要的依赖
pip install -r requirements.txt#处理音频时用的
pip install tensorflow

下载pytorch3d源码,如果下载不了,按上面的百度网盘下载:链接:https://pan.baidu.com/s/1xPFo-MQPWzkDMpLHhaloCQ
提取码:1422

git clone https://github.com/facebookresearch/pytorch3d.git
cd pytorch3d
python setup.py install

二、对话模型ChatGLM3

1. ChatGLM3简介

ChatGLM3作为一个支持中英双语的开源对话语言模型,由智谱 AI 和清华大学 KEG 实验室合作发布,基于 General Language Model (GLM) 架构,拥有 62 亿参数。ChatGLM3-6B 在保留了前两代模型对话流畅、部署门槛低等优点的基础上,还增加了更多特性。虽然目前ChatGLM 比 GPT 稍有逊色,但ChatGLM 在部署后可以完全本地运行,用户可以完全掌控模型的使用。这为用户提供了更多的灵活性和自主权。
ChatGLM3-6B 是一个更强大的基础模型,它的基础模型 ChatGLM3-6B-Base 采用了更多样的训练数据、更充分的训练步数和更合理的训练策略。在语义、数学、推理、代码、知识等不同角度的数据集上测评显示,ChatGLM3-6B-Base 具有在 10B 以下的基础模型中最强的性能。ChatGLM3-6B 还有更完整的功能支持。它采用了全新设计的 Prompt 格式,不仅支持正常的多轮对话,还原生支持工具调用(Function Call)、代码执行(Code Interpreter)和 Agent 任务等复杂场景。除了对话模型 ChatGLM3-6B,还有基础模型 ChatGLM3-6B-Base 和长文本对话模型 ChatGLM3-6B-32K 开源。所有这些权重都对学术研究完全开放,在填写问卷进行登记后也允许免费商业使用。
在这里插入代码片在这里插入图片描述

2.模型与下载

ChatGLM3-6B 开源ChatGLM3-6B、ChatGLM3-6B-Base、ChatGLM3-6B-32K三种模型:

ModelSeq LengthDownload
ChatGLM3-6B8kHuggingFace — ModelScope
ChatGLM3-6B-Base8kHuggingFace — ModelScope
ChatGLM3-6B-32K32kHuggingFace — ModelScope
量化等级生成 8k 长度的最小显存
FP1615.9 GB
INT811.1 GB
INT48.5 GB

3.项目部署

  1. 本项目需要 Python 3.10 或更高版本:
conda create -n ChatGLM3 python=3.10
conda activate ChatGLM3
  1. 下载源码与模型
git clone https://github.com/THUDM/ChatGLM3.git
git lfs clone https://huggingface.co/THUDM/chatglm3-6b
  1. 安装依赖:
cd ChatGLM3
pip install -r requirements.txt
  1. 多显卡需要安装accelerate
pip install accelerate

4.测试项目

打开basic_demo/cli_demo.py,把模型路径更改成刚刚下载的模型路径,要不然在运行的过程中,代码会自动去下载模型,有可能会下载失败:

MODEL_PATH = os.environ.get('MODEL_PATH', './chatglm3-6b')

在这里插入图片描述

三、语音合成Edge-tts

1.edge-tts安装

Edge-TTS 是一个使用微软的 Azure Cognitive Services 实现文本到语音转换(TTS)的 Python 库。它提供了一个简单的 API,允许将文本转换为语音,并支持多种语言和声音。

要使用 Edge-TTS 库,可以通过以下步骤进行安装:

pip install edge-tts

安装完成后,可以在 Python 中使用这个库,调用相应的 API 来进行文本到语音的转换。这通常包括向 Azure Cognitive Services 发送请求,并处理返回的语音数据。

2.edge-tts测试

async def main(voicename: str, text: str, OUTPUT_FILE):communicate = edge_tts.Communicate(text, voicename)with open(OUTPUT_FILE, "wb") as file:async for chunk in communicate.stream():if chunk["type"] == "audio":file.write(chunk["data"])elif chunk["type"] == "WordBoundary":pass

四、语音特征提取DeepSpeech

PaddleSpeech 是基于飞桨 PaddlePaddle 的语音方向的开源模型库,用于语音和音频中的各种关键任务的开发,包含大量基于深度学习前沿和有影响力的模型。这里使用DeepSpeech来对生成的语音进行特征提取,提取出来的语音特征保存为npy文件用于合成视频:

def main():"""Main body of script."""args = parse_args()in_audio = os.path.expanduser(args.input)if not os.path.exists(in_audio):raise Exception("Input file/directory doesn't exist: {}".format(in_audio))deepspeech_pb_path = args.deepspeech#adddeepspeech_pb_path = Trueargs.deepspeech = '~/.tensorflow/models/deepspeech-0_1_0-b90017e8.pb'#deepspeech_pb_path="/disk4/keyu/DeepSpeech/deepspeech-0.9.2-models.pbmm"if deepspeech_pb_path is None:deepspeech_pb_path = ""if deepspeech_pb_path:deepspeech_pb_path = os.path.expanduser(args.deepspeech)if not os.path.exists(deepspeech_pb_path):deepspeech_pb_path = get_deepspeech_model_file()if os.path.isfile(in_audio):extract_features(in_audios=[in_audio],out_files=[args.output],deepspeech_pb_path=deepspeech_pb_path,metainfo_file_path=args.metainfo)else:audio_file_paths = []for file_name in os.listdir(in_audio):if not os.path.isfile(os.path.join(in_audio, file_name)):continue_, file_ext = os.path.splitext(file_name)if file_ext.lower() == ".wav":audio_file_path = os.path.join(in_audio, file_name)audio_file_paths.append(audio_file_path)audio_file_paths = sorted(audio_file_paths)out_file_paths = [""] * len(audio_file_paths)extract_features(in_audios=audio_file_paths,out_files=out_file_paths,deepspeech_pb_path=deepspeech_pb_path,metainfo_file_path=args.metainfo)

五、视频合成ER-NeRF

1.语言模型

  • 简单回答
    为了测试方便,这里写了个简单的回复函数,如果机器没有大显存的话,可以使用这个函数来测试数字人是否能运行起来。
def test_answer(message):message = message.lower()if message == "你好":response = "你好,有什么可以帮到你吗?"elif message == "你是谁":response = f"我是虚拟数字人静静,这是我的一个测试版本。"elif message == "你能做什么":response = "我可以陪你聊天,回答你的问题,我还可以做很多很多事情!"else:response = "你的这个问题超出了我的理解范围,等我学习后再来回答你。或者你可以问我其他问题,能回答的我尽量回答你!"return response
  • GLM回答
    使用GLM语言模型来回答,可以直接把代码整合在一个推理代码里面,这样很吃GPU,如果没有12G以上的显存,建议把GLM做成服务器形势进行访问:
tokenizer = AutoTokenizer.from_pretrained("ChatGLM3/chatglm3-6b", trust_remote_code=True)
model = AutoModel.from_pretrained("ChatGLM3/chatglm3-6b", trust_remote_code=True, device='cuda')
video_pre_process()def glm_answer(query):global modelmodel = model.eval()query = query +"(请在20个字内回答)"response, history = model.chat(tokenizer, query, history=[])return response

2.语音合成与语音特征提取

选择生成语音发声人:

audio_eo_path,audio_path_wav = text_to_audio(response,dir,voicename)output_video_path = compound_video(audio_path_wav, audio_eo_path, cv_bg, dir, 0)return history, history, output_video_pathdef text_to_audio(text,save_path,voicename):global voices_list;asyncio.set_event_loop(asyncio.new_event_loop())name = ''if voicename == "晓晓":name = 'zh-CN-XiaoxiaoNeural'if voicename == "晓依":name = 'zh-CN-XiaoyiNeural'if voicename == "云霞":name = 'zh-CN-YunxiaNeural'if voicename == "东北":name = 'zh-CN-liaoning-XiaobeiNeural'if voicename == "陕西":name = 'zh-CN-shaanxi-XiaoniNeural'if voicename == "云剑":name = 'zh-CN-YunjianNeural'if voicename == "云溪":name = 'zh-CN-YunxiNeural'if voicename == "云阳":name = 'zh-CN-YunyangNeural'timestamp = int(time.time())audio_path_mp3 = os.path.join(save_path, str(timestamp) + ".mp3")audio_path_wav = os.path.join(save_path, str(timestamp) + ".wav")asyncio.get_event_loop().run_until_complete(main(name, text,audio_path_mp3))command = ['ffmpeg', '-i', audio_path_mp3, audio_path_wav]subprocess.run(command, capture_output=True, text=True)cmd = f'python data_utils/deepspeech_features/extract_ds_features.py --input {audio_path_wav}'os.system(cmd)audio_eo_path = os.path.join(save_path, str(timestamp) + ".npy")return audio_eo_path,audio_path_wav

3.合成视频

合成的视频可以选择使用的背景,还有人像所在的位置,分三个位置,左,中,右,也可以在执行中动态更改位置。

def answer(message, history,voicename,llm_name):global dirglobal cv_bghistory = history or []response = ''if llm_name =="测试":response = test_answer(message)elif llm_name =="ChatGLM3":response = glm_answer(message)history.append((message, response))audio_eo_path,audio_path_wav = text_to_audio(response,dir,voicename)output_video_path = compound_video(audio_path_wav, audio_eo_path, cv_bg, dir, 0)return history, history, output_video_path

4.webui代码整合

这里使用gradio来做交互的UI。

import gradio as gr
import time
import cv2
import os
from tools import video_pre_process, compound_videofrom transformers import AutoTokenizer, AutoModelimport asyncio
import edge_tts
import subprocessdir = "workspace"
cv_bg = cv2.imread('bg_1.jpg')tokenizer = AutoTokenizer.from_pretrained("ChatGLM3/chatglm3-6b", trust_remote_code=True)
model = AutoModel.from_pretrained("ChatGLM3/chatglm3-6b", trust_remote_code=True, device='cuda')
video_pre_process()def glm_answer(query):global modelmodel = model.eval()query = query +"(在20个字内回答)"response, history = model.chat(tokenizer, query, history=[])return responseasync def main(voicename: str, text: str, OUTPUT_FILE):communicate = edge_tts.Communicate(text, voicename)with open(OUTPUT_FILE, "wb") as file:async for chunk in communicate.stream():if chunk["type"] == "audio":file.write(chunk["data"])elif chunk["type"] == "WordBoundary":passdef test_answer(message):message = message.lower()if message == "你好":response = "你好,有什么可以帮到你吗?"elif message == "你是谁":response = f"我是虚拟数字人静静,这是我的一个测试版本。"elif message == "你能做什么":response = "我可以陪你聊天,回答你的问题,我还可以做很多很多事情!"else:response = "你的这个问题超出了我的理解范围,等我学习后再来回答你。或者你可以问我其他问题,能回答的我尽量回答你!"return responsedef answer(message, history,voicename,llm_name):global dirglobal cv_bghistory = history or []response = ''if llm_name =="测试":response = test_answer(message)elif llm_name =="ChatGLM3":response = glm_answer(message)history.append((message, response))audio_eo_path,audio_path_wav = text_to_audio(response,dir,voicename)output_video_path = compound_video(audio_path_wav, audio_eo_path, cv_bg, dir, 0)return history, history, output_video_pathdef text_to_audio(text,save_path,voicename):global voices_list;asyncio.set_event_loop(asyncio.new_event_loop())name = ''if voicename == "晓晓":name = 'zh-CN-XiaoxiaoNeural'if voicename == "晓依":name = 'zh-CN-XiaoyiNeural'if voicename == "云霞":name = 'zh-CN-YunxiaNeural'if voicename == "东北":name = 'zh-CN-liaoning-XiaobeiNeural'if voicename == "陕西":name = 'zh-CN-shaanxi-XiaoniNeural'if voicename == "云剑":name = 'zh-CN-YunjianNeural'if voicename == "云溪":name = 'zh-CN-YunxiNeural'if voicename == "云阳":name = 'zh-CN-YunyangNeural'timestamp = int(time.time())audio_path_mp3 = os.path.join(save_path, str(timestamp) + ".mp3")audio_path_wav = os.path.join(save_path, str(timestamp) + ".wav")asyncio.get_event_loop().run_until_complete(main(name, text,audio_path_mp3))command = ['ffmpeg', '-i', audio_path_mp3, audio_path_wav]subprocess.run(command, capture_output=True, text=True)cmd = f'python data_utils/deepspeech_features/extract_ds_features.py --input {audio_path_wav}'os.system(cmd)audio_eo_path = os.path.join(save_path, str(timestamp) + ".npy")return audio_eo_path,audio_path_wavwith gr.Blocks(css="#chatbot{height:300px} .overflow-y-auto{height:500px}") as rxbot:tts_checkbox = gr.Dropdown(["晓晓", "晓依", "云霞", "东北", "陕西", "云剑", "云溪", "云阳"],label="语音选择", info="晓晓:女, 晓依:女, 云霞:女, 东北:女, 陕西:女, 云剑:男, 云溪:男,云阳:男")answer_checkbox = gr.Dropdown(["测试","ChatGLM3", "ChatGPT", "LLaMA"],label="大语言模型",info="测试:只有固定的几个问题, ChatGLM3:GPU在12G以上可以选择这个模型, ChatGPT:暂时没有接入, LLaMA:暂时没有接入")with gr.Row():video_src = gr.Video(label="数字人", autoplay=True)with gr.Column():state = gr.State([])chatbot = gr.Chatbot(label="消息记录").style(color_map=("green", "pink"))txt = gr.Textbox(show_label=False, placeholder="请输入你的问题").style(container=False)txt.submit(fn=answer, inputs=[txt, state,tts_checkbox,answer_checkbox], outputs=[chatbot, state, video_src])# rxbot.launch()if __name__ == "__main__":# response = glm_answer('你好')# print(response)rxbot.launch()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/236304.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

众和策略:大盘涨手中的股票却大跌,到底怎么回事?

大盘涨手中的股票却大跌,究竟怎么回事: 1、大盘上涨是权重股所造成的 大盘上涨可能是受一些权重比较大的工作所影响,比如证券工作、钢铁工作、银行工作等等,这些工作的大涨,可以拉升大盘的上涨,可是其它工…

本地配置Java支付宝沙箱环境模拟支付并内网穿透远程调试

文章目录 前言1. 下载当面付demo2. 修改配置文件3. 打包成web服务4. 局域网测试5. 内网穿透6. 测试公网访问7. 配置二级子域名8. 测试使用固定二级子域名访问 前言 在沙箱环境调试支付SDK的时候,往往沙箱环境部署在本地,局限性大,在沙箱环境…

Dynamic Coarse-to-Fine Learning for Oriented Tiny Object Detection(CVPR2023待补)

文章目录 BeginningAbstract挑战方法成果 Introduction引出问题早期的work及存在的问题近期的work及存在的问题our workContribution Related Work(paper for me)Oriented Object DetectionPrior for Oriented ObjectsLabel Assignment Tiny Object Dete…

Opencv 入门三(视频滑动条窗口)

视频滑动条窗口源码如下&#xff1a; #include "opencv2\highgui\highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> #include <fstream> using namespace std; int g_slider_position 0; // 滑动条的位置 …

uniapp uview1.0 页面多个upload上传、回显之后处理数据

<view class"img-title w-s-color-3 f-28 row">商品图片</view><u-upload ref"images" :header"header" :file-list"fileListImages" :action"action" name"iFile" icon-name"camera"u…

论文学习——泰森多边形法在小流域面雨量计算中的应用

文章目录 0 摘要00 引言1 研究区域概况2 泰森多边形的建立3 流域多年面降雨量分析4 典型降雨场次面雨量分析5 典型降雨日面雨量分析6 结论7 个人总结0 摘要 研究泰森多边形算法,在小流域面雨量计算中的适用性。选取3种不同降雨量实例,流域多年面降雨量、典型场次、典型日面雨…

108基于matlab的使用模拟退火 (SA) 求解并行机器调度的程序

基于matlab的使用模拟退火 &#xff08;SA&#xff09; 求解并行机器调度的程序&#xff0c;程序已调通&#xff0c;可直接运行。 108 matlab模拟退火 &#xff08;SA) (xiaohongshu.com)

如何使用支付宝的沙箱环境在本地配置模拟支付并发布至公网测试

文章目录 前言1. 下载当面付demo2. 修改配置文件3. 打包成web服务4. 局域网测试5. 内网穿透6. 测试公网访问7. 配置二级子域名8. 测试使用固定二级子域名访问 前言 在沙箱环境调试支付SDK的时候&#xff0c;往往沙箱环境部署在本地&#xff0c;局限性大&#xff0c;在沙箱环境…

Redis一些常用的技术

文章目录 第1关&#xff1a;Redis 事务与锁机制第2关&#xff1a;流水线第3关&#xff1a;发布订阅第4关&#xff1a;超时命令第5关&#xff1a;使用Lua语言 第1关&#xff1a;Redis 事务与锁机制 编程要求 根据提示&#xff0c;在右侧编辑器Begin-End补充代码&#xff0c;根据…

MySQL是如何保证数据不丢失的?

文章目录 前言Buffer Pool 和 DML 的关系DML操作流程加载数据页更新记录 数据持久化方案合适的时机刷盘双写机制日志先行机制日志刷盘机制Redo Log 恢复数据 总结 前言 上篇文章《InnoDB在SQL查询中的关键功能和优化策略》对InnoDB的查询操作和优化事项进行了说明。但是&#…

【MyBatis学习笔记】MyBatis基础学习

MyBatis基础 MyBatis简介MyBatis特性MyBatis下载和其他持久化层技术对比 核心配置文件详解默认的类型别名 搭建MyBatis开发环境创建maven工程创建MyBatis的核心配置文件创建mapper接口创建MyBatis的映射文件通过junit测试功能加入log4j日志功能 MyBatis获取参数值的两种方式&am…

【无人机学习篇】构建mavros机载电脑连接,从机载电脑获取pixhawk数据

&#xff08;本文基于的pixhawk版本&#xff1a;6X minibase V2.2 &#xff0c;固件&#xff1a;apm&#xff09; 整个的步骤&#xff08;baseline&#xff09;&#xff1a; 具体的每一步都可以在网上查到教程&#xff0c;这里只是梳理出一个流程。并且ubantu与ros的版本也不是…

Java开发框架和中间件面试题(2)

8.说说自己对Spring MVC的了解&#xff1f; MVC是一种设计模式&#xff0c;Spring MVC是一款很优秀的MVC框架。Spring MVC可以帮助我们进行更简洁的Web层开发&#xff0c;并且它天生与Spring框架集成。SpringMVC下我们一般把后端项目分为Service&#xff08;处理业务&#xff0…

网上商城怎么做:五大关键步骤

在数字化浪潮中&#xff0c;开设网上商城已经成为商业发展的必然趋势。然而如何搭建一个功能齐全、用户体验优良的网上商城并非易事。以下为您介绍网上商城怎么做的五大关键步骤。 第一步&#xff0c;明确商业模式和定位 在开始搭建网上商城之前&#xff0c;需要清晰地定义你…

基于Java+SpringBoot+Mybaties-plus+Vue+ElementUI+Vant 电影院订票管理系统 的设计与实现

一.项目介绍 基于SpringBootVue 电影院订票管理系统 分为前端和后端。 前端&#xff08;用户&#xff09;&#xff1a; 登录后支持查看首页、电影、影院和我的信息 支持查看正在热映和即将上映的电影信息 支持购票&#xff08;需选择影院座位&#xff09;、看过&#xff08;评论…

java使用面向对象实现图书管理系统

꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN …

基本shell功能实现(exec系列程序替换函数练习)

shell 功能描述思路介绍1.实现常驻进程功能2.实现命令读取功能3. 实现命令解析功能4.实现子进程执行命令功能5.完善功能 补充内容让父进程运行内置命令实现子进程能够获得父进程的环境变量功能&#xff08;export命令&#xff09;shell实现重定向功能 全部代码如下&#xff1a;…

『 C++ 』二叉树进阶OJ题

文章目录 根据二叉树创建字符串 &#x1f996;&#x1f969; 题目描述&#x1f969; 解题思路&#x1f969; 代码 二叉树的层序遍历(分层遍历) &#x1f996;&#x1f969; 题目描述&#x1f969; 解题思路&#x1f969; 代码 二叉树的层序遍历(分层遍历)Ⅱ &#x1f996;&…

一篇文章带你了解SpringBoot目录结构

前言 SpringBoot是整合Spring技术栈的一站式框架&#xff0c;是简化Spring技术栈的快速开发脚手架&#xff0c;是一个能够快速构建生产级别的Spring应用的工具。SpringBoot是目前流行的微服务框架&#xff0c;倡导“约定优于配置”&#xff0c;简化Spring项目搭建及开发过程。…

速通Python基础语法--运算符篇

一、算术运算符 优先级&#xff1a; 除法的2个问题&#xff1a; 除零异常&#xff1a; 运行时才出现的错误&#xff0c;叫做“抛出异常” 如果程序运行过程中 抛出异常&#xff0c;程序就会直接终止&#xff0c;后面的代码不会执行。 除法的(不)截断问题&#xff1a; %取模/求…