mirror of
https://github.com/InternLM/InternBootcamp.git
synced 2026-04-19 12:58:04 +00:00
merge
This commit is contained in:
commit
b9a714f8cb
2 changed files with 4922 additions and 0 deletions
4755
internbootcamp/bootcamp/med_calculator/med_calculator.json
Normal file
4755
internbootcamp/bootcamp/med_calculator/med_calculator.json
Normal file
File diff suppressed because it is too large
Load diff
167
internbootcamp/bootcamp/med_calculator/med_calculator.py
Normal file
167
internbootcamp/bootcamp/med_calculator/med_calculator.py
Normal file
|
|
@ -0,0 +1,167 @@
|
||||||
|
import json
|
||||||
|
import math
|
||||||
|
import random
|
||||||
|
from internbootcamp.bootcamp.base import Basebootcamp
|
||||||
|
|
||||||
|
def remove_boxed(s):
|
||||||
|
if "\\boxed " in s:
|
||||||
|
left = "\\boxed "
|
||||||
|
assert s[:len(left)] == left
|
||||||
|
return s[len(left):]
|
||||||
|
|
||||||
|
left = "\\boxed{"
|
||||||
|
|
||||||
|
assert s[:len(left)] == left
|
||||||
|
assert s[-1] == "}"
|
||||||
|
|
||||||
|
return s[len(left):-1]
|
||||||
|
|
||||||
|
def last_boxed_only_string(string):
|
||||||
|
idx = string.rfind("\\boxed")
|
||||||
|
if "\\boxed " in string:
|
||||||
|
return "\\boxed " + string.split("\\boxed ")[-1].split("$")[0]
|
||||||
|
if idx < 0:
|
||||||
|
idx = string.rfind("\\fbox")
|
||||||
|
if idx < 0:
|
||||||
|
return None
|
||||||
|
|
||||||
|
i = idx
|
||||||
|
right_brace_idx = None
|
||||||
|
num_left_braces_open = 0
|
||||||
|
while i < len(string):
|
||||||
|
if string[i] == "{":
|
||||||
|
num_left_braces_open += 1
|
||||||
|
if string[i] == "}":
|
||||||
|
num_left_braces_open -= 1
|
||||||
|
if num_left_braces_open == 0:
|
||||||
|
right_brace_idx = i
|
||||||
|
break
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
if right_brace_idx is None:
|
||||||
|
retval = None
|
||||||
|
else:
|
||||||
|
retval = string[idx:right_brace_idx + 1]
|
||||||
|
|
||||||
|
return retval
|
||||||
|
|
||||||
|
class MedCalculatorSandbox(Basebootcamp): # 医学计算器类
|
||||||
|
def __init__(self, conf_file="med_calculator.json", seed=None):
|
||||||
|
random.seed(seed)
|
||||||
|
with open(conf_file, "r", encoding="utf-8") as f:
|
||||||
|
self.config = json.load(f)
|
||||||
|
|
||||||
|
def _gen_a_case(self, category, name):
|
||||||
|
details = self.config[category][name]
|
||||||
|
indicators = self.config["indicator"]
|
||||||
|
inputs = []
|
||||||
|
|
||||||
|
match category:
|
||||||
|
case 'equation':
|
||||||
|
while 1:
|
||||||
|
formula = details["formula"]
|
||||||
|
for i in details["inputs"]:
|
||||||
|
match indicators[i]["type"]:
|
||||||
|
case "int":
|
||||||
|
v = random.randint(*indicators[i]["range"])
|
||||||
|
case "float":
|
||||||
|
v = random.uniform(*indicators[i]["range"])
|
||||||
|
if 'precision' in indicators[i]:
|
||||||
|
v = round(v, indicators[i]["precision"])
|
||||||
|
case "choice":
|
||||||
|
v = random.choice(indicators[i]["range"])
|
||||||
|
|
||||||
|
t = i + str(v) + indicators[i].get("unit", "")
|
||||||
|
inputs.append(t)
|
||||||
|
formula = formula.replace(i, str(v))
|
||||||
|
|
||||||
|
try:
|
||||||
|
target = eval(formula)
|
||||||
|
break
|
||||||
|
except (ZeroDivisionError, ValueError):
|
||||||
|
pass
|
||||||
|
except Exception as e:
|
||||||
|
raise e
|
||||||
|
# print(name, formula, details["formula"])
|
||||||
|
# breakpoint()
|
||||||
|
out_k = name.split('—')[-1]
|
||||||
|
if 'precision' in indicators[out_k]:
|
||||||
|
target = round(target, indicators[out_k]["precision"])
|
||||||
|
case 'scale':
|
||||||
|
target = 0
|
||||||
|
for title, options in details["points"].items():
|
||||||
|
if isinstance(options, dict):
|
||||||
|
selected_option = random.choice(list(options.keys()))
|
||||||
|
inputs.append(f'{title}: {selected_option}')
|
||||||
|
target += options[selected_option]
|
||||||
|
else:
|
||||||
|
inputs.append(title)
|
||||||
|
target += options
|
||||||
|
|
||||||
|
ret = {
|
||||||
|
"category": category,
|
||||||
|
"name": name,
|
||||||
|
"inputs": inputs,
|
||||||
|
"target": target,
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def case_generator(self):
|
||||||
|
category = random.choice(['equation', 'scale'])
|
||||||
|
name = random.choice(list(self.config[category].keys()))
|
||||||
|
return self._gen_a_case(category, name)
|
||||||
|
|
||||||
|
def prompt_func(self, case):
|
||||||
|
indicators = self.config["indicator"]
|
||||||
|
inp_items = ','.join(case["inputs"])
|
||||||
|
out_item = case["name"]
|
||||||
|
|
||||||
|
other_item = ''
|
||||||
|
match case["category"]:
|
||||||
|
case 'equation':
|
||||||
|
out_name = out_item.split('—')[-1]
|
||||||
|
if 'precision' in indicators[out_name]:
|
||||||
|
other_item = f",保留{indicators[out_name]['precision']}位小数"
|
||||||
|
|
||||||
|
instruction = f"患者信息:{inp_items}。请计算{out_item}{other_item}。"
|
||||||
|
instruction_following = """Let's think step by step and output the final answer within \\boxed{xxx:xxx}. For example "\\boxed{BMI: 20.5}"."""
|
||||||
|
prompt = instruction + '\n' + instruction_following
|
||||||
|
return prompt
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def extract_output(output):
|
||||||
|
output = last_boxed_only_string(output)
|
||||||
|
if output is None:
|
||||||
|
return None
|
||||||
|
return remove_boxed(output)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _verify_correction(cls, solution, identity):
|
||||||
|
if ':' in solution:
|
||||||
|
solution = solution.split(':')[-1].strip()
|
||||||
|
elif ':' in solution:
|
||||||
|
solution = solution.split(':')[-1].strip()
|
||||||
|
|
||||||
|
return solution.strip() == str(identity['target'])
|
||||||
|
|
||||||
|
def gen_all_case(self, k=1):
|
||||||
|
cases = []
|
||||||
|
for category in ['equation', 'scale']:
|
||||||
|
for name in self.config[category]:
|
||||||
|
for _ in range(k):
|
||||||
|
case = self._gen_a_case(category, name)
|
||||||
|
cases.append(case)
|
||||||
|
return cases
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
bootcamp = MedCalculatorSandbox(seed=42)
|
||||||
|
identity = bootcamp.case_generator()
|
||||||
|
print(f'{identity = }')
|
||||||
|
|
||||||
|
prompt = bootcamp.prompt_func(identity)
|
||||||
|
print(f"Prompt: \n{prompt}")
|
||||||
|
|
||||||
|
response = "...some reasoning process...\\boxed{BMI: 134.7}"
|
||||||
|
print(f"Response: \n{response}")
|
||||||
|
score = bootcamp.verify_score(response, identity, short_penalty=False, format_penalty=False)
|
||||||
|
print(f"Score: {score}")
|
||||||
Loading…
Add table
Add a link
Reference in a new issue