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.
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.
| 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 |
| 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 |
Step-by-Step Deployment
Image 184 logs in as Ubuntu (capital U). If SSH offers extra keys and then fails, add -o IdentitiesOnly=yes.
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.
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.
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.
Verify Service Status
ssh -o IdentitiesOnly=yes Ubuntu@YOUR_VM_IP 'systemctl is-active sglang-openai'
Expected output: active
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.
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.
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.
- SGLang (this guide): high-throughput self-hosted serving, radix / prefix cache, OpenAI
/v1on port 30000. Best when you want an OpenAI-shaped client and concurrent traffic. - vLLM: the existing Massed Compute production OpenAI-API path. See Deploy vLLM with OpenAI API on GPU Cloud.
- TGI: Hugging Face–native serving. See Build an LLM Inference API with TGI.
- Ollama: single-user / local-dev, not this serving shape. See Deploy LLMs with Ollama on GPU Cloud.
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 lib64 → lib and libcudart.so → libcudart.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.











