Skip to main content
This tutorial shows how to build a vLLM application using FastAPI and deploy it as a load balancing Serverless endpoint on Runpod.
To get a basic understanding of how to build a load balancing worker (or for more general use cases), see Build a load balancing worker.

Requirements

Before you begin you’ll need:
  • A Runpod account.
  • Basic familiarity with Python, REST APIs, and vLLM.
  • Docker installed on your local machine.

Step 1: Create your project files

You can download a preconfigured repository containing the completed code for this tutorial on GitHub.
Start by creating a new directory for your project:
Then, create the following files and directories:
Your project structure should now look like this:
vllm_worker
Dockerfile
requirements.txt
src
handler.py
models.py
utils.py

Step 2: Define data models

We’ll start by creating the data models that define the structure of your API. These models specify what data your endpoints expect to receive and what they’ll return. Add the following code to src/models.py:
The GenerationRequest and ChatCompletionRequest models specify what data clients need to send, while GenerationResponse and ErrorResponse define what they’ll receive back. Each data model includes validation rules using Pydantic’s Field function to ensure parameters stay within acceptable ranges.

Step 3: Create utility functions

Next, we’ll create a few helper functions to support the main application. These utilities handle common tasks like formatting chat prompts and creating standardized error responses. Add the following code to src/utils.py:
The format_chat_prompt function converts chat-style conversations into the text format expected by language models. It first tries to use the model’s built-in chat template, then falls back to a generic format if that’s not available. The create_error_response function provides a consistent way to generate error messages throughout your application.

Step 4: Build the main FastAPI application

Now we’ll build the main application file, src/handler.py. This file acts as the orchestrator, bringing together the models and utilities we just created. It uses FastAPI to create the server, defines the API endpoints, and manages the vLLM engine’s lifecycle. Add the following code to src/handler.py:
This file creates a FastAPI server that manages the vLLM engine and exposes three API endpoints:
  • A health check at /ping that tells the load balancer when your worker is ready.
  • A text completion endpoint at /v1/completions.
  • An OpenAI-compatible chat endpoint at /v1/chat/completions.
The application handles both streaming and non-streaming responses, manages the language model lifecycle, and includes comprehensive error handling and logging.

Step 5: Set up dependencies and build steps

With the application code complete, we still need to define its dependencies and create a Dockerfile to package it into a container image.
  1. Add the following dependencies to requirements.txt:
  2. Add the following build steps to your Dockerfile:

Step 6: Build and push your Docker image

Build and push your Docker image to a container registry:

Step 7: Deploy to Runpod

Now, let’s deploy our application to a Serverless endpoint:
  1. Go to the Serverless page in the Runpod console.
  2. Click New Endpoint
  3. Click Import from Docker Registry.
  4. In the Container Image field, enter your Docker image URL:
    Then click Next.
  5. Give your endpoint a name.
  6. Under Endpoint Type, select Load Balancer.
  7. Under GPU Configuration, select at least one GPU type (16 GB or 24 GB GPUs are fine for this example).
  8. Leave all other settings at their defaults.
  9. Click Create Endpoint.

Step 8: Test your endpoints

You can find a Python script to test your vLLM load balancer locally on GitHub.
Once your endpoint has finished deploying, you can access your vLLM APIs at:
For example, the vLLM application we defined in step 4 exposes these endpoints:
  • Health check: https://ENDPOINT_ID.api.runpod.ai/ping
  • Generate text: https://ENDPOINT_ID.api.runpod.ai/v1/completions
  • Chat completions: https://ENDPOINT_ID.api.runpod.ai/v1/chat/completions
Use the curl commands below to make test requests to your vLLM load balancer, replacing ENDPOINT_ID and RUNPOD_API_KEY with your actual values. To run a health check:
ping
For text completions:
For chat completions:
After sending a request, your workers will take some time to initialize. You can track their progress by checking the logs in the Workers tab of your endpoint page.
If you see: {"error":"no workers available"}% after running the request, this means your workers did not initialize in time to process it. If you try running the request again, this will usually resolve the issue.For production applications, implement a health check with retries before sending requests. See Handling cold start errors for a complete code example.
Congratulations! You’ve created a load balancing vLLM endpoint and used it to serve a large language model.

Next steps

Now that you’ve deployed a load balancing vLLM endpoint, you can try:
  • Experimenting with different models and frameworks.
  • Adding authentication to your API.
  • Exploring advanced FastAPI features like background tasks and WebSockets.
  • Optimizing your application for performance and reliability.