From runpod
runpod-flash — code-first serverless: write Python locally, run it on remote Runpod GPUs/CPUs with `flash dev` (hot-reload + live worker logs), then `flash deploy`. Use for @Endpoint/@remote functions, resource config, and debugging flash deployments. For CLI-only infra management use runpodctl or runpod-mcp.
How this skill is triggered — by the user, by Claude, or both
Slash command
/runpod:flashThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Write code locally, iterate with `flash dev` — it runs your functions on remote Runpod GPUs/CPUs with hot-reload and live worker logs — then `flash deploy` to ship. `Endpoint` handles provisioning.
Write code locally, iterate with flash dev — it runs your functions on remote Runpod GPUs/CPUs with hot-reload and live worker logs — then flash deploy to ship. Endpoint handles provisioning.
Load on demand — this skill keeps the mental model + gotchas inline; details live in reference/:
| Need | Read |
|---|---|
Install, auth, flash init, and the full flash command list | reference/setup-and-cli.md |
Endpoint(...) constructor params, NetworkVolume/PodTemplate/EndpointJob, GPU & CPU enum tables | reference/api.md |
| Worked patterns — choosing a model, warm-worker model loading, CPU→GPU pipeline, parallel calls | reference/patterns.md |
Quick start: uv tool install runpod-flash → flash login (or export RUNPOD_API_KEY=...) → flash init my-project → flash dev. Details in reference/setup-and-cli.md.
flash dev — iterate. Local server at :8888, but your decorated functions
execute on remote GPU/CPU workers. Hot-reloads on save and streams the worker's
logs live to the terminal. No build/upload/deploy wait — use this the whole time you
develop.flash deploy — ship. Builds an artifact and deploys a stable endpoint. Slow
(build + upload + provision); only do this once the code works under flash dev.flash dev ships only the function body to the worker, so a NameError for a
module-level name surfaces immediately here. flash deploy imports the whole module and
can mask that bug (see Gotcha #1). Develop against flash dev and you catch it first.
flash dev is a long-running server. Three rules:
The captured log is the remote worker's live stream (cold start, model load, prints,
tracebacks) — read it to debug.
flash dev > /tmp/flash-dev.log 2>&1 & # background; never run it blocking
for i in $(seq 1 60); do grep -q "flash dev localhost:" /tmp/flash-dev.log && break; sleep 2; done # bounded ~2min; if it never appears, check the log for errors
URL=$(grep -o "localhost:[0-9]*" /tmp/flash-dev.log | head -1) # actual port (8888 bumps if taken)
curl -s "$URL/main/predict" -d '{"data": {...}}' # dispatches to the remote worker
✓ flash dev localhost:<port> plus the route table.main.py's /predict is served at /main/predict.422 naming the missing field in loc):
@api.post("/predict")) → POST /main/predict, body is the arg
at top level: a handler def predict(data: dict) wants {"data": {...}} (not the bare object).@Endpoint decorator) → POST /main/runsync (the local dev
server only generates /runsync; production also exposes /run),
body is double-wrapped in input: a handler def synthesize(data: dict) wants
{"input": {"data": {...}}}. The outer input is the queue envelope; the inner key is
the handler's param name.--auto-provision to skip the first-call cold start. kill %1 when done.Full constructor params and the GPU/CPU enum tables are in reference/api.md.
One function = one endpoint with its own workers.
from runpod_flash import Endpoint, GpuGroup
@Endpoint(name="my-worker", gpu=GpuGroup.AMPERE_80, workers=5, dependencies=["torch"])
async def compute(data):
import torch # MUST import inside function (cloudpickle)
return {"sum": torch.tensor(data, device="cuda").sum().item()}
result = await compute([1, 2, 3])
Multiple HTTP routes share one pool of workers.
from runpod_flash import Endpoint, GpuGroup
api = Endpoint(name="my-api", gpu=GpuGroup.ADA_24, workers=(1, 5), dependencies=["torch"])
@api.post("/predict")
async def predict(data: list[float]):
import torch
return {"result": torch.tensor(data, device="cuda").sum().item()}
@api.get("/health")
async def health():
return {"status": "ok"}
Deploy a pre-built Docker image and call it via HTTP.
from runpod_flash import Endpoint, GpuGroup, PodTemplate
server = Endpoint(
name="my-server",
image="my-org/my-image:latest",
gpu=GpuGroup.AMPERE_80,
workers=1,
env={"HF_TOKEN": "xxx"},
template=PodTemplate(containerDiskInGb=100),
)
# LB-style
result = await server.post("/v1/completions", {"prompt": "hello"})
models = await server.get("/v1/models")
# QB-style
job = await server.run({"prompt": "hello"}) # optional: webhook="https://..." for completion callback
await job.wait()
print(job.output)
Connect to an existing endpoint by ID (no provisioning):
ep = Endpoint(id="abc123")
job = await ep.runsync({"prompt": "hello"}) # runsync wraps this as {"input": {"prompt": "hello"}}
print(job.output)
| Parameters | Mode |
|---|---|
name= only | Decorator (your code) |
image= set | Client (deploys image, then HTTP calls) |
id= set | Client (connects to existing, no provisioning) |
The table above is how the mode is picked from params. When to reach for image=:
image= (custom container) vs your own codeDefault to writing Python (decorator / routes) — it runs arbitrary code with
dependencies=[...]/system_dependencies=[...] and needs no Dockerfile. Even large
HuggingFace models stay in decorator mode (weights stream at runtime — see
reference/patterns.md → Loading ML models).
Reach for image= only when you need:
image="vllm/vllm-openai:latest", or runpod/worker-vllm, runpod/worker-comfy)Trade-off: image= mode can't run arbitrary Python (the image owns all logic) and the
image must implement a Runpod Serverless handler. Full list + examples:
https://docs.runpod.io/flash/custom-docker-images
flash deploy imports the whole module so module globals happen to work; flash dev ships just the body, so a module-level name raises NameError. A handler that works deployed can break under dev — fix it by moving everything inside.await.dependencies=[].{"audio_b64": ...}) and decode client-side; for larger outputs write to a NetworkVolume or upload to storage and return a URL.image=/id= = client. Otherwise = decorator.gpu=[GpuGroup.ADA_24, GpuGroup.AMPERE_80]) and set workers=5 or higher. The platform only auto-switches GPU types based on supply when max workers is at least 5.runsync timeout is 60s -- cold starts can exceed 60s. Use ep.runsync(data, timeout=120) for first requests or use ep.run() + job.wait() instead.@api.post(...)): send the handler arg at the top level — {"data": {...}}.@Endpoint, hit via .../run or .../runsync): the worker calls
handler(**job_input), so the request's input keys must match the handler's parameter
names — def transcribe(input_data: dict) wants {"input": {"input_data": {...}}}, and
def read(input: dict) wants {"input": {"input": {...}}}. A mismatch fails with
got an unexpected keyword argument …. Use **kwargs if the handler ignores the payload.input. A QB request with {"input": {}} is rejected by the
worker SDK as Job has missing field(s): id or input — always include at least one key.ep.runsync(x), api.post(...)) hides the spreading, so this
only bites raw HTTP/external callers (mismatch behavior verified 2026-07-10 via worker logs).
See Autonomous Dev Loop.@Endpoint whose __init__ loads the model once per worker (see reference/patterns.md → Loading ML models). In function-form, reconcile with #1 by caching in a module global inside the body so it works under both flash dev and deploy:
global _MODEL
try: _MODEL
except NameError: _MODEL = load_model() # runs once per worker, reused across calls
dependencies=[] too -- e.g. CTranslate2/faster-whisper needs nvidia-cublas-cu12 + nvidia-cudnn-cu12 or it silently falls back to CPU. Add them alongside the Python package.RUNPOD_API_KEY env var overrides the flash login token, so a bad/expired key wins. The failure is quiet: provisioning logs GraphQL request failed: 401, but flash dev still prints its normal ready line ("failed endpoints deploy on-demand"), so it looks healthy. When endpoints fail to provision:
GraphQL request failed: 401.curl -s -o /dev/null -w '%{http_code}' https://rest.runpod.io/v1/endpoints -H "Authorization: Bearer $RUNPOD_API_KEY" (200 = good, 401 = bad).unset RUNPOD_API_KEY to fall back to the flash login token, or export a valid key.system_dependencies= adds to cold start -- apt packages (e.g. ["ffmpeg", "espeak-ng"]) install on the worker before first use, so the initial call is slower (on top of any model download); warm calls are unaffected.flash app delete <app> -- flash undeploy list may show "no endpoints" for an app that is deployed and serving; flash app delete (or runpodctl serverless delete <id>) reliably removes it.npx claudepluginhub runpod/runpod-plugins-official --plugin runpodStart here for any Runpod task — running GPU/CPU pods, deploying serverless endpoints, templates, network volumes, building images, or understanding how Runpod works. Routes the request to the right Runpod skill (runpod-mcp, runpodctl, flash, companion-clis, or runpod-usage). Use when it is unclear which Runpod skill applies.
Guides running Python code on Modal serverless platform for AI inference, batch jobs, web endpoints, scheduled tasks, and sandboxed execution. Activates on modal imports, decorators like @app.function, or CLI commands.
Deploys custom ML models on fal.ai serverless infrastructure using fal.App class, GPU selection (T4/A10G/A100/H100), setup for model loading, @fal.endpoint decorators, scaling config, secrets, persistent volumes, and fal deploy/run commands.