Logo VRAMfarm VRAMfarm
IT
Registrati
Documentazione

API VRAMfarm

Avvia server GPU da script e CI: trova una macchina disponibile, avviala con un’app pronta o con la tua immagine Docker, aspetta SSH, fermala. Semplice HTTPS e JSON, nessun SDK necessario.

URL di base dell’APIhttps://vramfarm.com/api
  • Le risposte sono in JSON, UTF-8. Le richieste POST richiedono l’header Content-Type: application/json.
  • Gli importi sono in euro. price è all’ora per l’intero server, tutte le schede incluse, come numero decimale con i centesimi (per esempio 0.39).
  • Gli orari nelle risposte sono in ISO 8601, UTC; il campo updated del catalogo è in millisecondi Unix.
  • I messaggi di errore arrivano nella lingua del tuo account o in quella dell’header Accept-Language, altrimenti in inglese.

Avvio rapido

Lo script avvia un server con RTX 4090, aspetta che sia pronto, stampa il comando SSH e ferma il server, anche se qualcosa va storto a metà.

Avvia, aspetta SSH, ferma
import os, time, requests

API = "https://vramfarm.com/api"
s = requests.Session()
s.headers["Authorization"] = f"Bearer {os.environ['GF_TOKEN']}"

r = s.post(f"{API}/instances", json={"gpu": "rtx-4090", "count": 1, "template": "pytorch"})
r.raise_for_status()
sid = r.json()["id"]
try:
    while True:
        srv = s.get(f"{API}/instances/{sid}").json()
        if srv["status"] == "running":
            break
        if srv["status"] == "stopped":
            raise RuntimeError(srv["error"])
        print(srv["stage_note"] or srv["stage"])
        time.sleep(10)
    print(srv["access"]["ssh"]["command"])
    # your work goes here: ssh, scp, requests to the app on the server
finally:
    s.post(f"{API}/instances/stop", json={"id": sid})

Autenticazione

Crea un token nella dashboard → Impostazioni → Token API. Un token ha la forma gf_live_… e viene mostrato una sola volta: salvalo nei secret della tua CI o nella variabile d’ambiente GF_TOKEN. Dallo stesso punto puoi revocare i token. Puoi avere fino a 10 token attivi.

Invia il token nell’header Authorization: Bearer gf_live_…. Non serve altro: le richieste non vengono firmate, non ci sono timestamp né recvWindow, e per le richieste con token non vengono controllati cookie e Origin.

import os, requests

H = {"Authorization": f"Bearer {os.environ['GF_TOKEN']}"}
print(requests.get("https://vramfarm.com/api/account", headers=H).json())

Un token dà accesso solo ai metodi di questa pagina. Password, chiave SSH ed emissione di nuovi token sono disponibili solo nella dashboard; con un token quegli endpoint restituiscono 403. Chi entra in possesso di un token può avviare e fermare server, ma non gestire il tuo account.

Il catalogo e /health funzionano senza token. Ma se invii un header Authorization con un token errato o revocato, tutti gli endpoint restituiscono 401.

Chiama l’API dal tuo server, da uno script o dalla CI. Le richieste da un browser su un altro sito non vanno a buon fine, e lì qualsiasi visitatore potrebbe vedere il token.

Prima del primo avvio, aggiungi una chiave SSH pubblica nelle impostazioni della dashboard: viene installata su ogni nuovo server. Puoi verificare che sia tutto pronto con GET /api/account.

Errori e limiti

In caso di errore ricevi uno stato HTTP e il body {"error": "message", "code": "snake_case_code"}. Il testo di error si può mostrare così com’è a una persona; nel codice basati su code, mai sul testo. Alcune risposte aggiungono un indizio per i programmi: unverified all’avvio, saving quando fermi il server.

