Files
wehub-resource-sync 94057c3d3e
PR Test (NPU) / check-changes (push) Has been cancelled
PR Test (NPU) / pr-gate (push) Has been cancelled
PR Test (NPU) / set-image-config (push) Has been cancelled
PR Test (NPU) / stage-b-test-1-npu-a2 (0) (push) Has been cancelled
PR Test (NPU) / stage-b-test-1-npu-a2 (1) (push) Has been cancelled
PR Test (NPU) / stage-b-test-2-npu-a2 (0) (push) Has been cancelled
PR Test (NPU) / stage-b-test-2-npu-a2 (1) (push) Has been cancelled
PR Test (NPU) / stage-b-test-4-npu-a3 (push) Has been cancelled
PR Test (NPU) / stage-b-test-16-npu-a3 (push) Has been cancelled
PR Test (NPU) / multimodal-gen-test-1-npu-a3 (push) Has been cancelled
PR Test (NPU) / multimodal-gen-test-2-npu-a3 (push) Has been cancelled
PR Test (Arm64) / pr-gate (push) Has been cancelled
PR Test (Arm64) / check-changes (push) Has been cancelled
PR Test (Arm64) / build-test (push) Has been cancelled
PR Test (sgl-router) / gate (push) Has been cancelled
PR Test (sgl-router) / tier-1 — lint (push) Has been cancelled
PR Test (sgl-router) / tier-2 — build + test (push) Has been cancelled
PR Test (sgl-router) / tier-3 — docker (placeholder) (push) Has been cancelled
PR Test (sgl-router) / tier-3 — k8s integration (push) Has been cancelled
PR Test (sgl-router) / tier-3 — e2e (push) Has been cancelled
PR Test (sgl-router) / finish (push) Has been cancelled
PR Test (NPU) / single-node-poc (map[name:qwen3_6_27b_w8a8_1p_in64k_out1k_50ms runner:linux-aarch64-a3-2 test_case:test/registered/ascend/performance/qwen3_6_27b/test_npu_qwen3_6_27b_w8a8_1p_in64k_out1k_50ms.py test_type:perf]) (push) Has been cancelled
PR Test (NPU) / pr-test-npu-finish (push) Has been cancelled
PR Test (Xeon) / pr-gate (push) Has been cancelled
PR Test (Xeon) / check-changes (push) Has been cancelled
PR Test (Xeon) / build-test (, xeon-gnr, base-b-test-cpu) (push) Has been cancelled
PR Test (XPU) / check-changes (push) Has been cancelled
PR Test (XPU) / pr-gate (push) Has been cancelled
PR Test (XPU) / stage-a-test-1-gpu-xpu (push) Has been cancelled
PR Test (XPU) / wait-for-stage-a (push) Has been cancelled
PR Test (XPU) / stage-b-test-1-gpu-xpu (push) Has been cancelled
PR Test (XPU) / finish (push) Has been cancelled
CI Model Inventory / build-inventory (push) Has been cancelled
Lint / lint (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark Compilation Check (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark - Manual Policy (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark - Request Processing (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark Summary (push) Has been cancelled
PR Test (SMG) / build-wheel (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on windows (x86_64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on macos (x86_64 - auto) (push) Has been cancelled
PR Test (SMG) / python-unit-tests (push) Has been cancelled
PR Test (SMG) / unit-tests (push) Has been cancelled
PR Test (SMG) / benchmarks (push) Has been cancelled
PR Test (SMG) / chat-completions (push) Has been cancelled
PR Test (SMG) / chat-completions-4gpu (push) Has been cancelled
PR Test (SMG) / e2e (push) Has been cancelled
PR Test (SMG) / docker-build-test (push) Has been cancelled
PR Test (SMG) / k8s-integration (push) Has been cancelled
PR Test (SMG) / finish (push) Has been cancelled
PR Test (SMG) / summarize-benchmarks (push) Has been cancelled
Release SGLang Model Gateway Docker Image / publish (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on macos (aarch64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (aarch64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (x86_64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (aarch64 - musllinux_1_1) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (x86_64 - musllinux_1_1) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / Build SDist (push) Has been cancelled
Release SGLang Model Gateway to PyPI / Upload to PyPI (push) Has been cancelled
Release SGLang Kernels / build-cu129-matrix (aarch64, 12.9, 3.10, arm-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / build-cu129-matrix (x86_64, 12.9, 3.10, x64-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / release-cu129 (push) Has been cancelled
Release SGLang Kernels / build-cu130-matrix (aarch64, 13.0, 3.10, arm-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / build-cu130-matrix (x86_64, 13.0, 3.10, x64-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / release-cu130 (push) Has been cancelled
Release SGLang Kernels / build-rocm-matrix (3.10, 700) (push) Has been cancelled
Release SGLang Kernels / build-rocm-matrix (3.10, 720) (push) Has been cancelled
Release SGLang Kernels / release-rocm700 (push) Has been cancelled
Release SGLang Kernels / release-rocm720 (push) Has been cancelled
Release SGLang Kernels / build-musa43 (43, 3.10) (push) Has been cancelled
Release SGLang Kernels / release-musa43 (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:38:16 +08:00

700 lines
25 KiB
Python

import collections
import collections.abc
import logging
from collections.abc import Callable, Sequence
from typing import Iterable, List, Optional, Tuple, TypeAlias, cast
import torch
import torch.nn as nn
import torchaudio.functional as F
from transformers import PretrainedConfig
from sglang.srt.layers.attention.vision import VisionAttention
from sglang.srt.layers.conv import Conv2dLayer
from sglang.srt.layers.linear import ColumnParallelLinear, RowParallelLinear
from sglang.srt.layers.quantization.base_config import QuantizationConfig
from sglang.srt.managers.mm_utils import (
MultiModalityDataPaddingPatternMultimodalTokens,
general_mm_embed_routine,
)
from sglang.srt.managers.schedule_batch import (
Modality,
MultimodalDataItem,
MultimodalInputs,
)
from sglang.srt.model_executor.forward_batch_info import ForwardBatch
from sglang.srt.model_loader.weight_utils import default_weight_loader
from sglang.srt.models.qwen2 import Qwen2ForCausalLM
from sglang.srt.utils import add_prefix
logger = logging.getLogger(__name__)
_Tuple2: TypeAlias = int | tuple[int, int] | Sequence[int]
def _resolve_tuple2(x: _Tuple2) -> tuple[int, int]:
if isinstance(x, collections.abc.Sequence):
assert (
len(x) == 2
), f"Expected a sequence of length 2, got {x} with length {len(x)}"
return cast(tuple[int, int], tuple(x))
return (x, x)
def calculate_mel_frames_dasheng(
audio_length_samples: int,
n_fft: int = 512,
hop_size: int = 160,
dasheng_subsampling: int = 4,
center=True,
model_subsampling: int = 5,
) -> int:
"""Calculate the number of Mel-spectrogram frames."""
if center:
audio_length_samples = audio_length_samples + n_fft
return (
int(1 + ((audio_length_samples - n_fft) / hop_size))
// dasheng_subsampling
// model_subsampling
)
class AudioPatchEmbed(nn.Module):
def __init__(
self,
input_size: _Tuple2 = 64,
patch_size: _Tuple2 = 16,
patch_stride: _Tuple2 = 16,
in_chans: int = 1,
embed_dim: int = 768,
norm_layer: Callable | None = None,
flatten: bool = False,
):
super().__init__()
self.input_size = _resolve_tuple2(input_size)
self.patch_size = _resolve_tuple2(patch_size)
self.patch_stride = _resolve_tuple2(patch_stride)
self.grid_size = (
self.input_size[0] // self.patch_stride[0],
self.input_size[1] // self.patch_stride[1],
)
self.num_patches = self.grid_size[0] * self.grid_size[1]
self.flatten = flatten
self.proj = Conv2dLayer(
in_chans,
embed_dim,
kernel_size=self.patch_size,
stride=self.patch_stride,
)
self.norm = norm_layer(embed_dim) if norm_layer else nn.Identity()
def forward(self, x: torch.Tensor) -> torch.Tensor:
x = self.proj(x)
if self.flatten:
x = torch.permute(torch.flatten(x, 2, 3), (0, 2, 1))
x = self.norm(x)
return x
class LayerScale(nn.Module):
def __init__(self, dim, init_values=1e-5, inplace=False):
super().__init__()
self.inplace = inplace
self.gamma = nn.Parameter(init_values * torch.ones(dim))
def forward(self, x: torch.Tensor) -> torch.Tensor:
return x.mul_(self.gamma) if self.inplace else x * self.gamma
class DashengMlp(nn.Module):
def __init__(
self,
in_features: int,
hidden_features: int | None = None,
out_features: int | None = None,
quant_config: Optional[QuantizationConfig] = None,
prefix: str = "",
):
super().__init__()
out_features = out_features or in_features
hidden_features = hidden_features or in_features
self.fc1 = ColumnParallelLinear(
input_size=in_features,
output_size=hidden_features,
bias=True,
quant_config=quant_config,
prefix=add_prefix("fc1", prefix),
)
self.act = nn.GELU()
self.fc2 = RowParallelLinear(
input_size=hidden_features,
output_size=out_features,
bias=True,
quant_config=quant_config,
prefix=add_prefix("fc2", prefix),
)
def forward(self, x: torch.Tensor) -> torch.Tensor:
x, _ = self.fc1(x)
x = self.act(x)
x, _ = self.fc2(x)
return x
class DashengAttention(nn.Module):
"""Audio encoder attention using VisionAttention for compatibility."""
def __init__(
self,
dim: int,
num_heads: int = 8,
qkv_bias: bool = False,
quant_config: Optional[QuantizationConfig] = None,
prefix: str = "",
):
super().__init__()
assert dim % num_heads == 0, "dim should be divisible by num_heads"
self.embed_dim = dim
self.num_heads = num_heads
self.head_dim = self.embed_dim // self.num_heads
self.scale = self.head_dim**-0.5
self.attn = VisionAttention(
embed_dim=dim,
num_heads=num_heads,
projection_size=dim,
use_qkv_parallel=True,
proj_bias=True,
qkv_bias=qkv_bias,
qkv_backend="sdpa",
softmax_in_single_precision=False,
flatten_batch=False,
quant_config=quant_config,
prefix=prefix,
)
def forward(self, x: torch.Tensor, mask: torch.Tensor | None = None):
"""
Args:
x: [B, N, C] tensor
mask: [B, N] boolean mask
"""
attn_mask = None
if mask is not None:
attn_mask = mask.unsqueeze(1).unsqueeze(2) # [B, 1, 1, N]
attn_mask = attn_mask.float()
attn_mask = (1.0 - attn_mask) * -10000.0
x = self.attn(x, attn_mask=attn_mask)
return x
class DashengBlock(nn.Module):
def __init__(
self,
dim: int,
num_heads: int,
mlp_ratio: float = 4.0,
qkv_bias: bool = False,
init_values: float | None = None,
quant_config: Optional[QuantizationConfig] = None,
prefix: str = "",
):
super().__init__()
self.norm1 = nn.LayerNorm(dim, eps=1e-6)
self.attn = DashengAttention(
dim,
num_heads=num_heads,
qkv_bias=qkv_bias,
quant_config=quant_config,
prefix=add_prefix("attn", prefix),
)
self.ls1 = (
LayerScale(dim, init_values=init_values) if init_values else nn.Identity()
)
self.norm2 = nn.LayerNorm(dim, eps=1e-6)
self.mlp = DashengMlp(
in_features=dim,
hidden_features=int(dim * mlp_ratio),
quant_config=quant_config,
prefix=add_prefix("mlp", prefix),
)
self.ls2 = (
LayerScale(dim, init_values=init_values) if init_values else nn.Identity()
)
def forward(
self,
x: torch.Tensor,
mask: torch.Tensor | None = None,
) -> torch.Tensor:
x = x + self.ls1(self.attn(self.norm1(x), mask))
x = x + self.ls2(self.mlp(self.norm2(x)))
return x
class DashengFrontend(nn.Module):
"""Audio frontend that converts waveforms to log mel-spectrograms."""
def __init__(self, config: PretrainedConfig):
super().__init__()
self.n_fft = config.n_fft
self.hop_length = config.hop_length
self.win_length = config.win_length
self.center = config.center
spectrogram_window = torch.hann_window(config.win_length)
self.register_buffer(
"spectrogram_window",
spectrogram_window,
persistent=False,
)
self.spectrogram_window: torch.Tensor
melscale_fbanks = F.melscale_fbanks(
n_freqs=config.n_fft // 2 + 1,
f_min=config.f_min,
f_max=config.f_max,
n_mels=config.n_mels,
sample_rate=config.sample_rate,
)
self.register_buffer("melscale_fbanks", melscale_fbanks, persistent=False)
self.melscale_fbanks: torch.Tensor
def forward(self, waveform: torch.Tensor) -> torch.Tensor:
"""Convert waveform to log mel-spectrogram.
Args:
waveform: [B, T] tensor of audio samples
Returns:
log_mel_spectrogram: [B, n_mels, time] tensor
"""
spectrogram = F.spectrogram(
waveform=waveform.to(torch.float32),
pad=0,
window=self.spectrogram_window,
n_fft=self.n_fft,
hop_length=self.hop_length,
win_length=self.win_length,
power=2,
normalized=False,
center=self.center,
)
mel_spectrogram = (spectrogram.mT @ self.melscale_fbanks.to(torch.float32)).mT
log_mel_spectrogram = F.amplitude_to_DB(
mel_spectrogram.unsqueeze(1),
multiplier=10,
amin=1e-10,
db_multiplier=0,
top_db=120,
).squeeze(1)
return log_mel_spectrogram.to(waveform.dtype)
class DashengAudioTransformer(nn.Module):
"""Audio encoder transformer."""
def __init__(
self,
config: PretrainedConfig,
quant_config: Optional[QuantizationConfig] = None,
prefix: str = "",
):
super().__init__()
self.target_length = config.target_length
self.hop_length = config.hop_length
self.front_end = DashengFrontend(config)
self.init_bn = nn.BatchNorm2d(config.n_mels, momentum=0.01)
self.patch_embed = AudioPatchEmbed(
input_size=(config.n_mels, config.target_length),
embed_dim=config.embed_dim,
in_chans=config.input_channels,
patch_size=config.patch_size,
flatten=False,
patch_stride=config.patch_stride,
)
self.time_pos_embed = nn.Parameter(
torch.empty(1, config.embed_dim, 1, self.patch_embed.grid_size[1])
)
self.freq_pos_embed = nn.Parameter(
torch.empty(1, config.embed_dim, self.patch_embed.grid_size[0], 1)
)
self.blocks = nn.ModuleList(
DashengBlock(
dim=config.embed_dim,
num_heads=config.num_heads,
mlp_ratio=config.mlp_ratio,
qkv_bias=config.qkv_bias,
init_values=config.init_values,
quant_config=quant_config,
prefix=add_prefix(f"blocks.{i}", prefix),
)
for i in range(config.depth)
)
self.norm = nn.LayerNorm(config.embed_dim, eps=1e-6)
def forward_features(
self,
x: torch.Tensor,
mask: torch.Tensor | None = None,
) -> torch.Tensor:
t = x.shape[-1]
x = x + self.time_pos_embed[:, :, :, :t]
x = x + self.freq_pos_embed[:, :, :, :]
x = torch.permute(torch.flatten(x, 2, 3), (0, 2, 1))
for block in self.blocks:
x = block(x, mask)
x = self.norm(x)
return x
def _to_mask(self, lengths: torch.Tensor, max_length: int) -> torch.Tensor:
batch_size = len(lengths)
idx = torch.arange(max_length, device=lengths.device)
idx = idx.repeat(batch_size).view(batch_size, max_length)
mask = (idx < lengths.unsqueeze(-1)).bool()
return mask
def forward(
self,
x: torch.Tensor,
x_length: torch.Tensor | None = None,
) -> tuple[torch.Tensor, torch.Tensor | None]:
"""
Args:
x: [B, T] audio waveform tensor
x_length: [B] tensor of audio lengths
Returns:
x: [B, seq_len, embed_dim] encoded features
mask: [B, seq_len] mask tensor
"""
x = self.front_end(x)
x = x.to(self.time_pos_embed.dtype)
target_length_in_patches = self.target_length // 4
x = x.unsqueeze(1)
x = torch.permute(x, (0, 2, 1, 3))
x = self.init_bn(x)
x = torch.permute(x, (0, 2, 1, 3))
x = self.patch_embed(x)
t = x.shape[-1]
input_splits = x.split(target_length_in_patches, dim=-1)
if x_length is not None:
assert len(x_length) == len(
x
), "batchsizes of input x and x_length need to be same"
assert x_length.ndim == 1, "Lengths are of size (B,)"
scaled_lengths = (x_length / (self.hop_length * 4)).long()
mask = self._to_mask(max_length=t, lengths=scaled_lengths)
split_masks = mask.split(target_length_in_patches, dim=-1)
else:
mask = None
split_masks = [None] * len(input_splits)
outputs = []
for split_x, split_mask in zip(input_splits, split_masks):
forward_kwargs = {}
forward_kwargs["mask"] = split_mask
split_x = self.forward_features(split_x, **forward_kwargs)
outputs.append(split_x)
x = torch.cat(outputs, dim=1)
return x, mask
class AudioProjectorSubsample(nn.Module):
"""Audio projector with subsampling."""
def __init__(
self,
in_dim: int,
out_dim: int,
downsample_rate=5,
dtype: torch.dtype | None = None,
quant_config: Optional[QuantizationConfig] = None,
prefix: str = "",
):
super().__init__()
self.k = downsample_rate
self.fc1 = ColumnParallelLinear(
input_size=in_dim * self.k,
output_size=out_dim,
bias=False,
quant_config=quant_config,
prefix=add_prefix("net.0", prefix),
)
self.act = nn.GELU()
self.fc2 = RowParallelLinear(
input_size=out_dim,
output_size=out_dim,
bias=False,
quant_config=quant_config,
prefix=add_prefix("net.2", prefix),
)
def forward(self, x, mask=None):
batch_size, seq_len, dim = x.shape
num_frames_to_discard = seq_len % self.k
if num_frames_to_discard > 0:
x = x[:, :-num_frames_to_discard, :]
if mask is not None:
mask = mask[:, :-num_frames_to_discard]
if mask is None:
mask = torch.ones(x.shape[:-1], dtype=torch.long, device=x.device)
x = x.reshape(batch_size, -1, self.k * dim)
x, _ = self.fc1(x)
x = self.act(x)
x, _ = self.fc2(x)
mask = mask.reshape(batch_size, -1, self.k)
mask = mask.any(dim=-1).long()
return x, mask
class MiDashengLMModel(nn.Module):
"""MiDashengLM model for audio-language processing."""
default_bitsandbytes_target_modules = [
".fc1.",
".fc2.",
".gate_up_proj.",
".down_proj.",
".q_proj.",
".k_proj.",
".v_proj.",
".o_proj.",
]
bitsandbytes_stacked_params_mapping = {
"q_proj": ("qkv_proj", 0),
"k_proj": ("qkv_proj", 1),
"v_proj": ("qkv_proj", 2),
"gate_proj": ("gate_up_proj", 0),
"up_proj": ("gate_up_proj", 1),
}
def __init__(
self,
config: PretrainedConfig,
quant_config: Optional[QuantizationConfig] = None,
prefix: str = "",
) -> None:
super().__init__()
self.config = config
rope_scaling = config.text_config.rope_parameters
if rope_scaling:
if "mrope_section" in rope_scaling:
# Remove mrope_section from rope_parameters so downstream
# code treats this as standard rotary embedding.
del rope_scaling["mrope_section"]
self.audio_encoder = DashengAudioTransformer(
config.audio_encoder_config,
quant_config=quant_config,
prefix=add_prefix("audio_encoder", prefix),
)
self.audio_projector = AudioProjectorSubsample(
in_dim=config.audio_encoder_config.embed_dim,
out_dim=config.text_config.hidden_size,
downsample_rate=config.subsample_factor,
quant_config=quant_config,
prefix=add_prefix("audio_projector", prefix),
)
self.language_model = Qwen2ForCausalLM(
config.text_config,
quant_config=quant_config,
prefix=add_prefix("decoder", prefix),
)
self.logits_processor = self.language_model.logits_processor
self.quant_config = quant_config
def pad_input_ids(self, input_ids: List[int], mm_inputs: MultimodalInputs):
"""Pad input IDs with multimodal tokens."""
pattern = MultiModalityDataPaddingPatternMultimodalTokens()
return pattern.pad_input_tokens(input_ids, mm_inputs)
def get_audio_feature(self, items: List[MultimodalDataItem]) -> torch.Tensor:
"""Process audio inputs and return embeddings.
Args:
items: List of multimodal data items containing audio features
Returns:
audio_embeddings: Concatenated audio embeddings
"""
logger.debug("=" * 80)
logger.debug(f"get_audio_feature called with {len(items)} items")
logger.debug("=" * 80)
for i, item in enumerate(items):
logger.debug(f"Item {i} feature shape: {item.feature.shape}")
logger.debug(
f"Item {i} audio_length: {getattr(item, 'audio_length', 'NOT SET')}"
)
logger.debug(f"Item {i} pad_value: {getattr(item, 'pad_value', 'NOT SET')}")
logger.debug(f"Item {i} hash: {getattr(item, 'hash', 'NOT SET')}")
input_values = torch.cat([item.feature for item in items], dim=0)
logger.debug(f"Concatenated input_values shape: {input_values.shape}")
audio_lengths = []
for item in items:
if hasattr(item, "audio_length") and item.audio_length is not None:
audio_lengths.append(item.audio_length)
else:
audio_lengths.append(item.feature.shape[-1])
audio_length = torch.tensor(audio_lengths, device=input_values.device)
logger.debug(f"audio_length: {audio_length}")
encoder_out, encoder_atts = self.audio_encoder(input_values, audio_length)
logger.debug(f"Encoder output shape: {encoder_out.shape}")
audio_embeddings, _ = self.audio_projector(encoder_out, encoder_atts)
audio_embeddings = audio_embeddings.to(input_values.dtype)
logger.debug(f"Projector output shape: {audio_embeddings.shape}")
batch_size, max_audio_tokens, embed_dim = audio_embeddings.shape
logger.debug(f"Using all {max_audio_tokens} audio tokens from projector output")
masked_audio_features = audio_embeddings.reshape(-1, embed_dim)
logger.debug(f"Final output shape: {masked_audio_features.shape}")
logger.debug(
f"Stats: min={masked_audio_features.min().item():.4f}, max={masked_audio_features.max().item():.4f}"
)
logger.debug(
f"Audio embeddings dtype: {masked_audio_features.dtype}, device: {masked_audio_features.device}"
)
logger.debug(
f"First 5 values of first audio token: {masked_audio_features[0, :5].tolist()}"
)
logger.debug("=" * 80)
return masked_audio_features
def get_input_embeddings(self):
return self.language_model.model.embed_tokens
@torch.no_grad()
def forward(
self,
input_ids: torch.Tensor,
positions: torch.Tensor,
forward_batch: ForwardBatch,
**kwargs,
):
"""Run forward pass for MiDashengLM.
Args:
input_ids: Flattened (concatenated) input_ids corresponding to a batch.
positions: Flattened (concatenated) position ids corresponding to a batch.
forward_batch: Forward batch information including multimodal data.
"""
if forward_batch.contains_mm_inputs():
logger.debug("=" * 80)
logger.debug(f"input_ids shape: {input_ids.shape}")
logger.debug(f"input_ids first 20: {input_ids[:20].tolist()}")
logger.debug(
f"input_ids unique values count: {len(torch.unique(input_ids))}"
)
if forward_batch.mm_inputs and len(forward_batch.mm_inputs) > 0:
mm_input = forward_batch.mm_inputs[0]
if mm_input and len(mm_input.mm_items) > 0:
pad_value = mm_input.mm_items[0].pad_value
logger.debug(f"Expected pad_value: {pad_value}")
logger.debug(
f"Count of pad_value in input_ids: {(input_ids == pad_value).sum().item()}"
)
if hasattr(mm_input, "audio_token_id") and mm_input.audio_token_id:
logger.debug(f"audio_token_id: {mm_input.audio_token_id}")
logger.debug(
f"Count of audio_token_id in input_ids: {(input_ids == mm_input.audio_token_id).sum().item()}"
)
logger.debug("=" * 80)
return general_mm_embed_routine(
input_ids=input_ids,
forward_batch=forward_batch,
language_model=self.language_model,
positions=positions,
data_embedding_funcs={Modality.AUDIO: self.get_audio_feature},
)
def load_weights(self, weights: Iterable[Tuple[str, torch.Tensor]]):
"""Load model weights."""
params_dict = dict(self.named_parameters(remove_duplicate=False))
buffers_dict = dict(self.named_buffers())
audio_encoder_loaded = []
audio_projector_loaded = []
skipped_weights = []
decoder_weights = []
for name, loaded_weight in weights:
if "rotary_emb.inv_freq" in name:
continue
if "rotary_emb.cos_cached" in name or "rotary_emb.sin_cached" in name:
continue
if name.startswith("decoder"):
decoder_weights.append((name, loaded_weight))
continue
original_name = name
if "audio_encoder.front_end" in name:
if ".mel_scale.fb" in name:
name = name.replace(".mel_scale.fb", ".melscale_fbanks")
elif ".spectrogram.window" in name:
name = name.replace(".spectrogram.window", ".spectrogram_window")
if "audio_encoder" in name and ".attn.qkv." in name:
name = name.replace(".attn.qkv.", ".attn.attn.qkv_proj.")
if "audio_encoder" in name and ".attn.proj." in name:
name = name.replace(".attn.proj.", ".attn.attn.proj.")
if "audio_projector" in name:
name = name.replace(".net.0.", ".fc1.")
name = name.replace(".net.2.", ".fc2.")
if (
name.endswith(".bias")
and name not in params_dict
and name not in buffers_dict
):
skipped_weights.append(f"{original_name} (bias not in params/buffers)")
continue
if name in params_dict:
param = params_dict[name]
weight_loader = getattr(param, "weight_loader", default_weight_loader)
weight_loader(param, loaded_weight)
elif name in buffers_dict:
buffers_dict[name].copy_(loaded_weight)
else:
if "audio_projector" in original_name:
skipped_weights.append(f"{original_name} -> {name} (NOT IN MODEL)")
else:
skipped_weights.append(f"{original_name} (not in model)")
continue
if "audio_encoder" in original_name:
audio_encoder_loaded.append(original_name)
elif "audio_projector" in original_name:
audio_projector_loaded.append(original_name)
if decoder_weights:
logger.debug(
f"Passing {len(decoder_weights)} decoder weights to language_model.load_weights()"
)
decoder_weights_stripped = [
(name.replace("decoder.", "", 1), weight)
for name, weight in decoder_weights
]
self.language_model.load_weights(decoder_weights_stripped)
logger.debug("=" * 80)
logger.debug(f"Audio encoder weights loaded: {len(audio_encoder_loaded)}")
logger.debug(f"Audio projector weights loaded: {len(audio_projector_loaded)}")
logger.debug(
f"Decoder weights passed to language_model: {len(decoder_weights)}"
)
logger.debug(f"Skipped weights: {len(skipped_weights)}")
encoder_skipped = [s for s in skipped_weights if "audio_encoder" in s]
projector_skipped = [s for s in skipped_weights if "audio_projector" in s]
if projector_skipped:
logger.debug("Skipped audio_projector weights:")
for s in projector_skipped:
logger.debug(f" {s}")
if encoder_skipped:
logger.debug(f"Skipped audio_encoder weights: {len(encoder_skipped)}")
non_bias_skipped = [s for s in encoder_skipped if "bias" not in s]
if non_bias_skipped:
logger.debug(" First 10 non-bias skipped:")
for s in non_bias_skipped[:10]:
logger.debug(f" {s}")
logger.debug("=" * 80)
def get_embed_and_head(self):
return (
self.language_model.model.embed_tokens.weight,
self.language_model.lm_head.weight,
)
EntryClass = [MiDashengLMModel]