windows本地运行dreamtalk踩坑总结

        dreamtalk是一个语音+图片转视频的一个工具,就是给一段语音加一个头像图片,然后生成一段头像跟语音对口型的视频,其实还是很有意思的,最近阿里发布了一个类似的模型,但是还没开源,从展示视频看,阿里的那个效果比dreamtalk要好,希望早日开源。

        本地运行其实坑主要在安装各种依赖包上,项目地址在dreamtalk · 模型库 (modelscope.cn),可以先把代码下下来,然后就开始装依赖包,第一个依赖:dlib,dlib是c++版本的dlib的一个python绑定,但是目前windows只有py3.6的,如果你的python版本正好是这个,那就直接pip install dlib就行,如果不是,就需要本地编译,本地编译的话,需要安装cmake,可以去官网下载https://github.com/Kitware/CMake/releases/download/v3.29.2/cmake-3.29.2-windows-x86_64.msi

如果访问不了可以用把连接复制到迅雷里用迅雷下(点赞迅雷),安装的时候记得勾选添加到环境变量,cmake是比较装的,第一软件大小比较小,第二页没什么其它的依赖,下载装上就行了,另外一个就是安装visual studio了,这个就比较大了,当然除了大,其它的也还好,只要网速快,硬盘够大,也没什么大问题。装完了这两个就能对dlib进行编译了,但是正常情况下,你装完了这个,下载了dlib源码,运行python setup.py install还是会编译失败,这时还需要添加一个参数,那就是去掉gif支持 python .\setup.py install --no DLIB_GIF_SUPPORT这样才能编译安装成功,至此,第一个依赖安装成功。

        第二个依赖就是ffmpeg,这个是个命令行软件,dreamtalk主要用它来生成视频文件用,这个安装比较简单,只需要下载下来,然后把ffmpeg.exe的路径添加环境变量里就行了。

        第三个依赖是ffmpeg的python绑定,叫pyav,这个比较简单,只要pip install av就行了。

        第四个依赖是神经网络库torch、torchvision、torchaudio了,我安装的是cpu版,这个看个人选择,因为我只想跑个结果,所以没用gpu,这块的安装如果有问题可以自己百度一下,我就不细写了,我这遇到的问题是版本问题,查了一下彼此的匹配版本,解决了问题,我的版本

torch                   1.10.1
torchaudio           0.10.1
torchvision           0.11.2

        第五个依赖是模型,dreamtalk依赖了一个叫jonatasgrosman/wav2vec2-large-xlsr-53-english的项目,这个项目托管在huggingface,需要翻墙,本来这个依赖代码里有自动下载代码,但是网络不通,下载时会报错,怎么办,百度搜到了一个镜像站HF-Mirror - Huggingface 镜像站,然后配置一个环境变量名字为HF_ENDPOINT,值就是镜像站首页地址,然后运行启动文件,文件也正常开始下载,但是不知道为什么,下了一部分的时候,就会报远程主机关闭连接的错误,可能是带宽问题,也可能是我电脑ip问题,如果屏幕前的你可以正常下那就再好不过,可惜我这自动下是不可能了,所以我就只能手动下,结果没想到手动也是报错,关键时刻,还是迅雷好使,连接一复制,非常快的就下载下来了(再次点赞迅雷)。下载好项目后,需要把项目放到dreamtalk根目录下,并且外边还要包一层jonatasgrosman目录,因为代码引用就是这个结构,所以要注意。

        其它python依赖,安装很简单,放个截图

        

        经历了5大依赖,近两天的折腾,本以为就要可以跑一下了,结果运行启动文件,又报错了,错误是关于cuda的,因为我装个的cpu版本的torch是不支持cuda的,所以需要把cuda的代码删掉,于是,我小心翼翼,删掉了调用cuda()函数的代码,终于是可以运行了。修改后的代码inference_for_demo_video.py

import argparse
import torch
import json
import os

from scipy.io import loadmat
import subprocess

import numpy as np
import torchaudio
import shutil

