Skip to content

feat: add bounded asynchronous hidden-state fan-out#811

Open
heiheiha798 wants to merge 22 commits into
vllm-project:mainfrom
heiheiha798:feat/bounded-async-window-fanout
Open

feat: add bounded asynchronous hidden-state fan-out#811
heiheiha798 wants to merge 22 commits into
vllm-project:mainfrom
heiheiha798:feat/bounded-async-window-fanout

Conversation

@heiheiha798

@heiheiha798 heiheiha798 commented Jul 18, 2026

Copy link
Copy Markdown

Purpose

Resolves #810.

Add opt-in bounded asynchronous hidden-state fan-out for independent consumers:

  • coalesce identical producer misses and atomically publish one packed artifact;
  • maintain an independent sliding window and committed cursor for each consumer;
  • retain artifacts only while they belong to a live window or active lease;
  • prioritize demand while filling bounded lookahead asynchronously;
  • support heterogeneous consumer rates without a shared progress barrier;
  • validate 1P1C/1P3C topology, request multiplicity, failure accounting, and common
    steady-state windows in a reproducible benchmark harness;
  • record role-aware NVML utilization and memory without initializing CUDA in the
    monitor; and
  • reduce DFlash consumer overhead with fused AdamW/integrated clipping and an optional,
    version-pinned Liger fused linear cross-entropy backend.

All new training behavior is opt-in. Existing online/offline data paths and optimizer
defaults remain unchanged. The first shared-artifact backend requires POSIX flock,
same-filesystem atomic rename, and directory fsync; it does not claim arbitrary NFS
or GPU-direct support.

Scope and related Mooncake work

This PR does not add a Mooncake payload backend. Its shared-artifact cache stores
safetensors on a shared POSIX filesystem, and all 1P3C throughput, memory, and NVML
results below measure that filesystem implementation.

A related Mooncake-backed bounded asynchronous producer/consumer implementation is
publicly available in
sgl-project/SpecForge#707. It includes
zero-copy transport and fan-out lifetime ownership. That implementation provides useful
related validation for the lifecycle invariants and benchmark design here, but its
Mooncake code is not included in this PR.

Upstream Mooncake work already exists in #605 and #710, with #735 providing the merged
hidden-state transfer abstraction and current file backend. This PR does not claim first
Mooncake support or attempt to duplicate those open changes.

The coordinator in this PR currently carries concrete filesystem paths in its read and
eviction leases. Supporting Mooncake for the shared fan-out payload therefore requires a
follow-up refactor to opaque artifact references and a store protocol; it is not an
already supported configuration or a drop-in adapter today. That follow-up should be
coordinated with #605/#710.

Three aligned Qwen3-8B DFlash 1P3C runs (3072 tokens, 256 anchors, heterogeneous block
sizes 4/8/16, 30 warmup plus 150 measured steps per consumer) produced aggregate steady
throughput of 6.3735, 6.2856, and 6.5702 steps/s. Median per-consumer rates were
2.2643/2.3135/1.6978 steps/s, and producer utilization was 100% over the common steady
interval.

Tests

  • make quality on Python 3.10, 3.12, and 3.13: passed (Ruff, formatting,
    Markdown, and Mypy).
  • Focused affected unit tests: 181 passed, 1 skipped.
  • Compiled optional Liger CUDA forward/backward integration: 1 passed.
  • Package build: sdist and wheel built successfully.
  • Isolated Python 3.13 wheel smoke without liger-kernel: installed-package import,
    lazy fused-CE import, training CLI help, benchmark config validation, and dependency
    consistency all passed.
  • git diff --check, DCO validation, and sensitive/local-path scan: passed.
  • 10k/100k window state-machine cases: passed as part of the focused tests.

An additional local mkdocs build --strict generated the complete site but did not
exit after generation. The same behavior and the same 17 pre-existing Griffe warnings
were reproduced at the upstream base commit; no warning points to a changed file.

Checklist

