Logotipo de VRAMfarm VRAMfarm
ES
Registrarse
Documentación

API de VRAMfarm

Lanza servidores GPU desde scripts y CI: busca una máquina disponible, iníciala con una app lista para usar o con tu propia imagen de Docker, espera al SSH y detenla. HTTPS y JSON sin más, no hace falta ningún SDK.

URL base de la APIhttps://vramfarm.com/api
  • Las respuestas son JSON en UTF-8. Las peticiones POST necesitan la cabecera Content-Type: application/json.
  • Los importes están en euros. price es el precio por hora de todo el servidor, con todas las tarjetas incluidas, como decimal con céntimos (por ejemplo, 0.39).
  • Las horas de las respuestas van en ISO 8601 y UTC; el campo updated del catálogo va en milisegundos Unix.
  • Los mensajes de error llegan en el idioma de tu cuenta o en el de la cabecera Accept-Language, y si no, en inglés.

Inicio rápido

El script lanza un servidor con RTX 4090, espera a que esté listo, muestra el comando SSH y detiene el servidor, aunque algo falle a mitad de camino.

Lanzar, esperar al SSH, detener
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})

Autenticación

Crea un token en panel → Ajustes → Tokens de API. Un token tiene el aspecto gf_live_… y se muestra una sola vez: guárdalo en los secretos de tu CI o en la variable de entorno GF_TOKEN. En el mismo sitio puedes revocar tokens. Puedes tener hasta 10 tokens activos.

Envía el token en la cabecera Authorization: Bearer gf_live_…. No hace falta nada más: las peticiones no se firman, no hay marca de tiempo ni recvWindow, y en las peticiones con token no se comprueban las cookies ni el 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 solo da acceso a los métodos de esta página. Tu contraseña, tu clave SSH y la emisión de tokens nuevos solo están disponibles en el panel; con un token, esos endpoints devuelven 403. Si se filtra un token, alguien podría lanzar y detener servidores, pero no gestionar tu cuenta.

El catálogo y /health funcionan sin token. Pero si envías una cabecera Authorization con un token incorrecto o revocado, todos los endpoints devuelven 401.

Llama a la API desde tu propio servidor, script o CI. Las peticiones desde un navegador en otra web no pasarán, y además cualquier visitante podría ver ahí el token.

Antes del primer lanzamiento, añade una clave SSH pública en los ajustes del panel: se instala en cada servidor nuevo. Puedes comprobar que todo está listo con GET /api/account.

Errores y límites

Si hay un error, recibes un estado HTTP y el cuerpo {"error": "message", "code": "snake_case_code"}. El texto de error se puede mostrar tal cual a una persona; en tu código, decide según code y nunca según el texto. Algunas respuestas añaden una pista para programas: unverified al lanzar y saving al detener.

EstadoCuándo
400Parámetros no válidos: imagen, disco, VRAM insuficiente, límite de servidores
401Token incorrecto o revocado, o cuenta bloqueada
402Saldo insuficiente; error indica cuánto hace falta
403Correo sin confirmar, o el método no está disponible con un token
404Servidor no encontrado o de otra cuenta; endpoint desconocido
409No hay máquinas disponibles de este tipo; la carpeta del servidor aún se está guardando
415POST sin Content-Type: application/json
429Límite de peticiones superado; espera los segundos que indique la cabecera Retry-After
500Un error por nuestra parte
502El catálogo no está disponible temporalmente
503El proveedor de máquinas está saturado; vuelve a intentar el lanzamiento en un minuto

Límites

  • 60 peticiones por minuto y token, sumando todos los métodos. El límite de un token no afecta a los demás.
  • 10 lanzamientos por minuto y token. Los lanzamientos fallidos también cuentan.
  • El catálogo tiene además un límite de 60 peticiones por minuto y dirección IP.
  • Hasta 4 servidores a la vez; el número exacto está en max_active_instances. ¿Necesitas más? Escríbenos.
  • Cuerpo de la petición de hasta 64 KB.

