Hardware a notebook needs

A notebook says what it needs in its script header, the block where marimo and uv already keep its dependencies. Whoever opens it is offered hardware that fits.

Declare it

Add a [tool.sciencehub.compute] table to the header at the top of the notebook's .py file. One line is enough:

Python
# /// script
# dependencies = ["numpy"]
#
# [tool.sciencehub.compute]
# ram_gb = 16
# ///

Every setting is a minimum. The header is part of the file, so the needs go wherever the notebook goes: a download, a fork, a git repository, a DOI release.

Without editing the file: open the notebook's settings and fill in Hardware it needs. Saving writes the same table as a new version.

What it changes

The runtime menu in the editor keeps hardware below the need in the list, greyed out, with the reason: Needs 16 GB of memory; this has 4 GB. A link to the notebook's /run page quotes hardware that fits. The notebook's page lists the needs and what an hour costs on hardware that fits.

max_hours sets how long a run starts for. The most a run can cost is its hourly price times that time; that amount is set aside from your balance when the run starts, and what the run does not use returns when it stops. An interactive run on ScienceHub compute lasts at most 4 hours. Once a notebook has run, the menu and the confirm step say what its last ten runs took on that hardware, the median and the long end, and the notebook's page says what reproducing it costs.

Hardware on ScienceHub compute now:

  • 1 vCPU, 1.5 GB: €0.04 an hour

Someone else's notebook

Whoever runs pays. On a public notebook you cannot edit, Run a copy beside its needs copies it into your account as a reproduction and shows the price there before anything starts. Pressing it again opens the copy you already have.

Settings

SettingMeaning
kind = "batch"How the notebook runs: "interactive" opens it with a kernel (the default), "batch" runs it top to bottom as a script, "distributed" spans several nodes, "qpu" submits circuits to a quantum processor.
cpu_cores = 4CPU cores, at least.
ram_gb = 16Memory in gigabytes, at least.
disk_gb = 50Disk space in gigabytes, at least.
gpus = "A100"GPUs per node: a count of any GPU (1), a type ("A100"), or both ("2x A100"). 0 means none.
nodes = 4Machines a distributed run spans. More than 1 makes the run distributed.
max_hours = 2The longest a run may last, in hours. A run on ScienceHub compute holds this much from your balance while it runs and returns what it does not use.
preemptible = trueWhether the run may be stopped and restarted to use cheaper spare capacity. False by default.

ScienceHub runs interactive notebooks today. Batch, distributed and quantum runs are read and shown, and run when their targets arrive.

A GPU

Python
# /// script
# dependencies = ["torch", "numpy"]
#
# [tool.sciencehub.compute]
# gpus = "A100"         # or 1 for any GPU, "2x A100" for two
# ram_gb = 32
# max_hours = 2
# ///

gpus takes a count of any GPU, a type, or both. A type names the GPU as its maker does: T4, L4, A10G, A100, A100-80GB, H100.

Check it

A setting ScienceHub cannot use is named with its line in the file, in the editor's runtime menu and on the notebook's page for its editors. Programs read the same from the project's description, under compute.problems:

Shell
curl -s https://sciencehub.sh/api/v1/projects/owner/project | jq .data.compute

On your computer, the sciencehub Python package reads a header the same way and names each problem with its file and line:

Shell
uvx sciencehub@0.2.1 check drift.py
# drift.py:7: memory is not a compute setting. Use ram_gb: ram_gb = 16.

The settings are described by a JSON Schema at https://sciencehub.sh/schemas/sciencehub.json, for editors and agents that write headers.

Where the names come from

cpu_cores, ram_gb, disk_gb and preemptible are the resource names of GA4GH's Task Execution Service, which Nextflow, Snakemake and Toil also use. Needs as minimums, with hardware below them shown and disabled, follow GitHub Codespaces' hostRequirements. gpus reads SkyPilot's and Modal's A100:2 as well as 2x A100.