Files
Kerry 4b731ff98b 1.0.0 Float_Animator
Float project applicable to ComfyUI.Generates speaking portrait video frames from an image and audio.适用于ComfyUI的强大[FLOAT]项目,实现由肖像生成音频驱动的说话视频。
2025-05-28 15:16:33 +08:00

447 lines
15 KiB
Python

import torch
import torch.nn as nn
import torch.nn.functional as F
from transformers import Wav2Vec2Config, Wav2Vec2Model
from transformers.modeling_outputs import BaseModelOutput
from torch import Tensor
from typing import Type, Any, Callable, Union, List, Optional
class BaseModel(torch.nn.Module):
def __init__(self):
super().__init__()
def print_architecture(self, verbose=False):
name = type(self).__name__
result = '-------------------%s---------------------\n' % name
total_num_params = 0
for i, (name, child) in enumerate(self.named_children()):
if 'loss' in name:
continue
num_params = sum([p.numel() for p in child.parameters()])
total_num_params += num_params
if verbose:
result += "%s: %3.3fM\n" % (name, (num_params / 1e6))
for i, (name, grandchild) in enumerate(child.named_children()):
num_params = sum([p.numel() for p in grandchild.parameters()])
if verbose:
result += "\t%s: %3.3fM\n" % (name, (num_params / 1e6))
result += '[Network %s] Total number of parameters : %.3f M\n' % (name, total_num_params / 1e6)
result += '-----------------------------------------------\n'
print(result)
def set_requires_grad(self, requires_grad):
for param in self.parameters():
param.requires_grad = requires_grad
def get_parameters_for_train(self):
return self.parameters()
def forward(self):
raise NotImplementedError()
# def linear_interpolation(features, seq_len):
# features = features.transpose(1, 2)
# output_features = F.interpolate(features, size=seq_len, align_corners=True, mode='linear')
# return output_features.transpose(1, 2)
# class Wav2Vec2Model(Wav2Vec2Model):
# def __init__(self, config: Wav2Vec2Config):
# super().__init__(config)
# def forward(
# self,
# input_values,
# seq_len,
# attention_mask=None,
# mask_time_indices=None,
# output_attentions=None,
# output_hidden_states=None,
# return_dict=None,
# ):
# self.config.output_attentions = True
# output_hidden_states = (
# output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
# )
# return_dict = return_dict if return_dict is not None else self.config.use_return_dict
# extract_features = self.feature_extractor(input_values)
# extract_features = extract_features.transpose(1, 2)
# extract_features = linear_interpolation(extract_features, seq_len=seq_len)
# if attention_mask is not None:
# # compute reduced attention_mask corresponding to feature vectors
# attention_mask = self._get_feature_vector_attention_mask(
# extract_features.shape[1], attention_mask, add_adapter=False
# )
# hidden_states, extract_features = self.feature_projection(extract_features)
# hidden_states = self._mask_hidden_states(
# hidden_states, mask_time_indices=mask_time_indices, attention_mask=attention_mask
# )
# encoder_outputs = self.encoder(
# hidden_states,
# attention_mask=attention_mask,
# output_attentions=output_attentions,
# output_hidden_states=output_hidden_states,
# return_dict=return_dict,
# )
# hidden_states = encoder_outputs[0]
# if self.adapter is not None:
# hidden_states = self.adapter(hidden_states)
# if not return_dict:
# return (hidden_states, ) + encoder_outputs[1:]
# return BaseModelOutput(
# last_hidden_state=hidden_states,
# hidden_states=encoder_outputs.hidden_states,
# attentions=encoder_outputs.attentions,
# )
# def feature_extract(
# self,
# input_values,
# seq_len,
# ):
# extract_features = self.feature_extractor(input_values)
# extract_features = extract_features.transpose(1, 2)
# extract_features = linear_interpolation(extract_features, seq_len=seq_len)
# return extract_features
# def encode(
# self,
# extract_features,
# attention_mask=None,
# mask_time_indices=None,
# output_attentions=None,
# output_hidden_states=None,
# return_dict=None,
# ):
# self.config.output_attentions = True
# output_hidden_states = (
# output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
# )
# return_dict = return_dict if return_dict is not None else self.config.use_return_dict
# if attention_mask is not None:
# # compute reduced attention_mask corresponding to feature vectors
# attention_mask = self._get_feature_vector_attention_mask(
# extract_features.shape[1], attention_mask, add_adapter=False
# )
# hidden_states, extract_features = self.feature_projection(extract_features)
# hidden_states = self._mask_hidden_states(
# hidden_states, mask_time_indices=mask_time_indices, attention_mask=attention_mask
# )
# encoder_outputs = self.encoder(
# hidden_states,
# attention_mask=attention_mask,
# output_attentions=output_attentions,
# output_hidden_states=output_hidden_states,
# return_dict=return_dict,
# )
# hidden_states = encoder_outputs[0]
# if self.adapter is not None:
# hidden_states = self.adapter(hidden_states)
# if not return_dict:
# return (hidden_states, ) + encoder_outputs[1:]
# return BaseModelOutput(
# last_hidden_state=hidden_states,
# hidden_states=encoder_outputs.hidden_states,
# attentions=encoder_outputs.attentions,
# )
def conv3x3(in_planes, out_planes, stride=1):
return nn.Conv2d(in_planes, out_planes, kernel_size=3, stride=stride, padding=1, bias=False)
def conv1x1(in_planes: int, out_planes: int, stride: int = 1) -> nn.Conv2d:
return nn.Conv2d(in_planes, out_planes, kernel_size=1, stride=stride, bias=False)
class SELayer(nn.Module):
def __init__(self, channel, reduction=16):
super(SELayer, self).__init__()
self.avg_pool = nn.AdaptiveAvgPool2d(1)
self.fc = nn.Sequential(
nn.Linear(channel, channel // reduction, bias=False),
nn.ReLU(inplace=True),
nn.Linear(channel // reduction, channel, bias=False),
nn.Sigmoid()
)
def forward(self, x):
b, c, _, _ = x.size()
y = self.avg_pool(x).view(b, c)
y = self.fc(y).view(b, c, 1, 1)
return x * y.expand_as(x)
class SEBasicBlock(nn.Module):
expansion = 1
def __init__(self, inplanes, planes, stride=1, downsample=None, groups=1,
base_width=64, dilation=1, norm_layer=None,
*, reduction=16):
super(SEBasicBlock, self).__init__()
if norm_layer is None:
norm_layer = nn.BatchNorm2d
self.conv1 = conv3x3(inplanes, planes, stride)
self.bn1 = norm_layer(planes)
self.relu = nn.ReLU(inplace=True)
self.conv2 = conv3x3(planes, planes, 1)
self.bn2 = norm_layer(planes)
self.se = SELayer(planes, reduction)
self.downsample = downsample
self.stride = stride
def forward(self, x):
residual = x
out = self.conv1(x)
out = self.bn1(out)
out = self.relu(out)
out = self.conv2(out)
out = self.bn2(out)
out = self.se(out)
if self.downsample is not None:
residual = self.downsample(x)
out += residual
out = self.relu(out)
return out
class SEBottleneck(nn.Module):
expansion = 4
def __init__(self, inplanes, planes, stride=1, downsample=None, groups=1,
base_width=64, dilation=1, norm_layer=None,
*, reduction=16):
super(SEBottleneck, self).__init__()
if norm_layer is None:
norm_layer= nn.BatchNorm2d
self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=1, bias=False)
self.bn1 = norm_layer(planes)
self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=stride, padding=1, bias=False)
self.bn2 = norm_layer(planes)
self.conv3 = nn.Conv2d(planes, planes * 4, kernel_size=1, bias=False)
self.bn3 = norm_layer(planes * 4)
self.relu = nn.ReLU(inplace=True)
self.se = SELayer(planes * 4, reduction)
self.downsample = downsample
self.stride = stride
def forward(self, x):
residual = x
out = self.conv1(x)
out = self.bn1(out)
out = self.relu(out)
out = self.conv2(out)
out = self.bn2(out)
out = self.relu(out)
out = self.conv3(out)
out = self.bn3(out)
out = self.se(out)
if self.downsample is not None:
residual = self.downsample(x)
out += residual
out = self.relu(out)
return out
class ResNet(nn.Module):
def __init__(
self,
block: Type[Union[SEBasicBlock, SEBottleneck]],
layers: List[int],
num_classes: int = 1000,
zero_init_residual: bool = False,
groups: int = 1,
width_per_group: int = 64,
replace_stride_with_dilation: Optional[List[bool]] = None,
norm_layer: Optional[Callable[..., nn.Module]] = None,
) -> None:
super().__init__()
if norm_layer is None:
norm_layer = nn.BatchNorm2d
self._norm_layer = norm_layer
self.inplanes = 64
self.dilation = 1
if replace_stride_with_dilation is None:
# each element in the tuple indicates if we should replace
# the 2x2 stride with a dilated convolution instead
replace_stride_with_dilation = [False, False, False]
if len(replace_stride_with_dilation) != 3:
raise ValueError(
"replace_stride_with_dilation should be None "
f"or a 3-element tuple, got {replace_stride_with_dilation}"
)
self.groups = groups
self.base_width = width_per_group
self.stem = nn.Sequential(
nn.Conv2d(3, self.inplanes, kernel_size=7, stride=2, padding=3, bias=False),
norm_layer(self.inplanes),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
)
self.layer1 = self._make_layer(block, 64, layers[0])
self.layer2 = self._make_layer(block, 128, layers[1], stride=2, dilate=replace_stride_with_dilation[0])
self.layer3 = self._make_layer(block, 256, layers[2], stride=2, dilate=replace_stride_with_dilation[1])
self.layer4 = self._make_layer(block, 512, layers[3], stride=2, dilate=replace_stride_with_dilation[2])
self.fc = nn.Sequential(
nn.AdaptiveAvgPool2d((1, 1)),
nn.Flatten(),
nn.Linear(512 * block.expansion, num_classes)
)
for m in self.modules():
if isinstance(m, nn.Conv2d):
nn.init.kaiming_normal_(m.weight, mode="fan_out", nonlinearity="relu")
elif isinstance(m, (nn.BatchNorm2d, nn.GroupNorm)):
nn.init.constant_(m.weight, 1)
nn.init.constant_(m.bias, 0)
# Zero-initialize the last BN in each residual branch,
# so that the residual branch starts with zeros, and each residual block behaves like an identity.
# This improves the model by 0.2~0.3% according to https://arxiv.org/abs/1706.02677
if zero_init_residual:
for m in self.modules():
if isinstance(m, SEBottleneck):
nn.init.constant_(m.bn3.weight, 0) # type: ignore[arg-type]
elif isinstance(m, SEBasicBlock):
nn.init.constant_(m.bn2.weight, 0) # type: ignore[arg-type]
def _make_layer(
self,
block: Type[Union[SEBasicBlock, SEBottleneck]],
planes: int,
blocks: int,
stride: int = 1,
dilate: bool = False,
) -> nn.Sequential:
norm_layer = self._norm_layer
downsample = None
previous_dilation = self.dilation
if dilate:
self.dilation *= stride
stride = 1
if stride != 1 or self.inplanes != planes * block.expansion:
downsample = nn.Sequential(
conv1x1(self.inplanes, planes * block.expansion, stride),
norm_layer(planes * block.expansion),
)
layers = []
layers.append(
block(
self.inplanes, planes, stride, downsample, self.groups, self.base_width, previous_dilation, norm_layer
)
)
self.inplanes = planes * block.expansion
for _ in range(1, blocks):
layers.append(
block(
self.inplanes,
planes,
groups=self.groups,
base_width=self.base_width,
dilation=self.dilation,
norm_layer=norm_layer,
)
)
return nn.Sequential(*layers)
def _forward_impl(self, x: Tensor) -> Tensor:
x = self.stem(x)
x = self.layer1(x)
x = self.layer2(x)
x = self.layer3(x)
x = self.layer4(x)
x = self.fc(x)
return x
def forward(self, x: Tensor) -> Tensor:
return self._forward_impl(x)
def se_resnet18(num_classes=1000, norm_layer=None):
"""Constructs a ResNet-18 model.
Args:
pretrained (bool): If True, returns a model pre-trained on ImageNet
"""
model = ResNet(SEBasicBlock, [2, 2, 2, 2], num_classes=num_classes, norm_layer=norm_layer)
return model
def se_resnet34(num_classes=1000, norm_layer=None):
"""Constructs a ResNet-34 model.
Args:
pretrained (bool): If True, returns a model pre-trained on ImageNet
"""
model = ResNet(SEBasicBlock, [3, 4, 6, 3], num_classes=num_classes, norm_layer=norm_layer)
return model
def se_resnet50(num_classes=1000, pretrained=False):
"""Constructs a ResNet-50 model.
Args:
pretrained (bool): If True, returns a model pre-trained on ImageNet
"""
model = ResNet(SEBottleneck, [3, 4, 6, 3], num_classes=num_classes)
return model
def se_resnet101(num_classes=1000):
"""Constructs a ResNet-101 model.
Args:
pretrained (bool): If True, returns a model pre-trained on ImageNet
"""
model = ResNet(SEBottleneck, [3, 4, 23, 3], num_classes=num_classes)
return model
def se_resnet152(num_classes=1000):
"""Constructs a ResNet-152 model.
Args:
pretrained (bool): If True, returns a model pre-trained on ImageNet
"""
model = ResNet(SEBottleneck, [3, 8, 36, 3], num_classes=num_classes)
return model