Gporrt commited on
Commit
ed781ed
·
verified ·
1 Parent(s): d7d99a5

Upload RAIF/COMPLEX_INSTRUCTIONS with huggingface_hub

Browse files
Files changed (1) hide show
  1. RAIF/COMPLEX_INSTRUCTIONS +462 -0
RAIF/COMPLEX_INSTRUCTIONS ADDED
@@ -0,0 +1,462 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os, json, requests, re, traceback, sys
2
+ from queue import Queue, Empty
3
+ import argparse
4
+ import threading
5
+ import asyncio
6
+ import aiohttp
7
+ import time
8
+ import pandas as pd
9
+ import xlsxwriter
10
+ from tqdm import tqdm
11
+ from datetime import datetime
12
+ from importlib import reload
13
+ import logging
14
+ import concurrent.futures
15
+ from transformers import AutoTokenizer
16
+
17
+ sys.path.insert(0, "/mnt")
18
+ from disk2.api.deepseek_v3_2 import deepseek_v3_2
19
+ from disk2.api.deepseek_v3_2_thinking import deepseek_v3_2_thinking
20
+ from disk2.api.deepseek_v4_pro import deepseek_v4_pro
21
+ from disk2.api.deepseek_v4_flash import deepseek_v4_flash
22
+ from disk2.api.qwen3_235b_a22b import qwen3_235b_a22b
23
+ from disk2.api.gpt51 import gpt51
24
+ from disk2.api.vllm_server import vllm_server
25
+ from disk2.api.openai_server import openai_server
26
+
27
+
28
+ parser = argparse.ArgumentParser()
29
+ parser.add_argument("--input_path", type=str, default="")
30
+ parser.add_argument("--input_file_type", type=str, default="jsonl")
31
+ parser.add_argument("--save_path", type=str, default="")
32
+ parser.add_argument("--model_id", type=str, default="")
33
+ parser.add_argument("--model_url", type=str, default="")
34
+
35
+ parser.add_argument("--question_type", type=str, default="conversations") #! TODO
36
+ parser.add_argument("--save_freq", type=int, default=10)
37
+ parser.add_argument("--qkey", type=str, default="q") # 输入文件种query对应的key
38
+ parser.add_argument("--akey", type=str, default="default") # 输出文件中answer对应的key
39
+ parser.add_argument("--system_prompt", type=str, default="You are a helpful assistant.")
40
+ parser.add_argument("--max_tokens", type=int, default=2048)
41
+ parser.add_argument("--resume", action="store_true", default=False)
42
+ parser.add_argument("--api_key", type=str, default="xxx")
43
+ parser.add_argument("--response_format", type=str, default="")
44
+ parser.add_argument("--verbose", type=bool, default=True)
45
+ parser.add_argument("--maxtry", type=int, default=3)
46
+ parser.add_argument("--tensor_parallel_size", type=int, default=4)
47
+
48
+
49
+
50
+ args = parser.parse_args()
51
+ global client
52
+
53
+
54
+ def process_streaming(response):
55
+ start_time = time.time()
56
+ collected_chunks = []
57
+ collected_messages = []
58
+ for chunk in response:
59
+ chunk_time = time.time() - start_time # calculate the time delay of the chunk
60
+ collected_chunks.append(chunk) # save the event response
61
+ chunk_message = chunk.choices[0].delta.content # extract the message
62
+ collected_messages.append(chunk_message) # save the message
63
+ print(f"Full response received {chunk_time:.2f} seconds after request")
64
+ collected_messages = [m for m in collected_messages if m is not None]
65
+ full_reply_content = "".join(collected_messages)
66
+ return full_reply_content
67
+
68
+
69
+
70
+ def build_model():
71
+ model_name_or_path = "/mnt/disk2/models/Qwen2.5-7B-Instruct"
72
+ tokenizer = AutoTokenizer.from_pretrained(model_name_or_path, use_fast=False)
73
+ print("loaded tokenizer qwen")
74
+ return tokenizer
75
+
76
+
77
+
78
+ def build_model_mistral():
79
+ model_name_or_path = "{YOUR_PATH_TO_PRETRAINED_MODELS}/pretrained_models/Mistral-7B-Instruct-v0.3"
80
+ tokenizer = AutoTokenizer.from_pretrained(model_name_or_path, use_fast=False)
81
+ print("loaded tokenizer mistral")
82
+ return tokenizer
83
+
84
+
85
+
86
+ def build_model_llama():
87
+ model_name_or_path = "{YOUR_PATH_TO_PRETRAINED_MODELS}/pretrained_models/Meta-Llama-3.1-8B-Instruct_meta-llama"
88
+ tokenizer = AutoTokenizer.from_pretrained(model_name_or_path, use_fast=False)
89
+ print("loaded tokenizer llama")
90
+ return tokenizer
91
+
92
+
93
+
94
+ def count_token(response, tokenizer):
95
+ inputs = tokenizer.encode(response)
96
+ return len(inputs)
97
+
98
+
99
+
100
+ def count_token_max(response, tokenizer_list):
101
+ response_token_len_list = [count_token(response, tokenizer_item) for tokenizer_item in tokenizer_list]
102
+ return max(response_token_len_list)
103
+
104
+
105
+
106
+ # global tokenizer
107
+ # if "mistral" in (args.model_id).lower() or "ministral" in (args.model_id).lower():
108
+ # tokenizer = build_model_mistral()
109
+ # elif "llama" in (args.model_id).lower():
110
+ # tokenizer = build_model_llama()
111
+ # else:
112
+ # tokenizer = build_model()
113
+
114
+
115
+ if args.question_type == "conversations":
116
+ args.qkey = "conversations"
117
+
118
+
119
+ def prepare_batch_item(index, data):
120
+ if "tools" in data:
121
+ tools = json.loads(data["tools"])
122
+ else:
123
+ tools = None
124
+
125
+ if args.question_type == "conversations":
126
+ messages = data[args.qkey]
127
+ else:
128
+ messages = [
129
+ {
130
+ "role":"system",
131
+ "content":args.system_prompt,
132
+ },
133
+ {
134
+ "role":"user",
135
+ "content":data[args.qkey],
136
+ }
137
+ ]
138
+
139
+
140
+ messages_new = []
141
+
142
+ for message in messages:
143
+ role = message["role"]
144
+ content = message["content"]
145
+
146
+ messages_new.append(
147
+ {
148
+ "role":role,
149
+ "content":content,
150
+ }
151
+ )
152
+ while messages_new[-1]["role"] == "assistant":
153
+ messages_new.pop(-1)
154
+
155
+ messages = messages_new
156
+ messages_str = ""
157
+ for message in messages:
158
+ if message["content"] is not None:
159
+ messages_str += message["content"]+"\n"
160
+
161
+ if "tool_calls" in message and message["tool_calls"] is not None:
162
+ messages_str += str(message["tools"])+"\n"
163
+
164
+ return {
165
+ "index": index,
166
+ "data": data,
167
+ "messages": messages,
168
+ "messages_str": messages_str,
169
+ "tools": tools,
170
+ }
171
+
172
+
173
+
174
+ def finalize_batch_item(item):
175
+ data = item["data"]
176
+ response = {
177
+ "choices": [
178
+ {
179
+ "message": {
180
+ "content": item["response"].get("content") if 'response' in item else None,
181
+ "reasoning_content": item["response"].get("reasoning_content") if 'response' in item else None,
182
+ "tool_calls": item["response"].get("tool_calls") if 'response' in item else None,
183
+ }
184
+ }
185
+ ]
186
+ }
187
+
188
+ result = response["choices"][0]["message"]["content"]
189
+ # assert (result is not None) or ("tool_calls" in response["choices"][0]["message"] and response["choices"][0]["message"]["tool_calls"] is not None)
190
+
191
+ if result and result.startswith("<answer>"):
192
+ result = (result[len("<answer>"):]).lstrip()
193
+ if "reasoning_content" in response["choices"][0]["message"]:
194
+ reasoning = response["choices"][0]["message"]["reasoning_content"]
195
+ else:
196
+ reasoning = None
197
+
198
+ if "tool_calls" in response["choices"][0]["message"]:
199
+ tool_calls = response["choices"][0]["message"]["tool_calls"]
200
+ else:
201
+ tool_calls = None
202
+
203
+ if args.akey == "default":
204
+ data[args.model_id] = result
205
+ if reasoning:
206
+ data[args.model_id + "_reasoning"] = reasoning
207
+ if tool_calls:
208
+ data[args.model_id + "_tool_calls"] = tool_calls
209
+ else:
210
+ data[args.akey] = result
211
+ if reasoning:
212
+ data[args.akey + "_reasoning"] = reasoning
213
+ if tool_calls:
214
+ data[args.model_id + "_tool_calls"] = tool_calls
215
+
216
+ return item["index"], data
217
+
218
+
219
+
220
+ def save_results(results, save_path):
221
+ """
222
+ 分批次保存输出结果, a+ mode
223
+ results: [index, result]
224
+ """
225
+ with open(save_path, "a+") as f:
226
+ for results_i in results:
227
+ f.writelines(json.dumps(results_i[1], ensure_ascii=False)+"\n")
228
+
229
+
230
+ def load_input_file(input_path, file_type="jsonl"):
231
+ if file_type == "jsonl":
232
+ with open(args.input_path) as f:
233
+ Data = f.readlines()
234
+ Data = [json.loads(i) for i in Data]
235
+ elif file_type == "json":
236
+ with open(args.input_path) as f:
237
+ Data = json.load(f)
238
+ else:
239
+ raise ValueError("file_type must be jsonl or json")
240
+ if args.question_type == "conversations":
241
+ for i in range(len(Data)):
242
+ #! 删掉最后的assistant
243
+ if Data[i][args.qkey][-1]["role"] == "assistant":
244
+ Data[i][args.qkey].pop(-1)
245
+
246
+ return Data
247
+
248
+
249
+ def get_resume_state(save_path, file_type="jsonl"):
250
+ count = 0
251
+ # 如果文件不存在
252
+ if not os.path.exists(save_path):
253
+ return count
254
+ # 如果文件存在,加载处理进度
255
+ if file_type == "jsonl":
256
+ with open(save_path, "r", encoding="utf-8") as f:
257
+ for line in f:
258
+ if line:
259
+ count += 1
260
+ elif file_type == "json":
261
+ with open(save_path, "r", encoding="utf-8") as f:
262
+ count = len(json.load(f))
263
+ else:
264
+ raise ValueError("file_type must be jsonl or json")
265
+ return count
266
+
267
+
268
+ def main():
269
+ global client
270
+
271
+ print('================================================')
272
+ print(f"[INFO] Starting inference with model_id: {args.model_id}, model_url: {args.model_url}")
273
+ print(f"[INFO] Input path: {args.input_path}, Input file type: {args.input_file_type}")
274
+ print(f"[INFO] Save path: {args.save_path}")
275
+ print(f"[INFO] Question type: {args.question_type}, Qkey: {args.qkey}, Answer key: {args.akey}")
276
+ print('================================================')
277
+
278
+
279
+ os.makedirs(os.path.dirname(args.save_path), exist_ok=True)
280
+ if args.resume:
281
+ resume_state = get_resume_state(args.save_path, args.input_file_type)
282
+ else:
283
+ resume_state = 0
284
+
285
+ # 加载输入文件
286
+ Data = load_input_file(args.input_path, args.input_file_type)
287
+ print(f"Data loaded. Total {len(Data)} records. {len(Data)-resume_state} records to run.")
288
+ # cut Data
289
+ Data = Data[resume_state:]
290
+
291
+ # 加载模型服务地址
292
+ model_url = args.model_url
293
+ model_id = args.model_id
294
+ print("加载模型服务地址:", model_url)
295
+ print("加载模型名称:", args.model_id)
296
+ max_threads = 200
297
+ llm = None
298
+ sampling_params = None
299
+ if model_url not in [None, "", "None"]:
300
+ from vllm import LLM, SamplingParams
301
+
302
+ print("加载本地离线 vLLM 模型:", model_url)
303
+ llm = LLM(
304
+ model=model_url,
305
+ gpu_memory_utilization=0.9,
306
+ tensor_parallel_size=args.tensor_parallel_size,
307
+ )
308
+ sampling_params = SamplingParams(max_tokens=args.max_tokens)
309
+ # llm = LLM(
310
+ # model=model_url,
311
+ # gpu_memory_utilization=0.9,
312
+ # tensor_parallel_size=1,
313
+ # pipeline_parallel_size=8,
314
+ # max_num_seqs=1000
315
+ # )
316
+ print(
317
+ f"Initialized offline vLLM with model={model_url}, "
318
+ f"max_tokens={args.max_tokens}"
319
+ )
320
+ max_threads = 1024
321
+ elif model_id == "deepseek_v3_2":
322
+ response_format = args.response_format if args.response_format != "" else "text"
323
+ client = deepseek_v3_2(response_format=response_format, cache_dir="./cache/deepseek_v3_2_cache", think_enabled='disabled')
324
+ elif model_id == "deepseek_v3_2_thinking":
325
+ response_format = args.response_format if args.response_format != "" else "text"
326
+ client = deepseek_v3_2_thinking(response_format=response_format, cache_dir="./cache/deepseek_v3_2_thinking_1_cache", think_enabled='enabled')
327
+ elif model_id == "deepseek_v4_pro":
328
+ response_format = args.response_format if args.response_format != "" else "text"
329
+ client = deepseek_v4_pro(response_format=response_format, cache_dir="./cache/deepseek_v4_pro_cache", think_enabled='enabled', reasoning_effort='high')
330
+ elif model_id == "deepseek_v4_flash":
331
+ response_format = args.response_format if args.response_format != "" else "text"
332
+ client = deepseek_v4_flash(response_format=response_format, cache_dir="./cache/deepseek_v4_flash_cache", think_enabled='enabled', reasoning_effort='high')
333
+ elif model_id == "qwen3_235b_a22b":
334
+ response_format = args.response_format if args.response_format != "" else "text"
335
+ client = qwen3_235b_a22b(response_format=response_format, cache_dir="./cache/qwen3_235b_a22b_cache")
336
+ elif model_id == "gpt51":
337
+ response_format = args.response_format if args.response_format != "" else "text"
338
+ client = gpt51(response_format=response_format, cache_dir="./cache/gpt51_cache")
339
+ elif model_id == "openai_server_crab":
340
+ client = openai_server(cache_dir="./models/cache/openai_server_cache")
341
+ elif model_id == "openai_server_conifer":
342
+ client = openai_server(cache_dir="./models/cache/openai_server_conifer_2_cache")
343
+ elif model_id == "openai_server_ultraif":
344
+ client = openai_server(cache_dir="./models/cache/openai_server_ultraif_cache")
345
+ elif model_id == "openai_server_llama3_70b":
346
+ client = openai_server(cache_dir="./models/cache/openai_server_llama3_70b_cache")
347
+ elif model_id == "openai_server_llama3_crab":
348
+ client = openai_server(cache_dir="./models/cache/openai_server_llama3_crab_cache")
349
+ else:
350
+ assert False, "Unsupported model_id, please provide a valid model_id or model_url."
351
+
352
+
353
+
354
+ continuous_results = [] # 待保存的连续输出结果序列
355
+ tbar = tqdm(total=len(Data)+resume_state, initial=resume_state, desc="Processing")
356
+ batch_items = [prepare_batch_item(i, Data[i]) for i in range(len(Data))]
357
+
358
+ if args.verbose:
359
+ for item in batch_items[:5]:
360
+ print('[INFO] 传递给模型的消息内容如下:')
361
+ print(json.dumps(item["messages"], ensure_ascii=False, indent=4))
362
+ print('================================================')
363
+
364
+
365
+ failed_items = list(batch_items)
366
+ num_retry = 0
367
+ while failed_items and num_retry < 1:
368
+
369
+
370
+ # for item in failed_items:
371
+ # print(item['messages'])
372
+ # input()
373
+
374
+
375
+
376
+ if llm is not None:
377
+ message_batches = [item["messages"] for item in failed_items]
378
+ outputs = []
379
+ offline_batch_size = 1000
380
+ for start_idx in range(0, len(message_batches), offline_batch_size):
381
+ message_batch = message_batches[start_idx:start_idx + offline_batch_size]
382
+ vllm_outputs = llm.chat(
383
+ message_batch,
384
+ sampling_params,
385
+ use_tqdm=True,
386
+ chat_template_kwargs={"enable_thinking": True},
387
+ )
388
+ for output in vllm_outputs:
389
+ # print(output)
390
+ raw_generated_text = None
391
+ finish_reason = None
392
+ generated_text = None
393
+ reasoning_content = None
394
+ if output.outputs:
395
+ raw_generated_text = output.outputs[0].text
396
+ finish_reason = getattr(output.outputs[0], "finish_reason", None)
397
+ if '</think>' in raw_generated_text:
398
+ generated_text = raw_generated_text.split('</think>')[-1].strip()
399
+ reasoning_content = raw_generated_text.split('</think>')[0].replace('<think>', '').strip()
400
+ # print(generated_text)
401
+ # print(reasoning_content)
402
+ # assert False
403
+ else:
404
+ generated_text = raw_generated_text.strip()
405
+ outputs.append(
406
+ {
407
+ "content": generated_text,
408
+ "reasoning_content": reasoning_content,
409
+ "raw_response": {
410
+ "prompt": output.prompt,
411
+ "finish_reason": finish_reason,
412
+ },
413
+ }
414
+ )
415
+ else:
416
+ outputs = client(
417
+ [item["messages"] for item in failed_items],
418
+ use_cache=(num_retry == 0),
419
+ max_threads=max_threads,
420
+ maxtry=args.maxtry,
421
+ )
422
+
423
+ # if args.verbose:
424
+ # for item, output in zip(failed_items[:3], outputs[:3]):
425
+ # print('[INFO] 模型的输出内容如下:')
426
+ # print(json.dumps(output, ensure_ascii=False, indent=4))
427
+ # print('================================================')
428
+
429
+
430
+ next_failed_items = []
431
+ for item, output in zip(failed_items, outputs):
432
+ if output is None:
433
+ next_failed_items.append(item)
434
+ continue
435
+ item["response"] = output
436
+
437
+ if next_failed_items:
438
+ print("!"*50)
439
+ num_retry += 1
440
+ time.sleep(5)
441
+ failed_items = next_failed_items
442
+ continue
443
+
444
+ failed_items = []
445
+
446
+ for item in batch_items:
447
+ index, result = finalize_batch_item(item)
448
+ continuous_results.append([index, result])
449
+ tbar.update(1)
450
+
451
+ if len(continuous_results) >= args.save_freq:
452
+ save_results(continuous_results, args.save_path)
453
+ continuous_results = []
454
+
455
+ # 保存剩余的结果
456
+ if continuous_results:
457
+ save_results(continuous_results, args.save_path)
458
+ return
459
+
460
+
461
+ if __name__ == "__main__":
462
+ main()