from core.utils import (
    get_pose_params,
    get_video_style_clip,
    get_wav2vec_audio_window,
    crop_src_image,
)
from configs.default import get_cfg_defaults
from generators.utils import get_netG, render_video
from core.networks.diffusion_net import DiffusionNet
from core.networks.diffusion_util import NoisePredictor, VarianceSchedule
from transformers import Wav2Vec2Processor
from transformers.models.wav2vec2.modeling_wav2vec2 import Wav2Vec2Model

device = torch.device("cpu")
@torch.no_grad()
def get_diff_net(cfg):
    diff_net = DiffusionNet(
        cfg=cfg,
        net=NoisePredictor(cfg),
        var_sched=VarianceSchedule(
            num_steps=cfg.DIFFUSION.SCHEDULE.NUM_STEPS,
            beta_1=cfg.DIFFUSION.SCHEDULE.BETA_1,
            beta_T=cfg.DIFFUSION.SCHEDULE.BETA_T,
            mode=cfg.DIFFUSION.SCHEDULE.MODE,
        ),
    )
    checkpoint = torch.load(cfg.INFERENCE.CHECKPOINT,map_location=torch.device('cpu'))
    model_state_dict = checkpoint["model_state_dict"]
    diff_net_dict = {
        k[9:]: v for k, v in model_state_dict.items() if k[:9] == "diff_net."
    }
    diff_net.load_state_dict(diff_net_dict, strict=True)
    diff_net.eval()

    return diff_net


@torch.no_grad()
def get_audio_feat(wav_path, output_name, wav2vec_model):
    audio_feat_dir = os.path.dirname(audio_feat_path)
    pass


