All workers cooperate on the same request. Each GPU runs a separate instance of the same
worker class. Every step calls the same
generate(input) implementation with the same input on
every worker. Your model uses rank to divide the computation and coordinate GPU-to-GPU
communication. The runner waits for all workers and returns rank 0’s complete result. If ranks
produce separate parts of the output, your model must gather them onto rank 0 inside generate()
before returning. The runner does not assemble outputs.One call reaches every GPU worker. The runner waits for all workers and returns rank 0's result.
Development preview: use a compatible runtime build, such as
3.5.0.dev99. Stable 3.5.0 and the
linked LingBot recipe’s current runtime pin do not include these APIs.Connect your model
Extend DistributedWorker and implementload(),
generate(), and reset(). The base class declares rank, world_size, and device and provides
is_leader for rank-0 checks. The runner assigns the attributes before load().
Define your worker
This adapter wraps the parallel model from yourvideo_model.py module. Here, ParallelVideoModel
accepts a weights path, device, rank, and worker count. It provides generate() and reset().
Adapt those calls to your model’s API.
video_worker.py
VideoInput(prompt=...), VideoResult, and RolloutExhausted also come from your model module.
The result holds CPU RGB frames in result.frames. In this example, every rank raises
RolloutExhausted when a rollout ends, and resetting lets the next prompt start another rollout.
This is a model-specific recovery contract. Only use that recovery branch if your model supports it.
Keep the worker at module level with a no-argument constructor. Use picklable inputs and results,
with contiguous CPU NumPy arrays for large payloads. Run one call at a time, on one machine.
Use the runner in a ReactorApp
Start the runner inload(), then call it from generate(). Client commands and tracks stay in the
application. The model keeps its inference code and session state.
video_app.py
process_output(), the expected model error resets the rollout and
skips that output. Other errors shut down the runner and end the session.
The change from an in-process model is in load(): construct and start DistributedRunner instead
of constructing and loading the model directly. Calls to generate() and reset() keep the same
interface. This isolates the model. Using multiple GPUs also requires the model’s own parallel
implementation.
Allocate GPUs
Match the runner’sworld_size to the GPU count in reactor.yaml:
Handle a failed step
The application example handles failures inprocess_output().
If every rank raises the same exception type, the runner stays healthy. Reset and continue only for
a model error that you know is recoverable, such as the example’s RolloutExhausted.
A crash, timeout, or rank disagreement leaves the runner unusable. The example shuts it down and
re-raises the error. This ends the session and stops the model loop. A new runner is required before
inference resumes. The runner does not restart workers or replay failed steps. See the
error contract.