File size: 19,606 Bytes
a80200a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
import os
def apply_RL_prompt(chunk, args, budget):
    if args.prompt_type == "deepseek3" and os.environ['tip'] == "Ahead":
        #### Ahead方法为:在问题的末尾加上remaining。
        return RL_deepseek3_prompt(chunk, budget)
    elif args.prompt_type == "deepseek3" and os.environ['tip'] == "prompt":
        return prompt_format(chunk, budget)
    elif args.prompt_type == "qwen25-math-cot" and os.environ['tip'] == "prompt":
        return prompt_format_qw(chunk, budget)
    elif args.prompt_type == "deepseek3" and os.environ['tip'] == "prompt-based":
        return deepseek3_prompt_based(chunk, budget)
    elif args.prompt_type == "deepseek3" and os.environ['tip'] == "prompt-based1":
        return deepseek3_prompt_based1(chunk, budget)
    elif args.prompt_type == "deepseek3" and os.environ['tip'] == "prompt-based2":
        return deepseek3_prompt_based2(chunk, budget)
    elif args.prompt_type == "deepseek3" and os.environ['tip'] == "prompt-based3":
        return deepseek3_prompt_based3(chunk, budget)
    elif os.environ['tip'] == "default":
        return chunk
    elif args.prompt_type == "deepseek3" and os.environ['tip'] == "ATD_A" or os.environ['tip'] == "ATD_R":
        return ATD_A_deepseek3_prompt(chunk, budget)
    elif args.prompt_type == "deepseek3" and os.environ['tip'] == "TCM": 
        return TCM_prompt(chunk, budget)
    elif args.prompt_type == "deepseek3" and os.environ['tip'] == "TCMv2":
        return TCMv2_prompt(chunk, budget)
    elif args.prompt_type == "deepseek3" and os.environ['tip'] == "withoutremaining":
        return withoutremaining_prompt(chunk, budget)
    elif args.prompt_type == "deepseek3" and os.environ['tip'] == "8ratio":
        return _8ratio_prompt(chunk, budget)
    elif args.prompt_type == "deepseek3" and "prompt_v1" in os.environ['tip']:
        return prompt_v1_prompt(chunk, budget)
    elif args.prompt_type == "deepseek3" and "prompt_v2" in os.environ['tip']:
        return prompt_v2_prompt(chunk, budget)
    elif args.prompt_type == "deepseek3" and "prompt_cod" in os.environ['tip']:
        return prompt_cod_prompt(chunk, budget)
    elif args.prompt_type == "deepseek3" and "prompt_c2f" in os.environ['tip']:
        return prompt_c2f_prompt(chunk, budget)
    elif args.prompt_type == "deepseek3" and os.environ['tip'] == "Laser":
        return Laser_prompt(chunk, budget)
    elif args.prompt_type == "deepseek3" and os.environ['tip'] == "TCM+":
        return TCMv2_prompt(chunk, budget)
    elif args.prompt_type == "deepseek3" and os.environ['tip'] == "SST":
        return SST_prompt(chunk, budget)
    elif args.prompt_type == "deepseek3" and os.environ['tip'] == "Tokenskip":
        return Tokenskip_prompt(chunk, budget)
    elif args.prompt_type == "deepseek3" and os.environ['tip'] == "thinkprune":
        return thinkprune_prompt(chunk, budget)
    else:
        return chunk





def Tokenskip_prompt(chunk, budget):
    find_strings = "<|Assistant|>"
    alpha = os.environ['alpha']
    for i in range(len(chunk)):
        head = chunk[i].split(find_strings)[0]
        tail = chunk[i].split(find_strings)[1]
        add_prompt = f'<|end▁of▁sentence|>{alpha}<|end▁of▁sentence|>'
        chunk[i] = head + add_prompt + find_strings + tail
    return chunk
    

