Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions python/sglang/test/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from concurrent.futures import ThreadPoolExecutor
from datetime import datetime
from functools import partial, wraps
from io import BytesIO
from pathlib import Path
from types import SimpleNamespace
from typing import Any, Awaitable, Callable, List, Optional, Tuple
Expand All @@ -25,6 +26,7 @@
import requests
import torch
import torch.nn.functional as F
from PIL import Image

from sglang.bench_serving import run_benchmark
from sglang.global_config import global_config
Expand Down Expand Up @@ -129,6 +131,22 @@
DEFAULT_TIMEOUT_FOR_SERVER_LAUNCH = 600


def download_image_with_retry(image_url: str, max_retries: int = 3) -> Image.Image:
for i in range(max_retries):
try:
response = requests.get(image_url, timeout=30)
response.raise_for_status()
image = Image.open(BytesIO(response.content))
image.load()
return image
except Exception as e:
if i == max_retries - 1:
raise RuntimeError(
f"Failed to download image after {max_retries} retries: {image_url}"
) from e
time.sleep(2**i)


def is_in_ci():
"""Return whether it is in CI runner."""
return get_bool_env_var("SGLANG_IS_IN_CI")
Expand Down
6 changes: 2 additions & 4 deletions test/srt/test_skip_tokenizer_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@

import json
import unittest
from io import BytesIO

import requests
from PIL import Image
from transformers import AutoProcessor, AutoTokenizer

from sglang.lang.chat_template import get_chat_template_by_model_path
Expand All @@ -20,6 +18,7 @@
DEFAULT_TIMEOUT_FOR_SERVER_LAUNCH,
DEFAULT_URL_FOR_TEST,
CustomTestCase,
download_image_with_retry,
popen_launch_server,
)

Expand Down Expand Up @@ -204,8 +203,7 @@ class TestSkipTokenizerInitVLM(TestSkipTokenizerInit):
@classmethod
def setUpClass(cls):
cls.image_url = DEFAULT_IMAGE_URL
response = requests.get(cls.image_url)
cls.image = Image.open(BytesIO(response.content))
cls.image = download_image_with_retry(cls.image_url)
cls.model = DEFAULT_SMALL_VLM_MODEL_NAME_FOR_TEST
cls.tokenizer = AutoTokenizer.from_pretrained(cls.model, use_fast=False)
cls.processor = AutoProcessor.from_pretrained(cls.model, trust_remote_code=True)
Expand Down
7 changes: 2 additions & 5 deletions test/srt/test_vlm_accuracy.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,11 @@
"""

import unittest
from io import BytesIO
from typing import List, Optional

import numpy as np
import requests
import torch
import torch.nn.functional as F
from PIL import Image
from transformers import AutoModel, AutoProcessor, AutoTokenizer

from sglang.srt.configs.model_config import ModelConfig
Expand All @@ -24,6 +21,7 @@
from sglang.srt.multimodal.processors.base_processor import BaseMultimodalProcessor
from sglang.srt.parser.conversation import generate_chat_conv
from sglang.srt.server_args import ServerArgs
from sglang.test.test_utils import download_image_with_retry


# Test the logits output between HF and SGLang
Expand All @@ -35,8 +33,7 @@ def setUpClass(cls):
cls.model_path = ""
cls.chat_template = ""
cls.processor = ""
response = requests.get(cls.image_url)
cls.main_image = Image.open(BytesIO(response.content))
cls.main_image = download_image_with_retry(cls.image_url)

def compare_outputs(self, sglang_output: torch.Tensor, hf_output: torch.Tensor):
# Convert to float32 for numerical stability if needed
Expand Down
7 changes: 2 additions & 5 deletions test/srt/test_vlm_input_format.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import json
import unittest
from io import BytesIO
from typing import Optional

import requests
import torch
from PIL import Image
from transformers import (
AutoProcessor,
Gemma3ForConditionalGeneration,
Expand All @@ -15,6 +12,7 @@
from sglang import Engine
from sglang.srt.entrypoints.openai.protocol import ChatCompletionRequest
from sglang.srt.parser.conversation import generate_chat_conv
from sglang.test.test_utils import download_image_with_retry

TEST_IMAGE_URL = "https://github.com/sgl-project/sglang/blob/main/examples/assets/example_image.png?raw=true"

Expand All @@ -31,8 +29,7 @@ def setUpClass(cls):
assert cls.chat_template is not None, "Set chat_template in subclass"
cls.image_url = TEST_IMAGE_URL
cls.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
response = requests.get(cls.image_url)
cls.main_image = Image.open(BytesIO(response.content))
cls.main_image = download_image_with_retry(cls.image_url)
cls.processor = AutoProcessor.from_pretrained(
cls.model_path, trust_remote_code=True, use_fast=True
)
Expand Down
Loading