@torch.no_grad()
def inference_one_video(
    cfg,
    audio_path,
    style_clip_path,
    pose_path,
    output_path,
    diff_net,
    max_audio_len=None,
    sample_method="ddim",
    ddim_num_step=10,
):
    audio_raw = audio_data = np.load(audio_path)

    if max_audio_len is not None:
        audio_raw = audio_raw[: max_audio_len * 50]
    gen_num_frames = len(audio_raw) // 2

    audio_win_array = get_wav2vec_audio_window(
        audio_raw,
        start_idx=0,
        num_frames=gen_num_frames,
        win_size=cfg.WIN_SIZE,
    )

    #audio_win = torch.tensor(audio_win_array).cuda()
    audio_win = torch.tensor(audio_win_array)
    audio = audio_win.unsqueeze(0)

    # the second parameter is "" because of bad interface design...
    style_clip_raw, style_pad_mask_raw = get_video_style_clip(
        style_clip_path, "", style_max_len=256, start_idx=0
    )

    #style_clip = style_clip_raw.unsqueeze(0).cuda()
    style_clip = style_clip_raw.unsqueeze(0)
    style_pad_mask = (
        #style_pad_mask_raw.unsqueeze(0).cuda()
        style_pad_mask_raw.unsqueeze(0)
        if style_pad_mask_raw is not None
        else None
    )

    gen_exp_stack = diff_net.sample(
        audio,
        style_clip,
        style_pad_mask,
        output_dim=cfg.DATASET.FACE3D_DIM,
        use_cf_guidance=cfg.CF_GUIDANCE.INFERENCE,
        cfg_scale=cfg.CF_GUIDANCE.SCALE,
        sample_method=sample_method,
        ddim_num_step=ddim_num_step,
    )
    gen_exp = gen_exp_stack[0].cpu().numpy()

    pose_ext = pose_path[-3:]
    pose = None
    pose = get_pose_params(pose_path)
    # (L, 9)

    selected_pose = None
    if len(pose) >= len(gen_exp):
        selected_pose = pose[: len(gen_exp)]
    else:
        selected_pose = pose[-1].unsqueeze(0).repeat(len(gen_exp), 1)
        selected_pose[: len(pose)] = pose

    gen_exp_pose = np.concatenate((gen_exp, selected_pose), axis=1)
    np.save(output_path, gen_exp_pose)
    return output_path


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="inference for demo")
    parser.add_argument("--wav_path", type=str, default="", help="path for wav")
    parser.add_argument("--image_path", type=str, default="", help="path for image")
    parser.add_argument("--disable_img_crop", dest="img_crop", action="store_false")
    parser.set_defaults(img_crop=True)

    parser.add_argument(
        "--style_clip_path", type=str, default="", help="path for style_clip_mat"
    )
    parser.add_argument("--pose_path", type=str, default="", help="path for pose")
    parser.add_argument(
        "--max_gen_len",
        type=int,
        default=1000,
        help="The maximum length (seconds) limitation for generating videos",
    )
    parser.add_argument(
        "--cfg_scale",
        type=float,
        default=1.0,
        help="The scale of classifier-free guidance",
    )
    parser.add_argument(
        "--output_name",
        type=str,
        default="test",
    )
    args = parser.parse_args()

    cfg = get_cfg_defaults()
    cfg.CF_GUIDANCE.SCALE = args.cfg_scale
    cfg.freeze()

    tmp_dir = f"tmp/{args.output_name}"
    os.makedirs(tmp_dir, exist_ok=True)

    # get audio in 16000Hz
    wav_16k_path = os.path.join(tmp_dir, f"{args.output_name}_16K.wav")
    command = f"ffmpeg -y -i {args.wav_path} -async 1 -ac 1 -vn -acodec pcm_s16le -ar 16000 {wav_16k_path}"
    subprocess.run(command.split())

    # get wav2vec feat from audio
    wav2vec_processor = Wav2Vec2Processor.from_pretrained(
        "jonatasgrosman/wav2vec2-large-xlsr-53-english"
    )
    wav2vec_model = (
        Wav2Vec2Model.from_pretrained("jonatasgrosman/wav2vec2-large-xlsr-53-english")
        .eval()
        #.cuda()
    )

    speech_array, sampling_rate = torchaudio.load(wav_16k_path)
    audio_data = speech_array.squeeze().numpy()
    inputs = wav2vec_processor(
        audio_data, sampling_rate=16_000, return_tensors="pt", padding=True
    )

    with torch.no_grad():
        audio_embedding = wav2vec_model(inputs.input_values, return_dict=False)[
            0
        ]

    audio_feat_path = os.path.join(tmp_dir, f"{args.output_name}_wav2vec.npy")
    np.save(audio_feat_path, audio_embedding[0].cpu().numpy())

    # get src image
    src_img_path = os.path.join(tmp_dir, "src_img.png")
    if args.img_crop:
        crop_src_image(args.image_path, src_img_path, 0.4)
    else:
        shutil.copy(args.image_path, src_img_path)

    with torch.no_grad():
        # get diff model and load checkpoint
        #diff_net = get_diff_net(cfg).cuda()
        diff_net = get_diff_net(cfg)
        # generate face motion
        face_motion_path = os.path.join(tmp_dir, f"{args.output_name}_facemotion.npy")
        inference_one_video(
            cfg,
            audio_feat_path,
            args.style_clip_path,
            args.pose_path,
            face_motion_path,
            diff_net,
            max_audio_len=args.max_gen_len,
        )
        # get renderer
        renderer = get_netG("checkpoints/renderer.pt")
        # render video
        output_video_path = f"output_video/{args.output_name}.mp4"
        render_video(
            renderer,
            src_img_path,
            face_motion_path,
            wav_16k_path,
            output_video_path,
            fps=25,
            no_move=False,
        )

        # add watermark
        # if you want to generate videos with no watermark (for evaluation), remove this code block.
        no_watermark_video_path = f"{output_video_path}-no_watermark.mp4"
        shutil.move(output_video_path, no_watermark_video_path)
        os.system(
            f'ffmpeg -y -i {no_watermark_video_path} -vf  "movie=media/watermark.png,scale= 120: 36[watermask]; [in] [watermask] overlay=140:220 [out]" {output_video_path}'
        )
        os.remove(no_watermark_video_path)

 dreamtalk/generators/utils.py

import argparse
import cv2
import json
import os

import numpy as np
import torch
import torchvision
import torchvision.transforms as transforms
from PIL import Image


