# Copyright (c) Meta Platforms, Inc. and affiliates.# All rights reserved.## This source code is licensed under the BSD-style license found in the# LICENSE file in the root directory of this source tree.from__future__importannotationsfromabcimportABC,abstractmethodfromtypingimportTYPE_CHECKING,cast,finalimporttorchfromtorchimportTensorfromtorch.nnimportModulefromtyping_extensionsimportoverridefromfairseq2.data_typeimportDataTypefromfairseq2.deviceimportDevice
[docs]classResidualConnect(Module,ABC):"""Represents a residual connection."""
[docs]@abstractmethoddefforward(self,seqs:Tensor,residual:Tensor)->Tensor:""" :param seqs: The sequences output by a module. *Shape:* :math:`(N,S,M)`, where :math:`N` is the batch size, :math:`S` is the sequence length, and :math:`M` is the dimensionality of the model. :param residual: The input sequences to the module. *Shape:* Same as ``seqs``. :returns: The output sequences with residuals applied. *Shape:* Same as ``seqs``. """
ifTYPE_CHECKING:__call__=forward
[docs]@finalclassAdditiveResidualConnect(ResidualConnect):"""Sums inputs and outputs of a module."""
[docs]@finalclassScaledResidualConnect(ResidualConnect):""" Scales residuals by a constant factor before adding them to the output of a Transformer module. """def__init__(self,scale:float)->None:""" :param scale: The scale factor. """self.scale=scale
@finalclassDropPathResidualConnect(ResidualConnect):""" Drops entire sequences from module outputs before adding residuals which effectively results in stochastic depth as described in section 3 of :cite:t:`https://doi.org/10.48550/arxiv.1603.09382`. .. note:: This implementation is mostly adapted from Ross Wightman's ``drop_path`` function in timm. """def__init__(self,drop_p:float,scale_by_keep:bool=True)->None:""" :param drop_p: The probability of dropping sequences from module outputs. :param scale_by_keep: If ``True``, non-dropped sequences will be scaled by the keep probability (i.e. ``1 - drop_p``) as in EfficientNet. """super().__init__()self.drop_p=drop_pself.scale_by_keep=scale_by_keep@overridedefforward(self,seqs:Tensor,residual:Tensor)->Tensor:ifnotself.trainingorself.drop_p==0.0:returnseqs+residualshape=[seqs.size(0)]+[1]*(seqs.ndim-1)keep_p=1.0-self.drop_p# (N)drop_mask=torch.rand(shape,device=seqs.device,dtype=seqs.dtype)+keep_pdrop_mask.floor_()# binarizeifself.scale_by_keep:seqs=seqs/keep_preturn(seqs*drop_mask)+residual@overridedefextra_repr(self)->str:returnf"drop_p={self.drop_p}, scale_by_keep={self.scale_by_keep}"@finalclassLAuReLResidualConnect(ResidualConnect):""" Learned Augmented Residual Layer (LAuReL) residual connection. Replaces identity residual with low-rank learned transformation followed by normalization. Used in Gemma3n to enhance residual paths with minimal parameter overhead. Reference: https://arxiv.org/abs/2411.07501 """def__init__(self,model_dim:int,rank:int,layer_norm:Module,*,device:Device|None=None,dtype:DataType|None=None,)->None:""" :param model_dim: Dimensionality of the model. :param rank: Rank of the low-rank factorization. :param layer_norm: Layer normalization applied after residual connection. """super().__init__()fromfairseq2.nn.projectionimportLinearself.linear_left=Linear(model_dim,rank,bias=False,device=device,dtype=dtype)self.linear_right=Linear(rank,model_dim,bias=False,device=device,dtype=dtype)self.layer_norm=layer_norm@overridedefforward(self,seqs:Tensor,residual:Tensor)->Tensor:residual_transformed=self.linear_right(self.linear_left(residual))returncast(Tensor,self.layer_norm(seqs+residual_transformed))@overridedefextra_repr(self)->str:returnf"rank={self.linear_left.output_dim}"