@@ -1105,9 +1105,7 @@ def adjust_amax_history_length(self, length: int, fwd: Optional[bool] = None) ->
11051105 qstate .global_amax_buffer [buffer_key ][pos ] = self .fp8_meta [
11061106 meta_key
11071107 ].amax_history [0 ]
1108- qstate .global_amax_devices [buffer_key ].add (
1109- self .fp8_meta [meta_key ].amax_history .device
1110- )
1108+ FP8GlobalStateManager ._refresh_global_amax_devices (buffer_key )
11111109
11121110 def _recipe_state_device (self ) -> torch .device :
11131111 """Device the module's quantization state must be allocated on.
@@ -1127,6 +1125,14 @@ def _recipe_state_device(self) -> torch.device:
11271125 return tensor .device
11281126 return torch .device ("cuda" , torch .cuda .current_device ())
11291127
1128+ def _release_forward_device_guard (self ) -> None :
1129+ """Release the most recently entered forward device guard, if any."""
1130+ if not self ._forward_device_guards :
1131+ return
1132+ guard = self ._forward_device_guards .pop ()
1133+ if guard is not None :
1134+ guard .__exit__ (None , None , None )
1135+
11301136 def set_meta_tensor (self , fwd : bool , recipe : Recipe ) -> None :
11311137 """Init scales and amaxes for fwd | bwd."""
11321138 fp8_meta_tensor_key = "scaling_fwd" if fwd else "scaling_bwd"
@@ -1632,68 +1638,81 @@ def prepare_forward(
16321638 guard = torch .cuda .device (inp .device )
16331639 guard .__enter__ ()
16341640 self ._forward_device_guards .append (guard )
1641+ nvtx_pushed = False
16351642
1636- self .fast_setattr (
1637- "allow_different_data_and_param_types" , allow_different_data_and_param_types
1638- )
1639- self .fast_setattr ("forwarded_at_least_once" , True )
1640-
1641- # Activation recomputation is used and this is the second forward phase.
1642- if self .fp8 and in_fp8_activation_recompute_phase ():
1643- delayed_scaling_recipe = _has_delayed_scaling_state (self .fp8_meta )
1644- FP8GlobalStateManager .get_old_fp8_meta_tensors_for_recompute (self .fp8_meta )
1645- else :
1646- if not inp .is_cuda :
1647- raise RuntimeError (
1648- f"TransformerEngine needs CUDA. Got input on device: { inp .device } "
1649- )
1643+ try :
1644+ self .fast_setattr (
1645+ "allow_different_data_and_param_types" , allow_different_data_and_param_types
1646+ )
1647+ self .fast_setattr ("forwarded_at_least_once" , True )
16501648
1651- if self .tp_size > 1 :
1652- if not self .tp_group_initialized :
1649+ # Activation recomputation is used and this is the second forward phase.
1650+ if self .fp8 and in_fp8_activation_recompute_phase ():
1651+ delayed_scaling_recipe = _has_delayed_scaling_state (self .fp8_meta )
1652+ FP8GlobalStateManager .get_old_fp8_meta_tensors_for_recompute (self .fp8_meta )
1653+ else :
1654+ if not inp .is_cuda :
16531655 raise RuntimeError (
1654- "Tensor parallel group not initialized. Call "
1655- "set_tensor_parallel_group() before forward pass when tp_size > 1."
1656+ f"TransformerEngine needs CUDA. Got input on device: { inp .device } "
16561657 )
16571658
1658- self .set_activation_dtype (inp )
1659- self .init_fp8_metadata (num_gemms = num_gemms )
1660- self ._check_weight_tensor_recipe_correspondence ()
1661-
1662- delayed_scaling_recipe = self .fp8 and _has_delayed_scaling_state (self .fp8_meta )
1663- if delayed_scaling_recipe :
1664- if self .sequence_parallel :
1665- assert (
1666- self .fp8_meta ["recipe" ].custom () or self .fp8_meta ["recipe" ].reduce_amax
1667- ), (
1668- "Amax reduction across tensor parallel group is "
1669- "necessary when using sequence parallelism with FP8."
1670- )
1659+ if self .tp_size > 1 :
1660+ if not self .tp_group_initialized :
1661+ raise RuntimeError (
1662+ "Tensor parallel group not initialized. Call "
1663+ "set_tensor_parallel_group() before forward pass when tp_size > 1."
1664+ )
1665+
1666+ self .set_activation_dtype (inp )
1667+ self .init_fp8_metadata (num_gemms = num_gemms )
1668+ self ._check_weight_tensor_recipe_correspondence ()
1669+
1670+ delayed_scaling_recipe = self .fp8 and _has_delayed_scaling_state (self .fp8_meta )
1671+ if delayed_scaling_recipe :
1672+ if self .sequence_parallel :
1673+ assert (
1674+ self .fp8_meta ["recipe" ].custom () or self .fp8_meta ["recipe" ].reduce_amax
1675+ ), (
1676+ "Amax reduction across tensor parallel group is "
1677+ "necessary when using sequence parallelism with FP8."
1678+ )
16711679
1672- if not FP8GlobalStateManager .fp8_graph_capturing ():
1673- FP8GlobalStateManager .add_fp8_tensors_to_global_buffer (self .fp8_meta )
1680+ if not FP8GlobalStateManager .fp8_graph_capturing ():
1681+ FP8GlobalStateManager .add_fp8_tensors_to_global_buffer (self .fp8_meta )
16741682
1675- # Activation recomputation is used and this is the first forward phase.
1676- if self .training and is_fp8_activation_recompute_enabled ():
1677- FP8GlobalStateManager .copy_forward_fp8_meta_tensors_for_recompute (self .fp8_meta )
1683+ # Activation recomputation is used and this is the first forward phase.
1684+ if self .training and is_fp8_activation_recompute_enabled ():
1685+ FP8GlobalStateManager .copy_forward_fp8_meta_tensors_for_recompute (
1686+ self .fp8_meta
1687+ )
16781688
1679- nvtx_range_push (self .__class__ .__name__ + " forward" )
1680- if not allow_non_contiguous and not inp .is_contiguous ():
1681- inp = inp .contiguous ()
1682- return inp
1689+ nvtx_range_push (self .__class__ .__name__ + " forward" )
1690+ nvtx_pushed = True
1691+ if not allow_non_contiguous and not inp .is_contiguous ():
1692+ inp = inp .contiguous ()
1693+ return inp
1694+ except BaseException :
1695+ try :
1696+ if nvtx_pushed :
1697+ nvtx_range_pop ()
1698+ finally :
1699+ self ._release_forward_device_guard ()
1700+ raise
16831701
16841702 def end_forward (self ):
16851703 """
16861704 Required to be called at the end of the forward function to properly handle
16871705 DelayedScaling metadata handling and the NVTX ranges.
16881706 """
1689- delayed_scaling_recipe = self .fp8 and _has_delayed_scaling_state (self .fp8_meta )
1690- if delayed_scaling_recipe and self .fp8 and in_fp8_activation_recompute_phase ():
1691- FP8GlobalStateManager .restore_fp8_meta_tensors (self .fp8_meta )
1692- nvtx_range_pop ()
1693- if self ._forward_device_guards :
1694- guard = self ._forward_device_guards .pop ()
1695- if guard is not None :
1696- guard .__exit__ (None , None , None )
1707+ try :
1708+ try :
1709+ delayed_scaling_recipe = self .fp8 and _has_delayed_scaling_state (self .fp8_meta )
1710+ if delayed_scaling_recipe and self .fp8 and in_fp8_activation_recompute_phase ():
1711+ FP8GlobalStateManager .restore_fp8_meta_tensors (self .fp8_meta )
1712+ finally :
1713+ nvtx_range_pop ()
1714+ finally :
1715+ self ._release_forward_device_guard ()
16971716
16981717 @contextmanager
16991718 def prepare_forward_ctx (
0 commit comments