def obtain_seq_index(index, num_frames, radius):
    seq = list(range(index - radius, index + radius + 1))
    seq = [min(max(item, 0), num_frames - 1) for item in seq]
    return seq
device = torch.device("cpu")

@torch.no_grad()
def get_netG(checkpoint_path):
    from generators.face_model import FaceGenerator
    import yaml

    with open("generators/renderer_conf.yaml", "r") as f:
        renderer_config = yaml.load(f, Loader=yaml.FullLoader)

    renderer = FaceGenerator(**renderer_config).to(device)

    checkpoint = torch.load(checkpoint_path, map_location=lambda storage, loc: storage)
    renderer.load_state_dict(checkpoint["net_G_ema"], strict=False)

    renderer.eval()

    return renderer


@torch.no_grad()
def render_video(
    net_G,
    src_img_path,
    exp_path,
    wav_path,
    output_path,
    silent=False,
    semantic_radius=13,
    fps=30,
    split_size=16,
    no_move=False,
):
    """
    exp: (N, 73)
    """
    target_exp_seq = np.load(exp_path)
    if target_exp_seq.shape[1] == 257:
        exp_coeff = target_exp_seq[:, 80:144]
        angle_trans_crop = np.array(
            [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.9370641, 126.84911, 129.03864],
            dtype=np.float32,
        )
        target_exp_seq = np.concatenate(
            [exp_coeff, angle_trans_crop[None, ...].repeat(exp_coeff.shape[0], axis=0)],
            axis=1,
        )
        # (L, 73)
    elif target_exp_seq.shape[1] == 73:
        if no_move:
            target_exp_seq[:, 64:] = np.array(
                [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.9370641, 126.84911, 129.03864],
                dtype=np.float32,
            )
    else:
        raise NotImplementedError

    frame = cv2.imread(src_img_path)
    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    src_img_raw = Image.fromarray(frame)
    image_transform = transforms.Compose(
        [
            transforms.ToTensor(),
            transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5), inplace=True),
        ]
    )
    src_img = image_transform(src_img_raw)

    target_win_exps = []
    for frame_idx in range(len(target_exp_seq)):
        win_indices = obtain_seq_index(
            frame_idx, target_exp_seq.shape[0], semantic_radius
        )
        win_exp = torch.tensor(target_exp_seq[win_indices]).permute(1, 0)
        # (73, 27)
        target_win_exps.append(win_exp)

    target_exp_concat = torch.stack(target_win_exps, dim=0)
    target_splited_exps = torch.split(target_exp_concat, split_size, dim=0)
    output_imgs = []
    for win_exp in target_splited_exps:
        #win_exp = win_exp.cuda()
        #cur_src_img = src_img.expand(win_exp.shape[0], -1, -1, -1).cuda()
        cur_src_img = src_img.expand(win_exp.shape[0], -1, -1, -1)
        output_dict = net_G(cur_src_img, win_exp)
        output_imgs.append(output_dict["fake_image"].cpu().clamp_(-1, 1))

    output_imgs = torch.cat(output_imgs, 0)
    transformed_imgs = ((output_imgs + 1) / 2 * 255).to(torch.uint8).permute(0, 2, 3, 1)

    if silent:
        torchvision.io.write_video(output_path, transformed_imgs.cpu(), fps)
    else:
        silent_video_path = f"{output_path}-silent.mp4"
        torchvision.io.write_video(silent_video_path, transformed_imgs.cpu(), fps)
        os.system(
            f"ffmpeg -loglevel quiet -y -i {silent_video_path} -i {wav_path} -shortest {output_path}"
        )
        os.remove(silent_video_path)

印象里就这两个文件,当然如果你装的gpu版本的torch,不需要改代码。 效果图,说的是你好,你会写代码吗

        总结来说,跑一个开源项目还是不太容易的,这还是不用写代码的情况,特别是第一次,之前什么都没装,跑起来可是真麻烦,我一度怀疑能跑起来,好在没放弃,搞了两天终于搞出来,记录一下,有需要的朋友可以参考一下,有什么问题也可以随时给我留言。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