def SST_prompt(chunk, budget):
    find_strings = "<|Assistant|>"
    up_to_50 = budget // 50 + 1
    N = up_to_50
    for i in range(len(chunk)):
        head = chunk[i].split(find_strings)[0]
        tail = chunk[i].split(find_strings)[1]
        # add_prompt = f'\n(Complete thinking within {budget} tokens or fewer.)'
        # add_prompt = f'\n(Complete thinking within {budget} tokens or fewer.)\n<remaining>{budget}</remaining>\n'
        add_prompt = f"\n(Complete thinking within {N} <countdown> or fewer.)"
        # add_prompt = f'\n<remaining>{budget}</remaining>\n'

        add_response = "\n<think>\n\n<countdown>\n"
        # head += f"\n<remaining>{budget}</remaining>\n"
        chunk[i] = head + add_prompt + find_strings + tail + add_response
        # print(f"chunk[i] = {chunk[i]}")
    return chunk


def TCMv2_prompt(chunk, budget):
    find_strings = "<|Assistant|>"
    for i in range(len(chunk)):
        head = chunk[i].split(find_strings)[0]
        tail = chunk[i].split(find_strings)[1]
        # add_prompt = f'\n(Complete thinking within {budget} tokens or fewer.)'
        # add_prompt = f'\n(Complete thinking within {budget} tokens or fewer.)\n<remaining>{budget}</remaining>\n'
        add_prompt = f"\n(Complete thinking within \n<remaining>{budget}</remaining>\n tokens or fewer.)"
        # add_prompt = f'\n<remaining>{budget}</remaining>\n'

        add_response = f""
        # head += f"\n<remaining>{budget}</remaining>\n"
        chunk[i] = head + add_prompt + find_strings + add_response + tail
        # print(f"chunk[i] = {chunk[i]}")
    return chunk



def withoutremaining_prompt(chunk, budget):
    find_strings = "<|Assistant|>"
    for i in range(len(chunk)):
        head = chunk[i].split(find_strings)[0]
        tail = chunk[i].split(find_strings)[1]
        # add_prompt = f'\n(Complete thinking within {budget} tokens or fewer.)'
        # add_prompt = f'\n(Complete thinking within {budget} tokens or fewer.)\n<remaining>{budget}</remaining>\n'
        add_prompt = f"\n(Complete thinking within {budget} tokens or fewer.)"
        # add_prompt = f'\n<remaining>{budget}</remaining>\n'

        add_response = f""
        # head += f"\n<remaining>{budget}</remaining>\n"
        chunk[i] = head + add_prompt + find_strings + add_response + tail
        # print(f"chunk[i] = {chunk[i]}")
    return chunk

def _8ratio_prompt(chunk, budget):
    os.environ['budget'] = str(budget)
    print(f"budget = {budget}")
    find_strings = "<|Assistant|>"
    for i in range(len(chunk)):
        head = chunk[i].split(find_strings)[0]
        tail = chunk[i].split(find_strings)[1]
        # add_prompt = f'\n(Complete thinking within {budget} tokens or fewer.)'
        add_prompt = f"\n(Complete thinking within {budget} tokens or fewer, 7 special tokens ( \n<remaining>7/8</remaining>\n , \n<remaining>6/8</remaining>\n , \n<remaining>5/8</remaining>\n , \n<remaining>4/8</remaining>\n , \n<remaining>3/8</remaining>\n , \n<remaining>2/8</remaining>\n , \n<remaining>1/8</remaining>\n ) will split the thinking process into 8 parts.)"
        
        add_response = f""

        chunk[i] = head + add_prompt + find_strings + add_response + tail
        
    return chunk

def Laser_prompt(chunk, budget):
    os.environ['budget'] = str(budget)
    print(f"budget = {budget}")
    find_strings = "<|Assistant|>"
    for i in range(len(chunk)):
        head = chunk[i].split(find_strings)[0]
        tail = chunk[i].split(find_strings)[1]
        add_prompt = "Please reason step by step, and put your final answer within \\boxed{}"
        add_response = f""

        chunk[i] = head + add_prompt + find_strings + add_response + tail
    return chunk

def prompt_v1_prompt(chunk, budget):
    os.environ['budget'] = str(budget)
    print(f"budget = {budget}")
    find_strings = "<|Assistant|>"
    for i in range(len(chunk)):
        head = chunk[i].split(find_strings)[0]
        tail = chunk[i].split(find_strings)[1]
        # add_prompt = f'\n(Complete thinking within {budget} tokens or fewer.)'
        add_prompt = f"\n(Complete thinking within {budget} tokens or fewer, please output the remaining number of tokens every 200 tokens to facilitate control of the remaining length of the thinking process, here is a template: 'now remaining tokens: xxx', xxx is the real remaining number of tokens.)"
        add_response = f""

        chunk[i] = head + add_prompt + find_strings + add_response + tail
        
    return chunk

