
Dspy Vllm
- 4 installs
- 11 repo stars
- Updated June 28, 2026
- lebsral/dspy-programming-not-prompting-lms-skills
Helps with ai & agent building tasks.
About
dspy-vllm is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- dspy-vllm
- AI & Agent Building
- AI-coding skill
Dspy Vllm by the numbers
- 4 all-time installs (skills.sh)
- Ranked #13,372 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 2, 2026 (Skillselion catalog sync)
npx skills add https://github.com/lebsral/dspy-programming-not-prompting-lms-skills --skill dspy-vllmAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 4 |
|---|---|
| repo stars | ★ 11 |
| Last updated | June 28, 2026 |
| Repository | lebsral/dspy-programming-not-prompting-lms-skills ↗ |
What it does
Helps with ai & agent building tasks.
Files
vLLM — High-Throughput Production Serving for DSPy
Guide the user through serving self-hosted models with vLLM for production DSPy deployments. High concurrency, multi-GPU, OpenAI-compatible API.
Step 1: Understand the setup
Before generating vLLM configuration, clarify:
1. What GPU hardware? — Model (A100, H100, RTX 4090), count, and VRAM per GPU. This determines tensor parallelism and quantization needs. 2. Which model? — Model name and size (7B, 13B, 70B). Determines VRAM requirements and whether quantization is needed. 3. Workload type? — Production serving (concurrent users), batch processing (offline), or optimization (running MIPROv2/BootstrapFewShot)? 4. Already using Ollama locally? — If yes, help them add vLLM for production while keeping Ollama for dev.
What is vLLM
vLLM is a high-throughput inference engine (74k+ GitHub stars) for LLMs. Key features:
- PagedAttention — 4x memory efficiency vs naive attention, serves more concurrent users
- Continuous batching — processes requests as they arrive, no waiting for batch to fill
- Tensor parallelism — split models across multiple GPUs
- OpenAI-compatible API — drop-in replacement, DSPy connects via
openai/provider - Speculative decoding — use a small draft model to speed up large model generation
When to use vLLM
| Scenario | Use vLLM? | Alternative |
|---|---|---|
| Production API (10+ concurrent users) | Yes | — |
| Multi-GPU serving | Yes | — |
| Batch processing (1000s of inputs) | Yes | — |
| Local development on macOS | No | Ollama (/dspy-ollama) |
| Apple Silicon (M1/M2/M3) | No | Ollama (/dspy-ollama) |
| Quick prototyping | No | Ollama (/dspy-ollama) |
| Cloud API (no self-hosting) | No | OpenAI/Anthropic (/dspy-lm) |
vLLM requires NVIDIA GPUs (CUDA). It does not support Apple Silicon or AMD GPUs (ROCm support is experimental).
Setup
Install
pip install vllmRequires: Python 3.9+, NVIDIA GPU with CUDA 12.1+, Linux (recommended) or WSL2.
Start a vLLM server
# Basic — serve a model with OpenAI-compatible API
vllm serve meta-llama/Llama-3.1-8B-Instruct
# With common options
vllm serve meta-llama/Llama-3.1-8B-Instruct \
--host 0.0.0.0 \
--port 8000 \
--max-model-len 8192 \
--gpu-memory-utilization 0.9 \
--dtype autoThe server exposes /v1/chat/completions and /v1/completions endpoints.
Connect DSPy to vLLM
import dspy
lm = dspy.LM(
"openai/meta-llama/Llama-3.1-8B-Instruct",
api_base="http://localhost:8000/v1",
api_key="none", # required but any value works
temperature=0.7,
max_tokens=1000,
)
dspy.configure(lm=lm)
# Now all DSPy modules use your vLLM-served model
classify = dspy.ChainOfThought("text -> category, reasoning")
result = classify(text="Server is down, customers can't log in!")
print(result.category)Note: dspy.HFClientVLLM is deprecated. Use dspy.LM("openai/...") with api_base instead.
Tensor parallelism (multi-GPU)
Split large models across multiple GPUs:
# 2 GPUs
vllm serve meta-llama/Llama-3.1-70B-Instruct \
--tensor-parallel-size 2
# 4 GPUs
vllm serve meta-llama/Llama-3.1-70B-Instruct \
--tensor-parallel-size 4Rule of thumb: --tensor-parallel-size = number of GPUs the model needs. A 70B FP16 model needs ~140GB VRAM → 2x A100-80GB or 4x A100-40GB.
GPU sizing guide
| Model size | FP16 VRAM | INT4 (AWQ/GPTQ) VRAM | Recommended GPU |
|---|---|---|---|
| 7-8B | ~16 GB | ~5 GB | 1x RTX 4090 or A10G |
| 13-14B | ~28 GB | ~8 GB | 1x A100-40GB or 1x RTX 4090 |
| 30-34B | ~68 GB | ~20 GB | 1x A100-80GB or 2x RTX 4090 |
| 70B | ~140 GB | ~40 GB | 2x A100-80GB or 4x A100-40GB |
| 70B | — | ~40 GB | 1x A100-80GB (quantized) |
Add ~20% overhead for KV cache. --gpu-memory-utilization 0.9 is a good default.
Quantization
Serve quantized models for reduced VRAM:
# AWQ quantized (recommended — fastest)
vllm serve TheBloke/Llama-2-70B-Chat-AWQ \
--quantization awq
# GPTQ quantized
vllm serve TheBloke/Llama-2-70B-Chat-GPTQ \
--quantization gptqAWQ is generally faster than GPTQ on NVIDIA GPUs. Quality loss from INT4 quantization is typically small for 70B+ models.
Key vLLM server options
vllm serve <model> \
--host 0.0.0.0 \ # bind address
--port 8000 \ # port
--tensor-parallel-size 1 \ # number of GPUs
--max-model-len 8192 \ # max sequence length
--gpu-memory-utilization 0.9 \ # fraction of GPU memory to use
--dtype auto \ # auto, float16, bfloat16
--max-num-seqs 256 \ # max concurrent sequences
--enable-prefix-caching \ # cache common prompt prefixes
--quantization awq \ # awq, gptq, or none
--speculative-model <draft-model> \ # enable speculative decoding
--num-speculative-tokens 5 # tokens to speculatePrefix caching
Enable --enable-prefix-caching when many requests share the same system prompt or few-shot prefix (common in DSPy optimized programs):
vllm serve meta-llama/Llama-3.1-8B-Instruct \
--enable-prefix-cachingThis caches the KV cache for shared prompt prefixes, significantly speeding up DSPy programs that use the same few-shot demos across requests.
DSPy optimization with vLLM
vLLM handles concurrent requests well, making it faster than Ollama for optimization:
import dspy
lm = dspy.LM(
"openai/meta-llama/Llama-3.1-8B-Instruct",
api_base="http://localhost:8000/v1",
api_key="none",
max_tokens=1000,
)
dspy.configure(lm=lm)
# MIPROv2 sends many concurrent LM calls — vLLM handles this well
optimizer = dspy.MIPROv2(metric=metric, auto="medium")
optimized = optimizer.compile(program, trainset=trainset)Tip: Start the vLLM server with --max-num-seqs 256 to handle the optimizer's parallel requests efficiently.
Develop with Ollama, deploy with vLLM
The recommended workflow for self-hosted models:
import os
import dspy
# Same DSPy code, different LM config
if os.environ.get("ENV") == "production":
# vLLM in production (high throughput, NVIDIA GPU)
lm = dspy.LM(
"openai/meta-llama/Llama-3.1-8B-Instruct",
api_base="http://gpu-server:8000/v1",
api_key="none",
)
else:
# Ollama in development (easy setup, any platform)
lm = dspy.LM(
"ollama_chat/llama3.1:8b",
api_base="http://localhost:11434",
api_key="",
num_ctx=8192,
)
dspy.configure(lm=lm)
# Everything below is identical regardless of backend
program = dspy.ChainOfThought("question -> answer")
program.load("optimized_program.json")
result = program(question="How do refunds work?")The optimized program (instructions + demos) transfers between backends because DSPy optimizes at the prompt level, not the model level.
Production deployment patterns
Docker
FROM vllm/vllm-openai:latest
ENV MODEL_NAME=meta-llama/Llama-3.1-8B-Instruct
EXPOSE 8000
CMD ["--model", "${MODEL_NAME}", "--host", "0.0.0.0", "--port", "8000", "--max-model-len", "8192"]Health check
curl http://localhost:8000/health
# Returns 200 when readyBehind a load balancer
Run multiple vLLM instances behind nginx or a cloud load balancer for horizontal scaling:
# Instance 1 (GPU 0)
CUDA_VISIBLE_DEVICES=0 vllm serve meta-llama/Llama-3.1-8B-Instruct --port 8001
# Instance 2 (GPU 1)
CUDA_VISIBLE_DEVICES=1 vllm serve meta-llama/Llama-3.1-8B-Instruct --port 8002Gotchas
- Claude uses the deprecated `dspy.HFClientVLLM` class. This was removed in DSPy 2.5+. Always use
dspy.LM("openai/model-name", api_base="http://localhost:8000/v1", api_key="none")instead. - Claude omits `api_key` when connecting to vLLM. LiteLLM (which DSPy uses under the hood) requires the
api_keyparameter even though vLLM does not authenticate. Setapi_key="none"— any non-empty string works. - Claude recommends vLLM for macOS or Apple Silicon users. vLLM requires NVIDIA GPUs with CUDA. If the user mentions macOS, M1/M2/M3/M4, or no NVIDIA GPU, route to
/dspy-ollamainstead. - Claude forgets `--enable-prefix-caching` for DSPy workloads. DSPy optimized programs prepend the same few-shot demos to every request. Without prefix caching, vLLM recomputes the KV cache for those shared tokens on every call. Always recommend it for DSPy serving.
- Claude sets `--max-model-len` too high for available VRAM. This causes OOM on startup. Calculate available VRAM minus ~20% for KV cache overhead. For a 70B FP16 model on 2x A100-80GB, cap at ~8192 tokens. Suggest
--gpu-memory-utilization 0.9as the default and tell users to lower--max-model-lenif they hit OOM.
Additional resources
- vLLM documentation
- vLLM serve CLI reference
- vLLM GitHub
- For API details, see reference.md
- For worked examples, see examples.md
Cross-references
Install any skill: npx skills add lebsral/DSPy-Programming-not-prompting-LMs-skills --skill <name>- LM configuration basics (providers, parameters, caching) —
/dspy-lm - Local development with Ollama —
/dspy-ollama - Deploying as an API (FastAPI wrapper around your DSPy program) —
/ai-serving-apis - Reducing costs (model routing, caching) —
/ai-cutting-costs - Install `/ai-do` if you do not have it — it routes any AI problem to the right skill and is the fastest way to work:
npx skills add lebsral/DSPy-Programming-not-prompting-LMs-skills --skill ai-do
[
{
"prompt": "I want to serve Llama 3.1 70B for my DSPy app in production. I have 2x A100-80GB GPUs.",
"expected_output": "A vLLM server command with tensor-parallel-size 2, prefix caching enabled, and DSPy connection code using dspy.LM with openai/ prefix and api_base",
"assertions": [
"uses vllm serve with --tensor-parallel-size 2",
"includes --enable-prefix-caching for DSPy workloads",
"connects DSPy with dspy.LM('openai/meta-llama/...', api_base=..., api_key='none')",
"does NOT use the deprecated dspy.HFClientVLLM",
"includes api_key parameter set to a non-empty string",
"suggests --gpu-memory-utilization around 0.9"
]
},
{
"prompt": "Set up vLLM for running MIPROv2 optimization with a local Llama model on my RTX 4090",
"expected_output": "vLLM server config for a single GPU with high concurrency settings, DSPy optimization code connecting to vLLM",
"assertions": [
"recommends an 8B or 13B model that fits in 24GB VRAM (RTX 4090)",
"includes --max-num-seqs 256 or similar for optimizer parallel requests",
"includes --enable-prefix-caching",
"connects DSPy with dspy.LM and openai/ prefix, not HFClientVLLM",
"shows MIPROv2 compile call using the vLLM-backed LM"
]
},
{
"prompt": "I develop with Ollama on my Mac but want to deploy with vLLM to our GPU server",
"expected_output": "A dual-config pattern using environment variables to switch between Ollama (dev) and vLLM (prod), showing that optimized DSPy programs transfer between backends",
"assertions": [
"does NOT recommend vLLM for macOS — uses Ollama for local dev",
"shows environment-based switching between ollama_chat/ and openai/ providers",
"explains that optimized programs (instructions + demos) transfer between backends",
"includes vLLM production config with api_base and api_key='none'",
"mentions program.save and program.load for transferring optimized programs"
]
}
]
vLLM Examples
Start a vLLM server and connect DSPy
# Install
pip install vllm
# Serve Llama 3.1 8B
vllm serve meta-llama/Llama-3.1-8B-Instruct \
--host 0.0.0.0 \
--port 8000 \
--max-model-len 8192 \
--gpu-memory-utilization 0.9 \
--enable-prefix-cachingimport dspy
lm = dspy.LM(
"openai/meta-llama/Llama-3.1-8B-Instruct",
api_base="http://localhost:8000/v1",
api_key="none",
temperature=0.7,
max_tokens=1000,
)
dspy.configure(lm=lm)
# Build a simple pipeline
class TicketRouter(dspy.Module):
def __init__(self):
self.classify = dspy.Predict("ticket -> category, priority")
self.respond = dspy.ChainOfThought("ticket, category, priority -> response")
def forward(self, ticket):
triage = self.classify(ticket=ticket)
return self.respond(
ticket=ticket,
category=triage.category,
priority=triage.priority,
)
router = TicketRouter()
result = router(ticket="I was charged twice and need a refund immediately")
print(f"Category: {result.category}")
print(f"Priority: {result.priority}")
print(f"Response: {result.response}")Multi-GPU serving (70B model)
# Serve Llama 3.1 70B on 2x A100-80GB
vllm serve meta-llama/Llama-3.1-70B-Instruct \
--tensor-parallel-size 2 \
--max-model-len 8192 \
--gpu-memory-utilization 0.9 \
--enable-prefix-caching
# Or quantized on a single A100-80GB
vllm serve TheBloke/Llama-2-70B-Chat-AWQ \
--quantization awq \
--max-model-len 8192 \
--gpu-memory-utilization 0.9import dspy
# Connect to the 70B model — same DSPy API
lm = dspy.LM(
"openai/meta-llama/Llama-3.1-70B-Instruct",
api_base="http://gpu-server:8000/v1",
api_key="none",
max_tokens=2000,
)
dspy.configure(lm=lm)
# Complex reasoning benefits from larger models
analyze = dspy.ChainOfThought("document -> summary, key_findings: list[str], risk_level")
result = analyze(document="... long contract text ...")
print(result.summary)
print(result.key_findings)
print(result.risk_level)Optimize with vLLM backend
import dspy
from dspy.evaluate import Evaluate
lm = dspy.LM(
"openai/meta-llama/Llama-3.1-8B-Instruct",
api_base="http://localhost:8000/v1",
api_key="none",
max_tokens=500,
)
dspy.configure(lm=lm)
# Prepare data
trainset = [
dspy.Example(question="What is Python?", answer="A programming language").with_inputs("question"),
dspy.Example(question="What is DSPy?", answer="A framework for programming LMs").with_inputs("question"),
dspy.Example(question="What is vLLM?", answer="A high-throughput LLM serving engine").with_inputs("question"),
# ... add 50+ examples for stable optimization
]
devset = trainset[:10]
def metric(example, prediction, trace=None):
from dspy.evaluate import SemanticF1
return SemanticF1()(example, prediction)
# Baseline
program = dspy.ChainOfThought("question -> answer")
evaluator = Evaluate(devset=devset, metric=metric, num_threads=8)
baseline = evaluator(program)
print(f"Baseline: {baseline:.1f}%")
# Optimize — vLLM handles concurrent optimizer calls efficiently
optimizer = dspy.MIPROv2(metric=metric, auto="light")
optimized = optimizer.compile(program, trainset=trainset)
optimized_score = evaluator(optimized)
print(f"Optimized: {optimized_score:.1f}%")
print(f"Delta: {optimized_score - baseline:+.1f}%")
# Save
optimized.save("optimized_qa.json")vLLM API Reference
Condensed from docs.vllm.ai. Verify against upstream for latest.
DSPy Connection
lm = dspy.LM(
"openai/<model-name>",
api_base="http://localhost:8000/v1",
api_key="none", # required but any value works
)
dspy.configure(lm=lm)dspy.HFClientVLLM is deprecated -- always use dspy.LM("openai/...") with api_base.
vllm serve
vllm serve <model> [options]| Option | Default | Description |
|---|---|---|
--host | 0.0.0.0 | Bind address |
--port | 8000 | Port number |
--tensor-parallel-size / -tp | 1 | Number of GPUs for tensor parallelism |
--max-model-len | auto | Max sequence length (supports "1k", "2M") |
--gpu-memory-utilization | 0.92 | Fraction of GPU memory to use (0-1) |
--dtype | auto | auto, float16, bfloat16 |
--quantization / -q | none | awq, gptq, or none |
--enable-prefix-caching | off | Cache common prompt prefixes |
--max-num-seqs | 256 | Max concurrent sequences |
--speculative-model | none | Draft model for speculative decoding |
--num-speculative-tokens | — | Tokens to speculate per step |
GPU Sizing
| Model Size | FP16 VRAM | INT4 VRAM | Recommended GPU |
|---|---|---|---|
| 7-8B | ~16 GB | ~5 GB | 1x RTX 4090 / A10G |
| 13-14B | ~28 GB | ~8 GB | 1x A100-40GB |
| 70B | ~140 GB | ~40 GB | 2x A100-80GB |
Add ~20% overhead for KV cache.
Health Check
curl http://localhost:8000/health # 200 when readyDocker
docker run --gpus all -p 8000:8000 vllm/vllm-openai:latest \
--model meta-llama/Llama-3.1-8B-Instruct