Files
vllm-omni/vllm_omni/model_executor/models/indextts2/codec/vocos.py
T
2026-08-11 23:00:35 +00:00

83 lines
2.3 KiB
Python

# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: Copyright contributors to the Amphion project
"""ConvNeXt Vocos backbone used by the IndexTTS 2.5 codec decoder."""
from __future__ import annotations
import torch
import torch.nn as nn
class ConvNeXtBlock(nn.Module):
def __init__(
self,
*,
dim: int,
intermediate_dim: int,
layer_scale_init_value: float,
):
super().__init__()
self.dwconv = nn.Conv1d(
dim,
dim,
kernel_size=7,
padding=3,
groups=dim,
)
self.norm = nn.LayerNorm(dim, eps=1e-6)
self.pwconv1 = nn.Linear(dim, intermediate_dim)
self.act = nn.GELU()
self.pwconv2 = nn.Linear(intermediate_dim, dim)
self.gamma = nn.Parameter(
layer_scale_init_value * torch.ones(dim),
requires_grad=True,
)
def forward(self, inputs: torch.Tensor) -> torch.Tensor:
residual = inputs
hidden = self.dwconv(inputs).transpose(1, 2)
hidden = self.norm(hidden)
hidden = self.pwconv1(hidden)
hidden = self.act(hidden)
hidden = self.pwconv2(hidden)
hidden = self.gamma * hidden
return residual + hidden.transpose(1, 2)
class VocosBackbone(nn.Module):
def __init__(
self,
*,
input_channels: int,
dim: int,
intermediate_dim: int,
num_layers: int,
):
super().__init__()
self.embed = nn.Conv1d(
input_channels,
dim,
kernel_size=7,
padding=3,
)
self.norm = nn.LayerNorm(dim, eps=1e-6)
layer_scale = 1 / num_layers
self.convnext = nn.ModuleList(
[
ConvNeXtBlock(
dim=dim,
intermediate_dim=intermediate_dim,
layer_scale_init_value=layer_scale,
)
for _ in range(num_layers)
]
)
self.final_layer_norm = nn.LayerNorm(dim, eps=1e-6)
def forward(self, inputs: torch.Tensor) -> torch.Tensor:
hidden = self.embed(inputs)
hidden = self.norm(hidden.transpose(1, 2)).transpose(1, 2)
for block in self.convnext:
hidden = block(hidden)
return self.final_layer_norm(hidden.transpose(1, 2))