Download tests/test_flow_encoder_pilot.py from coolpoodle/music3lab: direct link, hf CLI and curl.
- Browser
- Download file 6.14 kB
-
https://huggingface.co/coolpoodle/music3lab/resolve/main/tests/test_flow_encoder_pilot.py
- Command line
-
hf download hf://coolpoodle/music3lab/tests/test_flow_encoder_pilot.py
-
curl -L -o test_flow_encoder_pilot.py https://huggingface.co/coolpoodle/music3lab/resolve/main/tests/test_flow_encoder_pilot.py
6.14 kB
| from __future__ import annotations | |
| import subprocess | |
| import sys | |
| from pathlib import Path | |
| import pytest | |
| import torch | |
| from torch import nn | |
| from torch.nn import functional as F | |
| from music3lab.codec.flow_encoder import ( | |
| ContinuousFlowEncoder, | |
| audio_metrics, | |
| latent_normalized_mse, | |
| learning_rate, | |
| load_flow_encoder_config, | |
| prior_mean_latents, | |
| ) | |
| from music3lab.codec.runner import ( | |
| FileRecord, | |
| TeacherDatasetManifest, | |
| TeacherSplitRecord, | |
| ) | |
| from music3lab.vocoder import FlowVocoderLatents | |
| ROOT = Path(__file__).resolve().parents[1] | |
| CONFIG = ROOT / "configs" / "flow-encoder-v1.yaml" | |
| class TinyVocoder(nn.Module): | |
| def __init__(self) -> None: | |
| super().__init__() | |
| self.gain = nn.Parameter(torch.ones(2), requires_grad=False) | |
| def forward(self, latents: FlowVocoderLatents) -> torch.Tensor: | |
| value = F.interpolate( | |
| latents.tensor[:, :2].float(), | |
| size=44032, | |
| mode="linear", | |
| align_corners=False, | |
| ) | |
| return value * self.gain.view(1, 2, 1) | |
| def test_frozen_config_has_exact_geometry_and_disjoint_64_16_16_seeds() -> None: | |
| config = load_flow_encoder_config(CONFIG).config | |
| seeds = config.teacher.split_seeds() | |
| assert {key: len(value) for key, value in seeds.items()} == { | |
| "train": 64, | |
| "validation": 16, | |
| "heldout": 16, | |
| } | |
| assert len({item for values in seeds.values() for item in values}) == 96 | |
| assert config.capability.endswith("not_native_rvq") | |
| assert config.model.input_samples == 44032 | |
| assert config.model.latent_frames == 86 | |
| def test_encoder_exact_geometry_is_deterministic_and_has_gradients() -> None: | |
| loaded = load_flow_encoder_config(CONFIG).config | |
| torch.manual_seed(9) | |
| encoder = ContinuousFlowEncoder( | |
| loaded.model, latent_mean=loaded.loss.latent_mean | |
| ) | |
| audio = torch.randn(2, 2, 44032) | |
| first = encoder(audio) | |
| second = encoder(audio) | |
| assert first.shape == (2, 128, 86) | |
| assert torch.equal(first, second) | |
| target = torch.randn_like(first) | |
| latent_normalized_mse(first, target, loaded.loss).mean().backward() | |
| assert any( | |
| parameter.grad is not None and parameter.grad.abs().sum() > 0 | |
| for parameter in encoder.parameters() | |
| ) | |
| def test_prior_mean_baseline_and_schedule_are_frozen() -> None: | |
| config = load_flow_encoder_config(CONFIG).config | |
| prior = prior_mean_latents(3, config.model, config.loss) | |
| assert prior.shape == (3, 128, 86) | |
| assert float(prior.mean()) == pytest.approx(config.loss.latent_mean) | |
| assert learning_rate(0, config.training) == pytest.approx( | |
| config.training.maximum_learning_rate | |
| ) | |
| assert learning_rate(config.training.steps, config.training) == pytest.approx( | |
| config.training.minimum_learning_rate | |
| ) | |
| def test_frozen_decoder_has_no_weight_grad_while_encoder_input_does() -> None: | |
| decoder = TinyVocoder() | |
| latents = torch.randn(2, 128, 86, requires_grad=True) | |
| audio = decoder(FlowVocoderLatents(latents)) | |
| audio.square().mean().backward() | |
| assert latents.grad is not None and latents.grad.abs().sum() > 0 | |
| assert all(parameter.grad is None for parameter in decoder.parameters()) | |
| def test_audio_metrics_order_exact_before_distorted() -> None: | |
| target = torch.randn(2, 2, 44032) | |
| noise = 0.1 * torch.randn(2, 2, 44032) | |
| exact = audio_metrics(target, target) | |
| distorted = audio_metrics(target + noise, target) | |
| assert exact.mae == 0 | |
| assert exact.correlation > distorted.correlation | |
| assert exact.unscaled_snr_db > distorted.unscaled_snr_db | |
| def test_cli_help_is_cpu_safe() -> None: | |
| result = subprocess.run( | |
| [ | |
| sys.executable, | |
| "-B", | |
| str(ROOT / "scripts" / "run_flow_encoder_pilot.py"), | |
| "--help", | |
| ], | |
| check=True, | |
| text=True, | |
| capture_output=True, | |
| env={ | |
| "PATH": __import__("os").environ["PATH"], | |
| "PYTHONPATH": str(ROOT / "src"), | |
| "CUDA_VISIBLE_DEVICES": "-1", | |
| "PYTHONDONTWRITEBYTECODE": "1", | |
| }, | |
| ) | |
| normalized = " ".join(result.stdout.split()) | |
| assert "does not produce native RVQ tokens" in normalized | |
| def test_teacher_manifest_canonicalizes_nested_split_models() -> None: | |
| config = load_flow_encoder_config(CONFIG) | |
| counts = {"train": 64, "validation": 16, "heldout": 16} | |
| starts = {"train": 1000, "validation": 2000, "heldout": 3000} | |
| splits = { | |
| name: TeacherSplitRecord( | |
| count=count, | |
| seeds=tuple(range(starts[name], starts[name] + count)), | |
| file=FileRecord( | |
| path=f"{name}.safetensors", | |
| sha256="1" * 64, | |
| size=1, | |
| ), | |
| audio_shape=(count, 2, 44032), | |
| latent_shape=(count, 128, 86), | |
| audio_content_sha256="2" * 64, | |
| latent_content_sha256="3" * 64, | |
| ) | |
| for name, count in counts.items() | |
| } | |
| manifest = TeacherDatasetManifest.create( | |
| schema_version="music3lab.flow-encoder-teachers.v1", | |
| capability="continuous_flow_vocoder_latent_teacher_pairs_not_native_rvq", | |
| config_file_sha256=config.file_sha256, | |
| config_semantic_digest=config.semantic_digest, | |
| model_revision=config.config.model_revision, | |
| base_id=config.config.expected_base_id, | |
| base_manifest_file_sha256="4" * 64, | |
| diffusers_revision=config.config.diffusers_revision, | |
| prompt_sha256="5" * 64, | |
| lyrics_sha256="6" * 64, | |
| persistent_pipeline_load_count=1, | |
| replay_exact_count=96, | |
| producer_project_git_commit="7" * 40, | |
| publication_project_git_commit="8" * 40, | |
| recovered_from_complete_quarantine=True, | |
| generation_seconds=None, | |
| peak_cuda_allocated_bytes=None, | |
| splits=splits, | |
| ) | |
| assert ( | |
| TeacherDatasetManifest.model_validate_json( | |
| __import__( | |
| "music3lab.codec.flow_encoder", | |
| fromlist=["canonical_json_bytes"], | |
| ).canonical_json_bytes(manifest) | |
| ) | |
| == manifest | |
| ) | |