StatoQuando
400Parametri non validi: immagine, disco, VRAM insufficiente, limite di server
401Token errato o revocato, oppure account bloccato
402Credito insufficiente; error indica quanto serve
403Email non confermata, oppure metodo non disponibile con un token
404Server non trovato o appartenente a un altro account; endpoint sconosciuto
409Nessuna macchina di questo tipo disponibile; la cartella del server è ancora in fase di salvataggio
415POST senza Content-Type: application/json
429Limite di richieste superato; aspetta i secondi indicati nell’header Retry-After
500Un errore da parte nostra
502Il catalogo è temporaneamente non disponibile
503Il fornitore delle macchine è sovraccarico; riprova l’avvio tra un minuto

Limiti

  • 60 richieste al minuto per token, su tutti i metodi. Il limite di un token non influisce sugli altri.
  • 10 avvii al minuto per token. Contano anche gli avvii non riusciti.
  • Il catalogo è limitato anche a 60 richieste al minuto per indirizzo IP.
  • Fino a 4 server contemporaneamente; il numero esatto è in max_active_instances. Te ne servono di più? Scrivici.
  • Body della richiesta fino a 64 KB.

Lo stato del server cambia al massimo ogni pochi secondi, quindi interrogalo ogni 5–10 secondi.

Nuovo tentativo su 429, 502 e 503
import time, requests

def call(method, url, **kw):
    for attempt in range(5):
        r = requests.request(method, url, **kw)
        if r.status_code not in (429, 502, 503):
            return r
        time.sleep(int(r.headers.get("Retry-After", 30)))
    return r

Catalogo

Macchine disponibili

GET/api/offers

Un elenco delle macchine disponibili con il prezzo in euro all’ora, dalla più economica. Il catalogo si aggiorna ogni 10 minuti.

Parametri della query

ParametroTipoDescrizione
gpufacoltativostringModello di GPU, per esempio h200. Senza questo parametro, o con un modello sconosciuto, vengono restituiti tutti i modelli. L’elenco dei modelli è sotto la tabella.
countfacoltativointegerNumero di schede nella macchina: 1, 2, 4 o 8. Gli altri valori vengono ignorati.
allfacoltativostring1 mostra anche le macchine non verificate. Per impostazione predefinita solo quelle verificate (verified: true).

Modelli: b200 h200 h100 a100 a100-40 l40s l40 l4 rtx-pro-6000 rtx-a6000 rtx-a5000 rtx-a4000 rtx-5090 rtx-5080 rtx-5070-ti rtx-4090 rtx-4080 rtx-4060-ti rtx-3090 rtx-3080 rtx-3060. a100 è da 80 GB, a100-40 da 40 GB.

Campi della macchina
idintegerPassalo come offer_id all’avvio
gpu, gpu_namestringModello: codice per le richieste e nome visualizzato
num_gpusintegerNumero di schede
vramintegerVRAM di una scheda, GB
cpu, cpu_cores, cpu_ghzstring, integer, numberCPU, core disponibili, frequenza
ramintegerRAM, GB
disk, disk_bwintegerQuanti GB di disco puoi prendere; velocità del disco, MB/s
net_down, net_upintegerRete, Mbit/s
countrystringPaese, codice ISO
reliabilitynumberAffidabilità della macchina da 0 a 1
cuda, drivernumber, stringVersione massima supportata di CUDA e del driver
dlperf, tflops, mem_bw, pcienumberPrestazioni: punteggio DLPerf, TFLOPS, banda di memoria e PCIe
verifiedbooleanLa macchina è verificata
pricenumberEUR all’ora per l’intero server, con il disco minimo del template incluso
disk_eurnumberEUR all’ora per 1 GB di disco oltre la quantità inclusa
traffic_eur, traffic_up_eurnumberEUR per 1 GB di traffico in download e upload
durationintegerPer quanti altri giorni si può noleggiare la macchina
static_ip, portsboolean, integerIP statico, numero di porte aperte

Se live è false, il catalogo è disattivato e offers è vuoto. updated è l’orario della risposta in millisecondi Unix.

Errori

  • 401Token errato o revocato
  • 429Più di 60 richieste al minuto
  • 502Il catalogo è temporaneamente non disponibile; riprova tra un minuto
