On this page
GPU and cloud compute vendors
GPU and cloud compute vendors
Fifteen GPU and cloud compute vendors dispatch agent machines like gcp,
azure and aws: enable one in providers (or WC_PROVIDERS) and the
coordinator dispatches, reaps and counts its agents against the reservation
overlay. Arkane Cloud is the sixteenth adapter, but only lists, reads and
releases vendor machines; its deploy API cannot boot an agent. The adapters
share the provider-neutral VM lifecycle (providers::gpu_cloud) where their
vendor API supports it.
| Provider id (aliases) | Vendor | Settings (stado config set <path> <value>) |
Credential fields | Agent runs |
|---|---|---|---|---|
arkane (arkane-cloud) |
Arkane Cloud | none | api_key |
never: listed, read and released only |
crusoe |
Crusoe Cloud | crusoe.project_id, crusoe.location, crusoe.ssh_public_key; optional crusoe.image |
access_key_id, secret_key |
on the VM |
cudo (cudo-compute) |
Cudo Compute | cudo.project_id, cudo.data_center, cudo.image_id, cudo.vcpus, cudo.memory_gib |
api_key |
on the VM |
hyperstack |
Hyperstack | hyperstack.environment, hyperstack.image, hyperstack.key_name |
api_key |
on the VM |
lambda (lambda-labs) |
Lambda Cloud | lambda.region, lambda.ssh_key_name; optional lambda.image_family |
api_key |
on the instance |
latitude (latitude-sh) |
Latitude.sh | latitude.project, latitude.site; optional latitude.operating_system, latitude.ssh_key |
api_key |
on the VM |
nebius |
Nebius AI Cloud | nebius.project_id, nebius.subnet_id, nebius.image_family, nebius.jwt_lifetime_seconds |
service_account_id, key_id, private_key |
on the instance |
oblivus |
Oblivus Cloud | oblivus.location, oblivus.os_label, oblivus.os_name, oblivus.ssh_public_key |
api_key |
on the VM |
oracle (oci) |
Oracle Cloud Infrastructure | oracle.region, oracle.compartment_id, oracle.availability_domain, oracle.subnet_id, oracle.image_id; optional oracle.ssh_public_key |
tenancy, user, fingerprint, private_key |
on the instance |
ovhcloud (ovh) |
OVHcloud | ovhcloud.api, ovhcloud.project, ovhcloud.region, ovhcloud.image_id; optional ovhcloud.ssh_key_id |
application_key, application_secret, consumer_key |
on the instance |
runpod |
RunPod | runpod.image, runpod.cloud_type |
api_key |
inside the pod's container |
salad (saladcloud) |
SaladCloud | salad.organization, salad.project, salad.image, salad.vcpus, salad.memory_mb |
api_key |
inside the container |
scaleway |
Scaleway | scaleway.zone, scaleway.project_id, scaleway.image |
secret_key |
on the GPU Instance |
vast-rental |
Vast.ai | vast-rental.image |
api_key |
inside the instance's container |
voltage-park (voltagepark) |
Voltage Park | optional voltage-park.location |
api_key |
on the VM |
vultr |
Vultr | vultr.region, vultr.os_id; optional vultr.ssh_key_id |
api_key |
on the instance |
Every setting has an environment override: the upper-case provider and key
(LAMBDA_REGION, VOLTAGE_PARK_LOCATION), except Oracle's, which start with
OCI_ (OCI_COMPARTMENT_ID). stado config validate refuses a
profile that enables a vendor without one of its required settings, naming
the path and the variable: lambda provider needs lambda.region (environment override LAMBDA_REGION).
OVHcloud answers on one API endpoint per account zone, so ovhcloud.api
names the account's own (https://eu.api.ovh.com/1.0,
https://ca.api.ovh.com/1.0 or https://api.us.ovhcloud.com/1.0) and
nothing is assumed. Every call is signed with the application secret and
consumer key against OVHcloud's own time (GET /auth/time), so a skewed
clock on this host cannot void a signature. A launch first reads the
region's flavors: an instance type the region does not list, lists as not
available, or lists with no quota left is refused as capacity before
anything is ordered.
Vast.ai is a marketplace rather than a catalogue of instance types, so
vast-rental rents in two steps. For the accelerator's Vast.ai GPU name
(L4, RTX 4090, RTX A6000, L40S, H100 PCIE, H100 SXM, H200) it
searches the offers that are rentable, not already rented by this account,
verified, on-demand, carry one such GPU and have room for the job's boot
disk, and accepts the cheapest by total hourly price. An empty search is
capacity, so the dispatcher moves to the next tier as it does for any vendor
out of stock. The agent's startup script is the container's entrypoint
(bash -c), because Vast.ai cuts the onstart field at 4,048 characters;
the instance label is the agent's name and the script exports it as
STADO_WORKER_NAME. An instance whose container Vast.ai reports exited,
offline or unknown while it is meant to run never starts, by Vast.ai's
own documentation, and is read as failed, so the reaper releases it. Use a
Vast.ai API key of its own under cloud-vast-rental: it spends the account's
credit, while the selling side reads the host's key.
stado config set vast-rental.image <image with bash and the agent's runtime>
stado credentials item put --host <vault host> --role cloud-vast-rental --type api-key # {"api_key": "…"} on standard input
stado config set providers '["local", "vast-rental"]'
stado config validate
stado instances list --provider vast-rental
Credentials
A vendor's account credential is one Skarbiec item tagged
stado:role:cloud-<provider> (cloud-lambda, cloud-voltage-park, …),
holding the fields in the table. Store it on the vault host with the JSON
object on standard input, never on the command line:
stado credentials item put --host <vault host> --role cloud-lambda --type api-key
The coordinator reads the item through its own grant; a workload grant may
not carry it, and stado config validate refuses agent.skarbiec.roles or
agent.skarbiec.secret_fields that name any cloud-<provider> role. A
missing item is refused at the first call that needs it, naming the role and
this command: Lambda Cloud: no live Skarbiec item tagged stado:role:cloud-lambda carries a non-empty field api_key; store the Lambda Cloud credential with stado credentials item put --host <vault host> --role cloud-lambda --type api-key and the JSON object on standard input. A vendor
that refuses the credential is reported with the role and the vendor's own
answer: Lambda Cloud: list instances: the credential in Skarbiec role cloud-lambda was refused (HTTP 401): ….
How many machines run
No vendor exposes a quota Stado can read, so the reservation overlay is the
ceiling: config/quotas.json in the queue store declares, per vendor and
accelerator, how many machines may run at once. A vendor with no section
dispatches nothing, and stado doctor says so: lambda: has no quota API, and config/quotas.json in the queue store declares no lambda section, so no lambda machine is ever dispatched.
The operator declares total from its capacity agreement and reserved
from capacity it has committed elsewhere under the chosen vendor and
accelerator keys. Stado chooses neither count. Both are integers; a row that
states either in another shape, or omits one, is not counted as no capacity:
stado doctor fails it by name (<vendor>: config/quotas.json rows without integer total and reserved counts: <accel>=<row>) and names the remedy.
Each vendor declares the instance types it offers and the accelerator each
carries; a job's VRAM need selects the smallest offer whose accelerator
memory covers it, and a vendor that reports no capacity for a type moves the
job to the next larger offer. Lambda, Vultr, Voltage Park and Crusoe report
capacity before a launch (Vultr's region availability, Voltage Park's
instant presets, Crusoe's capacities, Lambda's insufficient-capacity code);
Scaleway's out_of_stock refusal is capacity too. Machines are rented on
demand only; a preemptible request is refused.
| Provider | Instance type → accelerator |
|---|---|
crusoe |
l40s-48gb.1x → nvidia-l40s, a100-80gb.1x → nvidia-a100-80gb, h100-80gb-sxm-ib.8x → nvidia-h100-80gb, h200-141gb-sxm-ib.8x → nvidia-h200-141gb |
cudo |
epyc-milan-rtx-a6000 → nvidia-rtx-a6000-48gb, epyc-milan-a100-pcie → nvidia-tesla-a100, sapphire-rapids-h100 → nvidia-h100-80gb |
hyperstack |
n3-RTX-A6000x1 → nvidia-rtx-a6000-48gb, n3-L40x1 → nvidia-l40-48gb, n3-A100x1 → nvidia-a100-80gb, n3-H100x1 → nvidia-h100-80gb, n3-H100-SXM5x8 → nvidia-h100-80gb |
lambda |
gpu_1x_a10 → nvidia-a10, gpu_1x_rtx6000 → nvidia-rtx6000-24gb, gpu_1x_a100_sxm4 → nvidia-tesla-a100, gpu_1x_a100 → nvidia-tesla-a100, gpu_1x_a6000 → nvidia-rtx-a6000-48gb, gpu_1x_h100_pcie → nvidia-h100-80gb, gpu_1x_h100_sxm5 → nvidia-h100-80gb, gpu_8x_a100_80gb_sxm4 → nvidia-a100-80gb, gpu_8x_v100 → nvidia-tesla-v100-16gb |
latitude |
g3.l40s.medium → nvidia-l40s, g3.h100.large → nvidia-h100-80gb |
nebius |
gpu-l40s-a/1gpu-8vcpu-32gb → nvidia-l40s, gpu-h100-sxm/1gpu-16vcpu-200gb → nvidia-h100-80gb, gpu-h200-sxm/1gpu-16vcpu-200gb → nvidia-h200-141gb |
oblivus |
RTX_4090_x1 → nvidia-rtx-4090-24gb, RTX_A6000_x1 → nvidia-rtx-a6000-48gb, L40_x1 → nvidia-l40-48gb, A100_PCIE_80GB_x1 → nvidia-a100-80gb, H100_PCIE_80GB_x1 → nvidia-h100-80gb |
oracle |
VM.GPU.A10.1 → nvidia-a10, VM.GPU3.1 → nvidia-tesla-v100-16gb, VM.GPU.L40S.1 → nvidia-l40s, BM.GPU.A100-v2.8 → nvidia-a100-80gb, BM.GPU.H100.8 → nvidia-h100-80gb |
runpod |
NVIDIA L4 → nvidia-l4, NVIDIA GeForce RTX 4090 → nvidia-rtx-4090-24gb, NVIDIA RTX A6000 → nvidia-rtx-a6000-48gb, NVIDIA L40S → nvidia-l40s, NVIDIA A100 80GB PCIe → nvidia-a100-80gb, NVIDIA A100-SXM4-80GB → nvidia-a100-80gb, NVIDIA H100 80GB HBM3 → nvidia-h100-80gb, NVIDIA H100 PCIe → nvidia-h100-80gb, AMD Instinct MI300X OAM → amd-mi300x-192gb |
salad |
RTX 3090 (24 GB) → nvidia-rtx-3090-24gb, RTX 4090 (24 GB) → nvidia-rtx-4090-24gb, RTX 5090 (32 GB) → nvidia-rtx-5090-32gb |
scaleway |
L4-1-24G → nvidia-l4, L40S-1-48G → nvidia-l40s, H100-1-80G → nvidia-h100-80gb |
voltage-park |
h100-sxm5-80gb → nvidia-h100-80gb, h200-sxm5-141gb → nvidia-h200-141gb |
vultr |
vcg-a40-8c-40g-16vram → nvidia-a40-16gb, vcg-a40-12c-60g-24vram → nvidia-a40-24gb, vcg-l40s-16c-180g-48vram → nvidia-l40s |
When two offers carry accelerators of the same memory, the one listed first is the one a job is sized onto; the others are still counted when they run.
The agent on a rented machine
Every machine boots the same provider-neutral startup script the other
clouds use, delivered as the vendor's cloud-init, user data, start script or
container command. On a virtual or bare-metal machine the script first sets
the hostname to the instance name (wisent-agent-<accel>-<tick>-<n>). A
container cannot set its hostname, so on RunPod and SaladCloud the script
exports STADO_WORKER_NAME instead — the instance name on SaladCloud, the
pod id from RUNPOD_POD_ID on RunPod — and the agent publishes capacity
under that name. The reaper matches the same name, and only machines whose
name starts with the fleet's instance prefix are treated as agents; anything
else the credential can see is left alone.
Arkane Cloud's deploy API takes no startup script, so no agent can boot
there. Its machines are listed, read and released, it has no sizing ladder,
the coordinator gives it no dispatch arm, and a launch is refused: Arkane Cloud: the vendor's deploy API takes no startup script, so Stado cannot boot an agent on a machine it rents there; arkane machines are listed, read and released but never dispatched.
Source: this website