酷开科技OTT大屏营销:开启新时代的营销革命

随着互联网技术的不断发展和普及,大屏已经成为越来越多家庭选择的娱乐方式。在这个背景下,酷开科技凭借其强大的技术实力和敏锐的市场洞察力,成功地将大屏转化为一种新的营销渠道,为品牌和企业带来了前所未有的商业机会。 酷开科技…

WEB3.0:互联网的下一阶段

随着互联网的发展,WEB3.0时代正在逐步到来。本文将深入探讨WEB3.0的定义、特点、技术应用以及未来展望,为读者带来全新的思考。 一、什么是WEB3.0? WEB3.0可以被理解为互联网发展的下一阶段,是当前WEB2.0的升级版。相较于2.0时代…

CentOS 各个版本下载地址

https://mirror.nsc.liu.se/centos-store/7.6.1810/isos/x86_64/ CentOS-7-x86_64-DVD-1810.iso 2018-Nov-26 00:55:20 4.2G application/octet-stream 正常版 CentOS-7-x86_64-DVD-1810.torrent 2018-Dec-03 16:03:27 85.9K application/x-bittorrent CentOS-7-x86_64-Every…

用户系统加密--Java

一个基本的用户系统如下: # 定义用户类 class User:def __init__(self, name, password):self.name nameself.password password# 创建用户列表 users []# 添加新用户 def add_user(name, password):new_user User(name, password)users.append(new_user)print…

洛谷-P1596 [USACO10OCT] Lake Counting S

P1596 [USACO10OCT] Lake Counting S - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) #include<bits/stdc.h> using namespace std; const int N110; int m,n; char g[N][N]; bool st[N][N]; //走/没走 int dx[] {-1,-1,-1,0,0,1,1,1}; //八联通 int dy[] {-1,0,1,1,-1,1…

LDF、DBC、BIN、HEX、S19、BLF、ARXML、slx等

文章目录 如题 如题 LDF是LIN报文格式文件&#xff0c;把这个直接拖到软件里面&#xff0c;可以发报文和接收报文 DBC是CAN报文格式文件&#xff0c;把这个直接拖到软件里面&#xff0c;可以发报文和接收报文 BIN文件烧录在BOOT里面&#xff08;stm32&#xff09;&#xff0c…

【前端】解决前端图表大数据配色难题:利用HSL动态生成颜色方案

解决前端图表大数据配色难题&#xff1a;利用HSL动态生成颜色方案 在数据可视化项目中&#xff0c;尤其是当需要绘制包含大量数据点的图表时&#xff0c;一个常见的挑战是如何为每个数据点分配一个独特而又视觉上容易区分的颜色。使用固定的颜色列表可能在数据点数量超过列表限…

CTF-SHOW SSRF

web351 存在一个flag.php页面&#xff0c;访问会返回不是本地用户的消息&#xff0c;那肯定是要让我们以本地用户去访问127.0.0.1/flag.php web352 代码中先判断是否为HTTP或https协议&#xff0c;之后判断我们传入的url中是否含有localhost和127.0.0&#xff0c;如果没有则…

课时93:流程控制_函数进阶_综合练习

1.1.3 综合练习 学习目标 这一节&#xff0c;我们从 案例解读、脚本实践、小结 三个方面来学习。 案例解读 案例需求 使用shell脚本绘制一个杨辉三角案例解读 1、每行数字左右对称&#xff0c;从1开始变大&#xff0c;然后变小为1。    2、第n行的数字个数为n个&#xf…

Golang | Leetcode Golang题解之第24题两两交换链表中的节点

题目&#xff1a; 题解&#xff1a; func swapPairs(head *ListNode) *ListNode {dummyHead : &ListNode{0, head}temp : dummyHeadfor temp.Next ! nil && temp.Next.Next ! nil {node1 : temp.Nextnode2 : temp.Next.Nexttemp.Next node2node1.Next node2.Nex…

项目实训2024.04.12日志:Self-QA生成问答对

