虚拟人的快速实现:语音驱动图片

背景

由于业务需要,近期调研了如何使用开源工具快速的实现一个虚拟人,这个虚拟人来自于一个图片,我们需要做的是要让这个图片动起来,且图中人物的口型能够跟对应的语音对应上。为此,我了解几个开源的工具或模型,最终选择使用SadTalker来实现该功能。

本文是对SadTalker的使用以及其用到的基础模型做一总结。希望能够对想要实现该功能的同学有所帮助。

要达成的目标

需要有个开源工具,能够实现如下的输入输出,效果要尽可能的好,并且方便我们将该服务本地化。

输入:一段文字脚本、一个音色模型、一张人物图片

输出:一个视频,该视频中的人物能够开口说话,并且用指定的音色说出文字脚本的内容

SadTalker相关信息

Github地址:https://github.com/OpenTalker/SadTalker

hugging face地址:https://huggingface.co/spaces/vinthony/SadTalker

SadTalker的使用

关于SadTalker的使用,其官方文档已经写的比较全面了,这里不再赘述。只提一下其中一些参数的使用要点。

  1. 如果要用preprocess的full参数,则一定要加上–still参数,不然效果会很糟糕。
  2. free-view Mode参数可以用于控制头像的转动,其中参数的详细含义如下:

input_yawinput_pitch 和 input_roll 通常用于描述物体或相机在三维空间中的旋转角度,也被称为欧拉角或俯仰、偏航和翻滚角。

  • input_yaw 表示绕垂直于地面的轴旋转的角度,也称为偏航角。通常以正北方向为0度,顺时针方向为正方向,逆时针方向为负方向。
  • input_pitch 表示绕水平轴旋转的角度,也称为俯仰角。通常以水平面为0度,向上旋转为正方向,向下旋转为负方向。
  • input_roll 表示绕前后轴旋转的角度,也称为翻滚角。通常以垂直于水平面的轴为0度,向右旋转为正方向,向左旋转为负方向。
  1. 就我目前来看,如果我们需要头部动起来,那么还是不设置旋转参数的效果更好。

SadTalker使用到的模型

模型介绍

shape_predictor_68_face_landmarks.dat

shape_predictor_68_face_landmarks.dat是一个基于dlib库的人脸关键点检测模型文件,可以用于检测人脸的68个关键点,包括眼睛、眉毛、鼻子、嘴巴等部位的位置信息。这个模型文件在很多人脸识别、表情识别、人脸姿态估计等领域都有广泛的应用。(基于随机森林的回归算法)

Deep3DFaceReconstruction

**Deep3DFaceReconstruction**是一种基于深度学习的人脸三维重建技术。它通过利用深度学习算法对人脸图像进行分析和处理,从而实现对人脸的三维重建。这种技术可以广泛应用于计算机视觉、虚拟现实、增强现实等领域,为人们带来更加逼真的视觉体验。

Deep3DFaceReconstruction的核心技术是利用深度学习算法对人脸图像进行分析和处理,从而提取出人脸的三维信息。具体来说,它通过对大量的人脸图像进行训练,学习到了一种高效的特征提取方法,可以快速准确地提取出人脸的关键特征,包括面部轮廓、眼睛、鼻子、嘴巴等。然后,它通过对这些特征进行三维重建,从而得到了一个高度逼真的人脸三维模型。

Deep3DFaceReconstruction具有许多优点,例如可以实现快速高效的三维重建、可以处理不同角度和光照条件下的人脸图像、可以处理不同种族和性别的人脸图像等。此外,它还可以应用于人脸识别、人脸动画、人脸表情识别等领域,具有广泛的应用前景。

auido2pose_00140-model.pth

auido2pose_00140-model.pth是一个训练好的PyTorch模型文件,用于音频到人体姿态的转换。该模型可以根据输入的音频数据,预测出对应的人体姿态信息。在这个文件中,auido2pose_00140-model.pth表示训练过程中的第140个epoch。在每个epoch中,模型会对训练数据进行一次完整的训练,以更新模型参数。通常情况下,训练的epoch次数越多,模型的预测效果会越好,但是也会增加训练时间和计算资源的开销。该模型文件可以被应用于很多领域,如虚拟现实、运动分析、人体姿态识别等。(PoseVAE模型,基于transformer模型的)

