Move TrainerRank micro-batch planning into trainer_rank/_micro_batch_planner - #1000
bradhilton wants to merge 2 commits into
Conversation
|
Schulman — no concrete blocker found in the reviewed scope. Reviewed head All 34 moved planner methods, plus the 26 prior memory methods, match main after narrowly normalizing module qualification, self annotations and docstring indentation. Retained method bodies and class state match. Warm-profile pricing, optimizer-counter validation, distributed planning-error coordination, generator cleanup and graph/slot lifetime behavior survive. Dynamic runtime globals remain accessed through Bounded framework-free controls passed for actual extracted bindings, sentinel identity, cancellation/error preservation, late distributed-module replacement, slot dispatch and optimizer-construction rollback. Independent AST/source comparisons passed. No full framework import, model, real optimizer numerics or GPU/distributed execution was performed by this review; reported CI success was observed, not independently rerun. Limits: function/module/frame metadata and private patch locations change. Frozen code-identity diagnostics need explicit adoption. Source preservation supports this refactor but is not a claim of identical measured gradients, memory peaks or compilation. A reviewer-only metadata-collection failure under an address-space cap is retained; no product source change or product-test failure resulted. |
|
Dalinar: memory/planner owner review. No blocking findings. Reviewed head What I checked
Validation
Low (none blocking)
Held planner-stack integration (my held drafts #963, #978, #981 and #986)
Limits: CPU tests only; no GPU smoke run. Behavioral equivalence comes from AST comparison and static reading. |
f0a2d88 to
78f6481
Compare
…d admission method bodies Pure code motion following the _memory / _gdn_memory precedent: 34 method bodies moved verbatim from _impl as module-level functions taking the rank as self. Names the bodies read from _impl's namespace (torch, dist, time, _telemetry_phase, plan/cost types, sibling helpers) are resolved as _impl.X at call time so tests that patch them on _impl keep intercepting; stdlib helpers and the unpatched prefix-tree / planner-cost functions are imported directly. @contextmanager stays on _planning_status and @_backward_region on _recover_admission. _forward_micro_batches carries the #991 caller-phase interval body.
…_micro_batch_planner The class body binds the module functions by assignment in place of the removed defs, so self._x(...) dispatch, per-instance monkeypatches and ranks built via TrainerRank.__new__ behave as before with no delegators. _micro_batch_planner is imported beside _memory immediately before the class because four signatures read _impl.Unset as a default at definition time. forward_micro_batches stays in _impl: its @overload stubs need the real def implementation beside them. Add _micro_batch_planner.py to the planner-miss source fingerprint, and drop the _impl imports neither extraction left in use; the three still read as _impl.X by _memory / _micro_batch_planner are marked as such.
35db954 to
ced0776
Compare
Summary
Second of three stacked
TrainerRankextractions (base: #999). Moves the 34 micro-batch planning / split / layout-selection / admission methods (~2,000 lines) fromsrc/art/trainer_rank/_impl.pyintosrc/art/trainer_rank/_micro_batch_planner.py, using the same pattern as #999 and the existing_gdn_memory.py/_planner_evidence.py: module-level functionsdef _name(self: TrainerRank, ...)with verbatim bodies, bound in the class body by assignment. No collaborator object, no delegators, no__init__change; sibling calls stayself._x(...)so per-instance monkeypatches andTrainerRank.__new__-built ranks keep working, andco_nameis preserved.Moved:
_forward_micro_batches,_planning_status(@contextmanagerapplied to the module function),_recover_admission(@_backward_regionapplied to the module function —regiontakes the rank positionally and reads_backward_work()at call time, so decoration site is irrelevant),_plan_structure,_flat_forward_plan,_split_forward_plan,_find_admissible_forward,_admit_plan,_admit_split_rung,_search_next_micro_batch,_select_next_micro_batch,_plan_flat_forward,_compute_group_layout,_select_group_layout,_submit_speculative_wave_planning,_fill_planner_snapshot,report_planner_oom,finish_planner_observation, and the admission/candidate/layout/wave/planner-report helpers. Full list:rg -n '= _micro_batch_planner\.' src/art/trainer_rank/_impl.py.Deliberately left in
_impl.py:forward_micro_batches(its four@overloadstubs must be immediately followed by a realdef; it dispatches to the moved implementation viaself.),_begin_planner_observation(tests/unit/test_trainer_rank_backward_work.py::actual_rankparses_impl.pyby name), the_planner_observationproperty/setter,planner_observation_scope,_telemetry_plan_signature,_execute_admitted_plan,_execute_flat_plan.Names tests patch on
_impl(torch,dist,time,_telemetry_phase,materialize_prefix_tree_layout,estimate_prefix_tree_packed_tokens) are read as_impl.Xat call time. Four names that only the planner used and nothing patches (COEFFICIENT_VERSION_FALLBACK,build_canonical_prefix_tree,prefix_tree_layout_candidates,select_prefix_tree_layout) are now imported directly from their origin modules and dropped from_impl.py, along with the deadGenerator,asdict,nullcontext,MethodType. Three_impl.pyimports that look unused but are read as_impl.Xby_memory.py/this module carry# noqa: F401comments. Def-time= _impl.Unsetdefaults mean_impl.pyimports the module immediately beforeclass TrainerRank:(shared import line with #999)._micro_batch_planner.pyis added to_planner_misses._SOURCE_NAMESso the planner-miss replay drift guard fingerprints the planner code it reruns (total 551 KB < 1 MiB); the existing test asserts it.Equivalence and stacking
main's current method bodies (modulo_impl.qualification, theselfannotation, docstring dedent). The merged class has 123 methods =main's 183 − (Move TrainerRank memory accounting into trainer_rank/_memory #999's 26 ∪ these 34), with 60 bindings; every remaining method is AST-identical tomain's (no stitched methods from the rebase); module level equalsmain's plus the pre-class import.mainafter authoring and modified_forward_micro_batches(theintervalparameter,self.__dict__.get("_peak_reading")after the tracked flat-plan run, andcaller_phase=True, interval=intervalon_update_peak_memory_profile); those lines are ported into the moved function and verified againstmain's body. No othermainhunk since the fork touched a moved method.Validation
tests/unit/test_trainer_rank_*.py(minusgpu_ci, plusplanner_reportsandmain's newprofile_warm) at-n 4: 1,257 passed vs 1,258 on the Move TrainerRank memory accounting into trainer_rank/_memory #999 baseline; the one branch-only failure is a known distributed subprocess-timeout flake that passes serially (6/6).test_trainer_rank_backward_work.py+test_trainer_rank_planning_status.pyserially: 32 passed.ruff check,ruff format --check,ruff --select F401clean;ty checkshows the same 6 pre-existing_checkpoint.pydiagnostics asmain._backward_work.region's implementation;_impl.Xtable for all 36 names cross-checked against every_implname patched in tests; three-way merge with Move TrainerRank memory accounting into trainer_rank/_memory #999 and the slots/optimizer branch dry-run. Bugbot found no bugs. Its two pre-merge items (stale_forward_micro_batchesvs Price warm waves by the fit later plans measured, not the first plan's #991; missing_SOURCE_NAMESentry) and two Lows (timevia_impl; import tidy) are addressed here.Observable non-behavioral change:
_planner_evidence.failureframe records for frames inside moved functions reportmodule: art.trainer_rank._micro_batch_planner._impl.py: 9,843 → 6,706 lines with #999 and this PR. The slots/optimizer extraction follows on top and brings it to ~5,640.