1. Self-QA技术 1.1. 为什么要用Self-QA技术 关于为什么要搜集问答对&#xff0c;我在创新实训2024.04.07日志&#xff1a;提取QA对这篇文章中提到过&#xff1a;训练大模型需要从业务侧积累的问题、资料、文档中提取出一些指令-问答对作为输入的语料。 之前我们对于问答对的…

ChatGPT加持,需求分析再无难题

简介 在实际工作过程中&#xff0c;常常需要拿到产品的PRD文档或者原型图进行需求分析&#xff0c;为产品的功能设计和优化提供建议。 而使用ChatGPT可以很好的帮助分析和整理用户需求。 实践演练 接下来&#xff0c;需要使用ChatGPT 辅助我们完成需求分析的任务 注意&…

【编程】C++ 常用容器以及一些应用案例

介绍一些我常用的C容器和使用方法&#xff0c;以及使用案例。blog 1 概述 容器&#xff08;Container&#xff09;是一个存储其他对象集合的持有者对象。容器以类模板实现&#xff0c;对支持的元素类型有很大的灵活性。容器管理元素的存储并提供多个成员函数来访问和操作元素…

鸿蒙OS开发学习:【第三方库调用】

介绍 本篇Codelab主要向开发者展示了在Stage模型中&#xff0c;如何调用已经上架到[三方库中心]的社区库和项目内创建的本地库。效果图如下&#xff1a; 相关概念 [Navigation]&#xff1a;一般作为Page页面的根容器&#xff0c;通过属性设置来展示页面的标题、工具栏、菜单。…

OpenHarmony编译构建系统

这篇来聊聊OpenHarmony的编译构建&#xff0c;经过前面的实践&#xff0c;再来看编译构建。 编译构建概述 在官网中提到了&#xff0c;OpenHarmony编译子系统是以GN和Ninja构建为基座&#xff0c;对构建和配置粒度进行部件化抽象、对内建模块进行功能增强、对业务模块进行功能…

二叉树-数据结构

二叉树-数据结构 二叉树是属性结构的一个重要类型。 如下图二叉树形状 二叉树特征如下&#xff1a; 1.二叉树由 n(n > 0) 个节点组成 2.如果 n 为 0&#xff0c;则为空树 3.如果 n 1&#xff0c;则只有一个节点称为根节点(root) 4.每个节点最多有两个节点&#xff0c;节…

【题目】【信息安全管理与评估】2022年国赛高职组“信息安全管理与评估”赛项样题2

【题目】【信息安全管理与评估】2022年国赛高职组“信息安全管理与评估”赛项样题2 信息安全管理与评估 网络系统管理 网络搭建与应用 云计算 软件测试 移动应用开发 任务书&#xff0c;赛题&#xff0c;解析等资料&#xff0c;知识点培训服务 添加博主wx&#xff1a;liuliu548…

【b站李同学的Lee】3 Github【gitgithub】入门教程,必学!

课程地址&#xff1a;【【git&github】入门教程&#xff0c;必学&#xff01;】 https://www.bilibili.com/video/BV1cE411G7yc/?share_sourcecopy_web&vd_sourceb1cb921b73fe3808550eaf2224d1c155 目录 3 Github 3.1 注册 3.2 多人协作开发流程 3.2.1 远程仓库 …

MYSQL5.7详细安装步骤

MYSQL5.7详细安装步骤&#xff1a; 0、更换yum源 1、打开 mirrors.aliyun.com&#xff0c;选择centos的系统&#xff0c;点击帮助 2、执行命令&#xff1a;yum install wget -y 3、改变某些文件的名称 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base…

windows系统电脑弹窗“试图引用不存在令牌“如何解决?

windows系统电脑,弹出提示:试图引用不存在令牌,应该如何解决? 以管理员身份执行以下命令:(等命令执行完成即可修复该问题) cd C:\WINDOWS\system32 for /f %s in (dir /b *.dll) do regsvr32 /s %s 命令行解释: 这行代码是一个Windows命令提示符(cmd)命令。它使用一…