Revvity Signals AI · GPU POC

Dev setup — self-hosted coding model

Our vLLM server speaks the OpenAI-compatible API, so anything that talks to OpenAI works: opencode, Cursor, Continue, Zed, Cline, Aider, or a plain SDK.

Connection details

Base URLhttps://gpu.revvitysignalsai.com/v1
API keyyour personal key — ask David
Modelsnot fixed — the set changes over time.
Discover what is live before you configure anything (see Which model is available? below)

Shared gateway, private repo — don't paste your key anywhere public.

The base URL is permanent. The gateway stays put and forwards to whichever GPU box is running that day. You never need a new address again.

Your key is yours. Each developer has their own, so usage is attributed per person and a key can be revoked without disturbing anyone else.

Which model is available?

The set of models changes from time to time — models are added, rotated and retired as the comparison progresses, so do not rely on any fixed list. Discover what is live right now from the gateway itself:

curl -s https://gpu.revvitysignalsai.com/v1/models \
  -H "Authorization: Bearer YOUR-KEY" | python3 -m json.tool

Whatever that returns is what you can use today. Configure those names in your client, and re-run the call whenever a model you expected is missing or you want to try something new. Switch per session with /models.

Which model is which

This is the full catalog of models we have run or may run — not the live set. Which of them are actually served changes from time to time, so always confirm against GET /v1/models before configuring one.

Checkpoint size is what gets downloaded at boot, and it's the main reason a cluster takes 20–60 minutes to come up. Context is what you can actually send.

ModelRepoCheckpoint Server maxSet in your clientVisionNotes
DeepSeek V4 Flash deepseek-ai/DeepSeek-V4-Flash 160 GB 1,048,576 160000 no Ran 14 Sep. Fastest to boot of anything we've run.
DeepSeek V4.1 Flash deepseek-ai/DeepSeek-V4.1-Flash 510 GB 1,048,576 1048576 yes Vision-language MoE, 552B backbone + Engram memory. Served at the full 1M native context on 2×B300.
DeepSeek V4 Pro deepseek-ai/DeepSeek-V4-Pro 865 GB not measured set when measured no Never successfully booted for a full day yet.
GLM-5.3-Flash zai-org/GLM-5.3-Flash 328 GB 262,144 262144 conditional Vision requires a local network volume (its processor loads processor_config.json by filesystem path), so treat it as text-only as configured.
GLM-5.3 zai-org/GLM-5.3 756 GB not measured set when measured no Text-only by architecture (GlmMoeDsaForCausalLM).
Kimi K3 moonshotai/Kimi-K3 1,561 GB not measured set when measured yes Needs 8×B300. That configuration has been free roughly 1.3% of the time we've sampled, so treat it as unavailable without reserved capacity.
Qwen3.8-Flash-Next Qwen/Qwen3.8-Flash-Next-FP8 185 GB 262,144 262144 yes Qwen4 preview: 125B + 51B N-gram table, 6B active. Thinking model (qwen3 reasoning, qwen3_coder tools) and the first profile needing expert parallelism. Serves images from HuggingFace — no volume required. 262K native context (from its config), not 1M — don't claim more.
Claude Opus 4.8 anthropic (via AWS Bedrock) n/a (API) 1,000,000 set per task yes Exception access only. Not on the default key. Ask David; grants are per-person with a hard daily/monthly budget. Model name: opus-4.8.
Qwen3-Coder 480B Qwen/Qwen3-Coder-480B-A35B-Instruct-FP8 482 GB not measured set when measured no No reasoning parser — it doesn't emit a separate reasoning field.
Qwen3-Coder-Next Qwen/Qwen3-Coder-Next-FP8 80 GB not measured set when measured no Tried 11 Sep, rejected on quality.

Not measured means exactly that — we haven't run it long enough to read max_model_len off a live pod, and a number invented here would be worse than an honest gap. Read the real value any time:

curl -s https://gpu.revvitysignalsai.com/v1/models \
  -H "Authorization: Bearer YOUR-KEY" | python3 -m json.tool

Match your client limit to the server max

Every model gets its own context limit in your config, matched to that model's backend. There is no single number that is right for all of them — a value that is safe for one model silently truncates or errors on another, and a client that claims more than the backend serves fails mid-conversation rather than at connect time.

Never exceed what the pod actually serves. V4.1 Flash is launched with --max-model-len 1048576, so the client is set to the same 1,048,576. The output budget comes out of that total, so a huge prompt plus a large max_tokens still has to fit underneath it.

About that 1M context