auido2exp_00300-model.pth

auido2exp_00300-model.pth是一个训练好的模型文件,用于将音频数据转换为对应的面部表情。该模型通过分析音频数据和面部表情数据之间的关系,可以预测出对应的面部表情信息。auido2exp_00300-model.pth可以被应用于很多领域,如虚拟现实、面部表情识别、情感分析等。通过分析音频数据和面部表情数据之间的关系,该模型可以实现对面部表情的快速、准确的预测。(ExpNet模型,基于transformer模型的)

wav2lip.pth

wav2lip.pth是一个基于深度学习的语音和口型同步技术的模型文件,可以将音频和视频中的语音和口型同步,生成逼真的合成视频。该模型使用了深度学习中的卷积神经网络和循环神经网络等技术,实现了对音频和视频的特征提取和匹配。wav2lip.pth可以被应用于很多领域,如虚拟现实、视频编辑、电影制作等。通过将音频和视频进行同步,可以实现更加逼真的人机交互和视频合成效果,提高用户体验。(基于循环神经网络)

mapping_00109-model.pth.tar

mapping_00109-model.pth.tar的作用是将输入音频中学习到的逼真的3D运动系数转换为对应的基础向量,从而生成一个逼真的3D人脸。具体来说,mappingNet模型学习从显式的3DMM运动系数(头部姿态和表情)到隐式的基础向量之间的关系,并将这个关系应用于输入音频中学习到的逼真的3D运动系数,从而生成对应的基础向量。最后,这个基础向量与3DMM模型中的基础向量相结合,生成一个逼真的3D人脸。(基于GAN神经网络)

facevid2vid_00189-model.pth.tar

facevid2vid_00189-model.pth.tar是一个基于深度学习的人脸动作转换模型,可以将输入的人脸视频转换成指定动作的人脸视频。简单来说,可以将上述3D模型视频转为穿了图片皮肤的视频。(基于GAN神经网络)

GFPGANv1.4.pth

GFPGANv1.4.pth是一种图像超分辨率重建模型,用于将低分辨率图像(LR)提升至高分辨率图像(HR)。它是由腾讯优图实验室提出的一种基于生成对抗网络(GAN)的方法,可以在不失真的情况下提高图像质量。GFPGANv1.4.pth是该模型的一个预训练权重文件,可以用于对新的低分辨率图像进行重建。该模型可以应用于许多领域,如数字娱乐、医学影像、安防监控等。(基于GAN神经网络)

处理流程中的相关模型

  1. 对原始图片进行裁剪,这一步用到shape_predictor_68_face_landmarks.dat算法模型识别出人脸,并使用CV2进行裁剪处理。
  2. 将原始图片中的人脸识别成一个3D人脸模型系数,并存储在mat格式的文件中。
  3. 3DMM提出给定视频中的眨眼动作。(将视频中的人脸识别成一个3D人脸模型系数,并存储在mat格式的文件中。)
  4. 3DMM提出给定视频中的姿势动作。(将视频中的人脸识别成一个3D人脸模型系数,并存储在mat格式的文件中。)
  5. 从音频中提取出姿势、表情以及唇形,并存储在mat格式的文件中。
  6. 使用上述系数渲染出一个3D人脸模型,并用ffmpeg命令将音频与视频做结合。
  7. 将视频与图片做结合。
  8. 效果增强,使视频变得更加清晰。

模型处理的时延测试

音频时长:10秒

处理总时间:366054毫秒(6分钟)

模型处理时间总占比:97.20%

测试机器配置:半张NVIDIA Tesla T4显卡、显存:8GB