Richiesta
import os, requests

API = "https://vramfarm.com/api"
H = {"Authorization": f"Bearer {os.environ['GF_TOKEN']}"}

r = requests.get(f"{API}/offers", headers=H, params={"gpu": "h200", "count": 4})
r.raise_for_status()
for o in r.json()["offers"][:5]:
    print(o["id"], o["gpu_name"], o["price"], "EUR/h", o["country"])
Risposta · 200
{
  "live": true,
  "updated": 1761040000000,
  "offers": [
    {
      "id": 18273645,
      "gpu": "h200",
      "gpu_name": "H200",
      "num_gpus": 4,
      "vram": 141,
      "cpu": "AMD EPYC 9354",
      "cpu_cores": 64,
      "ram": 512,
      "disk": 2000,
      "net_down": 8000,
      "net_up": 8000,
      "country": "DE",
      "reliability": 0.998,
      "cuda": 12.8,
      "verified": true,
      "price": 33.16,
      "disk_eur": 0.00005,
      "traffic_eur": 0.007,
      "traffic_up_eur": 0.007
    }
  ]
}

Tipi di macchina

GET/api/offer-types

Una riga per ogni coppia “modello × numero di schede”: la macchina più economica con affidabilità pari o superiore a 0,97 e quante macchine di questo tipo sono disponibili. Utile per scegliere gpu e count per un avvio.

Nessun parametro.

I campi sono gli stessi di una macchina del catalogo, più available, quante macchine di questo tipo sono libere, e max_dlperf, il miglior punteggio di prestazioni tra queste. La risposta viene messa in cache per un minuto.

Errori

  • 401Token errato o revocato
  • 429Più di 60 richieste al minuto
  • 502Il catalogo è temporaneamente non disponibile
Richiesta
import os, requests

API = "https://vramfarm.com/api"
H = {"Authorization": f"Bearer {os.environ['GF_TOKEN']}"}

types = requests.get(f"{API}/offer-types", headers=H).json()["types"]
for t in types:
    print(f'{t["num_gpus"]}x {t["gpu_name"]}: from {t["price"]} EUR/h, {t["available"]} available')
Risposta · 200
{
  "live": true,
  "updated": 1761040000000,
  "types": [
    {
      "id": 20311822,
      "gpu": "rtx-3090",
      "gpu_name": "RTX 3090",
      "num_gpus": 1,
      "vram": 24,
      "price": 0.3,
      "reliability": 0.991,
      "available": 37,
      "max_dlperf": 41
    }
  ]
}

Server

Avviare un server

POST/api/instances

Noleggia una macchina e ci avvia l’app scelta o la tua immagine Docker. La risposta arriva subito; il server impiega 2–5 minuti per essere pronto, o 8–15 con un’immagine tua.

Body della richiesta, JSON