def prompt_v2_prompt(chunk, budget):
    os.environ['budget'] = str(budget)
    print(f"budget = {budget}")
    find_strings = "<|Assistant|>"
    for i in range(len(chunk)):
        head = chunk[i].split(find_strings)[0]
        tail = chunk[i].split(find_strings)[1]
        # add_prompt = f'\n(Complete thinking within {budget} tokens or fewer.)'
        add_prompt = f"\n(Complete thinking within {budget} tokens or fewer)"
        add_response = f""

        chunk[i] = head + add_prompt + find_strings + add_response + tail
        
    return chunk

def prompt_cod_prompt(chunk, budget):
    os.environ['budget'] = str(budget)
    print(f"budget = {budget}")
    find_strings = "<|Assistant|>"
    for i in range(len(chunk)):
        head = chunk[i].split(find_strings)[0]
        tail = chunk[i].split(find_strings)[1]
        # add_prompt = f'\n(Complete thinking within {budget} tokens or fewer.)'
        add_prompt = f'''
        Please solve the following math problem step by step, but only record the most essential steps during the reasoning process. Each step should be concise and clear, focusing directly on the core calculation or logical transformation. No detailed explanation is needed; just write down the key derivations. After completing the reasoning, provide the final answer after.

        Example:
        Problem: Jason has 20 lollipops. After giving some to Denny, he now has 12 left. How many did he give to Denny?
        Reasoning:
        20 - x = 12  
        x = 20 - 12  
        x = 8  
        8
        Now please solve the above problem.\n(Complete thinking within {budget} tokens or fewer)
        '''
        add_response = f""

        chunk[i] = head + add_prompt + find_strings + add_response + tail
        
    return chunk

def prompt_c2f_prompt(chunk, budget):
    os.environ['budget'] = str(budget)
    print(f"budget = {budget}")
    find_strings = "<|Assistant|>"
    for i in range(len(chunk)):
        head = chunk[i].split(find_strings)[0]
        tail = chunk[i].split(find_strings)[1]
        # add_prompt = f'\n(Complete thinking within {budget} tokens or fewer.)'
        add_prompt = f'''
        Use the following pattern to solve the problem:

        **Coarse-Grained Reasoning**
        Provide a brief analysis and initial answer, focusing
        on efficiency and conciseness.

        **Fine-Grained Reasoning**
        Provide detailed reasoning step by step and a refined
        answer, focusing on correctness and rigor.

        Conclude with:
        Therefore, the final answer is: \\boxed{{[answer]}}.
        Where [answer] is just the final number or expression
        that solves the problem.

        Now please solve the above problem.\n(Complete thinking within {budget} tokens or fewer)
        '''
        add_response = f""

        chunk[i] = head + add_prompt + find_strings + add_response + tail
        
    return chunk




def thinkprune_prompt(chunk, budget):
    SYSTEM_PROMPT = (
    "A conversation between User and Assistant. The user asks a question, "
    "and the Assistant solves it."
    " The assistant first thinks about the reasoning process in the mind and then provides the user"
    " with the answer. The reasoning process and answer are enclosed within <think></think> and"
    " <answer></answer> tags, respectively, i.e., <think> reasoning process here</think>"
    "<answer> answer here</answer>."
    )
    find_strings = "<|Assistant|>"
    for i in range(len(chunk)):
        head = chunk[i].split(find_strings)[0]
        tail = chunk[i].split(find_strings)[1]
        # add_prompt = f'\n(Complete thinking within {budget} tokens or fewer.)'
        # add_prompt = f'\n(Complete thinking within {budget} tokens or fewer.)\n<remaining>{budget}</remaining>\n'
        add_prompt = SYSTEM_PROMPT + f"The output of the assistant should be within {budget} tokens"
        # add_prompt = f'\n<remaining>{budget}</remaining>\n'

        add_response = f""
        # head += f"\n<remaining>{budget}</remaining>\n"
        chunk[i] = head + add_prompt + find_strings + add_response + tail
        # print(f"chunk[i] = {chunk[i]}")
    return chunk

