|
1 | 1 | # ruff: noqa: RUF013 |
2 | 2 | ## built-in |
| 3 | +from typing import Optional |
| 4 | + |
3 | 5 | import torch |
4 | 6 | from torch import Tensor |
5 | 7 |
|
@@ -27,26 +29,41 @@ def __init__(self, hash_mapping, input_ids, hash_stream=None): |
27 | 29 | self.input_ids = input_ids |
28 | 30 | self.hash_stream = hash_stream |
29 | 31 | self._result = None |
30 | | - self._computation_started = False |
31 | | - |
32 | | - # torch.cuda.nvtx.range_push("LazyHashInputIds hash") |
33 | | - # Start async computation immediately if stream is available |
| 32 | + self._is_async_pending = False |
| 33 | + # Async |
34 | 34 | if self.hash_stream is not None: |
| 35 | + # self.hash_stream.wait_stream(torch.cuda.current_stream()) |
35 | 36 | with torch.cuda.stream(self.hash_stream): |
36 | 37 | self._result = self.hash_mapping.hash(self.input_ids) |
37 | | - self._computation_started = True |
38 | | - # torch.cuda.nvtx.range_pop() |
| 38 | + self._is_async_pending = True |
| 39 | + # record result to use across stream |
| 40 | + self._record_current_stream() |
39 | 41 |
|
40 | | - def __getitem__(self, key): |
41 | | - """Access hash result, synchronizing if necessary.""" |
| 42 | + def _record_current_stream(self): |
| 43 | + """Helper to record current stream on all result tensors""" |
42 | 44 | if self._result is None: |
43 | | - if self.hash_stream is not None and self._computation_started: |
44 | | - # Wait for async computation to complete |
45 | | - torch.cuda.current_stream().wait_stream(self.hash_stream) |
46 | | - self._computation_started = False # Mark as synchronized |
47 | | - else: |
48 | | - # Compute synchronously if no stream or computation not started |
49 | | - self._result = self.hash_mapping.hash(self.input_ids) |
| 45 | + return |
| 46 | + current_stream = torch.cuda.current_stream() |
| 47 | + if isinstance(self._result, dict): |
| 48 | + for t in self._result.values(): |
| 49 | + if isinstance(t, torch.Tensor): |
| 50 | + t.record_stream(current_stream) |
| 51 | + elif isinstance(self._result, torch.Tensor): |
| 52 | + self._result.record_stream(current_stream) |
| 53 | + |
| 54 | + def __getitem__(self, key): |
| 55 | + # Case 1: Async compute -> wait |
| 56 | + if self._is_async_pending: |
| 57 | + torch.cuda.current_stream().wait_stream(self.hash_stream) |
| 58 | + self._is_async_pending = False # Async finish |
| 59 | + self._record_current_stream() |
| 60 | + |
| 61 | + # Case 2: Sync but no compute -> start compute |
| 62 | + elif self._result is None: |
| 63 | + self._result = self.hash_mapping.hash(self.input_ids) |
| 64 | + |
| 65 | + # Case 3: Async or sync compute is finished. |
| 66 | + # print(f"[rank{torch.distributed.get_rank()}]: LazyHashInputIds result = {self._result}") |
50 | 67 | return self._result[key] |
51 | 68 |
|
52 | 69 | def get(self, key, default=None): |
@@ -171,7 +188,40 @@ def forward( |
171 | 188 | inference_context=inference_context, |
172 | 189 | ) |
173 | 190 |
|
174 | | - def sharded_state_dict( |
175 | | - self, prefix: str = "", sharded_offsets: tuple = (), metadata: dict | None = None |
| 191 | + def build_schedule_plan( |
| 192 | + self, |
| 193 | + input_ids: Tensor, |
| 194 | + position_ids: Tensor, |
| 195 | + attention_mask: Tensor, |
| 196 | + decoder_input: Tensor = None, |
| 197 | + labels: Tensor = None, |
| 198 | + inference_context: BaseInferenceContext = None, |
| 199 | + packed_seq_params: PackedSeqParams = None, |
| 200 | + extra_block_kwargs: dict = None, |
| 201 | + runtime_gather_output: Optional[bool] = None, |
| 202 | + inference_params: Optional[BaseInferenceContext] = None, |
| 203 | + loss_mask: Optional[Tensor] = None, |
176 | 204 | ): |
177 | | - raise NotImplementedError("Sharded state dict is not supported for EngramModel") |
| 205 | + """ |
| 206 | + Adaptation of overlap_moe_expert_parallel_comm. |
| 207 | + """ |
| 208 | + # Precompute the engram_hash_iput_ids, it will be used to create a TransformerChunkSchedulePlan. |
| 209 | + engram_hash_input_ids = LazyHashInputIds( |
| 210 | + hash_mapping=self.engram_hash, |
| 211 | + input_ids=input_ids, |
| 212 | + hash_stream=self._hash_stream, |
| 213 | + ) |
| 214 | + if extra_block_kwargs is None: |
| 215 | + extra_block_kwargs = { |
| 216 | + "engram_hash_input_ids": engram_hash_input_ids, |
| 217 | + } |
| 218 | + return super().build_schedule_plan( |
| 219 | + input_ids, |
| 220 | + position_ids, |
| 221 | + attention_mask, |
| 222 | + decoder_input, |
| 223 | + labels=labels, |
| 224 | + loss_mask=loss_mask, |
| 225 | + extra_block_kwargs=extra_block_kwargs |
| 226 | + ) |
| 227 | + |
0 commit comments