machine
from lium.sdk import machine
Defined in lium.sdk.decorators.
def machine(
machine: str,
template_id: Optional[str] = None,
cleanup: bool = True,
requirements: Optional[Sequence[str]] = None,
*,
timeout: Optional[float] = 3600,
keep_warm: float = 0,
local: bool = False,
quiet: bool = False
):
Decorator to execute a function on a remote Lium machine.
Creates a new pod, sends function source code and executes it remotely, returns the result, and optionally cleans up the pod.
The decorated function also offers f.remote(*a) (same as f(*a)),
f.local(*a) (run the original here), f.map(iterable) (run every item on one
pod, rented once) and f.close() (remove the pod kept by keep_warm).
Arguments travel as a pickle: your own bytes, loaded on your own pod as they are. The
result comes back from provider hardware, so nothing it contains is unpickled here:
it travels as a JSON envelope plus an .npz sidecar for numpy arrays, read with
allow_pickle=False. What round-trips, exactly: None, bool, int,
float, str, bytes; list, tuple, set, frozenset and
dict of those, nested; datetime/date/time/timedelta, Decimal,
pathlib.Path, uuid.UUID; numpy.ndarray (any dtype without Python objects,
any shape) and numpy scalars. Anything else — a dataclass, an Enum, an
OrderedDict, a tensor, an ndarray subclass — raises ResultEncodingError
on the pod, naming the type and its place in the result, and is re-raised here
(return .tolist(), dict(x), x.value instead).
Only the function's own def is sent: import what it needs inside the body and
pass everything else as arguments. Whatever the function prints is relayed to this
process's stdout/stderr while it runs. An exception raised on the pod is re-raised
here with the same type when that type is a builtin (except ValueError works;
its args come along when they are plain data, else its message); other types come
back as RemoteExecutionError. Either way the __cause__ is a
RemoteExecutionError carrying the remote traceback, exit code and captured
output.
Arguments:
- machine:
"<count>x<gpu>"or"<gpu>"— e.g."1xH200","RTX4090","2xA100". The count defaults to 1. The GPU is named aslium ls --gputakes it (H100,RTX4090,rtx pro 6000, a bare4090) and has to match the node's type whole —"A100"never rents an RTX A1000. The cheapest node with exactly that many GPUs of that type free to rent is rented (a split host with 2 of 8 free is a2xA100) and billed for those — by the backend in one call (rent()) when it offersrent_by_spec, else picked here from a listing; when none matches, the error names the types the listing has. - template_id: Docker template ID (optional, uses the node's default if not specified)
- cleanup: Whether to delete the pod after execution (default: True)
- requirements: Optional iterable of pip-installable packages to install on the pod. They go into a venv that also sees the image's own packages, created and populated once per pod and reused by later calls with the same list.
- timeout: Seconds the function may run on the pod before it is killed (default 1 h;
Nonefor no limit;0or a negative number is refused when decorating). A fraction of a second is rounded up to the next second for the kill. The pod is also scheduled for removal attimeout + 15 min(24 h whentimeout=None) so a caller that dies mid-call cannot leave it billing. - keep_warm: Seconds the pod stays after a call for the next one — from this process
or the next run of the script (the pod is found by name). Default 0: the pod
is removed when the call returns. The pod is scheduled for removal server-side
keep_warm + 2 minafter each call, so nothing depends on the caller coming back. - local: Run the function in this process instead (
LIUM_MACHINE_LOCAL=1does the same for every decorated function) — for tests and offline work. - quiet: Suppress the one-line progress messages written to stderr.