Download scripts/test_nf_closed_loop.py from Lingmin-Ran/SADAE: direct link, hf CLI and curl.
- Browser
- Download file 3.88 kB
-
https://huggingface.co/Lingmin-Ran/SADAE/resolve/main/scripts/test_nf_closed_loop.py
- Command line
-
hf download hf://Lingmin-Ran/SADAE/scripts/test_nf_closed_loop.py
-
curl -L -o test_nf_closed_loop.py https://huggingface.co/Lingmin-Ran/SADAE/resolve/main/scripts/test_nf_closed_loop.py
3.88 kB
| #!/usr/bin/env python3 | |
| """CPU checks for high-CFG reconstruction from independently decoded FP64 z.""" | |
| from io import BytesIO | |
| from pathlib import Path | |
| import sys | |
| import unittest | |
| sys.path.insert(0, str(Path(__file__).resolve().parents[1])) | |
| import torch | |
| from transformer_flow import Model | |
| from nf_roundtrip import closed_loop_forward, closed_loop_reverse, error_metrics | |
| class ClosedLoopTests(unittest.TestCase): | |
| def make_model(self, sos=True, patch_size=1, softplus=True): | |
| torch.manual_seed(42) | |
| model = Model(in_channels=4, img_size=4, patch_size=patch_size, channels=64, | |
| num_blocks=3, layers_per_block=[1, 0, 2], head_dim=64, | |
| rope=True, sos=sos, txt_size=4, txt_dim=16, | |
| cond_top_only=True, use_softplus=softplus, | |
| use_final_norm=True, soft_clip=4, seq_order='L2R').eval() | |
| with torch.no_grad(): | |
| for block in model.blocks: | |
| if hasattr(block, 'proj_out'): | |
| block.proj_out.weight.normal_(std=0.08) | |
| block.proj_out.bias.normal_(std=0.05) | |
| return model | |
| def test_saved_z_independent_decode_and_feedback(self): | |
| for sos, patch_size, softplus in ((True, 1, True), (False, 1, False), (True, 2, True)): | |
| model = self.make_model(sos, patch_size, softplus) | |
| x, y = torch.randn(2, 4, 4, 4), torch.randn(2, 4, 16) | |
| x, y = x.bfloat16().float(), y.bfloat16().float() | |
| for guidance in (0, 3.6, 7.2): | |
| with self.subTest(sos=sos, patch_size=patch_size, softplus=softplus, cfg=guidance): | |
| condition = torch.cat([y, torch.zeros_like(y)]) if guidance else y | |
| z, states, simulated = closed_loop_forward(model, x, condition, guidance) | |
| self.assertEqual(z.dtype, torch.float64) | |
| self.assertTrue(all(p.dtype == torch.float32 for p in model.parameters())) | |
| buffer = BytesIO() | |
| torch.save(z, buffer) | |
| buffer.seek(0) | |
| loaded_z = torch.load(buffer, weights_only=True) | |
| sequence = closed_loop_reverse(model, loaded_z, condition, guidance, return_sequence=True) | |
| self.assertEqual(len(sequence), len(model.blocks) + 1) | |
| torch.testing.assert_close(sequence[1].float(), simulated, atol=0, rtol=0) | |
| torch.testing.assert_close(sequence[1], model.unpatchify(states[-2]).double(), | |
| atol=1e-13, rtol=1e-13) | |
| torch.testing.assert_close(sequence[-1], x, atol=3e-5, rtol=3e-5) | |
| repeated = closed_loop_reverse(model, loaded_z, condition, guidance) | |
| torch.testing.assert_close(repeated, sequence[-1], atol=0, rtol=0) | |
| perturbed = closed_loop_reverse(model, loaded_z + 0.1, condition, guidance) | |
| self.assertGreater((perturbed - repeated).abs().mean().item(), 0.01) | |
| def test_rejects_truncated_z_and_low_precision_weights(self): | |
| model = self.make_model() | |
| x, condition = torch.zeros(1, 4, 4, 4), torch.zeros(2, 4, 16) | |
| with self.assertRaisesRegex(ValueError, 'original FP64 z'): | |
| closed_loop_reverse(model, x, condition, 3.6) | |
| with self.assertRaisesRegex(ValueError, 'FP32 model weights'): | |
| closed_loop_forward(model.bfloat16(), x, condition, 3.6) | |
| def test_metrics_preserve_fp64_errors(self): | |
| metrics = error_metrics(torch.tensor([1 + 1e-12], dtype=torch.float64), | |
| torch.ones(1, dtype=torch.float64)) | |
| self.assertGreater(metrics['mae'], 1e-13) | |
| self.assertLess(metrics['mae'], 2e-12) | |
| if __name__ == '__main__': | |
| torch.set_num_threads(2) | |
| unittest.main() | |