def TCM_prompt(chunk, budget):
    find_strings = "<|Assistant|>"
    for i in range(len(chunk)):
        head = chunk[i].split(find_strings)[0]
        tail = chunk[i].split(find_strings)[1]
        # add_prompt = f'\n(Complete thinking within {budget} tokens or fewer.)'
        add_prompt = f"\n(Complete thinking within \n<remaining>{budget}</remaining>\n tokens or fewer.)"
        # add_prompt = f'\n(Complete thinking within {budget} tokens or fewer.)\n<remaining>{budget}</remaining>\n'
        # add_prompt = f'\n<remaining>{budget}</remaining>\n'
        add_response = f""
        # head += f"\n<remaining>{budget}</remaining>\n"
        chunk[i] = head + add_prompt + find_strings + add_response + tail
        # print(f"chunk[i] = {chunk[i]}")
    return chunk


def prompt_format(chunk, budget):
    '''
     <|User|>Convert the point $(0,3)$ in rectangular coordinates to polar coordinates. 
     Enter your answer in the form $(r,\theta),$ where $r > 0$ and $0 \le \theta < 2 \pi.$
     <|Assistant|>
    '''
    find_strings = "<|Assistant|>"
    for i in range(len(chunk)):
        head = chunk[i].split(find_strings)[0]
        tail = chunk[i].split(find_strings)[1]
        head += f"\n(Complete thinking within {budget} tokens or fewer.)\n"
        chunk[i] = head + find_strings + tail
    return chunk


def prompt_format_qw(chunk, budget):
    '''
     <|User|>Convert the point $(0,3)$ in rectangular coordinates to polar coordinates. 
     Enter your answer in the form $(r,\theta),$ where $r > 0$ and $0 \le \theta < 2 \pi.$
     <|Assistant|>
    '''
    find_strings = "<|im_start|>assistant"

    for i in range(len(chunk)):
        head = chunk[i].split(find_strings)[0]
        tail = chunk[i].split(find_strings)[1]
        head += f"\n(Complete thinking within {budget} tokens or fewer.)\n"
        chunk[i] = head + find_strings + tail
    return chunk





def ATD_A_deepseek3_prompt(chunk, budget):
    find_strings = "<|Assistant|>"
    for i in range(len(chunk)):
        head = chunk[i].split(find_strings)[0]
        tail = chunk[i].split(find_strings)[1]
        add_prompt = f'\n(Respond in {budget} tokens or fewer. Complete the process between <think> and </think> within the token budget. Display the countdown exponentially as <remaining>xxx</remaining>, where xxx = 50 * 2^n, n >= 0. Think more concisely as countdown decreases.)\n'
        add_response = f"\n(I will complete the process within {budget} tokens and show the countdown as <remaining>xxx</remaining>, following the exponential rule.I will think more concisely as countdown decreases.)\n"
        # head += f"\n<remaining>{budget}</remaining>\n"
        chunk[i] = head + add_prompt + find_strings + add_response + tail
    return chunk




def RL_deepseek3_prompt(chunk, budget):
    '''
     <|User|>Convert the point $(0,3)$ in rectangular coordinates to polar coordinates. 
     Enter your answer in the form $(r,\theta),$ where $r > 0$ and $0 \le \theta < 2 \pi.$
     <|Assistant|>
    '''
    find_strings = "<|Assistant|>"
    for i in range(len(chunk)):
        head = chunk[i].split(find_strings)[0]
        tail = chunk[i].split(find_strings)[1]
        head += f"(Please respond in {budget} tokens or fewer)\n"
        # head += f"\n<remaining>{budget}</remaining>\n"
        chunk[i] = head + find_strings + tail
    return chunk
        
    
