Skip to content

feat: unified resume system with checkpoints.jsonl state tracking - #172

Closed
Hecate0821 wants to merge 2 commits into
mainfrom
feat/dataloader-state-tracking
Closed

Hecate0821 wants to merge 2 commits into
mainfrom
feat/dataloader-state-tracking

Conversation

@Hecate0821

@Hecate0821 Hecate0821 commented Mar 5, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Rebase the branch onto fix/pr168-merge-issues so the resume work sits on top of the shared RL utility fixes from PR feat: add FrozenLake multi-turn tool-call GRPO training example #168
  • Preserve the ref_logp fix by making ref_logprobs optional throughout the RL pipeline so kl_beta=0 works without a reference model, including the training/utils/rl/grpo.py conflict resolution from the rebase
  • Replace the dual-path resume logic (ResumeConfig + setup_resume regex parsing vs checkpoints.jsonl auto-resume) with a single source of truth: local_checkpoint_state.jsonl in a persistent log_path directory
  • Add checkpoint_utils.py with ResumeState dataclass, resolve_resume(), load_dcp(), dataset fingerprint validation, training shape validation, checkpoint availability check, and DCP load timing
  • Track dataset iteration progress (data_consumed) so resume skips already-trained data
  • Add init_from_dcp config field for loading pretrained DCP weights on a fresh dataset
  • Log perf/dcp_load_time to wandb on resume

Design

flowchart TD
    A[Training starts] --> B{local_checkpoint_state.jsonl exists?}
    B -->|Yes| C[Read last entry]
    C --> D["Validate: shape, dataset fingerprint"]
    D --> E["Load DCP, skip data_consumed rows"]
    B -->|No| F{init_from_dcp set?}
    F -->|Yes| G["Write initial entry: step=0, data_consumed=0"]
    G --> H[Load DCP weights, start from row 0]
    F -->|No| I[Fresh start, no DCP]
Loading

Changes

File Change
training/utils/checkpoint_utils.py New: ResumeState, resolve_resume(), load_dcp(), dataset fingerprint, shape validation
training/utils/resume.py Deleted: replaced by checkpoint_utils
training/utils/config.py Removed ResumeConfig dataclass
training/utils/__init__.py Removed ResumeConfig, setup_resume exports
training/utils/validation.py Removed resume parameter from validate_config
training/utils/client.py Added list_checkpoints() method to ReconnectableClient
training/utils/rl/train.py Added data_consumed counter to run_rl_loop
training/utils/rl/losses.py PromptGroup.ref_logprobs now optional (None when no ref model); combine_prompt_groups handles None
training/utils/rl/grpo.py Handle ref_logprobs=None with zero resp_ref; preserved through the PR #168 rebase conflict resolution
training/utils/rl/dapo.py Same
training/utils/rl/gspo.py Same
training/utils/rl/cispo.py Same
training/recipes/rl_loop.py Config: log_path + init_from_dcp. Resume via resolve_resume() + load_dcp(). ref_forward only called when use_reference=True. Save loop state alongside DCP
training/recipes/sft_loop.py Same pattern with data_consumed and epoch/batch offset
training/recipes/dpo_loop.py Migrated to new resume API
training/recipes/orpo_loop.py Migrated to new resume API
training/tests/e2e/conftest.py Added e2e_training_shape fixture
training/tests/e2e/test_grpo_resume_e2e.py Updated for new resume API, training shapes, TOKYO region
training/tests/e2e/test_sft_resume_e2e.py Updated for new resume API
training/tests/e2e/test_dpo_resume_e2e.py Updated for new resume API

Test plan

  • Run RL loop from scratch (no local_checkpoint_state.jsonl) -- verify fresh start
  • Run RL loop with init_from_dcp -- verify DCP loads, training starts from row 0
  • Kill and restart RL loop -- verify auto-resume from local_checkpoint_state.jsonl, rows skipped correctly
  • Change dataset between runs -- verify fingerprint warning
  • Change training shape between runs -- verify shape warning
  • Verify perf/dcp_load_time and perf/dcp_save_time appear in wandb
  • Run SFT loop with resume -- verify epoch/batch offset computed correctly
  • Run with kl_beta=0 (no reference model) -- verify no IndexError, KL penalty is zero
  • E2E GRPO resume test with ts-qwen3-30b-a3b-instruct-64k-rft-dev-cp8ep8-v1 in AP_TOKYO_2

@Hecate0821
Hecate0821 force-pushed the feat/dataloader-state-tracking branch 9 times, most recently from ccb797a to 50dd3d7 Compare March 6, 2026 01:59
PR #168 (FrozenLake example) incorrectly overwrote several shared
utilities with older/incompatible versions during merge:

- Restore TrainStepFns interface in train.py (reverts MinibatchTrainFns
  rewrite that broke rl_loop.py recipe)
- Remove _install_tinker_future_retrieve_compat() from client.py
  (workaround no longer needed, fixed server-side)
- Restore direct disable_speculative_decoding= in config.py
  (removes unnecessary inspect guard)
- Remove grad_accum param and restore apply_shape() in infra.py
- Update frozen_lake example to use TrainStepFns (1:1 loop)

Made-with: Cursor
@Hecate0821
Hecate0821 force-pushed the feat/dataloader-state-tracking branch 2 times, most recently from b1553ef to 1ec8904 Compare March 6, 2026 03:02
Replace the dual-path resume logic (ResumeConfig + setup_resume regex
parsing vs checkpoints.jsonl auto-resume) with a single source of truth:
checkpoints.jsonl in a persistent log_path directory.

- Add checkpoint_utils.py: ResumeState dataclass, resolve_resume(),
  load_dcp(), dataset fingerprint validation, training shape validation,
  checkpoint availability check, DCP load timing
- Delete resume.py and ResumeConfig -- all resume flows through
  resolve_resume() which reads checkpoints.jsonl
- Add rows_consumed tracking to run_rl_loop (RL) and examples_consumed
  tracking to sft_loop (SFT) for dataset position persistence
- Add init_from_checkpoint config field for loading pretrained weights
  on a fresh dataset (writes initial checkpoints.jsonl entry)
- Log perf/dcp_load_time to wandb on resume
- Update all 4 recipe loops (rl, sft, dpo, orpo) to use the new system

Made-with: Cursor
@Hecate0821
Hecate0821 force-pushed the feat/dataloader-state-tracking branch from 1ec8904 to 0763105 Compare March 11, 2026 03:52
@Hecate0821 Hecate0821 closed this Mar 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant