Skip to content

Fix resume training crash recovery and MLX checkpoints - #6796

Merged
danielhanchen merged 32 commits into
unslothai:mainfrom
NilayYadav:resume-training-bugfixes
Jul 21, 2026
Merged

danielhanchen merged 32 commits into
unslothai:mainfrom
NilayYadav:resume-training-bugfixes

Conversation

@NilayYadav

Copy link
Copy Markdown
Collaborator

Fixes several resume-training issues in Studio:

  • Allows errored runs with valid checkpoints to be resumed
  • Preserves output_dir so crashed runs do not lose their checkpoint path
  • Prevents finish_run from clearing an already-persisted output_dir
  • Marks resumed errored runs as continued so old runs are not offered again
  • Ensures MLX Stop and Save writes a resumable checkpoint
  • Adds a resume button in the historical run detail view
  • Updates Stop dialog copy to clarify resumability

@NilayYadav
NilayYadav requested a review from danielhanchen as a code owner July 1, 2026 20:51

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request enables resuming training runs that ended in an error state, persists the output directory to the database, and adds support for writing MLX stop checkpoints when training is stopped. It also updates the frontend to allow resuming training runs directly from the historical view. The feedback suggests defensively creating the checkpoint directory before saving stop checkpoints, disabling the resume button in the UI when another training run is already active, and including the 'running' status in database and frontend checks to prevent older runs from being marked as resumable when a newer run is active.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread studio/backend/core/training/worker.py
Comment thread studio/frontend/src/features/studio/historical-training-view.tsx
Comment thread studio/frontend/src/features/studio/historical-training-view.tsx Outdated
Comment thread studio/backend/storage/studio_db.py Outdated
Comment thread studio/backend/storage/studio_db.py Outdated
Comment thread studio/backend/storage/studio_db.py Outdated
Comment thread studio/frontend/src/features/studio/history-card-grid.tsx Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 839365f836

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread studio/backend/storage/studio_db.py Outdated
Comment thread studio/backend/core/training/worker.py Outdated
@NilayYadav
NilayYadav force-pushed the resume-training-bugfixes branch from 1c4615e to 2765a85 Compare July 1, 2026 21:10

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 99ac1c2717

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread studio/backend/storage/studio_db.py Outdated
Comment thread studio/backend/core/training/worker.py Outdated
NilayYadav and others added 2 commits July 2, 2026 02:56
… MLX checkpoint

- finish_run: add clear_output_dir flag; preserve output_dir for stopped/error
  unless cancel explicitly clears it (fixes pump finalization wiping persisted path).
- training pump: pass interrupted stop-and-save context into finalize_run_in_db.
- MLX stop-and-save: verify resumable checkpoint exists before sending complete;
  return bool from _write_mlx_stop_checkpoint and add regression tests.

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 095482aafc

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread studio/backend/core/training/worker.py Outdated
Comment thread studio/backend/core/training/training.py
NilayYadav and others added 2 commits July 2, 2026 03:08
…nalize

- Only skip MLX stop checkpoint write when checkpoint-{current_step} exists;
  stale periodic checkpoints no longer mask missing stop saves.
- Pass clear_output_dir through error-event finalization so Stop-without-save
  cannot leave a persisted output_dir that still offers Resume.

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e3f58281d5

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread studio/backend/core/training/worker.py
Comment thread studio/backend/core/training/worker.py Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 52c80757e9

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread studio/backend/core/training/resume.py Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e8d9603328

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread studio/backend/core/training/worker.py Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 427378cdb2

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread studio/backend/core/training/training.py Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 927cf0f598

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread studio/backend/core/training/resume.py Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fe06efccaa

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread studio/backend/core/training/training.py Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5b5f4e4933

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread studio/backend/core/training/worker.py Outdated
Comment thread studio/backend/core/training/training.py Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0fa0d0b692

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread studio/backend/storage/studio_db.py
@Lyxot

Lyxot commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Hooray!

Reviewed commit: fe51e14249

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3ef3b4648f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

self.eval_step_history.clear()
self.eval_enabled = False
self._output_dir = None
self._output_dir = config.get("output_dir") if resume_source_run_id else None

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Seed resume rows with the source output directory

When a user resumes from history/API, the route only sends resume_from_checkpoint (rewritten to the selected checkpoint-* path) and does not send output_dir, so with resume_source_run_id this initializes _output_dir to None. _ensure_db_run_created() then calls create_run(..., output_dir=None, resumed_from_run_id=...), whose source-claim query compares output_dir = ?; SQL NULL never matches the original run's saved output directory, so normal resume attempts terminate the worker and fail as “checkpoint is no longer available.” Derive the output directory from resume_from_checkpoint here or pass the validated resume output dir into start_training.

Useful? React with 👍 / 👎.

