Files
SoundGame/tools/stable-audio-3/stable_audio_3/models/bottleneck.py
T
xsl 24c526af68 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 全绿
2026-09-02 19:35:38 +08:00

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