El estado de un servidor cambia como mucho cada pocos segundos, así que consúltalo cada 5–10 segundos.

Reintentar ante 429, 502 y 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

Catálogo

Máquinas disponibles

GET/api/offers

Una lista de máquinas disponibles con su precio en euros por hora, de la más barata a la más cara. El catálogo se actualiza cada 10 minutos.

Parámetros de consulta

ParámetroTipoDescripción
gpuopcionalstringModelo de GPU, por ejemplo h200. Sin él, o con un modelo desconocido, se devuelven todos los modelos. La lista de modelos está debajo de la tabla.
countopcionalintegerNúmero de tarjetas de la máquina: 1, 2, 4 u 8. Otros valores se ignoran.
allopcionalstring1 muestra también las máquinas sin verificar. Por defecto, solo las verificadas (verified: true).

Modelos: 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 es la de 80 GB y a100-40, la de 40 GB.

Campos de la máquina
idintegerPásalo como offer_id al lanzar
gpu, gpu_namestringModelo: código para las peticiones y nombre visible
num_gpusintegerNúmero de tarjetas
vramintegerVRAM de una tarjeta, GB
cpu, cpu_cores, cpu_ghzstring, integer, numberCPU, núcleos disponibles, frecuencia
ramintegerRAM, GB
disk, disk_bwintegerCuántos GB de disco puedes usar; velocidad del disco, MB/s
net_down, net_upintegerRed, Mbit/s
countrystringPaís, código ISO
reliabilitynumberFiabilidad de la máquina de 0 a 1
cuda, drivernumber, stringVersión máxima de CUDA admitida y versión del driver
dlperf, tflops, mem_bw, pcienumberRendimiento: puntuación DLPerf, TFLOPS, ancho de banda de memoria y de PCIe
verifiedbooleanLa máquina está verificada
pricenumberEUR por hora para todo el servidor, con el disco mínimo de la plantilla incluido
disk_eurnumberEUR por hora por cada GB de disco por encima de lo incluido
traffic_eur, traffic_up_eurnumberEUR por cada GB de tráfico descargado y subido
durationintegerCuántos días más se puede alquilar la máquina
static_ip, portsboolean, integerIP fija, número de puertos abiertos

Si live es false, el catálogo está desactivado y offers viene vacío. updated es la hora de la respuesta en milisegundos Unix.

Errores

  • 401Token incorrecto o revocado
  • 429Más de 60 peticiones por minuto
  • 502El catálogo no está disponible temporalmente; vuelve a intentarlo en un minuto
Petición
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"])
Respuesta · 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
    }
  ]
}

Tipos de máquina

GET/api/offer-types

Una fila por cada par «modelo × número de tarjetas»: la máquina más barata con una fiabilidad de 0,97 o más y cuántas máquinas así hay disponibles. Útil para elegir gpu y count para un lanzamiento.

Sin parámetros.

Los campos son los mismos que los de una máquina del catálogo, más available, cuántas máquinas de este tipo están libres, y max_dlperf, la mejor puntuación de rendimiento entre ellas. La respuesta se guarda en caché durante un minuto.

Errores

  • 401Token incorrecto o revocado
  • 429Más de 60 peticiones por minuto
  • 502El catálogo no está disponible temporalmente
Petición
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')
Respuesta · 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
    }
  ]
}

Servidores

Lanzar un servidor

POST/api/instances

Alquila una máquina e inicia en ella la app elegida o tu imagen de Docker. La respuesta llega al instante; el servidor tarda 2–5 minutos en estar listo, u 8–15 con tu propia imagen.

Cuerpo de la petición, JSON

