BonanDing commited on
Commit
7a609df
·
1 Parent(s): d762809

Measure DeMemWM inference noise-route pruning

Browse files
.exp_artifact/dememwm_noise_route_inference_pruning/diagnostic.py CHANGED
@@ -1,6 +1,7 @@
1
  from pathlib import Path
2
  from types import SimpleNamespace
3
  import sys
 
4
 
5
  import torch
6
 
@@ -23,6 +24,8 @@ STREAM_VALUES = {"anchor": 20.0, "dynamic": 30.0, "revisit": 40.0}
23
  STREAM_NOISE_BASE = {"anchor": 200, "dynamic": 300, "revisit": 400}
24
  BATCH_SIZE = 2
25
  TARGET_LENGTH = 3
 
 
26
 
27
 
28
  def _make_inputs(stream_masks):
@@ -86,6 +89,22 @@ def _target_proxy(packed_latents, frame_memory_segments, frame_memory_masks):
86
  return target + contribution.unsqueeze(0)
87
 
88
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
  def _full_proxy_inputs(inputs, routed_masks):
90
  packed_latents = torch.cat(
91
  [inputs["target_latents"], *[inputs["stream_latents_by_key"][key] for key in _DEMEMWM_STREAM_KEYS]],
@@ -142,6 +161,8 @@ def _run_case(name, sampler_index, stream_masks, expected_active, expected_prune
142
  )
143
 
144
  full_segments = {"target": TARGET_LENGTH, **{key: STREAM_LENGTHS[key] for key in _DEMEMWM_STREAM_KEYS}}
 
 
145
  full_memory_tokens = sum(full_segments[key] for key in _DEMEMWM_STREAM_KEYS)
146
  pruned_memory_tokens = sum(active_segments[key] for key in _DEMEMWM_STREAM_KEYS)
147
 
@@ -156,7 +177,7 @@ def _run_case(name, sampler_index, stream_masks, expected_active, expected_prune
156
  _check(active_segments[key] == STREAM_LENGTHS[key], f"{name}: active {key} segment length changed")
157
  _check(torch.equal(active_masks[key], routed_masks[key]), f"{name}: active {key} mask changed")
158
 
159
- expected_total_len = TARGET_LENGTH + pruned_memory_tokens
160
  _check(active_packed_latents.shape == (expected_total_len, BATCH_SIZE, 2), f"{name}: packed latent shape mismatch")
161
  _check(active_packed_conditions.shape == (expected_total_len, BATCH_SIZE, 4), f"{name}: packed condition shape mismatch")
162
  _check(active_frame_memory_pose.shape == (expected_total_len, BATCH_SIZE, 3), f"{name}: packed pose shape mismatch")
@@ -180,14 +201,30 @@ def _run_case(name, sampler_index, stream_masks, expected_active, expected_prune
180
  )
181
 
182
  full_latents, full_proxy_segments, full_proxy_masks = _full_proxy_inputs(inputs, routed_masks)
183
- full_output = _target_proxy(full_latents, full_proxy_segments, full_proxy_masks)
184
- pruned_output = _target_proxy(active_packed_latents, active_segments, active_masks)
 
 
 
 
 
 
 
185
  target_max_abs_diff = (full_output - pruned_output).abs().max().item()
186
  _check(target_max_abs_diff == 0.0, f"{name}: proxy target output changed by {target_max_abs_diff}")
 
 
187
 
188
  print(f"case={name}")
189
  print(f" route=anchor:high,dynamic:low,revisit:all")
190
  print(f" denoising_step={sampler_index} noise_level={_sampler_index_noise(sampler_index)}")
 
 
 
 
 
 
 
191
  print(f" active_streams={active_streams}")
192
  print(f" pruned_streams={pruned_streams}")
193
  print(f" full_memory_token_count={full_memory_tokens}")
 
1
  from pathlib import Path
2
  from types import SimpleNamespace
3
  import sys
4
+ import time
5
 
6
  import torch
7
 
 
24
  STREAM_NOISE_BASE = {"anchor": 200, "dynamic": 300, "revisit": 400}
25
  BATCH_SIZE = 2
26
  TARGET_LENGTH = 3
27
+ TIMING_WARMUP = 20
28
+ TIMING_ITERS = 1000
29
 
30
 
31
  def _make_inputs(stream_masks):
 
89
  return target + contribution.unsqueeze(0)
90
 
91
 
92
+ def _time_proxy_call(fn, timing_tensor):
93
+ backend = "cuda_proxy" if timing_tensor.is_cuda else "cpu_proxy"
94
+ with torch.no_grad():
95
+ for _ in range(TIMING_WARMUP):
96
+ output = fn()
97
+ if timing_tensor.is_cuda:
98
+ torch.cuda.synchronize(timing_tensor.device)
99
+ start = time.perf_counter()
100
+ for _ in range(TIMING_ITERS):
101
+ output = fn()
102
+ if timing_tensor.is_cuda:
103
+ torch.cuda.synchronize(timing_tensor.device)
104
+ elapsed_ms = (time.perf_counter() - start) * 1000.0 / TIMING_ITERS
105
+ return output, elapsed_ms, backend
106
+
107
+
108
  def _full_proxy_inputs(inputs, routed_masks):
109
  packed_latents = torch.cat(
110
  [inputs["target_latents"], *[inputs["stream_latents_by_key"][key] for key in _DEMEMWM_STREAM_KEYS]],
 
161
  )
162
 
163
  full_segments = {"target": TARGET_LENGTH, **{key: STREAM_LENGTHS[key] for key in _DEMEMWM_STREAM_KEYS}}
164
+ full_tokens = sum(full_segments.values())
165
+ pruned_tokens = sum(active_segments.values())
166
  full_memory_tokens = sum(full_segments[key] for key in _DEMEMWM_STREAM_KEYS)
167
  pruned_memory_tokens = sum(active_segments[key] for key in _DEMEMWM_STREAM_KEYS)
168
 
 
177
  _check(active_segments[key] == STREAM_LENGTHS[key], f"{name}: active {key} segment length changed")
178
  _check(torch.equal(active_masks[key], routed_masks[key]), f"{name}: active {key} mask changed")
179
 
180
+ expected_total_len = pruned_tokens
181
  _check(active_packed_latents.shape == (expected_total_len, BATCH_SIZE, 2), f"{name}: packed latent shape mismatch")
182
  _check(active_packed_conditions.shape == (expected_total_len, BATCH_SIZE, 4), f"{name}: packed condition shape mismatch")
183
  _check(active_frame_memory_pose.shape == (expected_total_len, BATCH_SIZE, 3), f"{name}: packed pose shape mismatch")
 
201
  )
202
 
203
  full_latents, full_proxy_segments, full_proxy_masks = _full_proxy_inputs(inputs, routed_masks)
204
+ full_output, full_step_ms, full_backend = _time_proxy_call(
205
+ lambda: _target_proxy(full_latents, full_proxy_segments, full_proxy_masks),
206
+ full_latents,
207
+ )
208
+ pruned_output, pruned_step_ms, pruned_backend = _time_proxy_call(
209
+ lambda: _target_proxy(active_packed_latents, active_segments, active_masks),
210
+ active_packed_latents,
211
+ )
212
+ _check(full_backend == pruned_backend, f"{name}: timing backend changed across proxy calls")
213
  target_max_abs_diff = (full_output - pruned_output).abs().max().item()
214
  _check(target_max_abs_diff == 0.0, f"{name}: proxy target output changed by {target_max_abs_diff}")
215
+ token_reduction_pct = 100.0 * (1.0 - float(pruned_tokens) / float(full_tokens))
216
+ speedup_ratio = full_step_ms / pruned_step_ms if pruned_step_ms > 0.0 else float("inf")
217
 
218
  print(f"case={name}")
219
  print(f" route=anchor:high,dynamic:low,revisit:all")
220
  print(f" denoising_step={sampler_index} noise_level={_sampler_index_noise(sampler_index)}")
221
+ print(f" timing_backend={full_backend} timing_iters={TIMING_ITERS}")
222
+ print(f" full_tokens={full_tokens}")
223
+ print(f" pruned_tokens={pruned_tokens}")
224
+ print(f" token_reduction_pct={token_reduction_pct:.2f}")
225
+ print(f" full_step_ms={full_step_ms:.6f}")
226
+ print(f" pruned_step_ms={pruned_step_ms:.6f}")
227
+ print(f" speedup_ratio={speedup_ratio:.3f}")
228
  print(f" active_streams={active_streams}")
229
  print(f" pruned_streams={pruned_streams}")
230
  print(f" full_memory_token_count={full_memory_tokens}")