Support penalty in overlap mode; return logprob with chunked prefill; improve benchmark scripts (#3988)
Co-authored-by: SangBin Cho <rkooo567@gmail.com> Co-authored-by: dhou-xai <dhou@x.ai> Co-authored-by: Hanming Lu <hanming_lu@berkeley.edu>
This commit is contained in:
@@ -1,3 +1,8 @@
|
||||
"""
|
||||
python3 -m unittest test_skip_tokenizer_init.TestSkipTokenizerInit.test_parallel_sample
|
||||
python3 -m unittest test_skip_tokenizer_init.TestSkipTokenizerInit.run_decode_stream
|
||||
"""
|
||||
|
||||
import json
|
||||
import unittest
|
||||
|
||||
@@ -12,42 +17,26 @@ from sglang.test.test_utils import (
|
||||
popen_launch_server,
|
||||
)
|
||||
|
||||
_server_process = None
|
||||
_base_url = None
|
||||
_tokenizer = None
|
||||
|
||||
|
||||
def setUpModule():
|
||||
"""
|
||||
Launch the server once before all tests and initialize the tokenizer.
|
||||
"""
|
||||
global _server_process, _base_url, _tokenizer
|
||||
_server_process = popen_launch_server(
|
||||
DEFAULT_SMALL_MODEL_NAME_FOR_TEST,
|
||||
DEFAULT_URL_FOR_TEST,
|
||||
timeout=DEFAULT_TIMEOUT_FOR_SERVER_LAUNCH,
|
||||
other_args=["--skip-tokenizer-init"],
|
||||
)
|
||||
_base_url = DEFAULT_URL_FOR_TEST
|
||||
|
||||
_tokenizer = AutoTokenizer.from_pretrained(
|
||||
DEFAULT_SMALL_MODEL_NAME_FOR_TEST, use_fast=False
|
||||
)
|
||||
print(">>> setUpModule: Server launched, tokenizer ready")
|
||||
|
||||
|
||||
def tearDownModule():
|
||||
"""
|
||||
Terminate the server once after all tests have completed.
|
||||
"""
|
||||
global _server_process
|
||||
if _server_process is not None:
|
||||
kill_process_tree(_server_process.pid)
|
||||
_server_process = None
|
||||
print(">>> tearDownModule: Server terminated")
|
||||
|
||||
|
||||
class TestSkipTokenizerInit(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.model = DEFAULT_SMALL_MODEL_NAME_FOR_TEST
|
||||
cls.base_url = DEFAULT_URL_FOR_TEST
|
||||
cls.process = popen_launch_server(
|
||||
cls.model,
|
||||
cls.base_url,
|
||||
timeout=DEFAULT_TIMEOUT_FOR_SERVER_LAUNCH,
|
||||
other_args=["--skip-tokenizer-init", "--stream-output"],
|
||||
)
|
||||
cls.tokenizer = AutoTokenizer.from_pretrained(
|
||||
DEFAULT_SMALL_MODEL_NAME_FOR_TEST, use_fast=False
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
kill_process_tree(cls.process.pid)
|
||||
|
||||
def run_decode(
|
||||
self,
|
||||
prompt_text="The capital of France is",
|
||||
@@ -56,19 +45,19 @@ class TestSkipTokenizerInit(unittest.TestCase):
|
||||
top_logprobs_num=0,
|
||||
n=1,
|
||||
):
|
||||
input_ids = _tokenizer(prompt_text, return_tensors="pt")["input_ids"][
|
||||
input_ids = self.tokenizer(prompt_text, return_tensors="pt")["input_ids"][
|
||||
0
|
||||
].tolist()
|
||||
|
||||
response = requests.post(
|
||||
_base_url + "/generate",
|
||||
self.base_url + "/generate",
|
||||
json={
|
||||
"input_ids": input_ids,
|
||||
"sampling_params": {
|
||||
"temperature": 0 if n == 1 else 0.5,
|
||||
"max_new_tokens": max_new_tokens,
|
||||
"n": n,
|
||||
"stop_token_ids": [_tokenizer.eos_token_id],
|
||||
"stop_token_ids": [self.tokenizer.eos_token_id],
|
||||
},
|
||||
"stream": False,
|
||||
"return_logprob": return_logprob,
|
||||
@@ -83,13 +72,13 @@ class TestSkipTokenizerInit(unittest.TestCase):
|
||||
if item["meta_info"]["finish_reason"]["type"] == "stop":
|
||||
self.assertEqual(
|
||||
item["meta_info"]["finish_reason"]["matched"],
|
||||
_tokenizer.eos_token_id,
|
||||
self.tokenizer.eos_token_id,
|
||||
)
|
||||
elif item["meta_info"]["finish_reason"]["type"] == "length":
|
||||
self.assertEqual(
|
||||
len(item["token_ids"]), item["meta_info"]["completion_tokens"]
|
||||
len(item["output_ids"]), item["meta_info"]["completion_tokens"]
|
||||
)
|
||||
self.assertEqual(len(item["token_ids"]), max_new_tokens)
|
||||
self.assertEqual(len(item["output_ids"]), max_new_tokens)
|
||||
self.assertEqual(item["meta_info"]["prompt_tokens"], len(input_ids))
|
||||
|
||||
if return_logprob:
|
||||
@@ -113,6 +102,63 @@ class TestSkipTokenizerInit(unittest.TestCase):
|
||||
|
||||
print("=" * 100)
|
||||
|
||||
def run_decode_stream(self, return_logprob=False, top_logprobs_num=0, n=1):
|
||||
max_new_tokens = 32
|
||||
input_ids = [128000, 791, 6864, 315, 9822, 374] # The capital of France is
|
||||
requests.post(self.base_url + "/flush_cache")
|
||||
response = requests.post(
|
||||
self.base_url + "/generate",
|
||||
json={
|
||||
"input_ids": input_ids,
|
||||
"sampling_params": {
|
||||
"temperature": 0 if n == 1 else 0.5,
|
||||
"max_new_tokens": max_new_tokens,
|
||||
"n": n,
|
||||
"stop_token_ids": [119690],
|
||||
},
|
||||
"stream": False,
|
||||
"return_logprob": return_logprob,
|
||||
"top_logprobs_num": top_logprobs_num,
|
||||
"logprob_start_len": 0,
|
||||
},
|
||||
)
|
||||
ret = response.json()
|
||||
print(json.dumps(ret))
|
||||
output_ids = ret["output_ids"]
|
||||
|
||||
requests.post(self.base_url + "/flush_cache")
|
||||
response_stream = requests.post(
|
||||
self.base_url + "/generate",
|
||||
json={
|
||||
"input_ids": input_ids,
|
||||
"sampling_params": {
|
||||
"temperature": 0 if n == 1 else 0.5,
|
||||
"max_new_tokens": max_new_tokens,
|
||||
"n": n,
|
||||
"stop_token_ids": [119690],
|
||||
},
|
||||
"stream": True,
|
||||
"return_logprob": return_logprob,
|
||||
"top_logprobs_num": top_logprobs_num,
|
||||
"logprob_start_len": 0,
|
||||
},
|
||||
)
|
||||
ret = response.json()
|
||||
output_ids = ret["output_ids"]
|
||||
print("output from non-streaming request:")
|
||||
print(output_ids)
|
||||
|
||||
response_stream_json = []
|
||||
for line in response_stream.iter_lines():
|
||||
if line.startswith(b"data: ") and line[6:] != b"[DONE]":
|
||||
response_stream_json.append(json.loads(line[6:]))
|
||||
out_stream_ids = []
|
||||
for x in response_stream_json:
|
||||
out_stream_ids += x["output_ids"]
|
||||
print("output from streaming request:")
|
||||
print(out_stream_ids)
|
||||
assert output_ids == out_stream_ids
|
||||
|
||||
def test_simple_decode(self):
|
||||
self.run_decode()
|
||||
|
||||
@@ -126,6 +172,9 @@ class TestSkipTokenizerInit(unittest.TestCase):
|
||||
def test_eos_behavior(self):
|
||||
self.run_decode(max_new_tokens=256)
|
||||
|
||||
def test_simple_decode_stream(self):
|
||||
self.run_decode_stream()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user