ParametroTipoDescrizione
offer_idfacoltativointegerid della macchina dal catalogo. Se è già stata presa, ne scegliamo una simile dello stesso tipo. È obbligatorio offer_id oppure gpu.
gpufacoltativostringModello, se la macchina esatta non ti interessa: prendiamo la più economica affidabile che va bene.
countfacoltativointegerNumero di schede quando scegli per gpu, da 1 a 8. Predefinito 1.
templatefacoltativostringCosa avviare, pytorch per impostazione predefinita. Vedi la tabella qui sotto. Un valore sconosciuto viene trattato come pytorch.
imagefacoltativostringObbligatorio per custom: un’immagine pubblica, scritta come in docker pull.
cmdfacoltativostringPer custom: un comando da eseguire all’avvio, fino a 4000 caratteri.
diskfacoltativointegerDisco, GB. Un valore inferiore al minimo del template viene portato al minimo. Non più di 2000 e non più di quanto ha la macchina.
ws_restorefacoltativobooleanPredefinito true: la cartella di lavoro salvata torna sul server. false dà un server pulito.
Template (template)
CodiceCosa contieneDisco daMemoria della scheda da
pytorchPyTorch, CUDA, Jupyter60 GB
jupyterJupyter40 GB
customLa tua immagine da image60 GB
comfyuiComfyUI e Stable Diffusion 1.5100 GB
comfy-fluxComfyUI e Flux schnell100 GB16 GB
comfy-sdxlComfyUI e SDXL100 GB12 GB
comfy-wanComfyUI e Wan 2.2 5B, video100 GB24 GB
comfy-wan14ComfyUI e Wan 2.2 14B, video160 GB48 GB
comfy-qwenComfyUI e Qwen-Image100 GB24 GB
comfy-qeditComfyUI e Qwen-Image-Edit100 GB24 GB
comfy-hidreamComfyUI e HiDream-O160 GB24 GB
chatOpen WebUI e Ollama, modello qwen3:8b80 GB12 GB
chat-proOpen WebUI e Ollama, modello qwen3:32b100 GB24 GB
chat-mimoOpen WebUI e Ollama, modello MiMo 9B60 GB12 GB
vllmvLLM, modello Qwen/Qwen2.5-7B-Instruct100 GB
tts-qwen3Sintesi vocale Qwen3-TTS, Gradio40 GB12 GB
tts-voxcpmSintesi vocale VoxCPM2, Gradio40 GB12 GB
tts-chatterboxSintesi vocale Chatterbox, Gradio40 GB12 GB

La fatturazione è al minuto dal momento in cui il server diventa running, con un minimo di 15 minuti per avvio. Il credito deve coprire almeno un’ora di tutti i tuoi server, compreso quello nuovo. Quando il credito si esaurisce, i server si fermano e i loro dischi vengono cancellati.

Una richiesta identica entro 15 secondi restituisce il server già creato, con "duplicate": true; non noleggiamo una seconda macchina. Se un avvio fallisce per il credito o per un’email non confermata, per le richieste con token non viene messo in coda: riprova tu.

Errori

  • 400Nessuna GPU indicata, immagine non valida, disco troppo grande, VRAM insufficiente per il template o già 4 server attivi
  • 402Credito insufficiente per un’ora; l’importo è in error
  • 403Email non confermata; la risposta contiene "unverified": true
  • 409Nessuna macchina di questo tipo disponibile
  • 429Più di 10 avvii al minuto per token
  • 503Il fornitore delle macchine è sovraccarico; riprova tra un minuto
Richiesta
import os, requests

API = "https://vramfarm.com/api"
H = {"Authorization": f"Bearer {os.environ['GF_TOKEN']}"}

r = requests.post(f"{API}/instances", headers=H, json={
    "gpu": "h200", "count": 4, "template": "custom",
    "image": "nvidia/cuda:12.4.1-devel-ubuntu22.04", "disk": 200,
    "cmd": "pip install -q torch && python /workspace/train.py",
})
if not r.ok:
    raise SystemExit(f"{r.status_code} {r.json()['code']}: {r.json()['error']}")
print("server", r.json()["id"])
Risposta · 200
{
  "ok": true,
  "id": 1234,
  "status": "provisioning"
}

Elenco dei server

GET/api/instances

I tuoi server, dai più recenti, fino a 100. Per impostazione predefinita: attivi, in avvio e fermati negli ultimi 7 giorni.

Parametri della query

ParametroTipoDescrizione
statusfacoltativostringprovisioning, running o stopped: solo i server in quello stato.

Ogni elemento di instances ha la stessa struttura della risposta di GET /api/instances/{id}.

Errori

  • 401Token errato o revocato
Richiesta
import os, requests

API = "https://vramfarm.com/api"
H = {"Authorization": f"Bearer {os.environ['GF_TOKEN']}"}

r = requests.get(f"{API}/instances", headers=H, params={"status": "running"})
for s in r.json()["instances"]:
    print(s["id"], s["gpu_name"], s["cost_eur"], "EUR")
Risposta · 200
{
  "instances": [
    { "id": 1234, "status": "running", "gpu": "h200", "gpu_count": 4, "cost_eur": 0.55, "...": "..." }
  ]
}

