Deploy SGLang with an OpenAI-compatible API on a Massed Compute GPU.

Deploy SGLang with OpenAI API on GPU Cloud (2026 Guide)

SGLang is a high-throughput inference engine with an OpenAI-compatible API. This guide walks through launching a Massed Compute GPU VM, installing SGLang, running it as a systemd service, and hitting /v1/chat/completions the same way you would hit OpenAI.

GPUNVIDIAL40SGLangLLMInferenceUbuntu

You get a /v1 endpoint on port 30000 (vLLM’s default is 8000). The walkthrough uses an ungated Qwen 0.5B model so the API comes up without a Hugging Face token. Swap in a 7B–8B instruct model once the endpoint is green. This was validated on an NVIDIA L40 (48 GB) on August 20, 2026.

If you already run vLLM on Massed Compute, this is the SGLang path — radix attention / prefix cache, same OpenAI request shape, different engine. Do not copy the vLLM OpenAI API guide step-for-step; the install pins and port are different.

Technology Stack
Component Version Purpose
Ubuntu Server 24.04 LTS Base OS with NVIDIA drivers (image 184)
SGLang 0.5.17 Inference engine + OpenAI-compatible /v1 server
PyTorch 2.11.0 CUDA 13 backend (pulled with SGLang)
Model (smoke) Qwen/Qwen2.5-0.5B-Instruct Ungated chat model for the endpoint test
System Requirements
Resource Minimum Recommended
GPU Memory 24 GB 48 GB+ for 7B–8B models
System RAM 32 GB 72 GB+
vCPU 8 cores 14+ cores
Storage 256 GB 512 GB+ if you will cache several models
Network 1 Gbps Helps the first Hugging Face download

Massed Compute VM Pricing

GPU VMs that meet the minimum for this deploy. Lead with the L40 this guide was tested on.

Pricing fetched from the Massed Compute inventory API on August 20, 2026.

SKU Description vCPU RAM Storage Price Capacity
gpu_1x_A30 1x A30 (24GB) 16 48 GiB 256 GB $0.35/hr 1
gpu_1x_a5000 1x RTX A5000 (24GB) 10 32 GiB 256 GB $0.44/hr 0
gpu_2x_A30 2x A30 (24GB) 30 96 GiB 512 GB $0.70/hr 0
gpu_1x_l40_spot 1x L40 (48GB) [Spot] 14 72 GiB 625 GB $0.78/hr 23
gpu_1x_6000_ada 1x RTX 6000 ADA (48GB) 12 72 GiB 350 GB $0.79/hr 17
gpu_1x_l40 1x L40 (48GB) 14 72 GiB 625 GB $0.86/hr 23
Spot pricing available: Spot instances can be interrupted. Use on-demand for anything you cannot restart. The NVIDIA L40 is the card this walkthrough used; for a broader inference-card comparison see The Best GPU for LLM Inference Without Overpaying.

Step-by-Step Deployment

Image 184 logs in as Ubuntu (capital U). If SSH offers extra keys and then fails, add -o IdentitiesOnly=yes.

1

Launch GPU VM

Create a VM with GPU support and NVIDIA drivers pre-installed:

# Launch via Massed Compute dashboard or API
# Product: gpu_1x_l40 (or gpu_1x_l40_spot)
# Image: 184 (Ubuntu Server 24.04 w/ Drivers)
# SSH Key: attach your public key
# Instance name: sglang-openai-api

Wait until the VM is running and copy the SSH details.

2

Verify GPU Access

ssh -o IdentitiesOnly=yes Ubuntu@YOUR_VM_IP \
  'nvidia-smi --query-gpu=name,memory.total,memory.free --format=csv,noheader'

You should see the GPU name and VRAM. This run printed an L40 at 46068 MiB.

3

Bootstrap SGLang

Run the setup on the VM. Image 184 ships NVIDIA drivers, not a system nvcc. SGLang’s JIT path needs CUDA_HOME pointed at the CUDA 13 toolkit inside the venv.

ssh -o IdentitiesOnly=yes Ubuntu@YOUR_VM_IP 'bash -s' <<'EOF'
set -euxo pipefail

SGLANG_MODEL="${SGLANG_MODEL:-Qwen/Qwen2.5-0.5B-Instruct}"
SGLANG_PORT="${SGLANG_PORT:-30000}"

sudo apt-get update
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y \
  python3-venv python3-pip git curl

mkdir -p ~/sglang-openai
python3 -m venv ~/sglang-openai/venv
. ~/sglang-openai/venv/bin/activate

python -m pip install -U pip setuptools wheel uv
uv pip install --prerelease=allow 'sglang==0.5.17'

PYVER="$(python -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")')"
CU="$HOME/sglang-openai/venv/lib/python${PYVER}/site-packages/nvidia/cu13"
test -x "$CU/bin/nvcc"
ln -sfn lib "$CU/lib64"
ln -sfn libcudart.so.13 "$CU/lib/libcudart.so"
echo "$CU/lib" | sudo tee /etc/ld.so.conf.d/sglang-cu13.conf
sudo ldconfig

