Files
2026-07-13 12:24:33 +08:00

144 lines
3.8 KiB
Python

# SPDX-License-Identifier: Apache-2.0
# Standard
import argparse
import json
import os
# Third Party
from tqdm import tqdm
from transformers import AutoTokenizer
import numpy as np
_tokenizer: AutoTokenizer | None = None
def estimate_num_tokens(text: str) -> int:
global _tokenizer
if _tokenizer is None:
os.environ["TOKENIZERS_PARALLELISM"] = "false"
_tokenizer = AutoTokenizer.from_pretrained(args.model)
return len(_tokenizer.tokenize(text))
def is_human(human):
return human in ["human", "user"]
def is_gpt(gpt):
return gpt in ["gpt", "chatgpt", "bing", "bard"]
def is_system(system):
return system in ["system"]
def invalid_conversations(conversations):
# pair does not match
if len(conversations) < 2:
return True
# starting from gpt or systems
entry = conversations[0]
if is_gpt(entry["from"]) or is_system(entry["from"]):
return True
# ending with human
entry = conversations[-1]
if is_human(entry["from"]):
return True
prev_from = None
total_tokens = 0
for conv in conversations:
_from = conv["from"]
total_tokens += estimate_num_tokens(conv["value"])
# consecutive rounds (gpt followed by gpt, human followed by human, ..)
if prev_from == _from:
return True
# too long conversations
if total_tokens > (128 * 1024):
return True
# unknown from
if not is_human(_from) and not is_gpt(_from) and not is_system(_from):
return True
prev_from = _from
return False
parser = argparse.ArgumentParser(description="Process data percentage.")
parser.add_argument(
"--parse",
type=float,
default=1,
help="The percentage of data to process (0 to 1). Default is 1 (100%).",
)
parser.add_argument(
"--model",
type=str,
default="mistralai/Mistral-7B-Instruct-v0.2",
help="Model for tokenizer. Default is mistralai/Mistral-7B-Instruct-v0.2.",
)
parser.add_argument(
"--trace",
type=str,
default="ShareGPT_V3_unfiltered_cleaned_split.json",
help="Trace file. Default is ShareGPT_V3_unfiltered_cleaned_split.json",
)
args = parser.parse_args()
print("Loading trace file..")
with open(args.trace, "r", encoding="utf-8") as file:
data = json.load(file)
num_of_ids = len(data)
print(f"Number of IDs: {num_of_ids}")
# exclude invalid data
print("Veryfing trace..")
data = [d for d in tqdm(data) if not invalid_conversations(d["conversations"])]
excluded_ids = len(data)
num_of_ids -= excluded_ids
print(f"Excluded number of IDs: {excluded_ids}")
data_to_process = int(num_of_ids * args.parse)
data = data[:data_to_process]
print(f"Data to process: {data_to_process}")
for d in tqdm(data):
conversations = d["conversations"]
d["num_round"] = len(conversations) # human is one round, gpt is another round
human_tokens = []
gpt_tokens = []
for conv in conversations:
num_tokens = estimate_num_tokens(conv["value"])
if is_human(conv["from"]):
human_tokens.append(num_tokens)
elif is_gpt(conv["from"]):
conv["num_tokens"] = num_tokens
gpt_tokens.append(num_tokens)
else:
print("Invalid _from_")
if len(human_tokens) == 0:
d["average_human_token"] = 0
d["max_human_token"] = 0
else:
d["average_human_token"] = float(np.mean(human_tokens))
d["max_human_token"] = float(np.max(human_tokens))
if len(gpt_tokens) == 0:
d["average_gpt_token"] = 0
d["max_gpt_token"] = 0
else:
d["average_gpt_token"] = float(np.mean(gpt_tokens))
d["max_gpt_token"] = float(np.max(gpt_tokens))
with open("ShareGPT.json", "w", encoding="utf-8") as file:
json.dump(data, file, ensure_ascii=False, indent=2)