处理过程模型处理时间(单位:毫秒)处理时间占比
图片的预处理shape_predictor_68_face_landmarks.dat
epoch_20.pth92962.54%
眨眼视频的处理shape_predictor_68_face_landmarks.dat
epoch_20.pth4094811.19%
姿势视频的处理shape_predictor_68_face_landmarks.dat
epoch_20.pth300448.21%
音频提出系数auido2exp_00300-model.pth
auido2pose_00140-model.pth
wav2lip.pth10940.30%
3D人脸模型渲染mapping_00109-model.pth.tar12231233.41%
视频与图片做结合facevid2vid_00189-model.pth.tar66461.82%
效果增强gfpgan14544939.73%

可以看到,模型处理过程中,最耗时的是3D人脸模型渲染以及效果增强,两者耗时占比超70%。

SadTalker的部署与服务

SadTalker的项目代码是用Python编写的,我们可以用FastAPI很快速的把它改造为能够通过HTTP对外提供服务的方式,并且在服务器中用uvicorn启动该服务。这样就可以在自己的本地环境中稳定的提供服务了,在有代码变更的情况下,也无需手动重启服务。

我们的服务还与腾讯云COS存储打通了,语音和图片从COS中读取,并且将处理成功的视频文件写入到COS中,并将链接地址返回。

总结

本文是对SadTalker的使用以及其用到的基础模型做了一下总结,其中包括了模型的介绍以及各模型处理时长的试验结果,但并没有涉及到模型的原理以及优化细节。对于针对于业务的优化,可以后续视情况来续写分享。

参考资料

SadTalker Github地址:https://github.com/OpenTalker/SadTalker

SadTalker hugging face地址:https://huggingface.co/spaces/vinthony/SadTalker

SadTalker最佳实践:https://github.com/OpenTalker/SadTalker/blob/main/docs/best_practice.md

FastAPI:https://github.com/tiangolo/fastapi

ChatGPT实践——如何用LangChain基于LLM构建一个应用程序

ChatGPT实践——如何用LangChain基于LLM构建一个应用程序

LangChain是什么

随着大语言模型的出现和发展,开发者们都会思考一个问题,如何利用这些新技术来搭建一个有用的应用程序。但若只是基于各个独立的技术,是很难满足我们对应用程序的需求的。而LangChain这样的工具就是用来解决这一问题的,它能够将多个不同的技术组合起来供开发者使用,从而让开发者得以便捷的实现一个有用的应用程序。

LangChain可以实现的应用场景

Agents

这里的Agents指的是一个系统,该系统可以使用大语言模型来与其他工具进行交互,从而实现如智能问答、智能操作或是其它连接硬件进行行动的功能。我能想到的是可以实现一个类似于Siri这样的手机软件助手,应该会比它智能一些吧,还有像是科幻片种的智能机器人。

Chatbots(聊天机器人)

这个其实就是基于LLM来做一个能够对话的机器人,像OpenAI的ChatGPT就能直接进行对话的。但它这里可以提供更多复杂的功能,让LLM能够更加定制化,适用更多的应用场景。

Generate Examples(生成例子)

可以基于我们之前的样例按照某个模板生成更多相似的样例。

Data Augmented Generation(增强的数据生成)

目前的LLM只能是基于已训练好的通用模型进行数据生成(或者叫做对话),但我们有很多场景都是特殊的,我们希望LLM能够对我们自己的私人文档进行总结或是基于私人文档进行问答对话,又或者希望我们和LLM的对话能够基于我们的某个数据库。而使用该工具就可以实现这些场景了。

Question Answering(问答)

可以创建基于某个或多个文档的问答系统。对于基于多个文档的问答系统,可以做到创建各个文档的索引,从而在问答时能够快速挑选出最相关的文档发送给LLM,而不用每次都把所有文档都发送过去。

这个我能想到的是,可以把公司的iwiki系统接入进去(当然,这只是假设,因为数据敏感要求,肯定不能这么做),这样我们就可以不仅限于倒排索引进行检索了。

Summarization(摘要)

将多个长文档总结凝练成一小段核心的摘要。

Querying Tabular Data(查询表格数据)

有许多数据都是表格型数据,比如CSV、EXCEL表格,比如SQL表格。LangChain可以用于处理这些表格数据。

