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