Commit 73a48a8
DFlashProposer: platform-aware peak memory measurement (CUDA / MPS / CPU)
Step 3a of the post-PR-#93 merge plan. PR #93's DFlashProposer.
propose_block recorded peak activation bytes via:
peak = 0
if torch.cuda.is_available():
torch.cuda.reset_peak_memory_stats()
tokens = self.drafter.draft_block(...)
if torch.cuda.is_available():
peak = int(torch.cuda.max_memory_allocated())
return BlockProposal(..., peak_activation_bytes=peak)
This silently returned 0 on Mac MPS / CPU. The Mac MLX speculative-
decoding eval (next PR, Step 3b) needs honest peak memory numbers
on Apple Silicon for the BlockProposal accounting to be meaningful.
Fix: extract three module-level helpers in dflash_drafter.py that
dispatch by torch device type:
_detect_device(model) -> str
Reads model.parameters() to determine 'cuda' / 'mps' / 'cpu'.
Raises RuntimeError on parameterless models (defensive — every
real DFlashDrafter has parameters).
_reset_peak_memory(device) -> None
CUDA: torch.cuda.reset_peak_memory_stats() (existing behaviour)
MPS: no-op (MPS has no peak counter; see docstring caveat)
CPU: no-op (CPU peak measurement is psutil/tracemalloc territory)
Unknown device: no-op
_peak_memory_bytes(device) -> int
CUDA: torch.cuda.max_memory_allocated()
MPS: torch.mps.driver_allocated_memory() with try/except for
runtime failure (returns 0 on RuntimeError, e.g. MPS
attribute exists but actual MPS not initialised)
CPU: 0 (signal: unmeasured, NOT lying with a fake peak)
Unknown device: 0 (signal: unmeasured)
DFlashProposer.propose_block rewired to:
device = _detect_device(self.drafter)
_reset_peak_memory(device)
tokens = self.drafter.draft_block(...)
peak = _peak_memory_bytes(device)
return BlockProposal(..., peak_activation_bytes=peak)
CUDA path semantics unchanged (same helpers, same calls, same
output values). MPS/CPU paths now produce honest values instead
of silently returning 0 in all cases.
Caveats documented inline:
* MPS has no peak counter. We use post-forward
driver_allocated_memory as a tight upper bound on activations
released after the forward — close enough for spec-decode-loop
memory accounting in single-process scenarios. Stricter delta
measurement requires the caller to snapshot before/after via
torch.mps.driver_allocated_memory and subtract.
* CPU returns 0 deliberately (signal: unmeasured) rather than
lying with a fake measurement. CPU peak measurement is a
different problem (psutil RSS or tracemalloc) outside the
scope of activation-byte accounting in BlockProposal.
Tests added (TestPlatformAwarePeakMemory, 8 tests):
test_detect_device_cpu — synthetic small DFlashDrafter on CPU
returns 'cpu'
test_detect_device_raises_on_empty_model — defensive check
test_peak_memory_bytes_cpu_returns_zero — unmeasured signal
test_peak_memory_bytes_unknown_device_returns_zero — generic
fallthrough
test_reset_peak_memory_cpu_is_noop — no-op on cpu/unknown
test_propose_block_records_zero_peak_on_cpu — full path:
drafter on CPU → propose_block runs → BlockProposal has
peak_activation_bytes=0 (no crash, no fake)
test_peak_memory_bytes_mps_calls_driver_allocated_memory —
direct unit of the helper for the MPS branch using a
module-attribute swap (avoids monkeypatch scope creep on
torch internals during draft_block forward — torch.random
reaches into torch.mps._is_in_bad_fork etc.). Confirms
_peak_memory_bytes('mps') returns int(driver_allocated_memory())
test_peak_memory_bytes_mps_handles_runtime_failure — when
torch.mps.driver_allocated_memory raises (MPS attribute
exists but MPS not actually initialised), helper returns 0
not propagates.
Verified: stashing the fix and re-running these tests reproduces
7 of 8 failures cleanly (the 8th — empty model — passes by
luck because raise-on-empty was the original behaviour). Un-
stashing produces 28/28.
Tests: 315/315 v04 suite passes (307 pre-existing + 8 new
regression).
Stack: off main, post PR #93 + PR #99 + PR #94 merge. This is
Step 3a of the merge plan; Step 3b (Mac MLX speculative
decoding eval script + reviewer aid) lands as a follow-up
PR off main once Step 4 (mlx_lm Gemma 4 MoE compat fix)
has empirical evidence the user can act on.
Why split Step 3 into 3a + 3b:
* 3a (this PR) lands a small, fully-testable improvement to
PR #93's already-merged code. Useful regardless of when 3b
lands. Linux CI exercises the platform dispatch logic
without requiring Apple Silicon.
* 3b needs to write speculative MLX bridge code (mx.array →
torch.Tensor for hiddens; embed_fn / lm_head_fn callbacks
that span the two runtimes). Writing that without ability
to verify against a working mlx_lm verifier load = the same
'fake/fallback' pattern the user just got us out of with PR
#93. Better to wait for Step 4 evidence + a working
verifier load before authoring 3b.
Net effect: PR #93's BlockProposal.peak_activation_bytes now
reflects honest measurement on whichever device the drafter
actually runs on, instead of always being 0 on non-CUDA
hardware. Sets up Step 3b (Mac MLX eval) to produce meaningful
memory accounting.
Co-authored-by: FluffyAIcode <FluffyAIcode@users.noreply.github.com>1 parent 6251230 commit 73a48a8
2 files changed
Lines changed: 191 additions & 5 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
568 | 568 | | |
569 | 569 | | |
570 | 570 | | |
571 | | - | |
572 | | - | |
573 | | - | |
| 571 | + | |
| 572 | + | |
574 | 573 | | |
575 | 574 | | |
576 | 575 | | |
| |||
580 | 579 | | |
581 | 580 | | |
582 | 581 | | |
583 | | - | |
584 | | - | |
| 582 | + | |
585 | 583 | | |
586 | 584 | | |
587 | 585 | | |
| |||
592 | 590 | | |
593 | 591 | | |
594 | 592 | | |
| 593 | + | |
| 594 | + | |
| 595 | + | |
| 596 | + | |
| 597 | + | |
| 598 | + | |
| 599 | + | |
| 600 | + | |
| 601 | + | |
| 602 | + | |
| 603 | + | |
| 604 | + | |
| 605 | + | |
| 606 | + | |
| 607 | + | |
| 608 | + | |
| 609 | + | |
| 610 | + | |
| 611 | + | |
| 612 | + | |
| 613 | + | |
| 614 | + | |
| 615 | + | |
| 616 | + | |
| 617 | + | |
| 618 | + | |
| 619 | + | |
| 620 | + | |
| 621 | + | |
| 622 | + | |
| 623 | + | |
| 624 | + | |
| 625 | + | |
| 626 | + | |
| 627 | + | |
| 628 | + | |
| 629 | + | |
| 630 | + | |
| 631 | + | |
| 632 | + | |
| 633 | + | |
| 634 | + | |
| 635 | + | |
| 636 | + | |
| 637 | + | |
| 638 | + | |
| 639 | + | |
| 640 | + | |
| 641 | + | |
| 642 | + | |
| 643 | + | |
| 644 | + | |
| 645 | + | |
| 646 | + | |
| 647 | + | |
| 648 | + | |
| 649 | + | |
| 650 | + | |
| 651 | + | |
| 652 | + | |
| 653 | + | |
| 654 | + | |
| 655 | + | |
| 656 | + | |
| 657 | + | |
| 658 | + | |
| 659 | + | |
| 660 | + | |
| 661 | + | |
| 662 | + | |
| 663 | + | |
| 664 | + | |
| 665 | + | |
| 666 | + | |
| 667 | + | |
| 668 | + | |
| 669 | + | |
| 670 | + | |
| 671 | + | |
| 672 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
306 | 306 | | |
307 | 307 | | |
308 | 308 | | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
0 commit comments