Server e accesso

GET/api/instances/{id}

Lo stato di un server. Quando status è running, access contiene SSH, Jupyter e l’indirizzo dell’app.

Parametri del percorso

ParametroTipoDescrizione
idobbligatoriointegerid dalla risposta dell’avvio
Campi della risposta
statusstringprovisioning: in preparazione; running: attivo e fatturato; stopped: fermo
stage, stage_notestring | nullSolo durante provisioning: la fase (per esempio pick, loading) e cosa sta succedendo, nella lingua del tuo account
gpu, gpu_name, gpu_countstring, integerModello e numero di schede
template, imagestringTemplate e immagine (per custom)
disk_gbintegerDisco, GB
price_eur_hournumberPrezzo all’ora per l’intero server, EUR
cost_eurnumberAddebitato per questo avvio, EUR; per un server attivo, fino al minuto corrente
traffic_eurnumberAddebitato per il traffico, EUR
specsobject | nullSpecifiche della macchina
access.sshobject | nullhost, port, user e un command pronto
access.jupyterstring | nullLink a Jupyter con un token
access.appstring | nullIndirizzo dell’app per ComfyUI e vLLM; per custom, se l’immagine apre una propria porta. Maggiori dettagli in App sul server
access.workdirstringCartella di lavoro, /workspace
errorstring | nullPerché il server si è fermato da solo: download dell’immagine non riuscito, credito esaurito
created_at, started_at, stopped_atstring | nullOrario in ISO 8601, UTC

access viene compilato solo per un server attivo. La chiave SSH è quella aggiunta nelle impostazioni della dashboard. Se una macchina non si avvia, ne prendiamo un’altra gratuitamente; l’id del server resta lo stesso.

Lavorare con il server
ssh -p 31001 root@vramfarm.com nvidia-smi
scp -P 31001 root@vramfarm.com:/workspace/out.ckpt ./

Errori

  • 404Nessun server con questo id, oppure non è tuo
Richiesta
import os, requests

API = "https://vramfarm.com/api"
H = {"Authorization": f"Bearer {os.environ['GF_TOKEN']}"}

s = requests.get(f"{API}/instances/1234", headers=H).json()
if s["status"] == "running":
    print(s["access"]["ssh"]["command"])
else:
    print(s["status"], s["stage_note"] or s["error"])
Risposta · 200
{
  "id": 1234,
  "status": "running",
  "stage": null,
  "stage_note": null,
  "gpu": "h200",
  "gpu_name": "H200",
  "gpu_count": 4,
  "template": "custom",
  "image": "nvidia/cuda:12.4.1-devel-ubuntu22.04",
  "disk_gb": 200,
  "price_eur_hour": 33.16,
  "cost_eur": 0.55,
  "traffic_eur": 0,
  "specs": {
    "vram_gb": 141, "cpu": "AMD EPYC 9354", "cpu_cores": 64, "ram_gb": 512,
    "country": "DE", "cuda": 12.8, "net_down_mbps": 8000, "net_up_mbps": 8000
  },
  "access": {
    "ssh": {
      "host": "vramfarm.com",
      "port": 31001,
      "user": "root",
      "command": "ssh -p 31001 root@vramfarm.com"
    },
    "jupyter": "https://u.vramfarm.com/api/j/…/lab?token=…",
    "app": null,
    "workdir": "/workspace"
  },
  "error": null,
  "created_at": "2026-10-21T10:00:00.000Z",
  "started_at": "2026-10-21T10:04:12.000Z",
  "stopped_at": null
}

Fermare un server

POST/api/instances/stop

Ferma il server; la fatturazione si interrompe subito. Il disco del server viene cancellato; puoi salvare la cartella di lavoro.

Body della richiesta, JSON

ParametroTipoDescrizione
idobbligatoriointegerId del server
savefacoltativobooleantrue: prima salva /workspace, poi ferma. Non funziona per custom.
forcefacoltativobooleantrue: ferma subito, anche se la cartella è ancora in fase di salvataggio. Il salvataggio viene interrotto.