I have filled in:

  • The purpose of the PR, such as "Fix some issue (link existing issues this PR will resolve)".
  • The test plan/results, such as providing test command and pasting the results.
  • (Optional) The necessary documentation update.
  • I (a human) have written or reviewed the code in this pr to the best of my ability.

Follow-up validation at 5dfac24

  • The issue Enable CI/CD and standardize build system setup #1 lifecycle and benchmark follow-up fixes are included in commits 2d7156d, 47c2805, and 5dfac24.
  • make quality passes in the Python 3.12 project environment: Ruff, formatting, Markdown, and mypy (183 files).
  • Focused affected tests pass: 198 passed (19 warnings).
  • Wheel build passes and includes the corrected THIRD_PARTY_NOTICES.
  • The follow-up did not run the full test suite or CI.

Signed-off-by: heiheiha798 <2300012738@stu.pku.edu.cn>
Signed-off-by: heiheiha798 <2300012738@stu.pku.edu.cn>
Signed-off-by: heiheiha798 <2300012738@stu.pku.edu.cn>
Signed-off-by: heiheiha798 <2300012738@stu.pku.edu.cn>
Signed-off-by: heiheiha798 <2300012738@stu.pku.edu.cn>
Signed-off-by: heiheiha798 <2300012738@stu.pku.edu.cn>
Signed-off-by: heiheiha798 <2300012738@stu.pku.edu.cn>
Signed-off-by: heiheiha798 <2300012738@stu.pku.edu.cn>
Signed-off-by: heiheiha798 <2300012738@stu.pku.edu.cn>
Signed-off-by: heiheiha798 <2300012738@stu.pku.edu.cn>
Signed-off-by: heiheiha798 <2300012738@stu.pku.edu.cn>
Signed-off-by: heiheiha798 <2300012738@stu.pku.edu.cn>
Signed-off-by: heiheiha798 <2300012738@stu.pku.edu.cn>
Signed-off-by: heiheiha798 <2300012738@stu.pku.edu.cn>
Copilot AI review requested due to automatic review settings July 18, 2026 07:04

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6aa360ee-5168-45e6-980a-0333f7c31725

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The PR adds bounded shared hidden-state fan-out for independent trainers, a benchmark harness with GPU telemetry and request accounting, and optional DFlash/Liger fused training paths. It also adds CLI wiring, optimizer controls, extensive validation, and unit/integration coverage.

Changes

Shared hidden-state fan-out

