| 333 | |
| 334 | |
| 335 | class TensorParallelRNGTracker(RNGStateTracker): |
| 336 | def __init__(self, device_type: str = "cuda"): |
| 337 | super().__init__(device_type) |
| 338 | # copy the default RNG state |
| 339 | self.rng_states["tensor-parallel-rng"] = self._device_handle.get_rng_state() |
| 340 | |
| 341 | def _manual_seed( |
| 342 | self, |
| 343 | device_mesh: DeviceMesh, |
| 344 | base_seed: int = 1234, |
| 345 | tp_dim: int = 0, |
| 346 | ): |
| 347 | coordinate = device_mesh.get_coordinate() |
| 348 | assert coordinate is not None |
| 349 | tensor_parallel_rank = coordinate[tp_dim] |
| 350 | # this magic number 2718 comes from Megatron's code |
| 351 | # (https://github.com/NVIDIA/Megatron-LM/blob/060415572f4365a2e895f8036c4e37dad0efbdf5/megatron/core/tensor_parallel/random.py#L162-L163) |
| 352 | MegatronMagicNum = 2718 |
| 353 | tensor_parallel_seed = base_seed + MegatronMagicNum + tensor_parallel_rank |
| 354 | self.set_seed("tensor-parallel-rng", tensor_parallel_seed) |
| 355 | |
| 356 | @contextlib.contextmanager |
| 357 | def _distribute_region(self, spec: DTensorSpec): |
| 358 | # check if the tensor parallel rng state has been synchronized or not |
| 359 | if not self.rng_state_is_sync("tensor-parallel-rng"): |
| 360 | raise RuntimeError( |
| 361 | "TensorParallelRNGTracker requires the random state to be synchronized " |
| 362 | "before entering into a distribute region!" |
| 363 | ) |
| 364 | |
| 365 | if self.distribute_region_enabled: |
| 366 | with torch.random.fork_rng(self._devices, device_type=self._device_type): |
| 367 | self._device_handle.set_rng_state( |
| 368 | self.rng_states["tensor-parallel-rng"] |
| 369 | ) |
| 370 | try: |
| 371 | yield |
| 372 | finally: |
| 373 | self.rng_states[ |
| 374 | "tensor-parallel-rng" |
| 375 | ] = self._device_handle.get_rng_state() |
| 376 | else: |
| 377 | yield |
no outgoing calls
no test coverage detected
searching dependent graphs…