ParámetroTipoDescripción
offer_idopcionalintegerid de la máquina del catálogo. Si ya la han cogido, elegimos una similar del mismo tipo. Es obligatorio indicar offer_id o gpu.
gpuopcionalstringModelo, si te da igual la máquina concreta: cogemos la más barata y fiable que encaje.
countopcionalintegerNúmero de tarjetas al elegir por gpu, de 1 a 8. Por defecto, 1.
templateopcionalstringQué ejecutar; por defecto, pytorch. Consulta la tabla de abajo. Un valor desconocido se trata como pytorch.
imageopcionalstringObligatorio con custom: una imagen pública, escrita como en docker pull.
cmdopcionalstringCon custom: un comando que se ejecuta al iniciar, de hasta 4000 caracteres.
diskopcionalintegerDisco, GB. Si es menor que el mínimo de la plantilla, se sube al mínimo. No más de 2000 ni más de lo que tiene la máquina.
ws_restoreopcionalbooleanPor defecto, true: tu carpeta de trabajo guardada vuelve al servidor. Con false obtienes un servidor limpio.
Plantillas (template)
CódigoQué incluyeDisco desdeMemoria de la tarjeta desde
pytorchPyTorch, CUDA, Jupyter60 GB
jupyterJupyter40 GB
customTu imagen de image60 GB
comfyuiComfyUI y Stable Diffusion 1.5100 GB
comfy-fluxComfyUI y Flux schnell100 GB16 GB
comfy-sdxlComfyUI y SDXL100 GB12 GB
comfy-wanComfyUI y Wan 2.2 5B, vídeo100 GB24 GB
comfy-wan14ComfyUI y Wan 2.2 14B, vídeo160 GB48 GB
comfy-qwenComfyUI y Qwen-Image100 GB24 GB
comfy-qeditComfyUI y Qwen-Image-Edit100 GB24 GB
comfy-hidreamComfyUI y HiDream-O160 GB24 GB
chatOpen WebUI y Ollama, modelo qwen3:8b80 GB12 GB
chat-proOpen WebUI y Ollama, modelo qwen3:32b100 GB24 GB
chat-mimoOpen WebUI y Ollama, modelo MiMo 9B60 GB12 GB
vllmvLLM, modelo Qwen/Qwen2.5-7B-Instruct100 GB
tts-qwen3Texto a voz con Qwen3-TTS, Gradio40 GB12 GB
tts-voxcpmTexto a voz con VoxCPM2, Gradio40 GB12 GB
tts-chatterboxTexto a voz con Chatterbox, Gradio40 GB12 GB

La facturación es por minuto desde el momento en que el servidor pasa a running, con un mínimo de 15 minutos por lanzamiento. Tu saldo debe cubrir al menos una hora de todos tus servidores, incluido el nuevo. Cuando se acaba el saldo, los servidores se detienen y sus discos se borran.

Una petición idéntica en menos de 15 segundos devuelve el servidor ya creado, con "duplicate": true; no alquilaremos una segunda máquina. Si un lanzamiento falla por el saldo o por no haber confirmado el correo, en las peticiones con token no se deja en cola: vuelve a intentarlo tú.

Errores

  • 400No se indicó GPU, imagen no válida, disco demasiado grande, VRAM insuficiente para la plantilla o ya hay 4 servidores
  • 402Saldo insuficiente para una hora; el importe está en error
  • 403Correo sin confirmar; la respuesta incluye "unverified": true
  • 409No hay máquinas disponibles de este tipo
  • 429Más de 10 lanzamientos por minuto y token
  • 503El proveedor de máquinas está saturado; vuelve a intentarlo en un minuto
Petición
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"])
Respuesta · 200
{
  "ok": true,
  "id": 1234,
  "status": "provisioning"
}

Lista de servidores

GET/api/instances

Tus servidores, de más reciente a más antiguo, hasta 100. Por defecto: en marcha, iniciándose y detenidos en los últimos 7 días.

Parámetros de consulta

ParámetroTipoDescripción
statusopcionalstringprovisioning, running o stopped: solo los servidores en ese estado.

Cada elemento de instances tiene la misma forma que la respuesta de GET /api/instances/{id}.

Errores

  • 401Token incorrecto o revocado
