nemo_automodel.components.speculative.regen_loop
nemo_automodel.components.speculative.regen_loop
On-policy data regeneration loop for EAGLE-3 draft training (train-with-decode).
EAGLE-3 teacher-forces the draft on a static dataset whose assistant turns were
often written by a different model than the target being distilled, so the
draft trains against off-distribution supervision (this is why the recipes ship
an offline regenerate.py pass). This module runs that regeneration
online, interleaved with training:
- On a cadence (
regen.every_steps), rank 0 launches a detached worker subprocess pinned to a reserved GPU (regen.cuda_visible_devices). The worker boots a plain vLLM OpenAI server for the frozen target and drives the existingregeneratemachinery over a prompt slice, writing a fresh directory of parquet shards. Training never blocks; at most one cycle is in flight. - At the next epoch boundary the recipe checks for a completed cycle, and if one is ready all data-parallel ranks rebuild the training dataloader against the new shard directory in lockstep (the decision is broadcast from rank 0 so the ranks never diverge).
Because the EAGLE target is frozen, the regenerated distribution is stationary:
the value here is pipelining (regenerate just-in-time instead of one giant
upfront pass) and freshness (sampling new responses each cycle with
temperature > 0), plus the plumbing a future draft-in-the-loop mode would
reuse. The trainer process never imports vllm; the worker inherits the training
env minus the torchrun/elastic variables (see decode_eval._worker_env).
Module Contents
Classes
Functions
Data
API
Resolved settings for the online on-policy regeneration loop.
every_steps is the launch cadence in optimizer steps; a completed cycle
is only swapped in at an epoch boundary (mid-epoch dataloader rebuilds would
desync the sampler and the scheduler’s step count). cuda_visible_devices
is the GPU (or comma list) reserved for the regeneration engine; training
must not place work there. server_python is the interpreter used to
launch the vLLM server (the training env need not have vllm installed); the
regeneration client runs in the training env over HTTP.
Rank-0 trainer-side orchestrator: launch regeneration at cadence, hand ready cycles to the recipe.
At most one regeneration subprocess is alive at a time; a launch that lands
while the previous cycle is still running is skipped (the next cadence
boundary picks it up). A cycle is “ready” once its worker has written the
READY marker; :meth:take_ready_shards returns the newest ready cycle’s
shard directory exactly once, so the recipe can swap it into the dataloader.
Return valid cycle directories in numeric order, ignoring stray names.
Report a completed worker and release its Popen state.
Whether a new regeneration cycle should launch at this optimizer step.
Launch a regeneration worker if the cadence is due and none is running.
Align the launch cadence to a restored global_step after a resume.
Without this a resumed run starts with _last_bucket == 0 and
:meth:due fires immediately, relaunching a redundant cycle for a cadence
region that already ran before the checkpoint. Superseded on-disk cycles
left by the pre-crash run are reclaimed by :meth:take_ready_shards on the
next swap (it frees every ready cycle but the newest), so no cycle path
needs to be persisted across the checkpoint.
Terminate a still-running cycle (its vLLM child dies with the session).
Return the newest ready, not-yet-consumed cycle’s shard directory, or None.
A cycle is ready once its READY marker exists. Older ready cycles are
marked consumed and skipped so the recipe always trains on the freshest
regenerated data rather than replaying stale cycles.
Build the regenerate CLI args to run against the booted target server.
Build the plain (non-speculative) vLLM OpenAI server argv for the frozen target.
Worker entry: boot a target server, regenerate a shard dir, write the READY marker.
Read the optional regen: block from recipe_args.
Returns None when the block is absent or every_steps is unset/0
(feature disabled). Raises on a partially-configured block so a typo’d GPU
reservation fails at setup rather than silently regenerating on a training
GPU. Field defaults live on :class:RegenConfig only; the block just
overrides the fields it sets.