feat(assets): SA3 音效补齐 radio 11+1 与 dungeon 13源+15pan(token 走 hf-mirror 实测可用)
- 模型 17/17 文件经镜像全量缓存(gated+token,直连本机不通;sfx.md/setup.md/asset-pipeline.md 镜像结论同步更新) - 修复迁移遗留:stable_audio_3/models/ 源码子包被 .gitignore models/ 规则误伤丢失,从上游恢复并加白名单 - radio:arg_muffled/brake_screech 等叙事件落地(接线原有 L111/L154 零改动)+ phone_ring SYN→SA3 升级;dungeon 13 源 A/B 对齐(RMS 偏差 ≤0.3dB)全量同名替换,SYN 原版备份 tools/asset_fix_backup/sa3_ab_20260902/ - 关键玩法语义达标:echo 距离档 0.83<1.43<2.18<2.98s 严格递增;one-shot 真峰值全 ≤-3dBFS(解码回读法) - check_all_assets 8 游戏全绿(radio 254/254、dungeon 303/303);playtest radio 221/dungeon 1610 全绿
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
import torch
|
||||
from torch import nn
|
||||
|
||||
class SoftNormBottleneck(nn.Module):
|
||||
def __init__(self, dim = 32, noise_augment_dim=0, noise_regularize = False, auto_scale = False, freeze = False):
|
||||
super().__init__()
|
||||
|
||||
self.noise_augment_dim = noise_augment_dim
|
||||
self.scaling_factor = nn.Parameter(torch.ones(1,dim,1))
|
||||
self.bias = nn.Parameter(torch.zeros(1,dim,1))
|
||||
self.noise_scaling_factor = nn.Parameter(torch.ones(1,noise_augment_dim,1))
|
||||
self.noise_regularize = noise_regularize
|
||||
self.freeze = freeze
|
||||
if self.freeze:
|
||||
self.scaling_factor.requires_grad = False
|
||||
self.bias.requires_grad = False
|
||||
self.noise_scaling_factor.requires_grad = False
|
||||
if auto_scale:
|
||||
running_std = torch.ones(1)
|
||||
self.register_parameter("running_std", nn.Parameter(running_std, requires_grad=False))
|
||||
|
||||
def encode(self, x, return_info=False, **kwargs):
|
||||
info = {}
|
||||
|
||||
x = x * self.scaling_factor + self.bias
|
||||
|
||||
if self.training and hasattr(self,"running_std") and not self.freeze:
|
||||
# Update running std
|
||||
self.running_std.data = (self.running_std.data * 0.999 + x.std().detach() * 0.001).clamp(min = 1e-4)
|
||||
|
||||
if hasattr(self, "running_std"):
|
||||
x = x / self.running_std
|
||||
|
||||
if self.training and return_info:
|
||||
var = (x.std(dim=-1) ** 2).clip(min = 1e-4)
|
||||
logvar = torch.log(var)
|
||||
mean = x.mean(dim=-1)
|
||||
loss = (mean * mean + var - logvar - 1).mean()
|
||||
var = (x.std(dim=-2) ** 2).clip(min = 1e-4)
|
||||
logvar = torch.log(var)
|
||||
mean = x.mean(dim=-2)
|
||||
loss = loss + 0.4 * (mean * mean + var - logvar - 1).mean()
|
||||
info["softnorm_loss"] = loss
|
||||
|
||||
if return_info:
|
||||
return x, info
|
||||
|
||||
return x
|
||||
|
||||
def decode(self, x, **kwargs):
|
||||
if hasattr(self, "running_std"):
|
||||
x = x * self.running_std
|
||||
|
||||
if self.noise_regularize:
|
||||
if hasattr(self, "running_std"):
|
||||
scaling = self.running_std
|
||||
else:
|
||||
scaling = x.std(dim = -1).unsqueeze(-1)
|
||||
if self.training:
|
||||
scale = 5e-2
|
||||
else:
|
||||
scale = 1e-3
|
||||
noise = torch.randn_like(x) * scaling * scale
|
||||
x = x + noise
|
||||
|
||||
if self.noise_augment_dim > 0:
|
||||
noise = self.noise_scaling_factor * torch.randn(x.shape[0], self.noise_augment_dim,
|
||||
x.shape[-1]).type_as(x)
|
||||
x = torch.cat([x, noise], dim=1)
|
||||
|
||||
return x
|
||||
Reference in New Issue
Block a user