Layer / File(s) Summary
Artifact cache and coordination
src/speculators/data_generation/artifact_cache.py, src/speculators/data_generation/windowed_artifacts.py
Adds atomic shared artifact publication, request identity, SQLite window coordination, leases, retries, recovery, and bounded eviction.
Dataset and training integration
src/speculators/train/*, scripts/train.py
Wires shared-cache configuration through datasets and loaders, adds asynchronous production, lease-aware batches, and trainer lifecycle handling.
Validation coverage
tests/unit/data_generation/*, tests/unit/train/*
Covers cache coalescing, window limits, failure recovery, retention bounds, dataloader wiring, and lease acknowledgment behavior.

Independent-consumer benchmark

Layer / File(s) Summary
Benchmark harness and telemetry
src/speculators/benchmarks/*, scripts/benchmark_independent_consumers.py
Adds scenario validation, HTTP request accounting, process orchestration, NVML monitoring, evidence analysis, and report generation.
Fixture and documentation
benchmarks/independent_consumer_fanout/*, docs/cli/train.md
Defines 1p1c and 1p3c benchmark configurations, execution requirements, cache semantics, and CLI options.
Benchmark tests
tests/unit/benchmarks/*
Tests command restrictions, proxy accounting, multiplicity rules, cache evidence, timing analysis, and GPU summaries.

DFlash and optimizer paths

Layer / File(s) Summary
Fused CE implementation
src/speculators/ops/fused_linear_cross_entropy.py, src/speculators/models/dflash/*, pyproject.toml
Adds the pinned optional Liger operator, fused autograd wrapper, DFlash target selection, fused metrics, and dependency configuration.
Optimizer and CLI controls
src/speculators/train/optimizers.py, src/speculators/train/trainer.py, scripts/train.py
Adds AdamW backend selection, checkpoint restoration, fused gradient clipping, and related argument validation.
Model validation
tests/unit/models/*, tests/unit/ops/*, tests/unit/train/*, tests/integration/models/*
Validates fused CE outputs and gradients, DFlash label behavior, optimizer state handling, and optional CUDA execution.

Possibly related PRs

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The flex-attention return-type validation and its tests are unrelated to #810’s fan-out and DFlash scope. Split the flex-attention validation into a separate PR unless it is tied to a linked issue or required dependency.
Docstring Coverage ⚠️ Warning Docstring coverage is 8.98% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes implement #810’s bounded fan-out, windowed retention, benchmark accounting, filesystem constraints, and opt-in optimizer/loss improvements.
Title check ✅ Passed The title clearly summarizes the main change: opt-in bounded asynchronous hidden-state fan-out.
Description check ✅ Passed The description is directly aligned with the changeset and its scope, benchmarks, tests, and opt-in behavior.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@mergify mergify Bot added the documentation Improvements or additions to documentation label Jul 18, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 12

🧹 Nitpick comments (2)
tests/unit/models/test_dflash_optimized_ce.py (1)

72-103: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add draft-vocabulary coverage for both label sources.

Verify that input_ids is rejected when use_draft_vocab=True, while verifier-argmax targets remain valid reduced-vocabulary IDs without another remapping step.

As per path instructions, tests should cover vocabulary-mapping boundaries. Based on learnings, sliced verifier-head logits are already in draft-vocabulary space.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unit/models/test_dflash_optimized_ce.py` around lines 72 - 103, Add
tests around _ce_target_ids covering both label_source values with
use_draft_vocab=True: assert label_source="input_ids" is rejected, and assert
verifier-argmax targets remain valid draft-vocabulary IDs directly from the
sliced verifier-head logits without additional remapping. Include boundary cases
for the vocabulary mapping.

Sources: Path instructions, Learnings

tests/unit/benchmarks/test_independent_consumers.py (1)

135-152: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Validate the example’s windowed multiplicity contract.

This test only inspects --train-data-ratio, so the contradictory 1P3C multiplicity remains undetected. Load the fixture through load_config and assert that a windowed multi-consumer scenario uses expected service multiplicity 1.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unit/benchmarks/test_independent_consumers.py` around lines 135 - 152,
Update test_example_config_uses_train_only_workloads to load the fixture via
load_config instead of only json.loads, then inspect the windowed multi-consumer
scenario and assert its expected service multiplicity is 1. Preserve the
existing command count and --train-data-ratio assertions while adding coverage
for the 1P3C multiplicity contract.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/benchmark_independent_consumers.py`:
- Around line 18-26: Update the argument parser for --run-directory and --report
so they are optional during --validate-only execution, while still requiring
both when launching a benchmark. Adjust the validation or main execution flow to
enforce these paths only when validate-only is not set, preserving their
existing Path types and behavior.

In `@src/speculators/benchmarks/gpu_monitor.py`:
- Around line 431-463: The GPU window aggregation in the per-GPU summary
currently omits compute-process memory. Extend the `gpu_rows` aggregation to
collect non-null `used_memory_bytes` values from each row’s `compute_processes`,
then expose their maximum as a separate peak role-memory field in `per_gpu`,
using the existing MiB conversion and `None` behavior when no values are
present. Keep total device-memory aggregation unchanged.
- Around line 437-450: Update the per-GPU validation logic around gpu_rows and
_MIN_COVERAGE_SAMPLES so windows with fewer than two samples are marked invalid
and recorded in invalid_reasons. Ensure the existing valid path remains
unchanged for windows meeting the minimum sample requirement, and do not treat a
single sample with zero coverage as reliable evidence.
- Around line 228-256: Update GpuMonitor.start so the entire initialization
sequence, including the session-start _write and _thread.start calls, is covered
by failure cleanup rather than only backend.open. On any exception, close and
clear _output and invoke _close_backend(), while preserving the original
exception and successful startup behavior.

In `@src/speculators/benchmarks/independent_consumers.py`:
- Around line 91-103: Update _validate_single_process_command to reject
distributed launcher module names invoked via python -m, including
torch.distributed.launch and accelerate.commands.launch, alongside the existing
torch.distributed.run check. Preserve acceptance of direct Python commands that
do not invoke a distributed launcher.
- Around line 1169-1172: Update the windowed_artifacts_enabled detection over
scenario.consumers so each command token is normalized by splitting once at “=”
before comparing with --shared-hidden-states-consumer-id. Preserve recognition
of the standalone option while also enabling windowed mode for
--shared-hidden-states-consumer-id=value.
- Around line 1087-1099: Update terminate to catch and suppress
ProcessLookupError around both os.killpg calls, including the SIGTERM and
timeout-triggered SIGKILL paths. Continue waiting on self.process after either
race so the child is reaped, then preserve the existing finished_at and
close_log cleanup.
- Around line 193-200: Enforce the bounded-window multiplicity contract across
all sites: in src/speculators/benchmarks/independent_consumers.py lines 193-200,
update the model validation around
expected_service_completions_per_shared_sample to reject windowed multi-consumer
configurations unless multiplicity is 1; in
benchmarks/independent_consumer_fanout/config.example.json lines 312-318, change
the 1P3C expected multiplicity from 3 to 1; and in
tests/unit/benchmarks/test_independent_consumers.py lines 135-152, load the
fixture through the Pydantic model and assert this cross-field validation rule.

In `@src/speculators/data_generation/windowed_artifacts.py`:
- Around line 397-480: The register_positions flow must prune committed position
metadata so the positions table remains bounded across epochs. Update
register_positions and the corresponding completion path to delete positions
older than every active consumer’s lookbehind boundary, preserving positions
still needed by any consumer; add a multi-epoch test covering retention and
pruning behavior.

In `@src/speculators/train/data.py`:
- Around line 625-639: Update the pending-futures loops around wait in both
capture paths to renew each active claim while work remains pending and check
_windowed_producer_stop during each wait cycle. When shutdown is requested,
cancel pending futures, stop waiting for new results, and ensure the executor is
shut down without continuing background capture work; preserve
coordinator.fail_generation handling for completed futures and release or
finalize claims appropriately.

In `@src/speculators/train/dataloader.py`:
- Around line 272-276: Update the train and validation shared-artifacts consumer
ID construction near shared_artifacts_consumer_id so each data-parallel rank
receives a distinct coordinator key, incorporating the current dp_rank into the
existing :train and :val IDs. Apply the same change to both referenced branches
while preserving None when no consumer ID is configured.

In `@tests/unit/ops/test_fused_linear_cross_entropy.py`:
- Line 89: Update the pytest.raises match patterns in the affected tests to
escape the dot in the literal “torch.long” text, including both occurrences, so
Ruff RUF043 no longer treats the dots as regex metacharacters.

---

Nitpick comments:
In `@tests/unit/benchmarks/test_independent_consumers.py`:
- Around line 135-152: Update test_example_config_uses_train_only_workloads to
load the fixture via load_config instead of only json.loads, then inspect the
windowed multi-consumer scenario and assert its expected service multiplicity is
1. Preserve the existing command count and --train-data-ratio assertions while
adding coverage for the 1P3C multiplicity contract.

In `@tests/unit/models/test_dflash_optimized_ce.py`:
- Around line 72-103: Add tests around _ce_target_ids covering both label_source
values with use_draft_vocab=True: assert label_source="input_ids" is rejected,
and assert verifier-argmax targets remain valid draft-vocabulary IDs directly
from the sliced verifier-head logits without additional remapping. Include
boundary cases for the vocabulary mapping.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 33b98afb-923c-445d-bc7f-148d7c962e6a

📥 Commits

Reviewing files that changed from the base of the PR and between 1afb3b2 and 2af645e.

📒 Files selected for processing (36)
  • benchmarks/independent_consumer_fanout/README.md
  • benchmarks/independent_consumer_fanout/config.example.json
  • docs/cli/train.md
  • pyproject.toml
  • scripts/benchmark_independent_consumers.py
  • scripts/train.py
  • src/speculators/benchmarks/__init__.py
  • src/speculators/benchmarks/gpu_monitor.py
  • src/speculators/benchmarks/independent_consumers.py
  • src/speculators/data_generation/artifact_cache.py
  • src/speculators/data_generation/windowed_artifacts.py
  • src/speculators/models/attention.py
  • src/speculators/models/dflash/core.py
  • src/speculators/models/dflash/metrics.py
  • src/speculators/ops/__init__.py
  • src/speculators/ops/fused_linear_cross_entropy.py
  • src/speculators/train/data.py
  • src/speculators/train/dataloader.py
  • src/speculators/train/optimizers.py
  • src/speculators/train/trainer.py
  • tests/integration/models/test_model_forward.py
  • tests/unit/benchmarks/__init__.py
  • tests/unit/benchmarks/test_gpu_monitor.py
  • tests/unit/benchmarks/test_independent_consumers.py
  • tests/unit/data_generation/test_artifact_cache.py
  • tests/unit/data_generation/test_windowed_artifacts.py
  • tests/unit/models/test_attention.py
  • tests/unit/models/test_dflash_metrics.py
  • tests/unit/models/test_dflash_optimized_ce.py
  • tests/unit/ops/__init__.py
  • tests/unit/ops/test_fused_linear_cross_entropy.py
  • tests/unit/ops/test_fused_linear_cross_entropy_cuda.py
  • tests/unit/train/test_cli_args.py
  • tests/unit/train/test_optimizers.py
  • tests/unit/train/test_shared_artifacts.py
  • tests/unit/train/test_windowed_training.py

Comment thread scripts/benchmark_independent_consumers.py
Comment thread src/speculators/benchmarks/gpu_monitor.py Outdated
Comment thread src/speculators/benchmarks/gpu_monitor.py
Comment thread src/speculators/benchmarks/gpu_monitor.py
Comment thread src/speculators/benchmarks/independent_consumers.py
Comment thread src/speculators/benchmarks/independent_consumers.py
Comment thread src/speculators/data_generation/windowed_artifacts.py
Comment thread src/speculators/train/data.py Outdated
Comment thread src/speculators/train/dataloader.py
Comment thread tests/unit/ops/test_fused_linear_cross_entropy.py Outdated
@heiheiha798

heiheiha798 commented Jul 18, 2026

Copy link
Copy Markdown
Author

Scope clarification: Mooncake is intentionally not included in this change.

A related Mooncake-backed implementation is publicly available in
sgl-project/SpecForge#707. That open
PR includes managed Mooncake/SGLang supervision, zero-copy payload transfer, windowed
capture, and durable fan-out lifetime ownership. It provides useful related validation
for the lifecycle invariants and benchmark design in #811, but the implementation
submitted here uses a shared POSIX filesystem for fan-out payloads. All performance and
NVML results in the #811 description are from that filesystem implementation.

The updated description now also links the existing upstream Mooncake work in #605/#710
and the merged transfer abstraction in #735. Because #811 currently carries filesystem
paths in its read/eviction leases, a Mooncake fan-out backend still requires an opaque
artifact-reference/store abstraction; it is not a supported drop-in configuration in
this PR. No code changed as part of this clarification.

Signed-off-by: heiheiha798 <2300012738@stu.pku.edu.cn>
@heiheiha798

Copy link
Copy Markdown
Author

Review findings are addressed in commit 967ddf5.

The follow-up fixes make validation-only output paths optional; close partial NVML startup cleanly; distinguish device-wide from compute-process memory; reject one-sample, zero-coverage, and incomplete process-memory windows; reject additional distributed launchers; enforce publish-once multiplicity for windowed 1P3C; tolerate process-exit races; recognize option=value consumer IDs; bound position metadata across epochs; renew and release capture claims during shutdown; scope consumer IDs by DP rank; and cover the two review nits.

Validation:

  • Focused affected tests: 103 passed.
  • Ruff check, Ruff format check, compileall, git diff --check, and local/sensitive-path scan: passed.
  • A fresh serial four-GPU 1P3C run with heterogeneous DFlash b4/b8/b16 consumers completed successfully with 30 warmup plus 150 measured steps per consumer. Aggregate steady throughput was 6.1684 steps/s; per-consumer rates were 2.6297 / 2.1010 / 1.4377 steps/s.
  • The common GPU window was valid: 245 samples and 48.85 s coverage per GPU, exactly one compute process per GPU, zero unavailable process-memory samples, and no ownership violations. Mean utilization was 100.0% / 89.0% / 93.5% / 94.0% for producer / b4 / b8 / b16.
Role Device memory MiB Compute-process memory MiB
producer 37578.1 36956.0
b4 31287.8 30678.0
b8 31971.8 31362.0
b16 33890.1 33266.0

The report was valid with no invalid reasons; all role processes exited with code 0. This was a focused review validation, not a full-suite run.

Signed-off-by: heiheiha798 <2300012738@stu.pku.edu.cn>
Signed-off-by: heiheiha798 <2300012738@stu.pku.edu.cn>
Signed-off-by: heiheiha798 <2300012738@stu.pku.edu.cn>
@heiheiha798

Copy link
Copy Markdown
Author

Follow-up validation after the issue #1 audit fixes

Pushed commits: 2d7156d, 47c2805, and 5dfac24.

  • Hardened artifact invalidation, generation-claim recovery, acquire deadlines, eviction recovery, shutdown/error isolation, and benchmark failure evidence.
  • Fixed the remaining mypy errors and test typing boundaries; make quality now passes (Ruff, formatting, Markdown, and mypy; 183 files checked).
  • Focused affected tests: 198 passed (19 warnings).
  • The wheel builds successfully and packages THIRD_PARTY_NOTICES.
  • Third-party attribution now distinguishes the Apache-2.0 SpecForge window-coordinator portions from the MIT fused linear cross-entropy portion.

The follow-up validation used the Python 3.12 project environment. No full test suite or CI was run for this follow-up.

Signed-off-by: heiheiha798 <2300012738@stu.pku.edu.cn>
@heiheiha798

Copy link
Copy Markdown
Author

Reviewability and scope note: this PR is intentionally being left as the current end-to-end change for now, but I recognize that 37 files and roughly 11.5k additions make it substantially larger than a typical Speculators PR.

Rather than rewrite the branch speculatively and discard existing review context, I will keep the branch maintained while waiting for maintainer direction. If maintainers are interested in the functionality but need smaller review units, I can split it into a dependency-ordered series covering: (1) the shared artifact store and coordinator, (2) bounded-window training and CLI integration, (3) the DFlash consumer performance path, and (4) benchmark/NVML validation. The split would preserve the tested end-to-end behavior and performance evidence.

Mooncake remains deliberately outside #811. A follow-up can build on the transfer abstraction from #735 and coordinate with the active Mooncake work in #605/#710, instead of adding another backend and validation matrix to this already large review.

@heiheiha798

Copy link
Copy Markdown
Author

Final status update at 933a600:

  • The bounded asynchronous 1P3C fan-out implementation, lifecycle hardening, DFlash consumer path, benchmark harness, and NVML evidence are complete for the shared-POSIX/safetensors backend described in this PR.
  • The final local fix preserves compatibility with non-windowed training loaders after the full Buildkite-style reproduction exposed checkpoint-test failures. Its focused regression suite passes (18 passed).
  • Serial local validation completed on one process per GPU: Python 3.10 with Transformers 4.57.6 (648 passed, 27 skipped unit; 181 passed, 26 skipped integration), Python 3.10 with Transformers 5.13.1 (669 passed, 6 skipped; 203 passed, 5 skipped), and Python 3.13 with Transformers 5.13.1 (669 passed, 6 skipped; 203 passed, 5 skipped). Repository quality checks also pass on Python 3.10 and 3.13.
  • The scope is now frozen. Mooncake is intentionally reserved for a follow-up coordinated with [Prototype] Add Mooncake backend for hidden-states transfer #605/[Multi-node] Mooncake hidden state transfer over TCP/RDMA #710 and the transfer abstraction from Refactor hidden states transfer w/ abstract backend #735; no additional backend or feature axis will be added here.
  • The branch is kept as the complete end-to-end change for review. If maintainers want the functionality but require smaller review units, I can split it into a dependency-ordered series without changing the tested behavior or performance evidence.

This PR is ready for maintainer review.

@speculatorsbot speculatorsbot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Design-level assessment: The implementation is well-structured -- opt-in behavior is properly gated, existing training paths are unchanged, validation is thorough, and the test suite is comprehensive (198+ focused tests). The POSIX filesystem constraints are clearly documented and the code does not overreach on NFS or GPU-direct claims. The THIRD_PARTY_NOTICES attribution is appropriate.

However, this PR has a scope problem that makes meaningful code review impractical.

Splittability: At 37 files and ~11,500 added lines, this bundles at least four independent feature areas:

  1. Shared artifact store and coordinator (artifact_cache.py, windowed_artifacts.py) -- the core filesystem cache and SQLite-backed window coordination.
  2. Bounded-window training integration (data.py, dataloader.py, trainer.py, train.py CLI wiring) -- lifecycle management, lease semantics, producer thread.
  3. DFlash consumer performance path (fused_linear_cross_entropy.py, dflash/core.py, metrics.py, optimizers.py) -- Liger CE backend, AdamW backend selection, fused gradient clipping.
  4. Benchmark harness and NVML telemetry (independent_consumers.py, gpu_monitor.py, benchmark fixtures) -- 1P1C/1P3C orchestration and evidence collection.

The DFlash/optimizer changes (#3) are fully independent of the windowed artifact system. The benchmark harness (#4) tests the windowed system but is a standalone deliverable. Even #1 and #2 could be separated into a store-only PR followed by a training-integration PR. The author has already offered this split -- I would recommend taking them up on it. Smaller PRs get deeper reviews and faster iteration.

CONTRIBUTING.md process: This PR resolves #810, but that issue is not assigned to any contributor. Per the project's contribution guidelines, significant changes (new features, CLI/API modifications, 3+ files) should get a maintainer "green light" via issue assignment before implementation begins. There are also no maintainer comments on #810. This is a process observation for maintainers, not a code concern.

Code quality: After detailed review of all source files, the code does not exhibit AI-slop patterns -- it is dense, operationally correct, and avoids gratuitous documentation. The _FrozenLinearCrossEntropy autograd function correctly discards weight gradients and properly promotes to float32 for gradient scaling. The fused AdamW gradient clipping via grad_scale uses PyTorch's documented interface. The SQLite coordinator schema is well-designed with proper foreign keys and indices. DCO sign-off is present on all commits.

No line-level findings survived filtering (all below confidence 80 after verification). All 12 CodeRabbit findings were addressed in follow-up commits. The documentation corrections (request-timeout default 180->120, max-anchors 256->3072) are accurate -- they match the actual code on main.

Recommend splitting per the author's offer before detailed maintainer review.

🤖 Generated with Claude Code using the /pr-review skill

@speculatorsbot speculatorsbot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR introduces a well-designed bounded asynchronous fan-out system for independent consumer trainers. The SQLite coordinator, filesystem artifact cache, and windowed-cursor semantics are sound, and the existing CodeRabbit findings have been addressed. The primary concern is scope.

Splittability. At ~11.5k additions across 37 files, this PR bundles at least four independently reviewable units: (1) the artifact cache and windowed coordinator, (2) training integration (data.py, dataloader.py, trainer.py), (3) DFlash consumer optimizations (fused CE, optimizer backend, metrics), and (4) the benchmark harness with GPU monitoring. The author has already offered to split into a dependency-ordered series. I would recommend taking that offer -- smaller PRs get tighter review and merge faster, and each unit here can be validated independently.

Issue assignment. Per CONTRIBUTING.md, significant changes (this PR modifies the CLI/API, adds new modules, and touches 37 files) should reference an assigned issue with a maintainer green-light. Issue #810 exists and was opened by the author, but has no assignees. A maintainer should explicitly assign the issue to signal alignment before this merges.

Two minor inline findings below. Neither is a blocker.

🤖 Generated with Claude Code using the /pr-review skill

Comment on lines +1594 to +1598
def write_report(report: dict[str, Any], path: Path) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
temporary = path.with_suffix(path.suffix + ".tmp")
temporary.write_text(json.dumps(report, indent=2, sort_keys=True) + "\n")
temporary.replace(path)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

write_report uses a temporary-then-rename pattern without flush()/fsync(), while _atomic_write_json in the sibling gpu_monitor.py module correctly calls both before the rename. On a crash, the report file could be zero-length or truncated despite the rename having completed from the kernel’s perspective. Since this is the primary benchmark output, it should match the durability guarantees used elsewhere in this package:

def write_report(report: dict[str, Any], path: Path) -> None:
    path.parent.mkdir(parents=True, exist_ok=True)
    temporary = path.with_suffix(path.suffix + ".tmp")
    with temporary.open("w") as output:
        json.dump(report, output, indent=2, sort_keys=True)
        output.write("\n")
        output.flush()
        os.fsync(output.fileno())
    temporary.replace(path)

step_ms: float


def _percentile(values: list[float], percentile: float) -> float:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This _percentile is nearly identical to the one in gpu_monitor.py (line 429). Both live in the same speculators.benchmarks package. Extract a single shared utility to avoid the DRY violation.

Signed-off-by: heiheiha798 <2300012738@stu.pku.edu.cn>
@heiheiha798

Copy link
Copy Markdown
Author

Follow-up cd23186 addresses both non-blocking inline findings from the latest review:

  • the duplicate nearest-rank percentile implementations now use one shared benchmark utility;
  • benchmark report publication now flushes and fsyncs the complete JSON payload before atomic replacement, with temporary-file cleanup on failure.

Focused validation passes: 57 passed across the independent-consumer and GPU-monitor unit suites, along with targeted Ruff and format checks.

The implementation scope remains frozen. I will keep the branch maintained and wait for maintainer guidance on issue assignment and whether splitting the existing end-to-end change would materially help review; I will not restructure the PR or add Mooncake/new feature scope speculatively.

@mergify

mergify Bot commented Jul 20, 2026

Copy link
Copy Markdown

This pull request has merge conflicts that must be resolved before it can be
merged. Please rebase the PR, @heiheiha798.

https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork

@mergify mergify Bot added the needs-rebase label Jul 20, 2026
Signed-off-by: yangtianjian <143272889+heiheiha798@users.noreply.github.com>
@mergify mergify Bot removed the needs-rebase label Jul 21, 2026
@coderabbitai coderabbitai Bot mentioned this pull request Jul 22, 2026
4 tasks
@mergify

mergify Bot commented Jul 24, 2026

Copy link
Copy Markdown

Merge Protections

🔴 1 of 1 protections blocking · waiting on 👀 reviews

Protection Waiting on
🔴 Require approval from approved reviewers list 👀 reviews

🔴 Require approval from approved reviewers list

Waiting for any of

  • approved-reviews-by = dsikka
  • approved-reviews-by = fynnsu
  • approved-reviews-by = orestis-z
  • approved-reviews-by = rahul-tuli
  • approved-reviews-by = shanjiaz
This rule is failing.

All pull requests must have at least one approving review from a member of the approved reviewers list before merging.

  • any of:
    • approved-reviews-by = dsikka
    • approved-reviews-by = fynnsu
    • approved-reviews-by = orestis-z
    • approved-reviews-by = rahul-tuli
    • approved-reviews-by = shanjiaz

@mergify

mergify Bot commented Jul 24, 2026

Copy link
Copy Markdown

This pull request has merge conflicts that must be resolved before it can be
merged. Please rebase the PR, @heiheiha798.

https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork

@mergify mergify Bot added the needs-rebase label Jul 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation needs-rebase

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[RFC]: Bounded asynchronous hidden-state fan-out to independent consumers

3 participants