Upload 2 files
Browse files- .gitattributes +1 -0
- app.py +229 -0
- moss-dpo-47k-comparison-inference.xlsx +3 -0
.gitattributes
CHANGED
|
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
moss-dpo-47k-comparison-inference.xlsx filter=lfs diff=lfs merge=lfs -text
|
app.py
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import openai
|
| 2 |
+
import tiktoken
|
| 3 |
+
|
| 4 |
+
import numpy as np
|
| 5 |
+
import concurrent
|
| 6 |
+
import collections
|
| 7 |
+
import threading
|
| 8 |
+
import datetime
|
| 9 |
+
import time
|
| 10 |
+
import pytz
|
| 11 |
+
import json
|
| 12 |
+
import os
|
| 13 |
+
|
| 14 |
+
openai.api_key = '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'
|
| 15 |
+
os.environ["access_key"] = "key"
|
| 16 |
+
|
| 17 |
+
timezone = pytz.timezone('Asia/Shanghai')
|
| 18 |
+
timestamp2string = lambda timestamp: datetime.datetime.fromtimestamp(timestamp).astimezone(timezone).strftime('%Y-%m-%d %H:%M:%S')
|
| 19 |
+
|
| 20 |
+
def num_tokens_from_messages(messages, model="gpt-3.5-turbo"):
|
| 21 |
+
"""Returns the number of tokens used by a list of messages."""
|
| 22 |
+
try:
|
| 23 |
+
encoding = tiktoken.encoding_for_model(model)
|
| 24 |
+
except KeyError:
|
| 25 |
+
encoding = tiktoken.get_encoding("cl100k_base")
|
| 26 |
+
if model == "gpt-3.5-turbo": # note: future models may deviate from this
|
| 27 |
+
num_tokens = 0
|
| 28 |
+
len_values = 0
|
| 29 |
+
for message in messages:
|
| 30 |
+
num_tokens += 4 # every message follows <im_start>{role/name}\n{content}<im_end>\n
|
| 31 |
+
for key, value in message.items():
|
| 32 |
+
try:
|
| 33 |
+
num_tokens += len(encoding.encode(value))
|
| 34 |
+
except:
|
| 35 |
+
num_tokens += int(num_tokens/len_values*len(value)) # linear estimation
|
| 36 |
+
len_values += len(value)
|
| 37 |
+
if key == "name": # if there's a name, the role is omitted
|
| 38 |
+
num_tokens += -1 # role is always required and always 1 token
|
| 39 |
+
num_tokens += 2 # every reply is primed with <im_start>assistant
|
| 40 |
+
return num_tokens
|
| 41 |
+
else:
|
| 42 |
+
raise NotImplementedError(f"""num_tokens_from_messages() is not presently implemented for model {model}.
|
| 43 |
+
See https://github.com/openai/openai-python/blob/main/chatml.md for information on how messages are converted to tokens.""")
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
def read_tasks(cache_file="qas-5000.json"):
|
| 47 |
+
#from make_qas import input_dir
|
| 48 |
+
from make_qas_comparison import input_dir
|
| 49 |
+
file = f"{input_dir}/qas.json"
|
| 50 |
+
with open(file, "r", encoding="utf-8") as f:
|
| 51 |
+
qas = json.loads(f.read())
|
| 52 |
+
if cache_file is not None:
|
| 53 |
+
with open(cache_file, "r", encoding="utf-8") as f:
|
| 54 |
+
cache_qas = json.loads(f.read())
|
| 55 |
+
cache_q2a = {qa["q"]:qa["a"] for qa in cache_qas}
|
| 56 |
+
else:
|
| 57 |
+
cache_q2a = {}
|
| 58 |
+
qs = [qa["q"] for qa in qas if qa["a"] is None and qa["q"] not in cache_q2a] # 还未请求处理的queries
|
| 59 |
+
qas = [{"q":qa["q"], "a":qa["a"] if qa["a"] is not None else cache_q2a[qa["q"]]}
|
| 60 |
+
for qa in qas if qa["a"] is not None or qa["q"] in cache_q2a] # 已经完成请求处理的queries
|
| 61 |
+
print(f"read {len(qs)} queries without responses from {file} or {cache_file}")
|
| 62 |
+
print(f"read {len(qas)} queries with responses from {file} or {cache_file}")
|
| 63 |
+
return qs, qas
|
| 64 |
+
|
| 65 |
+
qs, qas = read_tasks()
|
| 66 |
+
start_time = time.time()
|
| 67 |
+
num_read_qas = len(qas)
|
| 68 |
+
|
| 69 |
+
def ask(query, timeout=600):
|
| 70 |
+
answer = None
|
| 71 |
+
dead_time = time.time() + timeout
|
| 72 |
+
attempt_times = 0
|
| 73 |
+
while answer is None and time.time()<dead_time and attempt_times<10:
|
| 74 |
+
try:
|
| 75 |
+
messages=[
|
| 76 |
+
{"role": "user", "content": query}
|
| 77 |
+
]
|
| 78 |
+
if num_tokens_from_messages(messages)>4096:
|
| 79 |
+
return None
|
| 80 |
+
answer = openai.ChatCompletion.create(
|
| 81 |
+
model="gpt-3.5-turbo-0301",
|
| 82 |
+
messages=messages,
|
| 83 |
+
temperature=0.1,
|
| 84 |
+
)["choices"][0]["message"]["content"]
|
| 85 |
+
except Exception as e:
|
| 86 |
+
if time.time()<dead_time:
|
| 87 |
+
print(e)
|
| 88 |
+
if "Please reduce the length of the messages." in str(e):
|
| 89 |
+
return None
|
| 90 |
+
else:
|
| 91 |
+
attempt_times += 1
|
| 92 |
+
wait_time = int(attempt_times*10)
|
| 93 |
+
time.sleep(wait_time)
|
| 94 |
+
print(f"retry in {attempt_times*10} seconds...")
|
| 95 |
+
return answer
|
| 96 |
+
|
| 97 |
+
|
| 98 |
+
def askingChatGPT(qs, qas, min_interval_seconds=3, max_interval_seconds=15, max_retry_times=3):
|
| 99 |
+
|
| 100 |
+
history_elapsed_time = [max_interval_seconds]*10
|
| 101 |
+
for i, q in enumerate(qs):
|
| 102 |
+
ask_start_time = time.time()
|
| 103 |
+
|
| 104 |
+
# 最直接的方法,调用ask函数,但可能因为超时等原因阻塞住
|
| 105 |
+
#a = ask(q)
|
| 106 |
+
|
| 107 |
+
# 下面是我之前设计的一系列,超时->重试,的方法
|
| 108 |
+
def ask_(q, timeout):
|
| 109 |
+
executor = concurrent.futures.ThreadPoolExecutor()
|
| 110 |
+
future = executor.submit(ask, q, timeout) # 提交函数调用任务
|
| 111 |
+
try:
|
| 112 |
+
a = future.result(timeout=timeout) # 等待函数调用任务完成,超时时间为30秒
|
| 113 |
+
return a
|
| 114 |
+
except concurrent.futures.TimeoutError:
|
| 115 |
+
print(f"ask call timed out after {timeout:.2f} seconds, retrying...")
|
| 116 |
+
executor.shutdown(wait=False)
|
| 117 |
+
return ask_(q, timeout*2) # 当超时时,重新调用函数
|
| 118 |
+
|
| 119 |
+
retry_times = 0
|
| 120 |
+
a = None
|
| 121 |
+
while a is None and retry_times<max_retry_times:
|
| 122 |
+
a = ask_(q, timeout=max(max_interval_seconds,np.mean(sorted(history_elapsed_time)[:8])))
|
| 123 |
+
retry_times += 1
|
| 124 |
+
|
| 125 |
+
qas.append({"q":q, "a":a})
|
| 126 |
+
|
| 127 |
+
ask_end_time = time.time()
|
| 128 |
+
elapsed_time = ask_end_time - ask_start_time
|
| 129 |
+
history_elapsed_time = history_elapsed_time[1:] + [elapsed_time]
|
| 130 |
+
delayTime = min_interval_seconds - elapsed_time
|
| 131 |
+
if delayTime>0:
|
| 132 |
+
time.sleep(delayTime)
|
| 133 |
+
|
| 134 |
+
print(f"{timestamp2string(time.time())}: iterations: {i+1} / {len(qs)} | elapsed time of this query (s): {elapsed_time:.2f}")
|
| 135 |
+
|
| 136 |
+
return
|
| 137 |
+
|
| 138 |
+
|
| 139 |
+
thread = threading.Thread(target=lambda :askingChatGPT(qs, qas))
|
| 140 |
+
thread.daemon = True
|
| 141 |
+
thread.start()
|
| 142 |
+
|
| 143 |
+
|
| 144 |
+
import gradio as gr
|
| 145 |
+
|
| 146 |
+
|
| 147 |
+
def showcase(access_key):
|
| 148 |
+
if not access_key==os.getenv('access_key'):
|
| 149 |
+
chatbot_ret = [(f"Your entered Access Key:<br>{access_key}<br>is incorrect.", f"So i cannot provide you any information in this private space.")]
|
| 150 |
+
else:
|
| 151 |
+
recent_qas = qas[-10:]
|
| 152 |
+
chatbot_ret = [(f"Your entered Access Key is correct.", f"The latest {len(recent_qas)} query-responses are displayed below.")]
|
| 153 |
+
for qa in recent_qas:
|
| 154 |
+
chatbot_ret += [(qa["q"].replace("\n","<br>"), str(qa["a"]).replace("\n","<br>"))]
|
| 155 |
+
return chatbot_ret
|
| 156 |
+
|
| 157 |
+
|
| 158 |
+
def download(access_key):
|
| 159 |
+
if not access_key.startswith(os.getenv('access_key')):
|
| 160 |
+
chatbot_ret = [(f"Your entered Access Key:<br>{access_key}<br>is incorrect.", f"So i cannot provide you any information in this private space.")]
|
| 161 |
+
file_ret = gr.File.update(value=None, visible=False)
|
| 162 |
+
else:
|
| 163 |
+
chatbot_ret = [(f"Your entered Access Key is correct.", f"The file containing all processed query-responses ({len(qas)} in total) can be downloaded below.")]
|
| 164 |
+
from make_qas import input_dir
|
| 165 |
+
filename = f"{input_dir}/qas-{len(qas)}.json"
|
| 166 |
+
with open(filename, "w", encoding="utf-8") as f:
|
| 167 |
+
f.write(json.dumps(qas, ensure_ascii=False, indent=4))
|
| 168 |
+
file_ret = gr.File.update(value=filename, visible=True)
|
| 169 |
+
return chatbot_ret, file_ret
|
| 170 |
+
|
| 171 |
+
|
| 172 |
+
def display(access_key):
|
| 173 |
+
if not access_key==os.getenv('access_key'):
|
| 174 |
+
chatbot_ret = [(f"Your entered Access Key:<br>{access_key}<br>is incorrect.", f"So i cannot provide you any information in this private space.")]
|
| 175 |
+
elif len(qas)-num_read_qas<1:
|
| 176 |
+
chatbot_ret = [(f"Your entered Access Key is correct.", f"But the progress has just started for a while and has no useful progress information to provide.")]
|
| 177 |
+
else:
|
| 178 |
+
num_total_qs, num_processed_qs = len(qs), len(qas) - num_read_qas
|
| 179 |
+
time_takes = time.time() - start_time
|
| 180 |
+
time_remains = time_takes * (num_total_qs-num_processed_qs) / num_processed_qs
|
| 181 |
+
end_time = start_time + time_takes + time_remains
|
| 182 |
+
|
| 183 |
+
messages = []
|
| 184 |
+
for qa in qas:
|
| 185 |
+
messages.append({"role":"user", "content":qa["q"]})
|
| 186 |
+
messages.append({"role":"assistant", "content":qa["a"] or ""})
|
| 187 |
+
num_tokens_processed = num_tokens_from_messages(messages)
|
| 188 |
+
num_tokens_total = int(num_tokens_processed * (num_total_qs+num_read_qas) / (num_processed_qs+num_read_qas))
|
| 189 |
+
dollars_tokens_processed = 0.002 * int(num_tokens_processed/1000)
|
| 190 |
+
dollars_tokens_total = 0.002 * int(num_tokens_total/1000)
|
| 191 |
+
|
| 192 |
+
chatbot_ret = [(f"Your entered Access Key is correct.", f"The information of progress is displayed below.")]
|
| 193 |
+
chatbot_ret += [(f"The number of processed / total queries:", f"{num_processed_qs} / {num_total_qs} (+{num_read_qas})")]
|
| 194 |
+
chatbot_ret += [(f"The hours already takes / est. remains:", f"{time_takes/3600:.2f} / {time_remains/3600:.2f}")]
|
| 195 |
+
chatbot_ret += [(f"The time starts / est. ends:", f"{timestamp2string(start_time)} / {timestamp2string(end_time)}")]
|
| 196 |
+
chatbot_ret += [(f"The number of processed / est. total tokens:", f"{num_tokens_processed} / {num_tokens_total}")]
|
| 197 |
+
chatbot_ret += [(f"The dollars of processed / est. total tokens:", f"{dollars_tokens_processed:.2f} / {dollars_tokens_total:.2f}")]
|
| 198 |
+
|
| 199 |
+
return chatbot_ret
|
| 200 |
+
|
| 201 |
+
|
| 202 |
+
with gr.Blocks() as demo:
|
| 203 |
+
|
| 204 |
+
gr.Markdown(
|
| 205 |
+
"""
|
| 206 |
+
Hello friends,
|
| 207 |
+
|
| 208 |
+
Thanks for your attention on this space. But this space is for my own use, i.e., building a dataset with answers from ChatGPT, and the access key for runtime feedback is only shared to my colleagues.
|
| 209 |
+
|
| 210 |
+
If you want to ask ChatGPT on Huggingface just as the title says, you can try this [one](https://huggingface.co/spaces/zhangjf/chatbot) I built for public.
|
| 211 |
+
"""
|
| 212 |
+
)
|
| 213 |
+
|
| 214 |
+
with gr.Column(variant="panel"):
|
| 215 |
+
chatbot = gr.Chatbot()
|
| 216 |
+
txt = gr.Textbox(show_label=False, container=False,
|
| 217 |
+
placeholder="Enter your Access Key to access this private space")
|
| 218 |
+
with gr.Row():
|
| 219 |
+
button_showcase = gr.Button("Show Recent Query-Responses")
|
| 220 |
+
button_download = gr.Button("Download All Query-Responses")
|
| 221 |
+
button_display = gr.Button("Display Progress Infomation")
|
| 222 |
+
|
| 223 |
+
downloadfile = gr.File(None, interactive=False, show_label=False, visible=False)
|
| 224 |
+
|
| 225 |
+
button_showcase.click(fn=showcase, inputs=[txt], outputs=[chatbot])
|
| 226 |
+
button_download.click(fn=download, inputs=[txt], outputs=[chatbot, downloadfile])
|
| 227 |
+
button_display.click(fn=display, inputs=[txt], outputs=[chatbot])
|
| 228 |
+
|
| 229 |
+
demo.launch()
|
moss-dpo-47k-comparison-inference.xlsx
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:1a13a4fdfca9b705f15214d791fa2c8a6697db457d350863e4e95c62e620f04b
|
| 3 |
+
size 13179564
|