TL;DR
If you launch training through a cookbook recipe (rl_loop, sft_loop, dpo_loop, orpo_loop, igpo_loop), you don’t have to call any checkpoint APIs yourself. Set two config fields and the recipe handles save, resume, and promote:
dcp_save_interval=N(top-levelConfigfield on every recipe) — save resumable checkpoints every N stepsoutput_model_id="my-model"— promote the final checkpoint to a deployable Fireworks model
log_path resumes from the last saved checkpoint automatically.
Config fields
On Serverless Training there is no trainer job, so the
"job-id:checkpoint-name" grammar does not apply. In serverless mode init_from_checkpoint accepts a bare checkpoint name (current run) or a fully qualified "<account>/run-<run-id>/<checkpoint-name>" cross-run reference. See Saving and loading checkpoints (serverless).Resume-training vs serving: which checkpoint to use
Each save can produce up to two different control-plane rows, and they are not interchangeable. Selecting the wrong one is the most common cause of a resume that produces incoherent output.
Key points:
- To resume training, load a
TRAINING/TRAINING_LORA(DCP) checkpoint. Only DCP checkpoints carry optimizer state. To continue a run with optimizer state (plus the step counter and data cursor), reattach the same trainer job and use automatic same-log_pathresume (recipe), or load the checkpoint withload_state_with_optimizer(SDK).init_from_checkpoint(recipe) is a weights warm start: it loads the checkpoint weights with a fresh optimizer and resets the step counter to 0. - To serve or promote, use the
INFERENCE_*sampler snapshot. These are weight-only, and are whatpromote_checkpointand hot-load expect. - The two rows saved at the same step represent the same weights but different payloads (DCP is weights plus optimizer, sampler is weights only). Do not assume a
TRAINING_LORAblob can be served directly, or that anINFERENCE_LORAblob can resume training.
Resume
Automatic (same log_path)
Just rerun with the samelog_path and the recipe resumes. It queries the control plane for the newest resumable checkpoint on the trainer job and reloads weights and optimizer state. The step counter and the cookbook’s data_consumed counter are restored from dataloader.json in log_path.
From another job
Safely saving a resumable checkpoint before you continue
To continue training from an existing run without losing progress, follow the same ordered procedure for every recipe, including the RL recipe (rl_loop): save a resumable checkpoint, verify it on the control plane, then resume from it. This applies whether the source run is still active, cancelled, or completed.
A common reason there is no resumable checkpoint to continue from is that
dcp_save_interval was left unset. It defaults to 0 (off), so the run never saved automatic DCP (resumable) checkpoints and there is nothing to continue from. Check this first: if the source job did not have dcp_save_interval set, force a save explicitly (Step 1) while the trainer job is still available, rather than assuming a periodic checkpoint already exists.1
Save a resumable (DCP) checkpoint
Make sure a
TRAINING/TRAINING_LORA checkpoint exists on the source job. Either set dcp_save_interval=N on the recipe config so periodic saves happen automatically, or force one save explicitly:resumable=True is what persists weights and optimizer state; without it the run cannot be continued from intermediate steps.2
Verify the checkpoint is visible on the control plane
The control plane is the source of truth for resume, so confirm the checkpoint landed before you tear anything down:Or via the SDK/API, see Listing checkpoints on a trainer. Look for your
step-N row with a TRAINING/TRAINING_LORA type.3
Continue training from it
Start (or restart) a trainer and point This loads the checkpoint weights with a fresh optimizer and resets the step counter to 0 (a weights warm start). To continue with optimizer state instead, reattach the same trainer job and use automatic same-
init_from_checkpoint at the verified checkpoint:log_path resume, or load the checkpoint with load_state_with_optimizer (SDK).Keep the source trainer job’s row around until the new run has loaded its checkpoint. A cancelled or completed trainer can still serve as a source of checkpoints, but its checkpoint blobs are what the resume reads from.
Troubleshooting
Resuming from a TRAINING_LORA checkpoint produces incoherent output while the INFERENCE_LORA snapshot of the same step serves correctly
Resuming from a TRAINING_LORA checkpoint produces incoherent output while the INFERENCE_LORA snapshot of the same step serves correctly
Symptoms: Promoting or serving an
INFERENCE_LORA sampler snapshot for a given step produces coherent output, but restarting training from the same step’s TRAINING_LORA (DCP) checkpoint and then exporting or serving those weights produces degenerate or incoherent output (for example, repeated or non-Latin tokens), sometimes with tool-call failures. A test prompt at temperature 0 may look identical to a different step, which suggests the loaded weights are not the ones you requested.Root cause (checklist):-
Wrong checkpoint type for the goal. Confirm you loaded a
TRAINING/TRAINING_LORA(DCP) checkpoint for the resume, not anINFERENCE_*snapshot, and that you are serving theINFERENCE_*snapshot, not the DCP blob. See which checkpoint to use. -
Export ordering after a resume.
save_weights_for_sampler/save_weights_for_sampler_extexport the trainer session’s currently active adapter/weights. In a normal training step it is preceded by anoptim_step, so the active weights are well defined. Immediately after a resume, export the weights you just loaded, and make sure nothing else (a stale adapter from an earlier state, another concurrent step) is active. If a sampler export right afterload_state_with_optimizeryields a different snapshot than the DCP step you requested, the loaded state is not the one being exported. See Resuming and then exporting weights. - A platform-side loader mismatch. In some cases the trainer-side checkpoint loader can resolve the latest checkpoint rather than the one you requested when a sampler export follows a cross-job resume, so the exported snapshot points at a different, later step. If you have ruled out (1) and (2) and a cross-job resume still exports the wrong weights, capture the source job ID, the requested checkpoint name, and the exported snapshot identity, and contact Fireworks support so they can check the trainer shape version and checkpoint loader.
Resume seems to load, but weights look unchanged from the base model
Resume seems to load, but weights look unchanged from the base model
Symptoms:
load_state_with_optimizer returns without error and the deployment is addressed correctly, but outputs look like the base model (or identical across steps that should differ).What to check:- Verify you passed a resumable (
TRAINING/TRAINING_LORA) checkpoint name, not a name that does not exist (a missing checkpoint can silently leave the trainer at its initial weights). List checkpoints first (see Safely saving a resumable checkpoint). - Confirm the sampler snapshot you served was exported after the resume load, not carried over from a previous state.
- Sanity-check that the deployment is actually serving your adapter and not falling back to base (compare against a known-good promoted checkpoint at temperature 0).
Promoting a checkpoint manually
If you want to promote an arbitrary checkpoint after training (not just the final one), use the cookbook’s promote script:--checkpoint-name <name> to promote a specific one.
You can also call the API directly — see Saving and Loading — Promoting.
Advanced internals
Most users can stop reading here. The sections below cover what the recipe does internally — useful only if you’re forking a recipe, calling the SDK directly, or debugging a checkpoint that doesn’t promote. The full SDK-level reference lives in Saving and Loading.
What gets saved, where
The recipe interacts with two surfaces:
There is no
checkpoints.jsonl registry — the control plane is queried at resume / promote time.
Two axes: resumable and promotable
When the recipe saves a checkpoint, it picks two independent capabilities:
Periodic saves use
resumable=True only. The final save uses both. RL weight sync saves sampler checkpoints and syncs their snapshot identities separately from DCP resume saves.
Forking a recipe
If you forkrl_loop.py (or another ported recipe) and need to drive checkpointing yourself, instantiate TrainingCheckpoints:
save_state / save_weights_for_sampler_ext / promote_checkpoint to the SDK and uses the control plane as the source of truth for resume and promotion. Recipes pass the SDK-managed service client as the control-plane checkpoint client. The full API surface those calls expose is documented in Saving and Loading.
Checkpoint kinds
This subsection is the canonical reference for checkpoint kinds and promotability across the stack — other pages link here. Three separate layers of the stack each have their own “type”, and confusing them is the usual reason a promotion fails. They are not synonyms:
When the cookbook saves with
promotable=True, it always calls the SDK with checkpoint_type="base", which the server detects as INFERENCE_BASE (full-param) or INFERENCE_LORA (LoRA). Both are promotable. The non-promotable INFERENCE_ARC_V2 only happens if you bypass the cookbook and call save_weights_for_sampler_ext("delta") on a full-parameter run.
Promotability cheat sheet
“Promotable” means the server will accept the blob for promotion — i.e. the checkpoint showspromotable=True in list_checkpoints. To actually promote, you need the checkpoint name plus source_job_id and base_model.
For SDK-level details on each row (full method signatures, base-vs-delta semantics, weight-sync lifecycle), see Saving and Loading.
Related guides
- Saving and Loading — SDK-level reference for save / load / promote
- Training and Sampling — SDK-managed sampler refresh lifecycle
- Cookbook RL — full GRPO walkthrough