Extraction(提取)

在我们工作场景中,大多数的API以及数据库处理的都是结构化的数据,因此,从一段文本中提取出我们所需要的结构化数据就显得很重要了。包括从一段文本中提取出一条或多条结构化数据插入到数据库中,以及从用户的查询中提取出正确的API参数等。

Model Comparison(模型比较)

在我们构建自己的应用程序时,肯定会涉及到对不同的模型、参数等进行选择。LangChain提供了一个叫做ModelLaboratory的工具,可以让开发者便捷的检验出不同的模型、参数等带来的不同效果,以此来快速判断出该如何进行选择。

LangChain的生态系统

LangChain集成了很多LLM以及各种常用的工具包,比如OpenAI、Wolfram Alpha Wrapper等。

AI研究数据管理自然语言处理搜索引擎其他
AI21 LabsAtlasDBBananaGoogle搜索封装器Chroma
CerebriumAIDeepInfraHugging FaceGoogle Serper封装器Cohere
Deep LakeGraphsignalNLPCloudOpenSearchDeepInfra
ForefrontAIMilvusPetalsSearxNG搜索APIGooseAI
OpenAIPineconePromptLayerSerpAPIHazy Research
StochasticAIPGVectorWeaviateWolfram Alpha封装器Modal
QdrantRunhouse
UnstructuredWeights & Biases

详见:https://langchain.readthedocs.io/en/latest/ecosystem.html

使用LangChain做了几个应用程序demo

结合自己的notion文档做对话

demo背景

因为我有每天做工作记录的习惯,所以想尝试使用这个工具结合自己的notion文档,看能否使用它对自己的notion文档做问答对话。

我的工作记录的notion文档部分截图如下:

问题一:把vanping在2022年6月的工作做一下总结

执行脚本运行的结果:

问题二:在2022月6月,什么工作是vanping的重点

代码

import os
from langchain.chains.question_answering import load_qa_chain
from langchain.chat_models import ChatOpenAI
from langchain.document_loaders import UnstructuredFileLoader

openaichat = ChatOpenAI(model_name="gpt-3.5-turbo")

loader = UnstructuredFileLoader("./vanping_work.txt")
docs = loader.load()

chain = load_qa_chain(openaichat, chain_type="stuff")
query = "在2022月6月,什么工作是vanping的重点"
result = chain.run(input_documents=docs, question=query)
print(result)

小结

这里用到了LangChain的Models、Indexes模块。

看起来使用该工具是能够非常便捷的导入文档以及和chatGPT做对话交互的。但我这里也只是展现了一个简单的demo,若是多加利用,应该是很好用的。

让应用程序扮演某个角色和我对话

demo背景

我想尝试使用LangChain中的chains,看看能否用加前后缀的方式,让应用程序可以扮演某个角色和我进行对话。

角色零:通用模型。问题:你每天都在干吗?

运行结果:

角色一:阴阳怪气的人。问题:你每天都在干吗?

运行结果:

角色零:通用模型。问题:给我讲下ChatGPT的应用场景?

运行结果:

角色二:言简意赅的人。问题:给我讲下ChatGPT的应用场景?

运行结果:

代码

import os
import sys
from langchain.prompts import PromptTemplate
from langchain.chat_models import ChatOpenAI
from langchain.chains import LLMChain

os.environ["OPENAI_API_KEY"] = "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"

openaichat = ChatOpenAI(model_name="gpt-3.5-turbo")

prompt = PromptTemplate(
   input_variables=["query"],
   template="假设你是个言简意赅,每次说话都不超过30个字的人,{query}",
)

chain = LLMChain(llm=openaichat, prompt=prompt)
result = chain.run(sys.argv[1])
print(result)

小结

这里用到了LangChain的Models、Prompts、Chains模块。

这应该是Chains最简单的用法了。实际上Chains是有很多高级的用法。可以参考:https://langchain.readthedocs.io/en/latest/modules/chains.html

私人问答助手(与搜索引擎结合,且具备记忆能力)