Fermare un server già fermo restituisce {"ok":true,"already":true}. Non è un errore, quindi puoi mettere la chiamata in finally o in un trap all’uscita dello script.

Con "save": true la risposta {"ok":true,"saving":true} arriva subito, e il server salva la cartella e si ferma da solo, di solito entro pochi minuti. L’archiviazione costa 0,03 € per GB al mese, con addebito giornaliero. Il tuo prossimo server riceve la cartella in automatico, a meno che tu non passi "ws_restore": false.

Errori

  • 404Nessun server con questo id, oppure non è tuo
  • 409La cartella è ancora in fase di salvataggio; la risposta contiene "saving": true. Aspetta oppure passa "force": true
Richiesta
import os, requests

API = "https://vramfarm.com/api"
H = {"Authorization": f"Bearer {os.environ['GF_TOKEN']}"}

r = requests.post(f"{API}/instances/stop", headers=H, json={"id": 1234})
print(r.json())
Risposta · 200
{
  "ok": true
}

Account

Account

GET/api/account

Credito e prontezza all’avvio. Utile per verificare prima di un avvio che l’email sia confermata e che sia stata aggiunta una chiave SSH.

Nessun parametro.

emailstringEmail dell’account
verifiedbooleanEmail confermata. Senza conferma, un avvio restituisce 403
balance_eurnumberCredito, EUR
ssh_key_setbooleanChiave SSH aggiunta. Senza chiave il server si avvia lo stesso, ma puoi entrare solo tramite Jupyter
active_instancesintegerQuanti server sono in avvio o attivi in questo momento
max_active_instancesintegerQuanti server puoi tenere attivi contemporaneamente

Errori

  • 401Token errato o revocato, oppure account bloccato
Richiesta
import os, requests

API = "https://vramfarm.com/api"
H = {"Authorization": f"Bearer {os.environ['GF_TOKEN']}"}

acc = requests.get(f"{API}/account", headers=H).json()
assert acc["verified"] and acc["ssh_key_set"], acc
print(acc["balance_eur"], "EUR")
Risposta · 200
{
  "email": "you@example.com",
  "verified": true,
  "balance_eur": 150.0,
  "ssh_key_set": true,
  "active_instances": 0,
  "max_active_instances": 4
}

Servizio

Stato del servizio

GET/api/health

Verifica che l’API sia attiva. Non serve un token.

Nessun parametro.

In caso di problemi la risposta è 503 con un breve motivo in why, per esempio {"ok":false,"why":"…"}.

Errori

  • 503Il servizio non funziona completamente; il motivo è in why
Richiesta
import requests

r = requests.get("https://vramfarm.com/api/health", timeout=10)
print(r.status_code, r.json())
Risposta · 200
{
  "ok": true,
  "status": "ok"
}

App sul server tramite API

ComfyUI, le app di sintesi vocale, la chat e vLLM hanno ciascuna la propria API. Usala per generare immagini, audio e testo da uno script senza aprire l’interfaccia. Queste app non hanno bisogno del tuo token VRAMfarm, che non viene mai inviato loro.

Dove trovare l’indirizzo dell’app:

  • ComfyUI e vLLM: il campo access.app in GET /api/instances/{id}, del tipo https://u.vramfarm.com/api/a/<key>/. Per vLLM termina già con v1.
  • Chat e sintesi vocale: un indirizzo del tipo http://<host>:<port> è indicato sulla card del server nella dashboard; non è in access.app. Da uno script è più affidabile un tunnel SSH: funziona ogni volta che funziona SSH.
  • La tua immagine (custom): access.app viene compilato se il container apre una porta diversa da 22, 8080 e 8888.
Tunnel SSH
# SSH port from access.ssh.port; -N: tunnel only, no shell
ssh -p 31001 root@vramfarm.com -N -L 11434:127.0.0.1:11434

