interlens.runner¶
interlens.runner
¶
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.
available_devices
¶
List the devices to spread conversations across: every CUDA GPU, else a single mps/cpu fallback.
Multi-GPU parallelism lives across conversations (they're independent); within one conversation turns are sequential, so more GPUs never speed up a single conversation — only throughput over many.
Source code in src/interlens/runner/devices.py
register_worker_init
¶
Register a zero-arg callable to run once at worker startup (e.g. to populate the tool/analyzer registries).
resolve_analyzer
¶
Accept either a callable (in-process) or a registered name (spawn-safe) and return the callable.
Source code in src/interlens/runner/analyzer_registry.py
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.