demo背景

当前的很多LLM模型都是基于历史的数据训练得来的,比如ChatGPT,就仅能支持查询21年以前的事件,之后的事件它就无能为力了。

比如,当我想知道”当前NBA赛季,洛杉矶湖人队的常规赛平均得分是多少? 与上赛季常规赛平均水平相比百分比变化如何?”

它的答复是这样的:

从结果我们就能看到,它对于这种事情是一窍不通的。

而如果我们想做一个私人问答助手,肯定是不能不知道当前时事的,因此,我就使用LangChain结合搜索引擎来做一个助手。

私人问答助手的答复

问题一:当前 NBA 赛季洛杉矶湖人队的常规赛平均得分是多少? 与上赛季常规赛平均水平相比百分比变化如何?

问题二:该队当前的主力队员有谁?

针对以上两个问题,这个私人问答助手都有答复。

答复一:洛杉矶湖人队本赛季常规赛场均得分为 116.7,比上赛季的场均得分 111.5 提高了 4.2%。

答复二:洛杉矶湖人队的主力球员是Anthony Davis,Wesley Gabriel,Rui Hachimura,LeBron James。

我在NBA APP中查了下球队数据,看起来也不十分精确,但相差也并不大。

我在这个demo中用到了LangChain的Memory、Agents模块,以及GoogleSerperAPIWrapper工具。

我还试验了一下,如果不要Memory模块,那么输出的结果会是如下这个样子。

第一个答复还依旧正常,但第二个答复就是胡说八道了:美中贸易战的主要参与者是越南、台湾、孟加拉国、韩国、智利、马来西亚、阿根廷、中国、美国、日本、印度和印度尼西亚。

代码

from langchain.agents import ZeroShotAgent, Tool, AgentExecutor
from langchain.memory import ConversationBufferMemory
from langchain import OpenAI, LLMChain
from langchain.utilities import GoogleSerperAPIWrapper
search = GoogleSerperAPIWrapper()
tools = [
   Tool(
       name = "Search",
       func=search.run,
       description="useful for when you need to answer questions about current events"
  )
]

prefix = """Have a conversation with a human, answering the following questions as best you can. You have access to the following tools:"""
suffix = """Begin!"

{chat_history}
Question: {input}
{agent_scratchpad}"""

prompt = ZeroShotAgent.create_prompt(
   tools,
   prefix=prefix,
   suffix=suffix,
   input_variables=["input", "chat_history", "agent_scratchpad"]
)
memory = ConversationBufferMemory(memory_key="chat_history")

llm_chain = LLMChain(llm=OpenAI(temperature=0), prompt=prompt)
agent = ZeroShotAgent(llm_chain=llm_chain, tools=tools, verbose=True)
agent_chain = AgentExecutor.from_agent_and_tools(agent=agent, tools=tools, verbose=True, memory=memory)

agent_chain.run(input="What is the regular season scoring average for the Los Angeles Lakers in the current NBA season? How is the percentage change compared to last season's regular season average?")
agent_chain.run(input="Who are its main players?")

小结

这里用到了LangChain的Models、Memory、Chains、Agents模块。

制作一个小助手算是非常常见的功能,我这里也只是简单的试用了一下。如果有更复杂的需求,可以参考文档:https://python.langchain.com/en/latest/use_cases/personal_assistants.html

总结

本文对LangChain做了一些简单的介绍,重点是后面列举了三个应用程序Demo。每个应用程序Demo虽然都比较简单,但也算是试用了一下LangChain所提供的一些功能。参考LangChain的官方文档,理论上就能实现很多场景更复杂的AI应用。

参考资料

LangChain官方文档:https://python.langchain.com/en/latest/index.html

ChatGPT分享-如何开发一个LLM应用:https://www.51cto.com/article/749570.html

学会任务理解、真正运算和时事搜索,GPT:我将以高达形态出击:https://km.woa.com/articles/show/573744

LangChain:Model as a Service 粘合剂,被 ChatGPT 插件干掉了吗?:https://foresightnews.pro/article/detail/28959