@@ -537,6 +537,58 @@ def test_latent_shape_matches_batch(self):
537537class TestTwoStageLoRAHelpers :
538538 """Test LoRA delta loading and application without checkpoints."""
539539
540+ def test_bf16_weight_snapshot_gate_uses_cuda_free_memory (self , monkeypatch ):
541+ from tensorrt_llm ._torch .visual_gen .models .ltx2 .pipeline_ltx2_two_stages import (
542+ _should_save_bf16_weights ,
543+ )
544+
545+ gib = 1024 ** 3
546+ monkeypatch .setattr (torch .cuda , "is_available" , lambda : True )
547+ monkeypatch .setattr (torch .cuda , "mem_get_info" , lambda : (116 * gib , 180 * gib ))
548+ assert _should_save_bf16_weights ()
549+
550+ monkeypatch .setattr (torch .cuda , "mem_get_info" , lambda : (115 * gib , 180 * gib ))
551+ assert not _should_save_bf16_weights ()
552+
553+ def _raise_mem_query_error ():
554+ raise RuntimeError ("mem_get_info failed" )
555+
556+ monkeypatch .setattr (torch .cuda , "mem_get_info" , _raise_mem_query_error )
557+ assert not _should_save_bf16_weights ()
558+
559+ monkeypatch .setattr (torch .cuda , "is_available" , lambda : False )
560+ assert not _should_save_bf16_weights ()
561+
562+ def test_bf16_weight_snapshot_saved_when_requested (self ):
563+ from tensorrt_llm ._torch .visual_gen .models .ltx2 .pipeline_ltx2_two_stages import (
564+ _apply_lora_deltas ,
565+ _restore_lora_state ,
566+ _subtract_dense_lora_deltas ,
567+ )
568+
569+ linear = torch .nn .Linear (32 , 32 , bias = False ).bfloat16 ()
570+ original_weight = linear .weight .data .clone ()
571+ deltas = {"weight" : torch .randn (32 , 32 ) * 0.1 }
572+
573+ applied , saved_state , snapshot_required = _apply_lora_deltas (
574+ linear ,
575+ deltas ,
576+ sign = 1.0 ,
577+ save_bf16_weights = True ,
578+ )
579+
580+ assert applied == 1
581+ assert snapshot_required == 1
582+ assert "weight" in saved_state
583+ assert torch .allclose (saved_state ["weight" ], original_weight )
584+ assert not torch .allclose (linear .weight .data , original_weight )
585+
586+ removed = _subtract_dense_lora_deltas (linear , deltas , saved_state )
587+ assert removed == 0
588+
589+ _restore_lora_state (linear , saved_state )
590+ assert torch .allclose (linear .weight .data , original_weight )
591+
540592 @pytest .mark .skipif (not torch .cuda .is_available (), reason = "CUDA not available" )
541593 def test_apply_and_remove_deltas_bf16 (self ):
542594 """Merge then unmerge in BF16 should leave weights approximately unchanged."""
@@ -554,7 +606,7 @@ def test_apply_and_remove_deltas_bf16(self):
554606
555607 applied , saved_state , snapshot_required = _apply_lora_deltas (linear , deltas , sign = 1.0 )
556608 assert applied == 1 , "Expected one parameter to be modified"
557- assert saved_state == {}, "Dense BF16 weights should not be snapshotted"
609+ assert saved_state == {}, "BF16 weights should not be snapshotted by default "
558610 assert snapshot_required == 0
559611 assert not torch .allclose (linear .weight .data , original_weight ), (
560612 "Weights should have changed after applying delta"
@@ -597,16 +649,16 @@ def test_multi_round_drift_bounded(self):
597649 rounds = 10
598650 for _ in range (rounds ):
599651 _ , saved_state , snapshot_required = _apply_lora_deltas (model , deltas , sign = 1.0 )
600- assert saved_state == {}, "Dense BF16 weights should not be snapshotted"
652+ assert saved_state == {}, "BF16 weights should not be snapshotted by default "
601653 assert snapshot_required == 0
602654 _subtract_dense_lora_deltas (model , deltas , saved_state )
603655
604656 drift = (model .weight .data .float () - original .float ()).abs ().max ().item ()
605657 assert drift < 0.1 , f"bf16 drift after { rounds } rounds too large: { drift :.2e} "
606658
607659 @pytest .mark .skipif (not torch .cuda .is_available (), reason = "CUDA not available" )
608- def test_dense_lora_state_not_saved_and_subtract_restores (self ):
609- """Dense weights are restored by subtraction without snapshot storage ."""
660+ def test_fp32_state_not_saved_and_subtract_restores (self ):
661+ """FP32 weights restore by subtraction, even when BF16 snapshots are enabled ."""
610662 from tensorrt_llm ._torch .visual_gen .models .ltx2 .pipeline_ltx2_two_stages import (
611663 _apply_lora_deltas ,
612664 _subtract_dense_lora_deltas ,
@@ -617,16 +669,21 @@ def test_dense_lora_state_not_saved_and_subtract_restores(self):
617669 original_weight = linear .weight .data .clone ()
618670
619671 deltas = {"weight" : torch .randn (32 , 32 , device = device ) * 0.1 }
620- _ , saved_state , snapshot_required = _apply_lora_deltas (linear , deltas , sign = 1.0 )
672+ _ , saved_state , snapshot_required = _apply_lora_deltas (
673+ linear ,
674+ deltas ,
675+ sign = 1.0 ,
676+ save_bf16_weights = True ,
677+ )
621678
622- assert saved_state == {}, "Dense FP32 weights should not be snapshotted "
679+ assert saved_state == {}, "FP32 weights should not use the BF16 snapshot path "
623680 assert snapshot_required == 0
624681 assert not torch .allclose (linear .weight .data , original_weight )
625682
626683 removed = _subtract_dense_lora_deltas (linear , deltas , saved_state )
627684 assert removed == 1
628685 assert torch .allclose (linear .weight .data , original_weight ), (
629- "Dense LoRA subtraction should restore weights"
686+ "FP32 LoRA subtraction should restore weights"
630687 )
631688
632689
@@ -1111,7 +1168,7 @@ def test_two_stage_lora_deltas_match_transformer(self, ltx2_two_stage_assets_exi
11111168 print (f"\n [Two-Stage] LoRA apply rate: { match_rate :.1f} % ({ applied } /{ total } )" )
11121169 assert match_rate > 99.0 , f"Expected >99% LoRA match rate, got { match_rate :.1f} %"
11131170
1114- assert saved_state == {}, "BF16 checkpoint should not snapshot dense weights"
1171+ assert saved_state == {}, "BF16 checkpoint should not snapshot weights by default "
11151172 assert snapshot_required == 0
11161173
11171174 # Verify dense unmerge by subtraction
0 commit comments