Linear layer with column parallelism. The linear layer is defined as Y = XA + b. A is parallelized along its second dimension as A = [A_1, ..., A_p]. Arguments: input_size: first dimension of matrix A. output_size: second dimension of matrix A. bias: If true, ad
| 177 | |
| 178 | |
| 179 | class ColumnParallelLinear(torch.nn.Module): |
| 180 | """Linear layer with column parallelism. |
| 181 | |
| 182 | The linear layer is defined as Y = XA + b. A is parallelized along |
| 183 | its second dimension as A = [A_1, ..., A_p]. |
| 184 | |
| 185 | Arguments: |
| 186 | input_size: first dimension of matrix A. |
| 187 | output_size: second dimension of matrix A. |
| 188 | bias: If true, add bias |
| 189 | gather_output: If true, call all-gether on output and make Y avaiable |
| 190 | to all GPUs, otherwise, every GPU will have its output |
| 191 | which is Y_i = XA_i |
| 192 | init_method: method to initialize weights. Note that bias is always set |
| 193 | to zero. |
| 194 | stride: For the strided linear layers. |
| 195 | keep_master_weight_for_test: This was added for testing and should be |
| 196 | set to False. It returns the master weights |
| 197 | used for initialization. |
| 198 | """ |
| 199 | def __init__(self, input_size, output_size, bias=True, gather_output=True, |
| 200 | init_method=init.xavier_normal_, stride=1, |
| 201 | keep_master_weight_for_test=False): |
| 202 | super(ColumnParallelLinear, self).__init__() |
| 203 | |
| 204 | # Keep input parameters |
| 205 | self.input_size = input_size |
| 206 | self.output_size = output_size |
| 207 | self.gather_output = gather_output |
| 208 | # Divide the weight matrix along the last dimension. |
| 209 | world_size = get_model_parallel_world_size() |
| 210 | self.output_size_per_partition = divide(output_size, world_size) |
| 211 | |
| 212 | # Parameters. |
| 213 | # Note: torch.nn.functional.linear performs XA^T + b and as a result |
| 214 | # we allocate the transpose. |
| 215 | self.weight = Parameter(torch.Tensor(self.output_size_per_partition, |
| 216 | self.input_size)) |
| 217 | self.weight.model_parallel = True |
| 218 | if bias: |
| 219 | self.bias = Parameter(torch.Tensor(self.output_size_per_partition)) |
| 220 | self.bias.model_parallel = True |
| 221 | # Always initialize bias to zero. |
| 222 | with torch.no_grad(): |
| 223 | self.bias.zero_() |
| 224 | else: |
| 225 | self.register_parameter('bias', None) |
| 226 | |
| 227 | # Initialize weight. |
| 228 | self.master_weight = _initialize_affine_weight( |
| 229 | self.weight, self.output_size, self.input_size, |
| 230 | self.output_size_per_partition, 0, init_method, |
| 231 | stride=stride, return_master_weight=keep_master_weight_for_test) |
| 232 | |
| 233 | def forward(self, input_): |
| 234 | # Set up backprop all-reduce. |
| 235 | input_parallel = copy_to_model_parallel_region(input_) |
| 236 | # Matrix multiply. |