def deepseek3_prompt_based(chunk, budget):
    '''
     <|User|>Convert the point $(0,3)$ in rectangular coordinates to polar coordinates. 
     Enter your answer in the form $(r,\theta),$ where $r > 0$ and $0 \le \theta < 2 \pi.$
     <|Assistant|>
    '''
    find_strings = "<|Assistant|>"
    for i in range(len(chunk)):
        head = chunk[i].split(find_strings)[0]
        tail = chunk[i].split(find_strings)[1]
        head += f"You should finish thinking with in {budget} tokens.\n"
        chunk[i] = head + find_strings + tail
    return chunk
    

def deepseek3_prompt_based1(chunk, budget):
    '''
     <|User|>Convert the point $(0,3)$ in rectangular coordinates to polar coordinates. 
     Enter your answer in the form $(r,\theta),$ where $r > 0$ and $0 \le \theta < 2 \pi.$
     <|Assistant|>
    '''
    find_strings = "<|Assistant|>"
    for i in range(len(chunk)):
        head = chunk[i].split(find_strings)[0]
        tail = chunk[i].split(find_strings)[1]
        head += f"(Please respond in {budget} tokens or fewer)\n"
        chunk[i] = head + find_strings + tail
    return chunk



def deepseek3_prompt_based2(chunk, budget):
    '''
     <|User|>Convert the point $(0,3)$ in rectangular coordinates to polar coordinates. 
     Enter your answer in the form $(r,\theta),$ where $r > 0$ and $0 \le \theta < 2 \pi.$
     <|Assistant|>
    '''
    find_strings = "<|Assistant|>"
    for i in range(len(chunk)):
        head = chunk[i].split(find_strings)[0]
        tail = chunk[i].split(find_strings)[1]
        head += f"(HARD STOP at {budget} tokens)\n"
        chunk[i] = head + find_strings + tail
    return chunk


def deepseek3_prompt_based3(chunk, budget):
    '''
     <|User|>Convert the point $(0,3)$ in rectangular coordinates to polar coordinates. 
     Enter your answer in the form $(r,\theta),$ where $r > 0$ and $0 \le \theta < 2 \pi.$
     <|Assistant|>
    '''
    find_strings = "<|Assistant|>"
    for i in range(len(chunk)):
        head = chunk[i].split(find_strings)[0]
        tail = chunk[i].split(find_strings)[1]
        head += f"(Response length limit: Strictly {budget} tokens max. Budget cannot be exceeded)\n"
        chunk[i] = head + find_strings + tail
    return chunk


    
    
    
# def solve_final_answer(chunk):
#     k = 0
#     for i in range(len(chunk)):
#         if "**Final Answer**\\boxed" in chunk[i][:-10] and "<|end▁of▁sentence|>" not in chunk[i]:
#             chunk[i] += "<|end▁of▁sentence|>"
#             k += 1
#     print(f"###added {k} final answer!")
#     return chunk

# import re

def is_balanced(s: str) -> bool:
    """验证大括号是否成对且正确嵌套"""
    stack = 0
    for char in s:
        if char == "{":
            stack += 1
        elif char == "}":
            stack -= 1
            if stack < 0:
                return False
    return stack == 0

def solve_final_answer(chunk: list) -> list:
    
    """处理包含嵌套大括号的答案匹配"""
    
    end_chunk = []
    open_chunk = []
    
    k = 0
    pattern = "**Final Answer**\\boxed{"  # 初级匹配
    
    for i in range(len(chunk)):
        line = chunk[i]
        if not pattern in line:
            open_chunk.append(chunk[i])
            continue
        # 深度扫描完整结构
        start_idx = line.find('**Final Answer**\\boxed{')
        if start_idx == -1:
            open_chunk.append(chunk[i])
            continue
        # 手动解析嵌套结构
        stack = 1
        end_idx = start_idx + len('**Final Answer**\\boxed{')
        while end_idx < len(line) and stack > 0:
            if line[end_idx] == "{":
                stack += 1
            elif line[end_idx] == "}":
                stack -= 1
            end_idx += 1
        
        # 验证闭合状态
        if stack == 0 and is_balanced(line[start_idx:end_idx]):
            
            chunk[i] += "<|end▁of▁sentence|>"  # 保持原有操作
            k += 1
            end_chunk.append(chunk[i])
        else:
            open_chunk.append(chunk[i])

    print(f"### Find {k} anwsers have final answer!")
    return chunk, end_chunk, open_chunk