Run a job to completion
Run a Python script or a container command on rented hardware, stream its output, and get its exit code back - with dependencies, arguments, environment, secrets, and detached runs.
hi compute run starts a fresh machine, runs one script or command, streams
its output, and releases the machine when it ends. hi exits with the job’s
own exit code, so it works in scripts and CI:
hi compute run --gpu a10g-small --max 1h train.py -- --epochs 3 && echo trained
Python scripts
A .py file runs with uv, so dependencies
declared inline in the script (PEP 723)
are installed on the machine. No requirements file or image is needed:
# /// script
# requires-python = ">=3.10"
# dependencies = ["torch", "rich"]
# ///
import sys
import torch
from rich import print
print(f"args={sys.argv[1:]} cuda={torch.cuda.is_available()}")
hi compute run --gpu a10g-small --max 30m check.py -- --verbose
Everything after -- is passed to the script as its arguments.
| Provider | How the script gets there | Limits |
|---|---|---|
| Hugging Face | Sent inside the job request; runs in ghcr.io/astral-sh/uv:python3.12-bookworm |
96 KB per script |
| Colab | colab run, on a fresh Colab runtime |
Python scripts only |
Scripts larger than 96 KB, or code in several files, belong in a container image or a Git repository the script clones.
Container images (Hugging Face)
On Hugging Face you can also run any public image. Put the command after --:
hi compute run --on hf --max 10m python:3.12 -- python -c 'print("hello")'
hi compute run --gpu l40sx1 --max 2h pytorch/pytorch:2.6.0-cuda12.4-cudnn9-devel -- python -m my.module
Environment and secrets
hi compute run --gpu a10g-small \
--env EPOCHS=10 --env RUN_NAME=baseline \
--secret WANDB_API_KEY --secret HF_TOKEN \
train.py
--env KEY=VALUEsets a plain environment variable. Values appear in the job’s settings, so never use it for credentials.--secret KEYsends the value of$KEYfrom your shell as an encrypted Hugging Face job secret. It must be set in your shell first, and its value never appears inhioutput or--dry-run.
Colab has no secret store, so
hirefuses--secreton Colab rather than putting the value on a command line.
Your team’s data
With a hi server that serves your team’s Hugging Face data
(hi data), --data downloads it on the instance before
the script starts:
hi compute run --gpu a10g-small --data hifinab/bars-1d train.py
hi compute run --gpu a10g-small --data hifinab/fdb/runs/2026-09 --data hifinab/ranker train.py
Each repository lands in data/<name> next to where the script runs, as
with hi data get. A folder or pattern after the name (/runs/2026-09,
/*.parquet) downloads only those files.
Script runs only. The instance can’t reach the hi server inside NetBird, so the data gets there one of two ways.
On Hugging Face Jobs, through the server’s public address. The server
opens a narrow public address with NetBird (netbird expose) that answers
only the data proxy, and gives the job a run token: it reads only the
repositories named with --data, until the run’s time limit, and travels
as an encrypted job secret. The job downloads through it, and the script
can then read those repositories itself:
from datasets import load_dataset
results = load_dataset("hifinab/fintabarena-results") # works in the job too
This needs Peer Expose turned on in NetBird (Settings > Clients); the server closes the address when no run needs it.
On Colab, or when the server can’t expose: signed links. hi asks the
server for a signed download link per file when the run starts, and sends
the links with the script; the instance never holds a token. The links
last about an hour, so the job must start within that time. On Hugging
Face Jobs this way, everything travels in one environment variable of at
most 120 KB: enough for a few hundred files. Small files that a
repository keeps in git rather than Hugging Face’s file storage, such as
an older model’s tokenizer.json, have no link and travel inside the job,
and hi says when they make it too large. Leave them out with a pattern,
or run on Colab, which has no such limit.
Long runs: detach, follow, and wait (Hugging Face)
Start a run and get your terminal back with --detach:
hi compute run --gpu a10g-small --max 6h --detach --name finetune train.py
Started job 6ab97cba…: https://huggingface.co/jobs/hifinab/6ab97cba…
Follow it with: hi compute logs finetune --follow
Wait for it: hi compute wait finetune
Then, from anywhere:
hi compute ls # it is listed while it runs
hi compute logs finetune --follow # stream output until it ends
hi compute logs finetune -n 100 # the last 100 lines, even after it ended
hi compute wait finetune # block until it ends; exits with its code
hi compute status finetune # state, hardware, when it started and stops
hi compute stop finetune # cancel it
Colab runs cannot detach. For long work on Colab, start an instance and run your script inside it.
Exit codes
| Result | hi exits with |
|---|---|
| The job finished successfully | 0 |
| The job failed | The job’s own exit code, when the provider reports it, else 1 |
| The job was stopped | 130 |
Results and files
A run’s machine is gone when it ends, and so is everything written to its
disk. Save results somewhere that outlives it: print them, push them to the
Hugging Face Hub from the script (pass --secret HF_TOKEN), or upload them to
your own storage. Train with uv scripts shows
uploading a model to the Hub.
Options
| Option | Meaning |
|---|---|
--gpu <hardware> |
Hardware from hi compute hardware; default is the cheapest CPU |
--max <duration> |
Stop after this long: hours (2), 30m, 2d, or none; default 1h |
--name <name> |
Name for logs, wait, and stop |
--env KEY=VALUE |
Environment variable; repeatable |
--data <org>/<name>[/<pattern>] |
Your team’s data into data/<name> first; repeatable |
--secret KEY |
Encrypted secret from your shell (Hugging Face); repeatable |
--detach |
Return after starting (Hugging Face) |
--namespace <ns> |
Bill this Hugging Face account for this run |
--high-mem |
High-RAM machine (Colab) |
--on <provider> |
colab or hf |
--yes |
Skip the cost confirmation |
--dry-run |
Show the request without starting anything |