Co-authored-by: Satyam Kumar <satyamk@linkedin.com>
This commit is contained in:
co-authored by
Satyam Kumar
parent
c11b34d599
commit
9fc3e8aac7
@@ -15,6 +15,7 @@
|
||||
import multiprocessing as mp
|
||||
import random
|
||||
import unittest
|
||||
from typing import Optional
|
||||
|
||||
import torch
|
||||
from transformers import AutoConfig, AutoTokenizer
|
||||
@@ -69,6 +70,7 @@ class TestEmbeddingModels(CustomTestCase):
|
||||
tp_size,
|
||||
torch_dtype,
|
||||
prefill_tolerance,
|
||||
matryoshka_dim: Optional[int] = None,
|
||||
) -> None:
|
||||
truncated_prompts = self._truncate_prompts(prompts, model_path)
|
||||
|
||||
@@ -76,6 +78,7 @@ class TestEmbeddingModels(CustomTestCase):
|
||||
model_path,
|
||||
torch_dtype=torch_dtype,
|
||||
model_type="embedding",
|
||||
matryoshka_dim=matryoshka_dim,
|
||||
) as hf_runner:
|
||||
hf_outputs = hf_runner.forward(truncated_prompts)
|
||||
|
||||
@@ -86,8 +89,13 @@ class TestEmbeddingModels(CustomTestCase):
|
||||
torch_dtype=torch_dtype,
|
||||
model_type="embedding",
|
||||
attention_backend=attention_backend,
|
||||
json_model_override_args=(
|
||||
{"matryoshka_dimensions": [matryoshka_dim]} if matryoshka_dim else None
|
||||
),
|
||||
) as srt_runner:
|
||||
srt_outputs = srt_runner.forward(truncated_prompts)
|
||||
srt_outputs = srt_runner.forward(
|
||||
truncated_prompts, dimensions=matryoshka_dim
|
||||
)
|
||||
|
||||
for i in range(len(prompts)):
|
||||
hf_logits = torch.Tensor(hf_outputs.embed_logits[i])
|
||||
@@ -113,6 +121,25 @@ class TestEmbeddingModels(CustomTestCase):
|
||||
DEFAULT_PROMPTS, model, tp_size, torch_dtype, prefill_tolerance
|
||||
)
|
||||
|
||||
def test_matryoshka_embedding(self):
|
||||
models_to_test = [
|
||||
model
|
||||
for model in MODELS
|
||||
if "Alibaba-NLP/gte-Qwen2-1.5B-instruct" == model[0]
|
||||
]
|
||||
assert len(models_to_test) == 1
|
||||
|
||||
for model, tp_size, prefill_tolerance in models_to_test:
|
||||
for torch_dtype in TORCH_DTYPES:
|
||||
self.assert_close_prefill_logits(
|
||||
DEFAULT_PROMPTS,
|
||||
model,
|
||||
tp_size,
|
||||
torch_dtype,
|
||||
prefill_tolerance,
|
||||
matryoshka_dim=128,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import json
|
||||
import os
|
||||
import unittest
|
||||
|
||||
import numpy as np
|
||||
import openai
|
||||
|
||||
from sglang.srt.utils import kill_process_tree
|
||||
@@ -92,6 +95,105 @@ class TestOpenAIEmbedding(CustomTestCase):
|
||||
# check the status code
|
||||
self.assertEqual(cm.exception.status_code, 400)
|
||||
|
||||
def test_embedding_with_dimensions_parameter(self):
|
||||
"""Test that non-Matryoshka models reject dimensions parameter."""
|
||||
client = openai.Client(api_key=self.api_key, base_url=self.base_url)
|
||||
|
||||
# Test that specifying dimensions fails for non-Matryoshka models
|
||||
with self.assertRaises(openai.BadRequestError) as cm:
|
||||
client.embeddings.create(
|
||||
model=self.model, input="Hello world", dimensions=512
|
||||
)
|
||||
|
||||
self.assertEqual(cm.exception.status_code, 400)
|
||||
|
||||
|
||||
class TestMatryoshkaEmbeddingModel(CustomTestCase):
|
||||
"""Test class for Model that supports Matryoshka embedding functionality, using OpenAI API."""
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.model = DEFAULT_SMALL_EMBEDDING_MODEL_NAME_FOR_TEST
|
||||
cls.base_url = DEFAULT_URL_FOR_TEST
|
||||
cls.api_key = "sk-123456"
|
||||
cls.matryoshka_dims = [128, 256, 512, 768, 1024]
|
||||
|
||||
# Configure embedding-specific args with Matryoshka support via json_model_override_args
|
||||
matryoshka_config = {
|
||||
"is_matryoshka": True,
|
||||
"matryoshka_dimensions": cls.matryoshka_dims,
|
||||
}
|
||||
other_args = [
|
||||
"--is-embedding",
|
||||
"--enable-metrics",
|
||||
"--json-model-override-args",
|
||||
json.dumps(matryoshka_config),
|
||||
]
|
||||
cls.process = popen_launch_server(
|
||||
cls.model,
|
||||
cls.base_url,
|
||||
timeout=DEFAULT_TIMEOUT_FOR_SERVER_LAUNCH,
|
||||
api_key=cls.api_key,
|
||||
other_args=other_args,
|
||||
)
|
||||
cls.base_url += "/v1"
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
if hasattr(cls, "process"):
|
||||
kill_process_tree(cls.process.pid)
|
||||
|
||||
def test_matryoshka_embedding_valid_dimensions(self):
|
||||
"""Test Matryoshka embedding with valid dimensions."""
|
||||
client = openai.Client(api_key=self.api_key, base_url=self.base_url)
|
||||
|
||||
# Test with various valid dimensions
|
||||
for dimensions in self.matryoshka_dims:
|
||||
with self.subTest(dimensions=dimensions):
|
||||
response = client.embeddings.create(
|
||||
model=self.model, input="Hello world", dimensions=dimensions
|
||||
)
|
||||
self.assertEqual(len(response.data), 1)
|
||||
self.assertEqual(len(response.data[0].embedding), dimensions)
|
||||
|
||||
def test_matryoshka_embedding_batch_same_dimensions(self):
|
||||
"""Test Matryoshka embedding with batch input and same dimensions."""
|
||||
client = openai.Client(api_key=self.api_key, base_url=self.base_url)
|
||||
|
||||
response = client.embeddings.create(
|
||||
model=self.model,
|
||||
input=["Hello world", "Test text", "Another example"],
|
||||
dimensions=256,
|
||||
)
|
||||
|
||||
self.assertEqual(len(response.data), 3)
|
||||
for embedding_data in response.data:
|
||||
self.assertEqual(len(embedding_data.embedding), 256)
|
||||
|
||||
def test_matryoshka_embedding_no_dimensions(self):
|
||||
"""Test embedding without specifying dimensions (should use full size)."""
|
||||
client = openai.Client(api_key=self.api_key, base_url=self.base_url)
|
||||
|
||||
response = client.embeddings.create(model=self.model, input="Hello world")
|
||||
|
||||
self.assertEqual(len(response.data), 1)
|
||||
|
||||
# Should return full embedding size when no dimensions specified
|
||||
self.assertEqual(len(response.data[0].embedding), 1536)
|
||||
|
||||
def test_matryoshka_embedding_invalid_dimensions(self):
|
||||
"""Test Matryoshka embedding with invalid dimensions."""
|
||||
client = openai.Client(api_key=self.api_key, base_url=self.base_url)
|
||||
|
||||
for dimensions in [100, 0, -1, 10000]:
|
||||
with self.assertRaises(openai.BadRequestError) as cm:
|
||||
client.embeddings.create(
|
||||
model=self.model,
|
||||
input="Hello world",
|
||||
dimensions=dimensions,
|
||||
)
|
||||
self.assertEqual(cm.exception.status_code, 400)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user