[Bug] save_model fires unconditionally at the final step regardless of --save-interval; final optimizer-state write can kill the job
Author: kugua2025aigc-codeCreated Sep 8, 2026Updated Sep 13, 2026
Summary
save_model fires unconditionally at the final training step regardless of --save-interval, because should_run_periodic_action returns True at the last step. Users who set --save-interval larger than the total number of rollout steps (intending "no checkpointing") still get a full optimizer-state checkpoint written at the end — and on our setups this final write killed the training job twice on two different machines.
Environment
- slime: main @
4c193f1f(also reproduced on an older checkout, different machine) - 2× separate vast.ai H100 boxes, single-GPU colocate, ray 2.58, sglang (slime-pinned)
- GRPO run, 50 rollout steps,
--save /workspace/ckpt --save-interval 200(interval > horizon = "no saves intended")
Observed
- At
rollout_id == num_rollout - 1,train.py:70-79callsactor_model.save_model(...)becauseshould_run_periodic_action(rollout_id, args.save_interval, ...)returns True at the final step (slime/utils/misc.py). The--save-interval 200setting is silently overridden. - The final save writes a ~36G Megatron checkpoint including optimizer state. On two independent machines the actor died inside this save:
- Box A: torch distributed-checkpoint write failed with
unexpected pos 704 vs 598(corrupt write), job hung until manually stopped. - Box B: actor vanished mid-save — driver raised
ray.exceptions.ActorUnavailableError: ... RPC error: Socket closed rpc_code: 14atslime/ray/actor_group.py:153. Because the crash is insave_modelbefore the final-step eval (train.py:95-96), the in-job eval never runs and the whole run's rollouts are lost.
- Box A: torch distributed-checkpoint write failed with
- Workaround confirmed:
--no-save-optimshrinks the final checkpoint to ~6G weights-only and the save completes (we never resume from GRPO checkpoints, so optimizer state was pure liability).
Expected behavior
One of:
--save-interval> num_rollouts should mean "no saves at all" (including the final step), or- an explicit
--no-final-saveflag, or - at minimum a docs note that the final step always saves regardless of
--save-interval.
Related
- #2290 / #1914 / #1798 (checkpoint retention bounding — same underlying pain: full optimizer-state checkpoints are heavy and dangerous)
Fix that worked for us
--no-save-optim(pre-existing flag, slime/utils/arguments.py:872)
Source: THUDM/slime