Tieni aperto il tunnel mentre gira lo script: le richieste a localhost:11434 arrivano al server. Per la sintesi vocale usa la porta 7860 (-L 7860:127.0.0.1:7860), per ComfyUI la 8188, per vLLM la 8000. L’app si avvia 5–10 minuti dopo running; fino ad allora l’indirizzo restituisce 502 o non risponde.

ComfyUI

Template comfyui e comfy-*. Costruisci un workflow nell’interfaccia e salvalo con Workflow → Export (API) come workflow_api.json. Poi lo script cambia il testo del prompt nel workflow, lo invia a /prompt, aspetta il risultato in /history/{prompt_id} e scarica le immagini tramite /view.

import json, time, requests

APP = "https://u.vramfarm.com/api/a/<key>/"                                   # access.app of the server
wf = json.load(open("workflow_api.json"))        # Workflow → Export (API) in ComfyUI
wf["6"]["inputs"]["text"] = "a cat in a spacesuit, photo"  # node number from your file

pid = requests.post(APP + "prompt", json={"prompt": wf}).json()["prompt_id"]
while pid not in (h := requests.get(APP + f"history/{pid}").json()):
    time.sleep(2)

for node in h[pid]["outputs"].values():
    for img in node.get("images", []):
        data = requests.get(APP + "view", params=img).content  # filename, subfolder, type
        open(img["filename"], "wb").write(data)

Sintesi vocale e altre app Gradio

I template tts-qwen3, tts-voxcpm e tts-chatterbox sono basati su Gradio. In fondo alla pagina dell’app c’è un link “Use via API” con l’elenco dei metodi, i loro parametri ed esempi pronti. I nomi dei metodi cambiano da un’app all’altra, quindi sostituisci /generate nell’esempio con il nome indicato in “Use via API” o in view_api().

# pip install gradio_client
from gradio_client import Client

client = Client("http://localhost:7860/")   # through an SSH tunnel or the address from the dashboard
client.view_api()                           # list of methods and their parameters

# method name and argument order: from view_api() or "Use via API"
audio_path = client.predict("Hello! This is a speech test.", api_name="/generate")
print(audio_path)                           # the result file on your computer

Chat: Ollama e Open WebUI

Template chat, chat-pro e chat-mimo: Open WebUI gira sopra Ollama. Da uno script è più semplice parlare direttamente con Ollama. È in ascolto solo all’interno del server, su 127.0.0.1:11434, quindi serve un tunnel SSH come nell’esempio qui sopra. Il modello viene scaricato dopo l’avvio; finché non è caricato, Ollama risponde che il modello manca.

import requests

r = requests.post("http://localhost:11434/api/chat", json={
    "model": "qwen3:8b",          # chat-pro uses qwen3:32b
    "messages": [{"role": "user", "content": "In one sentence: what is CUDA?"}],
    "stream": False,
})
print(r.json()["message"]["content"])

Ollama supporta anche il formato OpenAI su http://localhost:11434/v1/chat/completions, quindi le librerie OpenAI funzionano. Anche Open WebUI ha una propria API; la chiave si genera nelle impostazioni di Open WebUI.

vLLM

Il template vllm avvia un server compatibile con OpenAI con Qwen/Qwen2.5-7B-Instruct. L’indirizzo è access.app, che termina già con /v1. La chiave non viene verificata, ma la libreria OpenAI ne richiede una non vuota, quindi passane una qualsiasi. L’elenco dei modelli è in GET /v1/models.

# pip install openai
from openai import OpenAI

client = OpenAI(base_url="https://u.vramfarm.com/api/a/<key>/v1",  # access.app
                api_key="EMPTY")                                    # no key needed
r = client.chat.completions.create(
    model="Qwen/Qwen2.5-7B-Instruct",
    messages=[{"role": "user", "content": "Write a haiku about a graphics card"}],
)
print(r.choices[0].message.content)

Ti serve un token? Registrati, conferma l’email e crea un token nelle impostazioni della dashboard. Se qualcosa non corrisponde a questa pagina o ti serve un limite più alto, scrivici.