Petición
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")
Respuesta · 200
{
  "instances": [
    { "id": 1234, "status": "running", "gpu": "h200", "gpu_count": 4, "cost_eur": 0.55, "...": "..." }
  ]
}

Servidor y acceso

GET/api/instances/{id}

El estado de un servidor. Cuando status es running, access contiene el SSH, Jupyter y la dirección de la app.

Parámetros de ruta

ParámetroTipoDescripción
idobligatoriointegerid de la respuesta del lanzamiento
Campos de la respuesta
statusstringprovisioning: preparándose; running: en marcha y facturándose; stopped: detenido
stage, stage_notestring | nullSolo durante provisioning: la etapa (por ejemplo, pick, loading) y qué está pasando, en el idioma de tu cuenta
gpu, gpu_name, gpu_countstring, integerModelo y número de tarjetas
template, imagestringPlantilla e imagen (con custom)
disk_gbintegerDisco, GB
price_eur_hournumberPrecio por hora de todo el servidor, EUR
cost_eurnumberCobrado por este lanzamiento, EUR; en un servidor en marcha, hasta el minuto actual
traffic_eurnumberCobrado por el tráfico, EUR
specsobject | nullEspecificaciones de la máquina
access.sshobject | nullhost, port, user y un command listo para usar
access.jupyterstring | nullEnlace de Jupyter con token
access.appstring | nullDirección de la app para ComfyUI y vLLM; con custom, si la imagen abre su propio puerto. Más información en Apps del servidor
access.workdirstringCarpeta de trabajo, /workspace
errorstring | nullPor qué se detuvo el servidor por sí solo: la imagen no se pudo descargar, se acabó el saldo
created_at, started_at, stopped_atstring | nullHora en ISO 8601, UTC

access solo se rellena en un servidor en marcha. La clave SSH es la que añadiste en los ajustes del panel. Si una máquina no arranca, cogemos otra sin coste; el id del servidor no cambia.

Trabajar con el servidor
ssh -p 31001 root@vramfarm.com nvidia-smi
scp -P 31001 root@vramfarm.com:/workspace/out.ckpt ./

Errores

  • 404No hay ningún servidor con este id, o no es tuyo
Petición
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"])
Respuesta · 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
}

Detener un servidor

POST/api/instances/stop

Detiene el servidor; la facturación se para al instante. El disco del servidor se borra; puedes guardar la carpeta de trabajo.

Cuerpo de la petición, JSON

ParámetroTipoDescripción
idobligatoriointegerid del servidor
saveopcionalbooleantrue: primero guarda /workspace y después detiene. No funciona con custom.
forceopcionalbooleantrue: detiene en el acto, aunque la carpeta todavía se esté guardando. El guardado se interrumpe.

Detener un servidor que ya está detenido devuelve {"ok":true,"already":true}. No es un error, así que puedes poner la llamada en finally o en un trap al salir del script.

Con "save": true, la respuesta {"ok":true,"saving":true} llega al instante y el servidor guarda la carpeta y se detiene solo, normalmente en pocos minutos. El almacenamiento cuesta 0,03 € por GB al mes, con cargo diario. Tu siguiente servidor recibe la carpeta automáticamente, salvo que pases "ws_restore": false.

Errores

  • 404No hay ningún servidor con este id, o no es tuyo
  • 409La carpeta todavía se está guardando; la respuesta incluye "saving": true. Espera o pasa "force": true
Petición
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())
Respuesta · 200
{
  "ok": true
}

Cuenta

Cuenta

GET/api/account

Saldo y disponibilidad para lanzar. Útil para comprobar antes de un lanzamiento que tu correo está confirmado y que has añadido una clave SSH.

Sin parámetros.

emailstringCorreo de la cuenta
verifiedbooleanCorreo confirmado. Sin él, un lanzamiento devuelve 403
balance_eurnumberSaldo, EUR
ssh_key_setbooleanClave SSH añadida. Sin clave el servidor arranca igualmente, pero solo podrás entrar por Jupyter
active_instancesintegerCuántos servidores se están iniciando o están en marcha ahora
max_active_instancesintegerCuántos puedes tener en marcha a la vez