sudo tee /etc/systemd/system/sglang-openai.service >/dev/null <<UNIT
[Unit]
Description=SGLang OpenAI-compatible API
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=${USER}
Group=${USER}
WorkingDirectory=${HOME}/sglang-openai
Environment=HOME=${HOME}
Environment=CUDA_HOME=${CU}
Environment=PATH=${CU}/bin:${HOME}/sglang-openai/venv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
ExecStart=${HOME}/sglang-openai/venv/bin/python -m sglang.launch_server --model-path ${SGLANG_MODEL} --host 127.0.0.1 --port ${SGLANG_PORT} --attention-backend triton --disable-cuda-graph
Restart=on-failure
RestartSec=15
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
UNIT

sudo systemctl daemon-reload
sudo systemctl enable --now sglang-openai
EOF

--host 127.0.0.1 keeps the API on the VM until you add a firewall rule and auth. --attention-backend triton --disable-cuda-graph is the combo that served on image 184 without a system CUDA toolkit. Newer SGLang builds prefer --cuda-graph-backend-decode=disabled --cuda-graph-backend-prefill=disabled instead of --disable-cuda-graph.

To use a 7B–8B model later, set SGLANG_MODEL before the script, or edit ExecStart and restart the unit. Gated Llama weights need HF_TOKEN in the systemd Environment= lines.

4

Verify Service Status

ssh -o IdentitiesOnly=yes Ubuntu@YOUR_VM_IP 'systemctl is-active sglang-openai'

Expected output: active

5

Test Models Endpoint

First start downloads the model. Poll /v1/models until it answers:

ssh -o IdentitiesOnly=yes Ubuntu@YOUR_VM_IP 'bash -s' <<'EOF'
set -euo pipefail
for _ in $(seq 1 90); do
  if curl -sf http://127.0.0.1:30000/v1/models >/tmp/sglang-models.json; then
    cat /tmp/sglang-models.json
    echo
    echo SGLANG_MODELS_OK
    exit 0
  fi
  sleep 10
done
journalctl -u sglang-openai -n 160 --no-pager
exit 1
EOF

You should see Qwen/Qwen2.5-0.5B-Instruct in the JSON.

6

Run Chat Completion Test

ssh -o IdentitiesOnly=yes Ubuntu@YOUR_VM_IP 'bash -s' <<'EOF'
set -euo pipefail
curl -sf http://127.0.0.1:30000/v1/chat/completions \
  -H 'Content-Type: application/json' \
  -d '{"model":"Qwen/Qwen2.5-0.5B-Instruct","messages":[{"role":"user","content":"Reply with the single word pong."}],"max_tokens":16,"temperature":0}'
echo
EOF

The assistant message should be a short Pong (or Pong!). Same request shape as OpenAI and as the vLLM OpenAI API post — only the host port is 30000.

7

Confirm GPU Utilization

ssh -o IdentitiesOnly=yes Ubuntu@YOUR_VM_IP \
  'nvidia-smi --query-gpu=name,memory.used,utilization.gpu --format=csv,noheader'

This L40 sat at about 39799 MiB used after load. That is not 0.5B of weights. SGLang’s default mem-fraction-static (~0.85) reserves most of the card for the KV cache. For a smoke model, add --mem-fraction-static 0.3 to ExecStart if you want leftover VRAM. For a real 7B–8B serve, leaving the default is usually what you want.

Where SGLang Fits vs vLLM, TGI, and Ollama

Use this post for SGLang. Link out for the other engines — those guides already exist.

This is not a bake-off. Pick SGLang when prefix cache and high QPS matter; pick vLLM when you want the path we already run in production; pick TGI when you want the Hugging Face container workflow.

VRAM: When to Go Larger or Multi-GPU

BF16 weights are roughly 2 bytes × parameters. KV cache is extra and grows with context and batch.

Model class Weights (BF16) Practical GPU When to go bigger
0.5B–3B smoke ~1–6 GB 24 GB minimum Lower --mem-fraction-static if you need leftover VRAM
7B–8B instruct ~14–16 GB 24 GB minimum, 48 GB comfortable Long context or many concurrent users → L40 / 6000 Ada
~32B 4-bit ~16–20 GB 48 GB Watch context length
70B 4-bit ~35–40 GB 48 GB tight / 80 GB safer Prefer an 80 GB card or 2×L40 if context is long
70B BF16 ~140 GB 2×48 GB or 80 GB Add --tp 2 (or 4)

Go multi-GPU when a single card OOMs, context is much longer than 8k with a real batch, or tensor parallelism is required. gpu_2x_l40 ($1.72/hr, 10 free on August 20, 2026) is the next step up from this walkthrough. GPU pricing for current stock.

Concurrency, TTFT, and Throughput

