| 311 | |
| 312 | |
| 313 | class Linear(LinearBase): |
| 314 | |
| 315 | def __init__( |
| 316 | self, |
| 317 | in_features, |
| 318 | out_features, |
| 319 | bias=True, |
| 320 | dtype=None, |
| 321 | tp_group=None, |
| 322 | tp_size=1, |
| 323 | gather_output=True, |
| 324 | share_weight=None, |
| 325 | strict_dtype=False, |
| 326 | pad_lda=0, |
| 327 | pad_ldc=0, |
| 328 | prefer_managed_weight=True, |
| 329 | is_qkv=False, |
| 330 | ): |
| 331 | super().__init__( |
| 332 | local_in_features=in_features, |
| 333 | local_out_features=out_features // tp_size, |
| 334 | bias=bias, |
| 335 | dtype=dtype, |
| 336 | tp_group=tp_group, |
| 337 | tp_size=tp_size, |
| 338 | share_weight=share_weight, |
| 339 | strict_dtype=strict_dtype, |
| 340 | pad_lda=pad_lda, |
| 341 | pad_ldc=pad_ldc, |
| 342 | prefer_managed_weight=prefer_managed_weight, |
| 343 | ) |
| 344 | self.gather_output = gather_output |
| 345 | self.is_qkv = is_qkv |
| 346 | self.tp_dim = 0 |
| 347 | if bias: |
| 348 | set_obj_attrs( |
| 349 | self.bias, |
| 350 | { |
| 351 | "weight_loader": self.weight_loader, |
| 352 | }, |
| 353 | ) |
| 354 | |
| 355 | @classmethod |
| 356 | def tp_split_dim(cls) -> int: |
| 357 | return 0 |
| 358 | |
| 359 | def collect_and_bias(self, x, **kwargs): |
| 360 | |
| 361 | if self.bias is not None: |
| 362 | bias = cast(self.bias.value, x.dtype) |
| 363 | x = x + bias |
| 364 | |
| 365 | if self.gather_output and self.tp_size > 1 and self.tp_group is not None: |
| 366 | # [dim0, local_dim] -> [dim0 * tp_size, local_dim] --> [dim0, local_dim * tp_size] |
| 367 | x = allgather(x, self.tp_group, gather_dim=-1) |
| 368 | |
| 369 | return x |
| 370 |
no outgoing calls