DeepSeek V4.1 Flash genuinely accepts a million tokens, but the KV cache is shared across everyone on the box — measured at 35,113,964 tokens total (num_gpu_blocks 412,195 × 32-token blocks). That is roughly 33 concurrent sequences at the full 1M, and many more in practice since most sessions use far less. The configs below therefore set the client to the full 1,048,576. It is a shared budget: if many people run maximum-length agents at once, requests will queue.

opencode

~/.config/opencode/opencode.json — copy-paste, this is the working config. The model entries below are a snapshot of what was live when it was written — the set changes over time, so check GET /v1/models and add, remove or adjust entries to match what is actually served:

{
  "$schema": "https://opencode.ai/config.json",
  "disabled_providers": ["amazon-bedrock", "huggingface"],
  "provider": {
    "gpu-poc": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "GPU POC (self-hosted)",
      "options": {
        "baseURL": "https://gpu.revvitysignalsai.com/v1",
        "apiKey": "YOUR-KEY-HERE"
      },
      "models": {
        "qwen3.8-flash-next": {
          "name": "Qwen3.8 Flash Next (vision)",
          "limit": { "context": 262144, "output": 16384 },
          "tool_call": true,
          "reasoning": true,
          "attachment": true,
          "modalities": { "input": ["text", "image"], "output": ["text"] }
        },
        "deepseek-v41-flash": {
          "name": "DeepSeek V4.1 Flash (vision)",
          "limit": { "context": 1048576, "output": 16384 },
          "tool_call": true,
          "reasoning": true,
          "attachment": true,
          "modalities": { "input": ["text", "image"], "output": ["text"] },
          "options": { "reasoning_effort": "high" }
        },
        "glm-5.3-flash": {
          "name": "GLM-5.3 Flash",
          "limit": { "context": 262144, "output": 16384 },
          "tool_call": true,
          "reasoning": true
        }
      }
    }
  },
  "agent": {
    "default": { "model": "gpu-poc/qwen3.8-flash-next" },
    "plan":    { "model": "gpu-poc/qwen3.8-flash-next" },
    "build":   { "model": "gpu-poc/qwen3.8-flash-next" }
  }
}

qwen3.8-flash-next is set as the default for every agent, so opencode uses it without you picking anything. Switch per-session with /modelsGPU POC (self-hosted) — every model you declared appears there. If a model you want is missing, discover what the gateway is serving with GET /v1/models, add it to the config, and restart opencode.

Each limit.context matches what that pod actually serves (262,144 for Qwen3.8; 1,048,576 for DeepSeek V4.1). A client that claims more than the backend serves fails mid-conversation rather than at connect time, which is a miserable way to find out — so keep these equal to max_model_len from GET /v1/models, not higher.

Both attachment and modalities are required for images. attachment: true only permits a file to be attached; modalities.input containing "image" is what makes opencode send it as an image. With attachment alone, opencode degrades the file to a text part and the model replies "I can't view images — this model doesn't support image input" — which is true of what it received, not of the model. Verified 2026-09-14.

Only declare vision on models that have it. On a text-only model the image is dropped and you get a confident answer about nothing.

Config changes need an opencode restart. It reads config at startup.

disabled_providers keeps the picker clean. opencode auto-detects providers from environment credentials, so AWS creds pull in Bedrock and an HF_TOKEN pulls in HuggingFace — both then compete with our models in the list and get selected by accident.

Any other editor

Cursor, Continue, Zed, Cline — wherever it asks for an OpenAI-compatible or custom provider:

Base URLhttps://gpu.revvitysignalsai.com/v1
API keyyour personal key
Modelwhatever GET /v1/models returns — the set changes over time

Aider

aider --openai-api-base https://gpu.revvitysignalsai.com/v1 \
      --openai-api-key YOUR-KEY-HERE \
      --model openai/qwen3.8-flash-next

Sending an image

Standard OpenAI multimodal format, against a vision model only (qwen3.8-flash-next or deepseek-v41-flashnot glm-5.3-flash, which is text-only):

curl https://gpu.revvitysignalsai.com/v1/chat/completions \
  -H "Authorization: Bearer YOUR-KEY" -H 'Content-Type: application/json' \
  -d '{"model":"qwen3.8-flash-next","max_tokens":500,
       "messages":[{"role":"user","content":[
         {"type":"image_url","image_url":{"url":"data:image/png;base64,..."}},
         {"type":"text","text":"What does this screenshot show?"}]}]}'

image_url takes a data: URI or a public URL. Base64 counts against your context — a full-screen screenshot is often several thousand tokens.