Errores

  • 401Token incorrecto o revocado, o cuenta bloqueada
Petición
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")
Respuesta · 200
{
  "email": "you@example.com",
  "verified": true,
  "balance_eur": 150.0,
  "ssh_key_set": true,
  "active_instances": 0,
  "max_active_instances": 4
}

Servicio

Estado del servicio

GET/api/health

Comprueba que la API funciona. No necesita token.

Sin parámetros.

Si hay un fallo, la respuesta es 503 con un motivo breve en why, por ejemplo {"ok":false,"why":"…"}.

Errores

  • 503El servicio no funciona del todo; el motivo está en why
Petición
import requests

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

Apps del servidor por API

ComfyUI, las apps de texto a voz, el chat y vLLM tienen cada uno su propia API. Úsala para generar imágenes, audio y texto desde un script sin abrir la interfaz. Estas apps no necesitan tu token de VRAMfarm y nunca se les envía.

Dónde encontrar la dirección de la app:

  • ComfyUI y vLLM: el campo access.app en GET /api/instances/{id}, del tipo https://u.vramfarm.com/api/a/<key>/. En vLLM ya termina en v1.
  • Chat y texto a voz: en la tarjeta del servidor en el panel aparece una dirección del tipo http://<host>:<port>; no está en access.app. Desde un script es más fiable un túnel SSH: funciona siempre que funcione el SSH.
  • Tu propia imagen (custom): access.app se rellena si el contenedor abre un puerto distinto de 22, 8080 y 8888.
Túnel 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

Mantén el túnel abierto mientras se ejecuta tu script: las peticiones a localhost:11434 van al servidor. Para texto a voz usa el puerto 7860 (-L 7860:127.0.0.1:7860), para ComfyUI el 8188 y para vLLM el 8000. La app arranca 5–10 minutos después de running; hasta entonces la dirección devuelve 502 o no responde.

ComfyUI

Plantillas comfyui y comfy-*. Monta un workflow en la interfaz y guárdalo con Workflow → Export (API) como workflow_api.json. Después el script cambia el texto del prompt en el workflow, lo envía a /prompt, espera el resultado en /history/{prompt_id} y descarga las imágenes a través de /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)

Texto a voz y otras apps de Gradio

Las plantillas tts-qwen3, tts-voxcpm y tts-chatterbox están hechas con Gradio. Al pie de la página de la app hay un enlace «Use via API» con los métodos, sus parámetros y ejemplos listos para usar. Los nombres de los métodos cambian de una app a otra, así que sustituye /generate en el ejemplo por el nombre que aparezca en «Use via API» o en 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 y Open WebUI

Plantillas chat, chat-pro y chat-mimo: Open WebUI funciona sobre Ollama. Desde un script es más sencillo hablar directamente con Ollama. Solo escucha dentro del servidor, en 127.0.0.1:11434, así que necesitas un túnel SSH como en el ejemplo de arriba. El modelo se descarga después del lanzamiento; hasta que termina de cargarse, Ollama responde que el modelo no existe.

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 también habla el formato de OpenAI en http://localhost:11434/v1/chat/completions, así que las librerías de OpenAI funcionan. Open WebUI también tiene su propia API; la clave se genera en los ajustes de Open WebUI.

vLLM

La plantilla vllm inicia un servidor compatible con OpenAI con Qwen/Qwen2.5-7B-Instruct. La dirección es access.app, que ya termina en /v1. La clave no se comprueba, pero la librería de OpenAI exige una que no esté vacía, así que pasa cualquiera. La lista de modelos está en 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)

¿Necesitas un token? Regístrate, confirma tu correo y crea un token en los ajustes del panel. Si algo no coincide con esta página o necesitas un límite más alto, escríbenos.