Skip to content

Commit a5d2ff7

Browse files
committed
update
1 parent d69af13 commit a5d2ff7

File tree

8 files changed

+216
-61
lines changed

8 files changed

+216
-61
lines changed

fastchat/serve/monitor/basic_stats.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,13 @@
1616
LOG_ROOT_DIR = "~/fastchat_logs"
1717

1818

19-
def get_log_files(max_num_files=None):
19+
def get_log_files(max_num_files=None, is_vision=False):
2020
log_root = os.path.expanduser(LOG_ROOT_DIR)
2121
filenames = []
2222
for i in range(NUM_SERVERS):
2323
for filename in os.listdir(f"{log_root}/server{i}"):
24+
if is_vision and not filename.startswith("vision-"):
25+
continue
2426
if filename.endswith("-conv.json"):
2527
filepath = f"{log_root}/server{i}/{filename}"
2628
name_tstamp_tuple = (filepath, os.path.getmtime(filepath))
@@ -39,7 +41,12 @@ def load_log_files(filename):
3941
for retry in range(5):
4042
try:
4143
for l in open(filename):
42-
row = json.loads(l)
44+
try:
45+
row = json.loads(l)
46+
except json.decoder.JSONDecodeError:
47+
print(f"JSONDecodeError: {l}")
48+
continue
49+
4350
data.append(
4451
dict(
4552
type=row["type"],
@@ -232,9 +239,11 @@ def report_basic_stats(log_files):
232239
if __name__ == "__main__":
233240
parser = argparse.ArgumentParser()
234241
parser.add_argument("--max-num-files", type=int)
242+
parser.add_argument("--vision", action="store_true")
243+
235244
args = parser.parse_args()
236245

237-
log_files = get_log_files(args.max_num_files)
246+
log_files = get_log_files(args.max_num_files, args.vision)
238247
basic_stats = report_basic_stats(log_files)
239248

240249
print(basic_stats["action_hist_md"] + "\n")

fastchat/serve/monitor/clean_battle_data.py

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,22 @@ def replace_model_name(old_name, tstamp):
130130
"im-also-a-late-june-chatbot": "gemma-2-9b-it",
131131
"gemini-test-1": "gemini-1.5-pro-exp-0801",
132132
"gemini-test-2": "gemini-1.5-pro-exp-0801",
133-
"anonymous-chatbot": "chatgpt-4o-latest",
133+
"anonymous-chatbot": "chatgpt-4o-latest-20240808",
134134
"toto-mini": "jamba-1.5-mini",
135135
"toto-medium": "jamba-1.5-large",
136+
"gemini-test-3": "gemini-1.5-pro-exp-0827",
137+
"engine-test": "gemini-1.5-flash-exp-0827",
138+
"little-engine-test": "gemini-1.5-flash-8b-exp-0827",
139+
"chatgpt-4o-latest": "chatgpt-4o-latest-20240808",
140+
"anonymous-chatbot-0903": "chatgpt-4o-latest-20240903",
141+
"the-real-chatbot-v1": "llama-3.1-405b-instruct-bf16",
142+
"llama-3.1-405b-instruct": "llama-3.1-405b-instruct-fp8",
143+
"gemini-test-5": "gemini-1.5-pro-002-test",
144+
"dumbledore-v3": "llama-3.2-vision-90b-instruct",
145+
"potter-v1": "llama-3.2-vision-11b-instruct",
146+
"sharp-game-player-v1": "llama-3.2-3b-instruct",
147+
"zeus-flare-thunder-v1": "llama-3.2-1b-instruct",
148+
"qwen-vl-max-0809": "qwen2-vl-72b",
136149
}
137150
if old_name in ["gpt-4", "gpt-3.5-turbo"]:
138151
if tstamp > 1687849200:
@@ -166,7 +179,7 @@ def replace_model_name(old_name, tstamp):
166179
if old_name == "deepseek-coder-v2" and tstamp > 1721663428:
167180
return "deepseek-coder-v2-0724"
168181
if old_name == "meta-llama-3.1-405b-instruct" and tstamp > 1721847659:
169-
return "llama-3.1-405b-instruct"
182+
return "llama-3.1-405b-instruct-fp8"
170183
if old_name == "meta-llama-3.1-70b-instruct-sp" and tstamp > 1721847659:
171184
return "llama-3.1-70b-instruct"
172185
if old_name == "meta-llama-3.1-8b-instruct-sp" and tstamp > 1721847659:
@@ -185,8 +198,12 @@ def read_file(filename, vision=False):
185198
for retry in range(5):
186199
try:
187200
# lines = open(filename).readlines()
188-
for l in open(filename):
189-
row = json.loads(l)
201+
for i, l in enumerate(open(filename)):
202+
try:
203+
row = json.loads(l)
204+
except json.JSONDecodeError as e:
205+
print(f"JSON Decode Error in file {filename} line {i}")
206+
continue
190207
if row["type"] in VOTES:
191208
data.append(row)
192209
break
@@ -225,6 +242,7 @@ def process_data(
225242
count_dict = {
226243
"anony": 0,
227244
"invalid": 0,
245+
"encoding_invalid": 0,
228246
"leaked_identity": 0,
229247
"banned": 0,
230248
"error": 0,
@@ -312,6 +330,13 @@ def process_data(
312330
else:
313331
flag_none_msg = True
314332

333+
# test if message string can be encoded to utf-8
334+
try:
335+
messages.encode("utf-8")
336+
except:
337+
count_dict["encoding_invalid"] += 1
338+
continue
339+
315340
if vision != flag_vision:
316341
count_dict["invalid"] += 1
317342
continue
@@ -353,7 +378,7 @@ def process_data(
353378
if exclude_model_names:
354379
exclude = False
355380
for exclude_model in exclude_model_names:
356-
if exclude_model in models[0] or exclude_model in models[1]:
381+
if models[0] == exclude_model or models[1] == exclude_model:
357382
count_dict["exclude_model"] += 1
358383
exclude = True
359384
break

fastchat/serve/monitor/clean_chat_data.py

Lines changed: 59 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
import os
1111
from pytz import timezone
1212
import time
13+
import pandas as pd
14+
import tiktoken
1315

1416
from tqdm import tqdm
1517

@@ -26,16 +28,20 @@
2628
)
2729

2830

29-
def get_log_files(max_num_files=None):
31+
def get_log_files(max_num_files=None, is_vision=False):
3032
dates = []
31-
for month in range(4, 12):
32-
for day in range(1, 33):
33-
dates.append(f"2023-{month:02d}-{day:02d}")
33+
for year in range(2023, 2025):
34+
for month in range(1, 13):
35+
for day in range(1, 33):
36+
dates.append(f"{year}-{month:02d}-{day:02d}")
3437

3538
filenames = []
3639
for d in dates:
3740
for i in range(NUM_SERVERS):
38-
name = os.path.expanduser(f"~/fastchat_logs/server{i}/{d}-conv.json")
41+
prefix = ""
42+
if is_vision:
43+
prefix = "vision-tmp-"
44+
name = os.path.expanduser(f"~/fastchat_logs/server{i}/{prefix}{d}-conv.json")
3945
if os.path.exists(name):
4046
filenames.append(name)
4147
max_num_files = max_num_files or len(filenames)
@@ -44,7 +50,8 @@ def get_log_files(max_num_files=None):
4450
return filenames
4551

4652

47-
def clean_chat_data(log_files, action_type):
53+
def clean_chat_data(log_files, action_type, remove_prompt=False):
54+
encoding = tiktoken.encoding_for_model("gpt-3.5-turbo")
4855
raw_data = []
4956
for filename in tqdm(log_files, desc="read files"):
5057
for retry in range(5):
@@ -65,11 +72,15 @@ def clean_chat_data(log_files, action_type):
6572
ct_invalid_conv_id = 0
6673
ct_invalid = 0
6774
ct_network_error = 0
75+
ct_img_chat = 0
76+
ct_csam = 0
6877
for row in raw_data:
6978
try:
7079
if action_type in ["chat", "upvote", "downvote"]:
7180
state = row["state"]
7281
model = row["model"]
82+
if state.get("has_csam_image", False):
83+
ct_csam += 1
7384
elif action_type == "leftvote":
7485
state = row["states"][0]
7586
model = row["states"][0]["model_name"]
@@ -92,17 +103,31 @@ def clean_chat_data(log_files, action_type):
92103
model = replace_model_name(model, row["tstamp"])
93104

94105
try:
95-
lang_code = detect_language(state["messages"][state["offset"]][1])
96-
except IndexError:
106+
msg = state["messages"][state["offset"]][1]
107+
if isinstance(msg, list):
108+
ct_img_chat += 1
109+
msg = msg[0]
110+
lang_code = detect_language(msg)
111+
if not all(isinstance(x["content"][0], str) for x in conversation):
112+
ct_invalid += 1
113+
except (IndexError, TypeError):
97114
ct_invalid += 1
98115
continue
99116

100-
if not all(isinstance(x["content"], str) for x in conversation):
101-
ct_invalid += 1
102-
continue
117+
# add token length
118+
messages_concat = ""
119+
for x in conversation:
120+
msg = x["content"]
121+
if isinstance(x["content"], list):
122+
msg = x["content"][0]
123+
x["num_tokens"] = len(
124+
encoding.encode(msg, allowed_special="all")
125+
)
126+
messages_concat += msg.lower()
103127

104-
messages = "".join([x["content"] for x in conversation]).lower()
105-
if NETWORK_ERROR_MSG in messages:
128+
if remove_prompt:
129+
x.pop("content")
130+
if NETWORK_ERROR_MSG in messages_concat:
106131
ct_network_error += 1
107132
continue
108133

@@ -141,10 +166,10 @@ def clean_chat_data(log_files, action_type):
141166
dedup_chats.append(chats[i])
142167

143168
print(
144-
f"#raw: {len(raw_data)}, #chat: {len(chats)}, #dedup_chat: {len(dedup_chats)}"
169+
f"#raw: {len(raw_data)}, #chat: {len(chats)}, #dedup_chat: {len(dedup_chats)}, #csam: {ct_csam}"
145170
)
146171
print(
147-
f"#invalid_conv_id: {ct_invalid_conv_id}, #network_error: {ct_network_error}, #invalid: {ct_invalid}"
172+
f"#invalid_conv_id: {ct_invalid_conv_id}, #network_error: {ct_network_error}, #invalid: {ct_invalid}, #img-chat: {ct_img_chat}"
148173
)
149174
print(f"#models: {len(all_models)}, {all_models}")
150175
print(f"last-updated: {last_updated_datetime}")
@@ -156,16 +181,30 @@ def clean_chat_data(log_files, action_type):
156181
parser = argparse.ArgumentParser()
157182
parser.add_argument("--action-type", type=str, default="chat")
158183
parser.add_argument("--max-num-files", type=int)
184+
parser.add_argument("--vision", action="store_true")
185+
parser.add_argument("--start-time", type=str) # example: 2024-08-01
186+
parser.add_argument("--end-time", type=str) # example: 2024-08-01
187+
parser.add_argument("--remove-prompt", action="store_true")
159188
args = parser.parse_args()
160189

161-
log_files = get_log_files(args.max_num_files)
162-
chats = clean_chat_data(log_files, args.action_type)
163-
last_updated_tstamp = chats[-1]["tstamp"]
190+
log_files = get_log_files(args.max_num_files, args.vision)
191+
# print(log_files)
192+
chats = clean_chat_data(log_files, args.action_type, args.remove_prompt)
193+
print(len(chats))
194+
# convert to dataframe
195+
chats = pd.DataFrame(chats)
196+
if args.start_time is not None:
197+
chats = chats[pd.to_datetime(chats["tstamp"], unit="s") >= pd.to_datetime(args.start_time)]
198+
chats = chats[pd.to_datetime(chats["tstamp"], unit='s') < pd.to_datetime(args.end_time)]
199+
print(len(chats))
200+
201+
last_updated_tstamp = chats.iloc[-1]["tstamp"]
164202
cutoff_date = datetime.datetime.fromtimestamp(
165203
last_updated_tstamp, tz=timezone("US/Pacific")
166204
).strftime("%Y%m%d")
167205

168206
output = f"clean_{args.action_type}_conv_{cutoff_date}.json"
169-
with open(output, "w") as fout:
170-
json.dump(chats, fout, indent=2, ensure_ascii=False)
207+
# with open(output, "w") as fout:
208+
# json.dump(chats, fout, indent=2, ensure_ascii=False)
209+
chats.to_json(output, orient="records", indent=2, force_ascii=False)
171210
print(f"Write cleaned data to {output}")

fastchat/serve/monitor/dataset_release_scripts/lmsys_chat_1m/compute_stats.py

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import plotly.express as px
1616
import plotly.graph_objects as go
1717
from tqdm import tqdm
18+
import tiktoken
1819

1920
import plotly.io as pio
2021

@@ -91,11 +92,16 @@ def to_remove(x):
9192
fig.show()
9293
fig.write_image("daily_conversation_count.pdf")
9394

94-
import transformers
95+
# import transformers
9596

96-
tokenizer = transformers.AutoTokenizer.from_pretrained(
97-
"lmsys/vicuna-7b-v1.5", use_fast=False
98-
)
97+
# tokenizer = transformers.AutoTokenizer.from_pretrained(
98+
# "lmsys/vicuna-7b-v1.5", use_fast=False
99+
# )
100+
101+
def num_tokens_from_string(string: str) -> int:
102+
encoding = tiktoken.encoding_for_model("gpt-4")
103+
num_tokens = len(encoding.encode(string))
104+
return num_tokens
99105

100106
prompts = []
101107
responses = []
@@ -110,10 +116,25 @@ def to_remove(x):
110116
print(f"#responses: {len(responses)}")
111117

112118

113-
prompt_lens = [len(tokenizer(x).input_ids) for x in tqdm(prompts)]
114-
print()
115-
print(f"mean prompt len: {np.mean(prompt_lens):.2f}")
119+
prompt_lens = []
120+
response_lens = []
121+
for x in tqdm(prompts):
122+
try:
123+
if isinstance(x, list):
124+
x = x[0]
125+
prompt_lens.append(num_tokens_from_string(x))
126+
except Exception as e:
127+
print(f"Error processing prompt: {e}")
128+
print(x)
129+
130+
for x in tqdm(responses):
131+
try:
132+
if isinstance(x, list):
133+
x = x[0]
134+
response_lens.append(num_tokens_from_string(x))
135+
except Exception as e:
136+
print(f"Error processing prompt: {e}")
137+
print(x)
116138

117-
response_lens = [len(tokenizer(x).input_ids) if x else 0 for x in tqdm(responses)]
118-
print()
139+
print(f"mean prompt len: {np.mean(prompt_lens):.2f}")
119140
print(f"mean response len: {np.mean(response_lens):.2f}")

0 commit comments

Comments
 (0)