Short check on the same L40, Qwen2.5-0.5B-Instruct, triton backend, CUDA graphs off, localhost, August 20, 2026. Not a vLLM comparison.

Metric Value
Time to first token (median of 5 streams) 34.3 ms
8 concurrent chat completions, wall clock 554 ms
Combined output throughput, 8-way 373 tok/s

One stream after a pause hit 335 ms TTFT; that is warmup. Report the median.

Eight-way smoke from the VM:

ssh -o IdentitiesOnly=yes Ubuntu@YOUR_VM_IP 'bash -s' <<'EOF'
set -euo pipefail
for i in $(seq 1 8); do
  curl -sf http://127.0.0.1:30000/v1/chat/completions \
    -H 'Content-Type: application/json' \
    -d '{"model":"Qwen/Qwen2.5-0.5B-Instruct","messages":[{"role":"user","content":"Reply with one short sentence."}],"max_tokens":32,"temperature":0}' \
    >/tmp/sglang-c$i.json &
done
wait
echo SGLANG_CONCURRENCY_OK
EOF

Troubleshooting

SSH fails or keeps asking for a password. Image 184’s user is Ubuntu, not ubuntu. Use -o IdentitiesOnly=yes so ssh does not offer a pile of other keys. Refresh host keys with ssh-keygen -R YOUR_VM_IP if the instance was relaunched.

CUDA / nvcc errors on startup. Image 184 has drivers only. Point CUDA_HOME at venv/.../nvidia/cu13, symlink lib64lib and libcudart.solibcudart.so.13, then restart the unit. Check journalctl -u sglang-openai -n 160 --no-pager.

Flashinfer or CUDA-graph compile fails. Keep --attention-backend triton --disable-cuda-graph (or the newer --cuda-graph-backend-*=disabled flags).

Tiny model using ~40 GB. Default mem-fraction-static reserves KV cache. Add --mem-fraction-static 0.3 for smoke tests.

Gated model 401. Use Qwen 0.5B for this walkthrough, or set HF_TOKEN on the systemd unit and accept the model license.

Nothing on port 8000. SGLang’s default is 30000. vLLM uses 8000.

Laptop curl to http://YOUR_VM_IP:30000 hangs. Expected while --host 127.0.0.1. Test from the VM, or bind 0.0.0.0, open the firewall, and put auth in front before you expose it.

Out of memory. Smaller model, lower --mem-fraction-static, shorter context, or a larger SKU / --tp.

Deploy SGLang on High-Performance GPUs

Launch NVIDIA L40 instances optimized for OpenAI-compatible inference. Get 48GB VRAM, blazing-fast NVMe storage, and per-second billing.

Think it. Build it. Scale it.

Quick Setup Reference

# 1. Launch gpu_1x_l40, image 184
# 2. Verify GPU
ssh -o IdentitiesOnly=yes Ubuntu@YOUR_VM_IP 'nvidia-smi'

# 3. Bootstrap SGLang (script in step 3)

# 4. Test endpoints
ssh -o IdentitiesOnly=yes Ubuntu@YOUR_VM_IP 'curl -sf http://127.0.0.1:30000/v1/models'
ssh -o IdentitiesOnly=yes Ubuntu@YOUR_VM_IP \
  'curl -sf http://127.0.0.1:30000/v1/chat/completions -H "Content-Type: application/json" -d "{...}"'

# 5. Monitor
ssh -o IdentitiesOnly=yes Ubuntu@YOUR_VM_IP 'journalctl -u sglang-openai -f'

Frequently Asked Questions

01What models work with this setup?

Any Hugging Face causal LM SGLang can load. This guide uses Qwen/Qwen2.5-0.5B-Instruct so you can prove /v1 without a token. For a typical serve, use a 7B–8B instruct model on 48 GB. Gated Llama weights need a Hugging Face token.

02How do I change the model after deployment?

Edit /etc/systemd/system/sglang-openai.service, change --model-path, then sudo systemctl daemon-reload && sudo systemctl restart sglang-openai. The new weights download on restart.

03SGLang vs vLLM?

Same client: /v1/chat/completions. SGLang is the high-throughput / prefix-cache option. vLLM is the OpenAI-API path we already documented for production. See Deploy vLLM with OpenAI API on GPU Cloud. For Llama-specific vLLM vs TGI notes, see Llama 3 Inference: vLLM vs TGI.

04Can I run a 70B model?

BF16 70B needs two 48 GB GPUs or one 80 GB GPU and --tp 2 (or 4). 4-bit 70B can fit a 48 GB card but gets tight with long context.

05How do I enable external access?

Change --host 127.0.0.1 to --host 0.0.0.0, open the firewall for 30000, and put TLS plus auth in front (reverse proxy). Do not leave an open inference API on the public internet.

06What’s the difference between spot and on-demand?

Spot is cheaper and can be interrupted. On-demand stays up. Use spot for this walkthrough; use on-demand if the endpoint has to stay up.

Recipe tested on August 20, 2026.