Comment on lines +771 to +773
UPDATE training_runs SET resume_blocked = 1
WHERE id = ? AND status IN ('stopped', 'error')
AND output_dir = ? AND resume_blocked = 0

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Release source run when resumed cancel saves nothing

When a user starts a resumed run and then chooses Stop without saving, the new run clears its own output_dir, but the original source run remains permanently resume_blocked=1 from this initial claim. Since the canceled continuation no longer has the same output_dir, the dynamic resumed_later check will not hide the source, yet can_resume_run() still rejects it via resume_blocked, so the unchanged original checkpoint can no longer be resumed; unblock the source when the continuation finalizes as a no-save cancel, or defer this permanent claim until the resumed run preserves a replacement output directory/checkpoint.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Good catch. The source is kept resume_blocked here by design so a partially consumed output_dir is never offered for resume twice; the on-disk checkpoint itself is untouched. Releasing it correctly needs a resumed_from_run_id link to know which source to unblock, so tracking that as a small follow-up rather than in this PR.

@Imagineer99

Copy link
Copy Markdown
Member

Focused CI passes on current PR #6796 head: https://github.com/Imagineer99/unsloth/actions/runs/29747712420
75 resume, cancellation, crash recovery, watchdog, and MLX checkpoint tests passed
Backend Ruff passed
Frontend typecheck and production build passed
No issues found in the targeted scope.

- Reject unrecognized shard formats and keep indexed shard paths inside the checkpoint dir
- Require a non-empty tensor record when validating .pt/.bin optimizer and model state
- Always finalize TensorBoard and W&B on stop-save-failure exits
- Refuse writing an MLX stop checkpoint through a symlinked directory
- Clarify the resume rejection message to cover errored runs
@danielhanchen

Copy link
Copy Markdown
Member

Pushed a small follow-up (1770fdd60) hardening the checkpoint validation and stop-and-save paths:

  • Checkpoint validation now binds indexed shards to the index format (model.safetensors.index.json -> .safetensors, pytorch_model.bin.index.json -> .bin) and keeps shard paths contained inside the checkpoint dir, so absolute paths, ../ escapes and unrecognized suffixes are rejected instead of silently accepted (which could let a stale/partial file displace an older valid checkpoint).
  • .pt / .bin validation requires a non-empty tensor storage record, so a zero-byte record that parses but fails torch.load no longer counts as valid state.
  • MLX Stop and Save now finalizes the TensorBoard writer and W&B run on the stop-checkpoint-failure return paths (previously those early returns leaked them), and refuses to write the stop checkpoint through a pre-existing symlinked directory.
  • The resume rejection message now mentions errored runs, matching the newly supported errored-run resume path.

No behavior change for valid HF, sharded, legacy .bin or MLX checkpoints. The focused resume suite (test_training_resume, test_mlx_stop_checkpoint, test_training_stop_watchdog, test_training_pump_resilience) passes, and the rest of the studio backend suite is unchanged with these applied.

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 296f1f7f66

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +771 to +773
UPDATE training_runs SET resume_blocked = 1
WHERE id = ? AND status IN ('stopped', 'error')
AND output_dir = ? AND resume_blocked = 0

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Unblock source when deleting a continuation

When a continuation created from history is later deleted (for example, a resume attempt fails before useful progress and the user removes that row), this permanent update leaves the source run with resume_blocked=1. Since delete_run() only removes the continuation row and can_resume_run() rejects resume_blocked before checking the still-valid output directory, the original stopped/errored run loses its Resume button even though no newer row remains to supersede it; the block needs to be released when the claiming continuation is deleted or otherwise produces no replacement.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Good catch. The source is kept resume_blocked here by design so a partially consumed output_dir is never offered for resume twice; the on-disk checkpoint itself is untouched. Releasing it correctly needs a resumed_from_run_id link to know which source to unblock, so tracking that as a small follow-up rather than in this PR.

@danielhanchen

Copy link
Copy Markdown
Member

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🎉

Reviewed commit: 296f1f7f66

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@danielhanchen

Copy link
Copy Markdown
Member

@codex review

1 similar comment
@danielhanchen

Copy link
Copy Markdown
Member

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Can't wait for the next one!

Reviewed commit: d0b756a98f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

- Re-validate the current-step checkpoint in the dead-worker and error finalization paths so a stop-and-save that actually wrote a valid checkpoint is not wrongly marked error/resume_blocked
- Accept a valid tensor-free optimizer state (e.g. SGD without momentum); the model-state check still requires real tensors
- Include errored runs in the frontend resume rejection message
@danielhanchen

Copy link
Copy Markdown
Member

@codex review

@danielhanchen

Copy link
Copy Markdown
Member

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 👍

Reviewed commit: a7fcf56ffe

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@danielhanchen
danielhanchen merged commit f3c085a into unslothai:main Jul 21, 2026
46 checks passed
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.

4 participants