interlens.runner.pool¶
interlens.runner.pool
¶
The execution engine behind Conversation.rollout and interlens.run.
A job is a (job_id, Conversation) pair — an unrun, fully-resolved conversation (lazy participants, no
dataset). run_jobs runs a list of them across devices with checkpointing, resume, per-job failure isolation,
and (by default) batched co-stepping within each device. Each finished conversation is returned on its
RunResult so it can be sampled/inspected afterwards. The analyzer travels ON each conversation
(conv._analyzer) — a callable in-process, or a registered name across a spawn boundary.
RunReport
dataclass
¶
Aggregate outcome of a run. Failures are isolated, not fatal: results holds every attempted job,
failed lists the ones that errored, skipped lists resume-skipped (already-checkpointed) ids.
RunResult
dataclass
¶
RunResult(
job_id: str,
conversation: object = None,
transcript: object = None,
analysis: object = None,
error: str | None = None,
device: str | None = None,
)
Outcome of one job: the finished conversation (weightless participants + completed transcript), its
transcript and (serializable) analysis, or an error string if it failed. conversation is the
object to sample()/inspect after a rollout (the source recipe is never mutated).
tokens_generated
property
¶
Total generated tokens in this conversation (summed from each turn's metadata['n_tokens']) — the
realized compute, for verifying matched-compute comparisons. 0 if the job failed.
run
¶
run(
conversations,
devices=None,
out_dir=None,
resume=False,
batched=True,
max_batch_size=None,
) -> RunReport
Run several conversation lineups in ONE pool — the multi-lineup entry point (e.g. a ladder of model pairs × conditions in one overnight job).
Each conversation is expanded to its jobs (one per data() row if it has data, else a single conversation),
with job ids namespaced by that conversation's name (default conv{i}) so ids stay unique and resumable.
All jobs go into one pool, so GPUs stay packed across lineups (no idle tail between sequential rollouts) under a
single out_dir/resume namespace, returning one merged RunReport. Mixing lineups is safe: batched
co-stepping groups by schedule signature, so each distinct lineup forms its own batch group.
Conversation.rollout is the single-lineup sugar for this (run([conv], ...)-equivalent via run_jobs).
Source code in src/interlens/runner/pool.py
run_jobs
¶
run_jobs(
jobs,
devices=None,
out_dir=None,
resume=False,
batched=True,
max_batch_size=None,
) -> RunReport
Run (job_id, Conversation) jobs across devices, with checkpointing, resume, and per-job failure isolation.
Parallel by default on two axes: one worker process per device (jobs round-robined; multi-GPU spawns via
torch.multiprocessing since fork+CUDA is broken — a single device runs in-process), and within each device
batched co-stepping (batched=True). Jobs are grouped by co-step schedule signature so same-schedule jobs
batch into one model.generate — correct for ANY mix. batched=False gives the DETERMINISTIC path.