@@ -21,10 +21,21 @@ class ResidualConnection(nn.Module, ABC):
2121 ``forward`` validates the common contract and retains the incoming residual
2222 stream as the first tensor in ``ResidualConnectionState``. Concrete connections
2323 own bias, dropout, mapping, and residual-update semantics.
24+
25+ ``operation`` fixes an instance to one operation at construction.
2426 """
2527
26- def __init__ (self , residual_stream_hidden_size : int , branch_hidden_size : int ):
28+ def __init__ (
29+ self ,
30+ residual_stream_hidden_size : int ,
31+ branch_hidden_size : int ,
32+ * ,
33+ operation : ResidualConnectionOperation ,
34+ ):
2735 super ().__init__ ()
36+ if operation not in ("read" , "write" ):
37+ raise ValueError (f"Unsupported residual connection operation: { operation } ." )
38+ self .operation = operation
2839 if residual_stream_hidden_size <= 0 :
2940 raise ValueError ("Residual-stream hidden size must be positive." )
3041 if branch_hidden_size <= 0 :
@@ -49,7 +60,6 @@ def forward(
4960 self ,
5061 value : Tensor ,
5162 * ,
52- operation : Literal ["read" ],
5363 fp32_residual_connection : bool = False ,
5464 branch_input_dtype : torch .dtype | None = None ,
5565 ) -> tuple [Tensor , ResidualConnectionState ]: ...
@@ -59,7 +69,6 @@ def forward(
5969 self ,
6070 value : ResidualBranchOutput ,
6171 * ,
62- operation : Literal ["write" ],
6372 state : ResidualConnectionState ,
6473 dropout_probability : float ,
6574 training : bool ,
@@ -69,7 +78,6 @@ def forward(
6978 self ,
7079 value : ResidualBranchOutput ,
7180 * ,
72- operation : ResidualConnectionOperation ,
7381 state : ResidualConnectionState | None = None ,
7482 fp32_residual_connection : bool = False ,
7583 branch_input_dtype : torch .dtype | None = None ,
@@ -82,37 +90,39 @@ def forward(
8290 dtype; otherwise compatible connections may produce that dtype directly in a fused read.
8391 """
8492
85- if operation == "read" :
86- if not torch .is_tensor (value ):
87- raise TypeError ("Residual connection read expects a tensor." )
88- if state is not None or dropout_probability is not None or training is not None :
89- raise TypeError ("Residual connection read received write-only arguments." )
90- if branch_input_dtype is not None and (
91- not isinstance (branch_input_dtype , torch .dtype )
92- or not branch_input_dtype .is_floating_point
93- ):
94- raise TypeError (
95- "branch_input_dtype must be a floating-point torch.dtype or None, got "
96- f"{ branch_input_dtype !r} ."
93+ match self .operation :
94+ case "read" :
95+ if not torch .is_tensor (value ):
96+ raise TypeError ("Residual connection read expects a tensor." )
97+ if state is not None or dropout_probability is not None or training is not None :
98+ raise TypeError ("Residual connection read received write-only arguments." )
99+ if branch_input_dtype is not None and (
100+ not isinstance (branch_input_dtype , torch .dtype )
101+ or not branch_input_dtype .is_floating_point
102+ ):
103+ raise TypeError (
104+ "branch_input_dtype must be a floating-point torch.dtype or None, got "
105+ f"{ branch_input_dtype !r} ."
106+ )
107+ return self ._read_with_validation (
108+ value ,
109+ fp32_residual_connection = fp32_residual_connection ,
110+ branch_input_dtype = branch_input_dtype ,
97111 )
98- return self ._read_with_validation (
99- value ,
100- fp32_residual_connection = fp32_residual_connection ,
101- branch_input_dtype = branch_input_dtype ,
102- )
103- if operation == "write" :
104- if fp32_residual_connection or branch_input_dtype is not None :
105- raise TypeError ("Residual connection write received read-only arguments." )
106- if state is None :
107- raise TypeError ("Residual connection write requires connection state." )
108- if dropout_probability is None or training is None :
109- raise TypeError (
110- "Residual connection write requires dropout_probability and training."
112+ case "write" :
113+ if fp32_residual_connection or branch_input_dtype is not None :
114+ raise TypeError ("Residual connection write received read-only arguments." )
115+ if state is None :
116+ raise TypeError ("Residual connection write requires connection state." )
117+ if dropout_probability is None or training is None :
118+ raise TypeError (
119+ "Residual connection write requires dropout_probability and training."
120+ )
121+ return self ._write_with_validation (
122+ value , state , dropout_probability = dropout_probability , training = training
111123 )
112- return self ._write_with_validation (
113- value , state , dropout_probability = dropout_probability , training = training
114- )
115- raise ValueError (f"Unsupported residual connection operation: { operation } ." )
124+ case _:
125+ raise ValueError (f"Unsupported residual connection operation: { self .operation } ." )
116126
117127 def _read_with_validation (
118128 self ,
0 commit comments