94057c3d3e
PR Test (NPU) / check-changes (push) Has been cancelled
PR Test (NPU) / pr-gate (push) Has been cancelled
PR Test (NPU) / set-image-config (push) Has been cancelled
PR Test (NPU) / stage-b-test-1-npu-a2 (0) (push) Has been cancelled
PR Test (NPU) / stage-b-test-1-npu-a2 (1) (push) Has been cancelled
PR Test (NPU) / stage-b-test-2-npu-a2 (0) (push) Has been cancelled
PR Test (NPU) / stage-b-test-2-npu-a2 (1) (push) Has been cancelled
PR Test (NPU) / stage-b-test-4-npu-a3 (push) Has been cancelled
PR Test (NPU) / stage-b-test-16-npu-a3 (push) Has been cancelled
PR Test (NPU) / multimodal-gen-test-1-npu-a3 (push) Has been cancelled
PR Test (NPU) / multimodal-gen-test-2-npu-a3 (push) Has been cancelled
PR Test (Arm64) / pr-gate (push) Has been cancelled
PR Test (Arm64) / check-changes (push) Has been cancelled
PR Test (Arm64) / build-test (push) Has been cancelled
PR Test (sgl-router) / gate (push) Has been cancelled
PR Test (sgl-router) / tier-1 — lint (push) Has been cancelled
PR Test (sgl-router) / tier-2 — build + test (push) Has been cancelled
PR Test (sgl-router) / tier-3 — docker (placeholder) (push) Has been cancelled
PR Test (sgl-router) / tier-3 — k8s integration (push) Has been cancelled
PR Test (sgl-router) / tier-3 — e2e (push) Has been cancelled
PR Test (sgl-router) / finish (push) Has been cancelled
PR Test (NPU) / single-node-poc (map[name:qwen3_6_27b_w8a8_1p_in64k_out1k_50ms runner:linux-aarch64-a3-2 test_case:test/registered/ascend/performance/qwen3_6_27b/test_npu_qwen3_6_27b_w8a8_1p_in64k_out1k_50ms.py test_type:perf]) (push) Has been cancelled
PR Test (NPU) / pr-test-npu-finish (push) Has been cancelled
PR Test (Xeon) / pr-gate (push) Has been cancelled
PR Test (Xeon) / check-changes (push) Has been cancelled
PR Test (Xeon) / build-test (, xeon-gnr, base-b-test-cpu) (push) Has been cancelled
PR Test (XPU) / check-changes (push) Has been cancelled
PR Test (XPU) / pr-gate (push) Has been cancelled
PR Test (XPU) / stage-a-test-1-gpu-xpu (push) Has been cancelled
PR Test (XPU) / wait-for-stage-a (push) Has been cancelled
PR Test (XPU) / stage-b-test-1-gpu-xpu (push) Has been cancelled
PR Test (XPU) / finish (push) Has been cancelled
CI Model Inventory / build-inventory (push) Has been cancelled
Lint / lint (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark Compilation Check (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark - Manual Policy (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark - Request Processing (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark Summary (push) Has been cancelled
PR Test (SMG) / build-wheel (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on windows (x86_64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on macos (x86_64 - auto) (push) Has been cancelled
PR Test (SMG) / python-unit-tests (push) Has been cancelled
PR Test (SMG) / unit-tests (push) Has been cancelled
PR Test (SMG) / benchmarks (push) Has been cancelled
PR Test (SMG) / chat-completions (push) Has been cancelled
PR Test (SMG) / chat-completions-4gpu (push) Has been cancelled
PR Test (SMG) / e2e (push) Has been cancelled
PR Test (SMG) / docker-build-test (push) Has been cancelled
PR Test (SMG) / k8s-integration (push) Has been cancelled
PR Test (SMG) / finish (push) Has been cancelled
PR Test (SMG) / summarize-benchmarks (push) Has been cancelled
Release SGLang Model Gateway Docker Image / publish (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on macos (aarch64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (aarch64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (x86_64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (aarch64 - musllinux_1_1) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (x86_64 - musllinux_1_1) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / Build SDist (push) Has been cancelled
Release SGLang Model Gateway to PyPI / Upload to PyPI (push) Has been cancelled
Release SGLang Kernels / build-cu129-matrix (aarch64, 12.9, 3.10, arm-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / build-cu129-matrix (x86_64, 12.9, 3.10, x64-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / release-cu129 (push) Has been cancelled
Release SGLang Kernels / build-cu130-matrix (aarch64, 13.0, 3.10, arm-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / build-cu130-matrix (x86_64, 13.0, 3.10, x64-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / release-cu130 (push) Has been cancelled
Release SGLang Kernels / build-rocm-matrix (3.10, 700) (push) Has been cancelled
Release SGLang Kernels / build-rocm-matrix (3.10, 720) (push) Has been cancelled
Release SGLang Kernels / release-rocm700 (push) Has been cancelled
Release SGLang Kernels / release-rocm720 (push) Has been cancelled
Release SGLang Kernels / build-musa43 (43, 3.10) (push) Has been cancelled
Release SGLang Kernels / release-musa43 (push) Has been cancelled
522 lines
18 KiB
Python
522 lines
18 KiB
Python
import json
|
|
import os
|
|
import random
|
|
import string
|
|
|
|
import numpy as np
|
|
from PIL import Image
|
|
from transformers import AutoTokenizer
|
|
|
|
|
|
def load_jsonl(path):
|
|
"""Load data from a JSONL file, one JSON object per line."""
|
|
data = []
|
|
with open(path, "r", encoding="utf-8") as f:
|
|
for line in f:
|
|
line = line.strip()
|
|
if line:
|
|
data.append(json.loads(line))
|
|
return data
|
|
|
|
|
|
def save_jsonl(data, file_path):
|
|
"""Save a list of dicts to a JSONL file, one JSON object per line."""
|
|
file_dir = os.path.dirname(file_path)
|
|
if file_dir:
|
|
os.makedirs(file_dir, exist_ok=True)
|
|
with open(file_path, "w", encoding="utf-8") as f:
|
|
for item in data:
|
|
f.write(json.dumps(item, ensure_ascii=False) + "\n")
|
|
|
|
|
|
def format_qa(item):
|
|
"""Format a GSM8K data entry into QA text for the few-shot pool."""
|
|
question = item["question"]
|
|
answer = item["answer"]
|
|
return f"Question: {question}\nLet's think step by step\nAnswer:\n{answer}\n\n"
|
|
|
|
|
|
def pad_to_target_tokens(
|
|
question,
|
|
few_shot_pool_token_ids,
|
|
tokenizer,
|
|
target_tokens,
|
|
test_template="Question: {question}\nLet's think step by step\nAnswer:\n",
|
|
):
|
|
"""Pad a question text to the target token length.
|
|
|
|
Tokenizes the question using the test_template, calculates the remaining tokens
|
|
needed, and prepends randomly sampled few-shot token ids from the pool to reach
|
|
target_tokens. If the few-shot pool is insufficient, repeats the first sample
|
|
to fill the remaining gap.
|
|
|
|
Args:
|
|
question: The test question text.
|
|
few_shot_pool_token_ids: List of token id lists from the few-shot training pool.
|
|
tokenizer: The tokenizer instance.
|
|
target_tokens: Target input token length.
|
|
test_template: Question template string, defaults to GSM8K format.
|
|
"""
|
|
test_prompt = test_template.format(question=question)
|
|
test_token_ids = tokenizer.encode(test_prompt, add_special_tokens=False)
|
|
|
|
remaining_tokens = target_tokens - len(test_token_ids)
|
|
if remaining_tokens <= 0:
|
|
return tokenizer.decode(
|
|
test_token_ids[:target_tokens], skip_special_tokens=True
|
|
)
|
|
|
|
shuffled_ids = list(range(len(few_shot_pool_token_ids)))
|
|
random.shuffle(shuffled_ids)
|
|
|
|
prefix_ids = []
|
|
for idx in shuffled_ids:
|
|
fs_ids = few_shot_pool_token_ids[idx]
|
|
if len(prefix_ids) + len(fs_ids) <= remaining_tokens:
|
|
prefix_ids.extend(fs_ids)
|
|
else:
|
|
partial_gap = remaining_tokens - len(prefix_ids)
|
|
if partial_gap > 0:
|
|
prefix_ids.extend(fs_ids[:partial_gap])
|
|
break
|
|
|
|
if len(prefix_ids) < remaining_tokens and few_shot_pool_token_ids:
|
|
padding_source_ids = few_shot_pool_token_ids[shuffled_ids[0]]
|
|
repeat_count = (remaining_tokens // len(padding_source_ids)) + 1
|
|
padding_ids = (padding_source_ids * repeat_count)[
|
|
: remaining_tokens - len(prefix_ids)
|
|
]
|
|
prefix_ids.extend(padding_ids)
|
|
|
|
full_ids = prefix_ids + test_token_ids
|
|
return tokenizer.decode(full_ids[:target_tokens], skip_special_tokens=True)
|
|
|
|
|
|
def generate_custom_dataset(
|
|
train_path,
|
|
test_path,
|
|
tokenizer_path,
|
|
target_tokens,
|
|
num_prompts,
|
|
trust_remote_code=False,
|
|
test_template="Question: {question}\nLet's think step by step\nAnswer:\n",
|
|
):
|
|
"""Generate a custom dataset with a fixed input token length.
|
|
|
|
Builds a few-shot pool from the training set and pads test questions to the
|
|
specified token length. If the test set has fewer samples than num_prompts,
|
|
it cycles and repeats to fill the required count.
|
|
|
|
Args:
|
|
train_path: Path to the GSM8K training JSONL file.
|
|
test_path: Path to the GSM8K test JSONL file.
|
|
tokenizer_path: Path to the tokenizer.
|
|
target_tokens: Target input token length.
|
|
num_prompts: Number of prompts to generate; 0 means use all test samples.
|
|
trust_remote_code: Whether to trust remote code when loading the tokenizer.
|
|
test_template: Question template string.
|
|
|
|
Returns:
|
|
list[dict]: Each item contains fields defined in test_template.
|
|
"""
|
|
tokenizer = AutoTokenizer.from_pretrained(
|
|
tokenizer_path, trust_remote_code=trust_remote_code
|
|
)
|
|
|
|
train_data = load_jsonl(train_path)
|
|
test_data = load_jsonl(test_path)
|
|
if num_prompts > 0 and num_prompts > len(test_data):
|
|
multiplier = (num_prompts // len(test_data)) + 1
|
|
test_data = (test_data * multiplier)[:num_prompts]
|
|
elif num_prompts > 0:
|
|
test_data = test_data[:num_prompts]
|
|
|
|
few_shot_pool = [format_qa(item) for item in train_data]
|
|
few_shot_pool_token_ids = [
|
|
tokenizer.encode(fs, add_special_tokens=False) for fs in few_shot_pool
|
|
]
|
|
|
|
output_data = []
|
|
for i, test_item in enumerate(test_data):
|
|
padded_question = pad_to_target_tokens(
|
|
question=test_item["question"],
|
|
few_shot_pool_token_ids=few_shot_pool_token_ids,
|
|
tokenizer=tokenizer,
|
|
target_tokens=target_tokens,
|
|
test_template=test_template,
|
|
)
|
|
output_data.append(
|
|
{
|
|
"question": padded_question,
|
|
"answer": test_item["answer"],
|
|
}
|
|
)
|
|
if (i + 1) % 100 == 0:
|
|
actual_tokens = len(
|
|
tokenizer.encode(padded_question, add_special_tokens=False)
|
|
)
|
|
print(
|
|
f"Processed {i + 1}/{len(test_data)}, last item tokens: {actual_tokens}"
|
|
)
|
|
|
|
token_counts = [
|
|
len(tokenizer.encode(item["question"], add_special_tokens=False))
|
|
for item in output_data
|
|
]
|
|
print(
|
|
f"Token count stats: min={min(token_counts)}, max={max(token_counts)}, avg={sum(token_counts)/len(token_counts):.1f}"
|
|
)
|
|
|
|
return output_data
|
|
|
|
|
|
def generate_random_images(mm_dataset_data, size):
|
|
"""Generate random image files for a multimodal dataset.
|
|
|
|
Creates random RGB images at the specified resolution for each image path
|
|
listed in the dataset entries.
|
|
|
|
Args:
|
|
mm_dataset_data: List of multimodal data entries, each with a "path" field
|
|
containing a list of image file paths.
|
|
size: Image size tuple (width, height), e.g. (1080, 1920).
|
|
"""
|
|
total_image_num = len(mm_dataset_data)
|
|
print(f"begin to generate images, total {total_image_num}")
|
|
|
|
file_count = 0
|
|
for item in mm_dataset_data:
|
|
image_paths = item.get("path")
|
|
|
|
for image_path in image_paths:
|
|
if not image_path:
|
|
print("Error: The image path is none.")
|
|
continue
|
|
|
|
dir_name = os.path.dirname(image_path)
|
|
if dir_name and not os.path.exists(dir_name):
|
|
os.makedirs(dir_name, exist_ok=True)
|
|
|
|
random_array = np.random.randint(
|
|
0, 256, (size[1], size[0], 3), dtype=np.uint8
|
|
)
|
|
|
|
img = Image.fromarray(random_array)
|
|
img.save(image_path, quality=95)
|
|
if os.path.isfile(image_path):
|
|
file_count += 1
|
|
|
|
print(f"Finish images generation. Image num: {file_count}")
|
|
|
|
|
|
def generate_mm_dataset(
|
|
train_path,
|
|
test_path,
|
|
tokenizer_path,
|
|
target_tokens=3500,
|
|
num_prompts=1024,
|
|
trust_remote_code=False,
|
|
test_template="Question: {question}\nLet's think step by step\nAnswer:\n",
|
|
image_dir="/tmp/datasets/image",
|
|
size=None,
|
|
):
|
|
"""Generate a multimodal (text + image) dataset.
|
|
|
|
First generates fixed-length text data via generate_fixed_len_dataset, then
|
|
attaches random image paths and type labels to each entry, and generates
|
|
the corresponding random image files.
|
|
|
|
Args:
|
|
train_path: Path to the GSM8K training JSONL file.
|
|
test_path: Path to the GSM8K test JSONL file.
|
|
tokenizer_path: Path to the tokenizer.
|
|
target_tokens: Target input token length.
|
|
num_prompts: Number of prompts to generate.
|
|
trust_remote_code: Whether to trust remote code when loading the tokenizer.
|
|
test_template: Question template string.
|
|
image_dir: Directory to save generated image files.
|
|
size: Image size string in "widthxheight" format, e.g. "1080x1920".
|
|
|
|
Returns:
|
|
list[dict]: Each item contains "question", "answer", "type", and "path" fields.
|
|
"""
|
|
output_data = []
|
|
text_data = generate_custom_dataset(
|
|
train_path,
|
|
test_path,
|
|
tokenizer_path,
|
|
target_tokens,
|
|
num_prompts,
|
|
trust_remote_code,
|
|
test_template,
|
|
)
|
|
|
|
for item in text_data:
|
|
random_string = "".join(
|
|
random.choices(string.ascii_letters + string.digits, k=10)
|
|
)
|
|
item["type"] = "image"
|
|
item["path"] = [f"{image_dir}/{random_string}.jpg"]
|
|
output_data.append(item)
|
|
|
|
size = tuple(map(int, size.split("x")))
|
|
generate_random_images(output_data, size)
|
|
return output_data
|
|
|
|
|
|
def generate_gsm8k_dataset(
|
|
model_path, source_dataset_path, batch_size, input_len, output_file
|
|
):
|
|
"""Generate a dataset with a fixed input token length from GSM8K (JSONL format).
|
|
|
|
Reads GSM8K source data, repeats or truncates each question's tokens to input_len,
|
|
then trims or replicates the dataset to batch_size entries, shuffles, and writes
|
|
to the output file.
|
|
|
|
Args:
|
|
model_path: Model path used to load the tokenizer.
|
|
source_dataset_path: Path to the GSM8K source JSONL file.
|
|
batch_size: Number of samples to generate.
|
|
input_len: Target input token length.
|
|
output_file: Output JSONL file path.
|
|
"""
|
|
tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)
|
|
dataset = []
|
|
with open(source_dataset_path, "r", encoding="utf-8") as f:
|
|
for line in f:
|
|
data = json.loads(line)
|
|
dataset.append(data["question"])
|
|
|
|
dataset_new = []
|
|
for sentence in dataset:
|
|
words = tokenizer.tokenize(sentence)
|
|
len_num = len(words) // input_len
|
|
if len_num == 0:
|
|
multiplier = (input_len // len(words)) + 1
|
|
repeated_len = words * multiplier
|
|
words = repeated_len[:input_len]
|
|
decoded_text = tokenizer.convert_tokens_to_string(words)
|
|
if len(words) != input_len:
|
|
print(
|
|
f"Generate DataSet Error: the length of new input is {len(words)}, not {input_len}"
|
|
)
|
|
dataset_new.append(decoded_text)
|
|
|
|
batch_num = len(dataset_new) // batch_size
|
|
if batch_num == 0:
|
|
multiplier = (batch_size // len(dataset_new)) + 1
|
|
repeated_batch = dataset_new * multiplier
|
|
dataset_new = repeated_batch[:batch_size]
|
|
else:
|
|
dataset_new = dataset_new[:batch_size]
|
|
|
|
random.shuffle(dataset_new)
|
|
|
|
if len(dataset_new) != batch_size:
|
|
print(
|
|
f"Generate DataSet Error: the size of new dataset is {len(dataset_new)}, not {batch_size}"
|
|
)
|
|
|
|
output_dir = os.path.dirname(output_file)
|
|
if output_dir:
|
|
os.makedirs(output_dir, exist_ok=True)
|
|
|
|
with open(output_file, "w", encoding="utf-8") as f:
|
|
for i in range(len(dataset_new)):
|
|
f.write(
|
|
json.dumps(
|
|
{"question": f"{dataset_new[i]}", "answer": "none"},
|
|
ensure_ascii=False,
|
|
)
|
|
)
|
|
f.write("\n")
|
|
|
|
|
|
def generate_random_dataset(
|
|
model_path,
|
|
source_dataset_path,
|
|
batch_size,
|
|
input_len,
|
|
output_file,
|
|
output_len=1024,
|
|
range_ratio=1,
|
|
):
|
|
"""Generate a random dataset with logic matching bench_serving's --dataset-name random.
|
|
|
|
Samples real conversation text from the ShareGPT dataset as prompts, adjusting
|
|
to the target token length via truncation or repetition. Input/output lengths
|
|
are randomly sampled from [target*range_ratio, target]. Output format is a
|
|
JSON array compatible with ais_bench's ShareGPTDataset.
|
|
|
|
If source_dataset_path is not a valid JSON file, automatically downloads the
|
|
ShareGPT dataset from HuggingFace (anon8231489123/ShareGPT_Vicuna_unfiltered).
|
|
|
|
Args:
|
|
model_path: Model path used to load the tokenizer.
|
|
source_dataset_path: Path to the ShareGPT JSON file; auto-downloaded if invalid.
|
|
batch_size: Number of samples to generate.
|
|
input_len: Target input token length.
|
|
output_file: Output JSON file path.
|
|
output_len: Target output token length, default 1024.
|
|
range_ratio: Random range ratio for input/output lengths. Actual lengths are
|
|
uniformly sampled from [target*range_ratio, target]. Default 1 (fixed length).
|
|
"""
|
|
SHAREGPT_REPO_ID = "anon8231489123/ShareGPT_Vicuna_unfiltered"
|
|
SHAREGPT_FILENAME = "ShareGPT_V3_unfiltered_cleaned_split.json"
|
|
|
|
def _is_file_valid_json(path):
|
|
"""Check if the path points to a valid JSON file (exists and parseable)."""
|
|
if not os.path.isfile(path):
|
|
return False
|
|
try:
|
|
with open(path, encoding="utf-8") as f:
|
|
json.load(f)
|
|
return True
|
|
except json.JSONDecodeError:
|
|
return False
|
|
|
|
def _download_and_cache_hf_file(repo_id, filename, repo_type="dataset"):
|
|
"""Download and cache a file from HuggingFace Hub."""
|
|
from huggingface_hub import hf_hub_download
|
|
|
|
return hf_hub_download(repo_id=repo_id, filename=filename, repo_type=repo_type)
|
|
|
|
tokenizer = AutoTokenizer.from_pretrained(model_path)
|
|
|
|
# Randomly sample input/output lengths per request in [target*range_ratio, target]
|
|
input_lens = np.random.randint(
|
|
max(int(input_len * range_ratio), 1),
|
|
input_len + 1,
|
|
size=batch_size,
|
|
).tolist()
|
|
output_lens = np.random.randint(
|
|
max(int(output_len * range_ratio), 1),
|
|
output_len + 1,
|
|
size=batch_size,
|
|
).tolist()
|
|
|
|
# Subtract special tokens to ensure the actual encoded length does not exceed target
|
|
num_special_tokens = int(tokenizer.num_special_tokens_to_add())
|
|
for i in range(batch_size):
|
|
input_lens[i] = max(1, input_lens[i] - num_special_tokens)
|
|
|
|
# Auto-download ShareGPT dataset from HuggingFace if local file is invalid
|
|
if not _is_file_valid_json(source_dataset_path):
|
|
print(
|
|
f"source_dataset_path '{source_dataset_path}' is not a valid file, downloading from HuggingFace..."
|
|
)
|
|
source_dataset_path = _download_and_cache_hf_file(
|
|
repo_id=SHAREGPT_REPO_ID,
|
|
filename=SHAREGPT_FILENAME,
|
|
)
|
|
|
|
# Load ShareGPT dataset, filter for >=2 turns, take the first turn (human) as prompt
|
|
with open(source_dataset_path, "r", encoding="utf-8") as f:
|
|
dataset = json.load(f)
|
|
|
|
dataset = [
|
|
data
|
|
for data in dataset
|
|
if len(data.get("conversations", data.get("conversation", []))) >= 2
|
|
]
|
|
dataset = [
|
|
(
|
|
data.get("conversations", data.get("conversation", []))[0]["value"],
|
|
data.get("conversations", data.get("conversation", []))[1]["value"],
|
|
)
|
|
for data in dataset
|
|
]
|
|
random.shuffle(dataset)
|
|
|
|
# Sample prompts, truncating or repeating tokens to reach target input length
|
|
input_requests = []
|
|
for data in dataset:
|
|
i = len(input_requests)
|
|
if i == batch_size:
|
|
break
|
|
|
|
prompt = data[0]
|
|
prompt_token_ids = tokenizer.encode(prompt)
|
|
prompt_len = len(prompt_token_ids)
|
|
|
|
if prompt_len == 0:
|
|
continue
|
|
|
|
if prompt_len > input_lens[i]:
|
|
input_ids = prompt_token_ids[: input_lens[i]]
|
|
else:
|
|
ratio = (input_lens[i] + prompt_len - 1) // prompt_len
|
|
input_ids = (prompt_token_ids * ratio)[: input_lens[i]]
|
|
input_content = tokenizer.decode(input_ids)
|
|
# Output format compatible with ais_bench ShareGPTDataset
|
|
input_requests.append(
|
|
{
|
|
"id": str(i),
|
|
"conversations": [
|
|
{"from": "human", "value": input_content},
|
|
{"from": "gpt", "value": "none"},
|
|
],
|
|
}
|
|
)
|
|
|
|
print(f"#Input tokens: {np.sum(input_lens[:len(input_requests)])}")
|
|
print(f"#Output tokens: {np.sum(output_lens[:len(input_requests)])}")
|
|
|
|
output_dir = os.path.dirname(output_file)
|
|
if output_dir:
|
|
os.makedirs(output_dir, exist_ok=True)
|
|
|
|
# Output as JSON array format, compatible with ais_bench's json.load()
|
|
with open(output_file, "w", encoding="utf-8") as f:
|
|
json.dump(input_requests, f, ensure_ascii=False, indent=2)
|
|
|
|
|
|
def main():
|
|
import argparse
|
|
|
|
parser = argparse.ArgumentParser(
|
|
description="Generate GSM8K dataset with exact input token length"
|
|
)
|
|
parser.add_argument(
|
|
"--train_path", type=str, required=True, help="Path to GSM8K train.jsonl"
|
|
)
|
|
parser.add_argument(
|
|
"--test_path", type=str, required=True, help="Path to GSM8K test.jsonl"
|
|
)
|
|
parser.add_argument(
|
|
"--output_path", type=str, required=True, help="Output jsonl path"
|
|
)
|
|
parser.add_argument(
|
|
"--tokenizer_path", type=str, required=True, help="Path to model tokenizer"
|
|
)
|
|
parser.add_argument(
|
|
"--target_tokens", type=int, default=3500, help="Target input token length"
|
|
)
|
|
parser.add_argument(
|
|
"--trust_remote_code",
|
|
action="store_true",
|
|
help="Trust remote code for tokenizer",
|
|
)
|
|
parser.add_argument(
|
|
"--num_prompts",
|
|
type=int,
|
|
default=0,
|
|
help="Number of prompts to generate, 0 means all",
|
|
)
|
|
args = parser.parse_args()
|
|
|
|
output_data = generate_custom_dataset(
|
|
train_path=args.train_path,
|
|
test_path=args.test_path,
|
|
tokenizer_path=args.tokenizer_path,
|
|
target_tokens=args.target_tokens,
|
|
num_prompts=args.num_prompts,
|
|
trust_remote_code=args.trust_remote_code,
|
|
)
|
|
save_jsonl(output_data, args.output_path)
|
|
print(f"Done! Output {len(output_data)} items to {args.output_path}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|