[Misc][Doc] Add Example of using OpenAI Server with VLM (#5832)

This commit is contained in:
Roger Wang 2024-06-25 20:34:25 -07:00 committed by GitHub
parent dda4811591
commit 3aa7b6cf66
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 101 additions and 3 deletions

View File

@ -130,6 +130,8 @@ To consume the server, you can use the OpenAI client like in the example below:
) )
print("Chat response:", chat_response) print("Chat response:", chat_response)
A full code example can be found in `examples/openai_vision_api_client.py <https://github.com/vllm-project/vllm/blob/main/examples/openai_vision_api_client.py>`_.
.. note:: .. note::
By default, the timeout for fetching images through http url is ``5`` seconds. You can override this by setting the environment variable: By default, the timeout for fetching images through http url is ``5`` seconds. You can override this by setting the environment variable:

View File

@ -0,0 +1,90 @@
"""An example showing how to use vLLM to serve VLMs.
Launch the vLLM server with the following command:
python -m vllm.entrypoints.openai.api_server \
--model llava-hf/llava-1.5-7b-hf \
--image-input-type pixel_values \
--image-token-id 32000 \
--image-input-shape 1,3,336,336 \
--image-feature-size 576 \
--chat-template template_llava.jinja
"""
import base64
import requests
from openai import OpenAI
# Modify OpenAI's API key and API base to use vLLM's API server.
openai_api_key = "EMPTY"
openai_api_base = "http://localhost:8000/v1"
client = OpenAI(
# defaults to os.environ.get("OPENAI_API_KEY")
api_key=openai_api_key,
base_url=openai_api_base,
)
models = client.models.list()
model = models.data[0].id
image_url = "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg"
# Use image url in the payload
chat_completion_from_url = client.chat.completions.create(
messages=[{
"role":
"user",
"content": [
{
"type": "text",
"text": "Whats in this image?"
},
{
"type": "image_url",
"image_url": {
"url": image_url
},
},
],
}],
model=model,
)
result = chat_completion_from_url.choices[0].message.content
print(f"Chat completion output:{result}")
# Use base64 encoded image in the payload
def encode_image_base64_from_url(image_url: str) -> str:
"""Encode an image retrieved from a remote url to base64 format."""
with requests.get(image_url) as response:
response.raise_for_status()
result = base64.b64encode(response.content).decode('utf-8')
return result
image_base64 = encode_image_base64_from_url(image_url=image_url)
chat_completion_from_base64 = client.chat.completions.create(
messages=[{
"role":
"user",
"content": [
{
"type": "text",
"text": "Whats in this image?"
},
{
"type": "image_url",
"image_url": {
"url": f"data:image/jpeg;base64,{image_base64}"
},
},
],
}],
model=model,
)
result = chat_completion_from_base64.choices[0].message.content
print(f"Chat completion output:{result}")

View File

@ -1,6 +1,7 @@
import base64 import base64
from io import BytesIO from io import BytesIO
from typing import Optional, Union from typing import Optional, Union
from urllib.parse import urlparse
import aiohttp import aiohttp
from PIL import Image from PIL import Image
@ -28,6 +29,10 @@ class ImageFetchAiohttp:
"""Load PIL image from a url or base64 encoded openai GPT4V format""" """Load PIL image from a url or base64 encoded openai GPT4V format"""
if image_url.startswith('http'): if image_url.startswith('http'):
parsed_url = urlparse(image_url)
if parsed_url.scheme not in ["http", "https"]:
raise ValueError("Invalid 'image_url': A valid 'image_url' "
"must have scheme 'http' or 'https'.")
# Avoid circular import # Avoid circular import
from vllm import __version__ as VLLM_VERSION from vllm import __version__ as VLLM_VERSION
@ -44,8 +49,9 @@ class ImageFetchAiohttp:
image = load_image_from_base64(image_url.split(',', 1)[1]) image = load_image_from_base64(image_url.split(',', 1)[1])
else: else:
raise ValueError("Invalid image url: A valid image url must start " raise ValueError(
"with either 'data:image' or 'http'.") "Invalid 'image_url': A valid 'image_url' must start "
"with either 'data:image' or 'http'.")
return image return image
@ -56,7 +62,7 @@ async def async_get_and_parse_image(image_url: str) -> ImagePixelData:
def encode_image_base64(image: Image.Image, format: str = 'JPEG') -> str: def encode_image_base64(image: Image.Image, format: str = 'JPEG') -> str:
"""encode image to base64 format.""" """Encode a pillow image to base64 format."""
buffered = BytesIO() buffered = BytesIO()
if format == 'JPEG': if format == 'JPEG':