- 模型 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 全绿
72 lines
2.6 KiB
Python
72 lines
2.6 KiB
Python
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
|