OpenAI API - 비전

OpenAI API - 비전 (Vision)

SGLang은 OpenAI 호환 API를 제공해서, OpenAI 서비스에서 셀프호스팅 로컬 모델로 부드럽게 전환할 수 있게 해 줘요. API의 전체 레퍼런스는 OpenAI API Reference에서 볼 수 있고요. 이 튜토리얼은 비전 언어 모델을 위한 비전 API를 다룰게요.

출처: 공식문서

SGLang은 Llama 3.2, LLaVA-OneVision, Qwen2.5-VL, Gemma 3 등 다양한 비전 언어 모델을 지원하고, 전체 목록은 멀티모달 언어 모델 페이지에서 확인할 수 있어요.

OpenAI API의 대안으로 SGLang 오프라인 엔진도 쓸 수 있어요. offline_batch_inference_vlm.py 예시를 참고하세요.

서버 실행

터미널에서 서버를 실행하고 초기화가 끝날 때까지 기다려요.

from sglang.test.doc_patch import launch_server_cmd
from sglang.utils import wait_for_server, print_highlight, terminate_process

example_image_url = "https://raw.githubusercontent.com/sgl-project/sglang/main/examples/assets/example_image.png"
logo_image_url = (
    "https://raw.githubusercontent.com/sgl-project/sglang/main/assets/logo.png"
)

vision_process, port = launch_server_cmd("""
python3 -m sglang.launch_server --model-path Qwen/Qwen2.5-VL-7B-Instruct --log-level warning
""")

wait_for_server(f"http://localhost:{port}", process=vision_process)

cURL 사용하기

서버가 뜨면 curl이나 requests로 테스트 요청을 보낼 수 있어요.

import subprocess

curl_command = f"""
curl -s http://localhost:{port}/v1/chat/completions \\
  -H "Content-Type: application/json" \\
  -d '{
    "model": "Qwen/Qwen2.5-VL-7B-Instruct",
    "messages": [
      {
        "role": "user",
        "content": [
          {
            "type": "text",
            "text": "What’s in this image?"
          },
          {
            "type": "image_url",
            "image_url": {
              "url": "{example_image_url}"
            }
          }
        ]
      }
    ],
    "max_tokens": 300
  }'
"""

response = subprocess.check_output(curl_command, shell=True).decode()
print_highlight(response)


response = subprocess.check_output(curl_command, shell=True).decode()
print_highlight(response)

Python Requests 사용하기

import requests

url = f"http://localhost:{port}/v1/chat/completions"

data = {
    "model": "Qwen/Qwen2.5-VL-7B-Instruct",
    "messages": [
        {
            "role": "user",
            "content": [
                {"type": "text", "text": "What’s in this image?"},
                {
                    "type": "image_url",
                    "image_url": {"url": example_image_url},
                },
            ],
        }
    ],
    "max_tokens": 300,
}

response = requests.post(url, json=data)
print_highlight(response.text)

OpenAI Python 클라이언트 사용하기

from openai import OpenAI

client = OpenAI(base_url=f"http://localhost:{port}/v1", api_key="None")

response = client.chat.completions.create(
    model="Qwen/Qwen2.5-VL-7B-Instruct",
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "text",
                    "text": "What is in this image?",
                },
                {
                    "type": "image_url",
                    "image_url": {"url": example_image_url},
                },
            ],
        }
    ],
    max_tokens=300,
)

print_highlight(response.choices[0].message.content)

다중 이미지 입력

모델이 지원한다면 서버는 여러 이미지와 텍스트·이미지가 번갈아 나오는 입력도 지원해요.

from openai import OpenAI

client = OpenAI(base_url=f"http://localhost:{port}/v1", api_key="None")

response = client.chat.completions.create(
    model="Qwen/Qwen2.5-VL-7B-Instruct",
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "image_url",
                    "image_url": {
                        "url": example_image_url,
                    },
                },
                {
                    "type": "image_url",
                    "image_url": {
                        "url": logo_image_url,
                    },
                },
                {
                    "type": "text",
                    "text": "I have two very different images. They are not related at all. "
                    "Please describe the first image in one sentence, and then describe the second image in another sentence.",
                },
            ],
        }
    ],
    temperature=0,
)

print_highlight(response.choices[0].message.content)
terminate_process(vision_process)

더 알아보기 (Learn more)