- 共享引擎(app/src/main):GestureEngine 6 手势识别、AudioEngine 三层音频 (ExoPlayer BGM 交叉淡入 / 对白 ducking / SoundPool 低延迟)、Game/GameEngine 状态机接口、MainActivity 全屏封面 + TalkBack - 《声命线》storyline:末世互动广播剧,3 幕 8 抉择点 4 结局 - 《声东击西》reflex:听声辨位反应,12 波战斗 + BGM 三档 BPM 变速 - 《暗室》escape:3x3 网格密室逃脱,钥匙→铁柜→保险丝→电箱→大门谜题链 - 文档:setup(从零搭建)/ architecture(架构)/ engine-api(引擎 API)/ asset-pipeline(资产流水线)/ games/*(三款游戏设计文档) - 资产管线:Qwen3-TTS 对白 + 程序合成音效/BGM + Mureka BGM 的 gen 脚本与台账, 全部 ogg 资产入库可复现 - env.d 环境脚本:android/tts 入库;sfx/mureka 含密钥不入库,仅提交 .example.sh 模板
91 lines
2.3 KiB
Python
91 lines
2.3 KiB
Python
import numpy as np
|
|
import pytest
|
|
|
|
pytest.importorskip("mlx.core")
|
|
|
|
import mlx.core as mx
|
|
|
|
from optimized.mlx.models.defs.training import (
|
|
rectified_flow_loss,
|
|
sample_training_timesteps,
|
|
shift_training_timesteps,
|
|
)
|
|
|
|
|
|
def test_truncated_logit_normal_sampler_matches_sa3_distribution():
|
|
values = sample_training_timesteps(
|
|
"trunc_logit_normal",
|
|
20_000,
|
|
rng=np.random.default_rng(17),
|
|
)
|
|
|
|
assert values.dtype == np.float32
|
|
assert np.all((values >= 0.0) & (values <= 1.0))
|
|
assert 0.52 < float(values.mean()) < 0.55
|
|
assert 0.52 < float(np.median(values)) < 0.56
|
|
|
|
|
|
def test_full_training_shift_matches_sa3_defaults():
|
|
shifted = shift_training_timesteps(
|
|
[0.5],
|
|
507,
|
|
shift_type="full",
|
|
)
|
|
|
|
assert shifted[0] == pytest.approx(0.6323907626)
|
|
|
|
|
|
def test_rectified_flow_loss_uses_velocity_target_and_mask():
|
|
clean = mx.array([[[1.0, 2.0, 3.0]]], dtype=mx.float32)
|
|
noise = mx.array([[[4.0, 5.0, 6.0]]], dtype=mx.float32)
|
|
timesteps = mx.array([0.25], dtype=mx.float32)
|
|
mask = mx.array([[True, False, True]])
|
|
|
|
def perfect_model(noised, timestep):
|
|
del noised, timestep
|
|
return noise - clean
|
|
|
|
def zero_model(noised, timestep):
|
|
del timestep
|
|
return mx.zeros_like(noised)
|
|
|
|
assert float(
|
|
rectified_flow_loss(
|
|
perfect_model,
|
|
clean,
|
|
timesteps,
|
|
noise=noise,
|
|
loss_mask=mask,
|
|
)
|
|
) == pytest.approx(0.0)
|
|
assert float(
|
|
rectified_flow_loss(
|
|
zero_model,
|
|
clean,
|
|
timesteps,
|
|
noise=noise,
|
|
loss_mask=mask,
|
|
)
|
|
) == pytest.approx(9.0)
|
|
|
|
|
|
def test_rectified_flow_loss_averages_masked_loss_per_sample():
|
|
clean = mx.zeros((2, 1, 3), dtype=mx.float32)
|
|
noise = mx.array([[[1.0, 1.0, 1.0]], [[3.0, 3.0, 3.0]]], dtype=mx.float32)
|
|
timesteps = mx.array([0.25, 0.25], dtype=mx.float32)
|
|
mask = mx.array([[True, False, False], [True, True, True]])
|
|
|
|
def zero_model(noised, timestep):
|
|
del noised, timestep
|
|
return mx.zeros_like(clean)
|
|
|
|
loss = rectified_flow_loss(
|
|
zero_model,
|
|
clean,
|
|
timesteps,
|
|
noise=noise,
|
|
loss_mask=mask,
|
|
)
|
|
|
|
assert float(loss) == pytest.approx(5.0)
|