diff --git a/evaluator.py b/evaluator.py
new file mode 100644
index 0000000..96faac8
--- /dev/null
+++ b/evaluator.py
@@ -0,0 +1,142 @@
+from typing import Dict, Union
+import argparse
+import re
+import json
+import time
+from datetime import datetime
+from threading import Lock
+from concurrent.futures import ThreadPoolExecutor
+from pathlib import Path
+import pandas as pd
+from openai import OpenAI
+
+# Constants
+TIME_START = datetime.now().strftime("%Y%m%d_%H%M%S")
+LOCK = Lock()
+
+def get_args():
+ parser = argparse.ArgumentParser()
+ parser.add_argument('-o', '--model-output-dir', help='Model Output Directory', required=True)
+ parser.add_argument('-k', '--openai-api-key', help='OpenAI API Key', required=True)
+ parser.add_argument('-j', '--judge-model', help='Judge Model', default='gpt-4-1106-preview')
+ parser.add_argument('-t', '--threads', help='Thread count', default=42, type=int)
+ return parser.parse_args()
+
+def create_azure_client(api_key: str):
+ return OpenAI(
+ api_key=api_key
+ )
+
+def load_judge_template() -> pd.DataFrame:
+ return pd.read_json('judge_template.jsonl', lines=True)
+
+def create_answers(client, model_output, judge_model, df_judge_template, is_multi_turn: bool = False, i=0) -> Dict[str, Union[str, float]]:
+ model_questions = model_output['questions']
+ model_outputs = model_output['outputs']
+ model_references = model_output['references']
+
+ prompt = (
+ f"아래의 내용을 주어진 평가 기준들을 충실히 반영하여 평가해라. 특히 모델 답변이 언어 요구사항을 준수하는지 반드시 확인해야 한다.\n\n"
+ f"**Question**\n{model_questions[0]}"
+ )
+
+ if model_references and model_references[0]:
+ prompt += f"\n\n**Additional Reference**\n{model_references[0]}"
+
+ prompt += f"\n\n**Model's Response**\n{model_outputs[0]}"
+
+ if is_multi_turn:
+ prompt += f"\n\n**Follow-up Question.**\n{model_questions[1]}"
+ if model_references and model_references[1]:
+ prompt += f"\n\n**Additional Reference**\n{model_references[1]}"
+ prompt += f"\n\n**Model's Response**\n{model_outputs[1]}"
+
+ prompt += "\n\n[[대화 종료. 평가 시작.]]"
+
+ try:
+ response = client.chat.completions.create(
+ model=judge_model,
+ temperature=0.0,
+ n=1,
+ messages=[
+ {"role": "system", "content": df_judge_template.iloc[1 if is_multi_turn else 0]['system_prompt']},
+ {"role": "user", "content": prompt}
+ ]
+ )
+
+ content = response.choices[0].message.content
+ judge_message_match = re.search(r"평가:(.*?)점수:", content.replace("*", ''), re.DOTALL)
+ judge_message = judge_message_match.group(1).strip() if judge_message_match else "No judge message found"
+ judge_score_match = re.search(r"점수:\s*(\d+(\.\d+)?)", content.replace("*", ''))
+ if judge_score_match:
+ judge_score = float(judge_score_match.group(1))
+ else:
+ raise ValueError("No score found in response")
+
+ return {
+ 'judge_message': judge_message,
+ 'judge_score': judge_score
+ }
+
+ except Exception as e:
+ print("Error. Retrying after 20 sec", e)
+ time.sleep(20)
+
+ # 현재는 에러에 따라서 다르게 핸들링 하지 않고 있음. 업데이트 필요함.
+ if i > 3:
+ print("Impossible prompt, aborting..!")
+ return {
+ 'judge_message': "Impossible to judge due to repetition.",
+ 'judge_score': 0.0
+ }
+ i += 1
+ return create_answers(client, model_output, judge_model, df_judge_template, is_multi_turn, i)
+
+def process_item(client, row, judge_model, df_judge_template, output_file):
+ query_single = create_answers(client, row, judge_model, df_judge_template)
+ query_multi = create_answers(client, row, judge_model, df_judge_template, is_multi_turn=True)
+
+ row['query_single'] = query_single
+ row['query_multi'] = query_multi
+ row = row.to_dict()
+
+ with LOCK:
+ with output_file.open('a', encoding='utf-8-sig') as f:
+ f.write(json.dumps(row, ensure_ascii=False))
+ f.write('\n')
+
+def process_file(client, file_path: Path, output_dir: Path, judge_model, df_judge_template, threads: int):
+ print(f"- 현재 Processing : {file_path}")
+ df_model_outputs = pd.read_json(file_path, lines=True)
+
+ output_file = output_dir / file_path.relative_to(args.model_output_dir)
+ output_file.parent.mkdir(parents=True, exist_ok=True)
+
+ with ThreadPoolExecutor(max_workers=threads) as executor:
+ for row in df_model_outputs.iterrows():
+ executor.submit(process_item, client, row[1], judge_model, df_judge_template, output_file)
+
+def is_hidden(filepath: Path) -> bool:
+ return any(part.startswith('.') for part in filepath.parts)
+
+def main():
+ args = get_args()
+ client = create_azure_client(args.openai_api_key)
+ df_judge_template = load_judge_template()
+
+ input_dir = Path(args.model_output_dir)
+ output_dir = Path('./evaluated')
+
+ # Filter out hidden files
+ json_files = [file for file in input_dir.rglob('*.jsonl') if not is_hidden(file)]
+
+ for file_path in json_files:
+ output_file_path = output_dir / file_path.relative_to(input_dir)
+ if output_file_path.exists():
+ print(f"이미 평가 완료.. : {file_path}")
+ continue
+ process_file(client, file_path, output_dir, args.judge_model, df_judge_template, args.threads)
+ time.sleep(20) # ratelimit!
+
+if __name__ == "__main__":
+ main()
\ No newline at end of file
diff --git a/generator.py b/generator.py
index 88dce93..2cc117c 100644
--- a/generator.py
+++ b/generator.py
@@ -1,69 +1,153 @@
import argparse
-import os
-
import pandas as pd
-from vllm import LLM, SamplingParams
+import os
+# Use aphrodite-engine or vLLM
+try:
+ from aphrodite import LLM, SamplingParams
+ print("- Using aphrodite-engine")
+
+except ImportError:
+ from vllm import LLM, SamplingParams
+ print("- Using vLLM")
+
+PROMPT_STRATEGY = {
+ "cot-1-shot": [
+ {"role": "system", "content": "문제를 해결하는 과정을 단계별로 명확하게 설명한 다음, 최종 답변을 제시해 주세요."},
+ {"role": "user", "content": "한 도시에서 매년 나무를 심고 있습니다. 첫해에 100그루를 심었고, 매년 전년도에 심은 나무의 수보다 20%씩 더 많은 나무를 심고 있습니다. 2년 후에는 총 몇 그루의 나무를 심게 될까요?"},
+ {"role": "assistant", "content": """이 문제를 해결하기 위해 단계별로 접근해 보겠습니다.
+
+1단계: 주어진 정보 정리
+- 첫해에 100그루를 심음
+- 매년 전년도보다 20% 더 많은 나무를 심음
+- 2년 후의 총 나무 수를 구해야 함
+
+2단계: 두 번째 해에 심은 나무 수 계산
+- 첫해보다 20% 증가
+- 100 + (100의 20%) = 100 + 20 = 120그루
+
+3단계: 세 번째 해에 심은 나무 수 계산
+- 두 번째 해보다 20% 증가
+- 120 + (120의 20%) = 120 + 24 = 144그루
+
+4단계: 3년 동안 심은 총 나무 수 계산
+- 첫해: 100그루
+- 둘째 해: 120그루
+- 셋째 해: 144그루
+- 총합: 100 + 120 + 144 = 364그루
+
+따라서, 2년 후(즉, 3년째)에는 총 364그루의 나무를 심게 됩니다."""}
+ ],
+
+ "1-shot": [
+ {"role": "user", "content": "Git의 rebase와 merge의 차이점을 설명하고, 각각 어떤 상황에서 사용하는 것이 좋은지 예를 들어 설명해주세요."},
+ {"role": "assistant", "content": """Git에서 `rebase`와 `merge`는 두 개의 브랜치를 통합하는 데 사용되는 두 가지 주요 명령어입니다. 이들의 차이점과 사용 상황을 설명하겠습니다.
+
+### Rebase
+
+#### 개념
+- `rebase`는 하나의 브랜치의 커밋을 다른 브랜치의 끝에 다시 적용하는 것입니다. 즉, 커밋 히스토리를 새로 만든다고 할 수 있습니다.
+- 결과적으로 커밋 히스토리가 깔끔하게 정리됩니다.
+
+#### 사용 상황
+- **깔끔한 히스토리가 필요할 때**: 브랜치 히스토리가 병합 없이 일직선으로 이어지도록 하고 싶을 때 유용합니다.
+- **작업 중인 브랜치를 최신 상태로 유지하고 싶을 때**: 예를 들어, `feature` 브랜치에서 작업 중인데 `main` 브랜치에서 업데이트가 있을 경우, `feature` 브랜치를 `rebase`하여 최신 상태로 유지할 수 있습니다.
+
+#### 예제
+1. `feature` 브랜치에서 작업 중입니다.
+2. `main` 브랜치에 새로운 커밋이 추가되었습니다.
+3. `feature` 브랜치에서 `git rebase main`을 실행합니다.
+4. `feature` 브랜치의 커밋들이 `main` 브랜치의 최신 커밋들 뒤에 재배치됩니다.
+
+```bash
+git checkout feature
+git rebase main
+```
+
+### Merge
+
+#### 개념
+- `merge`는 두 개의 브랜치를 합치는 방법으로, 두 브랜치의 히스토리를 유지하며 새로운 병합 커밋을 생성합니다.
+- `merge`는 기존의 히스토리를 그대로 보존합니다.
+
+#### 사용 상황
+- **히스토리를 유지하고 싶을 때**: 각 브랜치의 작업 기록을 그대로 보존하면서 병합할 때 사용합니다.
+- **협업 중 충돌을 명확히 해결하고 기록을 남기고 싶을 때**: 여러 사람이 같은 저장소에서 작업할 때, `merge`는 충돌 해결 과정과 그 기록을 명확히 남길 수 있습니다.
+
+#### 예제
+1. `feature` 브랜치에서 작업을 완료했습니다.
+2. `main` 브랜치에 병합하고 싶습니다.
+3. `main` 브랜치로 체크아웃한 후 `feature` 브랜치를 병합합니다.
+
+```bash
+git checkout main
+git merge feature
+```
+
+### 요약
+
+- **Rebase**는 히스토리를 깔끔하게 정리하는 데 유리하며, 주로 개인 작업이나 `feature` 브랜치를 최신 상태로 유지할 때 사용됩니다.
+- **Merge**는 두 브랜치의 작업 히스토리를 보존하면서 병합하며, 협업 과정에서 충돌 해결과 기록을 명확히 남기는 데 유리합니다.
+
+각 방법의 장단점과 사용 상황을 고려하여 적절히 선택하는 것이 중요합니다."""}
+],
+ "default": [],
+}
parser = argparse.ArgumentParser()
-parser.add_argument("--gpu_devices", help=" : CUDA_VISIBLE_DEVICES", default="0")
-parser.add_argument("--model", help=" : Model to evaluate", default="yanolja/EEVE-Korean-Instruct-2.8B-v1.0")
-parser.add_argument("--template", help=" : Template File Location", default="./templates/template-EEVE.json")
-parser.add_argument("--model_len", help=" : Maximum Model Length", default=4096, type=int)
+parser.add_argument('-g' ,'--gpu_devices', help=' : CUDA_VISIBLE_DEVICES', default='0')
+parser.add_argument('-m', '--model', help=' : Model to evaluate', default='yanolja/EEVE-Korean-Instruct-2.8B-v1.0')
+parser.add_argument('-ml', '--model_len', help=' : Maximum Model Length', default=4096, type=int)
args = parser.parse_args()
-os.environ["CUDA_VISIBLE_DEVICES"] = args.gpu_devices
-gpu_counts = len(args.gpu_devices.split(","))
+print(f"Args - {args}")
-df_config = pd.read_json(args.template, typ="series")
-SINGLE_TURN_TEMPLATE = df_config.iloc[0]
-DOUBLE_TURN_TEMPLATE = df_config.iloc[1]
+os.environ["CUDA_VISIBLE_DEVICES"] = args.gpu_devices
+gpu_counts = len(args.gpu_devices.split(','))
llm = LLM(
- model=args.model, tensor_parallel_size=gpu_counts, max_model_len=int(args.model_len), gpu_memory_utilization=0.95
-)
+ model=args.model,
+ tensor_parallel_size=gpu_counts,
+ max_model_len=args.model_len,
+ gpu_memory_utilization=0.8,
+ trust_remote_code=True # !
+ )
+
sampling_params = SamplingParams(
temperature=0,
- top_p=1,
- top_k=-1,
- early_stopping=True,
- best_of=4,
- use_beam_search=True,
- skip_special_tokens=False,
+ skip_special_tokens=True,
max_tokens=args.model_len,
- stop=["<|endoftext|>", "", "<|im_end|>", "[INST]", "[/INST]", "", ""],
-)
-
-df_questions = pd.read_json("questions.jsonl", orient="records", encoding="utf-8-sig", lines=True)
-
-
-def format_single_turn_question(question):
- return SINGLE_TURN_TEMPLATE.format(question[0])
-
-
-single_turn_questions = df_questions["questions"].map(format_single_turn_question)
-single_turn_outputs = [
- output.outputs[0].text.strip() for output in llm.generate(single_turn_questions, sampling_params)
-]
-
-
-def format_double_turn_question(question, single_turn_output):
- return DOUBLE_TURN_TEMPLATE.format(question[0], single_turn_output, question[1])
-
-
-multi_turn_questions = df_questions[["questions", "id"]].apply(
- lambda x: format_double_turn_question(x["questions"], single_turn_outputs[x["id"] - 1]), axis=1
-) # bad code ig?
-
-multi_turn_outputs = [output.outputs[0].text.strip() for output in llm.generate(multi_turn_questions, sampling_params)]
-
-df_output = pd.DataFrame(
- {
- "id": df_questions["id"],
- "category": df_questions["category"],
- "questions": df_questions["questions"],
- "outputs": list(zip(single_turn_outputs, multi_turn_outputs)),
- "references": df_questions["references"],
- }
-)
-df_output.to_json(f'{str(args.model).replace("/", "_")}.jsonl', orient="records", lines=True, force_ascii=False)
+ stop=[
+ '<|endoftext|>',
+ '[INST]', '[/INST]',
+ '<|im_end|>',
+ '<|end|>'
+ ]
+ )
+
+df_questions = pd.read_json(
+ 'questions.jsonl',
+ orient='records',
+ encoding="utf-8-sig",
+ lines=True
+ )
+
+if not os.path.exists("./generated/" + args.model):
+ os.makedirs("./generated/" + args.model)
+
+for strategy_name, prompts in PROMPT_STRATEGY.items():
+ def format_single_turn_question(question):
+ return llm.llm_engine.tokenizer.tokenizer.apply_chat_template(prompts + [{"role": "user", "content": question[0]}], tokenize=False, add_generation_prompt=True)
+
+ single_turn_questions = df_questions['questions'].map(format_single_turn_question)
+ print(single_turn_questions.iloc[0])
+ single_turn_outputs = [output.outputs[0].text.strip() for output in llm.generate(single_turn_questions, sampling_params)]
+
+ def format_double_turn_question(question, single_turn_output):
+ return llm.llm_engine.tokenizer.tokenizer.apply_chat_template(prompts + [{"role": "user", "content": question[0]}, {"role": "assistant", "content": single_turn_output}, {"role": "user", "content": question[1]}], tokenize=False, add_generation_prompt=True)
+
+ multi_turn_questions = df_questions[['questions', 'id']].apply(lambda x: format_double_turn_question(x['questions'], single_turn_outputs[x['id']-1]), axis=1)
+ multi_turn_outputs = [output.outputs[0].text.strip() for output in llm.generate(multi_turn_questions, sampling_params)]
+
+ df_output = pd.DataFrame({'id': df_questions['id'], 'category': df_questions['category'], 'questions': df_questions['questions'], 'outputs': list(zip(single_turn_outputs, multi_turn_outputs)), "references": df_questions['references']})
+ df_output.to_json('./generated/' + os.path.join(args.model, f'{strategy_name}.jsonl'), orient='records', lines=True, force_ascii=False)
diff --git a/generator_claude.py b/generator_claude.py
deleted file mode 100644
index 7aa5263..0000000
--- a/generator_claude.py
+++ /dev/null
@@ -1,62 +0,0 @@
-import pandas as pd
-from anthropic import Anthropic
-from tqdm import tqdm
-
-
-MAX_MODEL_LEN = 4096
-MODEL = "claude-3-5-sonnet-20240620" # Update this to the appropriate Anthropic model
-
-client = Anthropic(api_key="...") # Replace with your Anthropic API key
-
-df_questions = pd.read_json("questions.jsonl", orient="records", encoding="utf-8-sig", lines=True)
-
-
-def format_single_turn_question(question):
- return question[0]
-
-
-single_turn_questions = df_questions["questions"].map(format_single_turn_question)
-single_turn_outputs = []
-
-for question in tqdm(single_turn_questions, desc="Processing single-turn questions"):
- response = client.messages.create(
- model=MODEL,
- max_tokens=MAX_MODEL_LEN,
- messages=[{"role": "user", "content": question}],
- temperature=0,
- )
- single_turn_outputs.append(response.content[0].text)
-
-
-def format_double_turn_question(question, single_turn_output):
- return [question[0], single_turn_output, question[1]]
-
-
-multi_turn_questions = df_questions[["questions", "id"]].apply(
- lambda x: format_double_turn_question(x["questions"], single_turn_outputs[x["id"] - 1]), axis=1
-)
-multi_turn_outputs = []
-
-for question in tqdm(multi_turn_questions, desc="Processing multi-turn questions"):
- response = client.messages.create(
- model=MODEL,
- max_tokens=MAX_MODEL_LEN,
- messages=[
- {"role": "user", "content": question[0]},
- {"role": "assistant", "content": question[1]},
- {"role": "user", "content": question[2]},
- ],
- temperature=0,
- )
- multi_turn_outputs.append(response.content[0].text)
-
-df_output = pd.DataFrame(
- {
- "id": df_questions["id"],
- "category": df_questions["category"],
- "questions": df_questions["questions"],
- "outputs": list(zip(single_turn_outputs, multi_turn_outputs)),
- "references": df_questions["references"],
- }
-)
-df_output.to_json(f'{str(MODEL).replace("/", "_")}.jsonl', orient="records", lines=True, force_ascii=False)
diff --git a/generator_openai.py b/generator_openai.py
deleted file mode 100644
index f264ce9..0000000
--- a/generator_openai.py
+++ /dev/null
@@ -1,71 +0,0 @@
-import time
-
-import pandas as pd
-from openai import OpenAI
-from tqdm import tqdm
-
-
-MAX_MODEL_LEN = 1600
-# MODEL = "solar-1-mini-chat"
-# MODEL = "gpt4-turbo-0409"
-MODEL = "gpt-4-turbo-2024-04-09"
-
-client = OpenAI(api_key="...")
-
-df_questions = pd.read_json("questions.jsonl", orient="records", encoding="utf-8-sig", lines=True)
-
-
-def format_single_turn_question(question):
- return question[0]
-
-
-single_turn_questions = df_questions["questions"].map(format_single_turn_question)
-single_turn_outputs = []
-
-for question in tqdm(single_turn_questions, desc="Processing Single Turn Questions"):
- response = client.chat.completions.create(
- model=MODEL,
- messages=[{"role": "user", "content": question}],
- max_tokens=MAX_MODEL_LEN,
- n=1,
- stop=None,
- temperature=0,
- )
- time.sleep(10)
- single_turn_outputs.append(response.choices[0].message.content.strip())
-
-
-def format_double_turn_question(question, single_turn_output):
- return [question[0], single_turn_output, question[1]]
-
-
-multi_turn_questions = df_questions[["questions", "id"]].apply(
- lambda x: format_double_turn_question(x["questions"], single_turn_outputs[x["id"] - 1]), axis=1
-)
-multi_turn_outputs = []
-for question in tqdm(multi_turn_questions, desc="Processing Multi Turn Questions"):
- response = client.chat.completions.create(
- model=MODEL,
- messages=[
- {"role": "user", "content": question[0]},
- {"role": "assistant", "content": question[1]},
- {"role": "user", "content": question[2]},
- ],
- max_tokens=MAX_MODEL_LEN,
- n=1,
- stop=None,
- temperature=0,
- )
- time.sleep(10)
- multi_turn_outputs.append(response.choices[0].message.content.strip())
-
-df_output = pd.DataFrame(
- {
- "id": df_questions["id"],
- "category": df_questions["category"],
- "questions": df_questions["questions"],
- "outputs": list(zip(single_turn_outputs, multi_turn_outputs)),
- "references": df_questions["references"],
- }
-)
-df_output.to_json(f'{str(MODEL).replace("/", "_")}.jsonl', orient="records", lines=True, force_ascii=False)
diff --git a/generator_vllm.py b/generator_vllm.py
deleted file mode 100644
index 1c3c021..0000000
--- a/generator_vllm.py
+++ /dev/null
@@ -1,113 +0,0 @@
-import os
-import time
-from concurrent.futures import ThreadPoolExecutor
-
-import pandas as pd
-import requests
-from torch.utils.data import DataLoader, Dataset
-
-
-MODEL_NAME = os.environ.get("MODEL_NAME", "VLLM_MODEL_NAME")
-
-VLLM_HOST = os.environ.get("VLLM_HOST", "http://VLLM_HOST:VLLM_PORT")
-API_ENDPOINT = f"{VLLM_HOST}/v1/chat/completions"
-API_KEY = os.environ.get("API_KEY", "token-abc123")
-MAX_TOKENS = int(os.environ.get("MAX_TOKENS", 4096))
-
-df_questions = pd.read_json("questions.jsonl", orient="records", encoding="utf-8-sig", lines=True)
-
-
-class QuestionDataset(Dataset):
- def __init__(self, df):
- self.df = df
-
- def __len__(self):
- return len(self.df)
-
- def __getitem__(self, idx):
- return self.df.iloc[idx]
-
-
-def collate_fn(batch):
- return pd.DataFrame(batch)
-
-
-def request_with_messages(messages, max_retries=20):
- payload = {
- "messages": messages,
- "model": MODEL_NAME,
- "frequency_penalty": 0,
- "max_tokens": MAX_TOKENS,
- "presence_penalty": 0,
- "stream": False,
- "temperature": 0,
- "top_p": 1,
- }
-
- retries = 0
- while retries < max_retries:
- try:
- response = requests.post(
- API_ENDPOINT, json=payload, headers={"Authorization": f"Bearer {API_KEY}"}, timeout=120
- )
- response.raise_for_status()
- result = response.json()
- return result["choices"][0]["message"]["content"].strip()
- except (requests.RequestException, KeyError) as e:
- print(f"Error: {e}")
- retries += 1
- time.sleep(2) # wait for 2 seconds before retrying
- return "Failed to generate response after several attempts."
-
-
-def process_batch(batch):
- single_turn_outputs = []
-
- for question in batch["questions"]:
- messages = [
- {"role": "user", "content": question[0]},
- ]
- output = request_with_messages(messages)
- single_turn_outputs.append(output)
-
- multi_turn_questions = []
- for idx, row in batch.iterrows():
- multi_turn_prompt = [
- {"role": "user", "content": row["questions"][0]},
- {"role": "assistant", "content": single_turn_outputs[0]},
- {"role": "user", "content": row["questions"][1]},
- ]
- multi_turn_questions.append(multi_turn_prompt)
-
- multi_turn_outputs = []
- for prompt in multi_turn_questions:
- multi_turn_outputs.append(prompt)
-
- return pd.DataFrame(
- {
- "id": batch["id"],
- "category": batch["category"],
- "questions": batch["questions"],
- "outputs": list(zip(single_turn_outputs, multi_turn_outputs)),
- "references": batch["references"],
- }
- )
-
-
-def process_data(df_questions, batch_size=1, num_workers=42):
- dataset = QuestionDataset(df_questions)
- dataloader = DataLoader(
- dataset, batch_size=batch_size, shuffle=False, num_workers=num_workers, collate_fn=collate_fn, pin_memory=True
- )
-
- with ThreadPoolExecutor() as executor:
- results = list(executor.map(process_batch, dataloader))
-
- df_output = pd.concat(results, ignore_index=True)
- output_json = f"{MODEL_NAME}.jsonl"
- os.makedirs(os.path.dirname(output_json), exist_ok=True)
- df_output.to_json(output_json, orient="records", lines=True, force_ascii=False)
-
-
-# Call the process_data function with appropriate parameters
-process_data(df_questions, batch_size=1, num_workers=42)
diff --git a/judgement.py b/judgement.py
deleted file mode 100644
index f066e52..0000000
--- a/judgement.py
+++ /dev/null
@@ -1,100 +0,0 @@
-import argparse
-import json
-import re
-import time
-from concurrent.futures import ThreadPoolExecutor
-from datetime import datetime
-from threading import Lock
-from typing import Dict, Union
-
-import pandas as pd
-from openai import OpenAI
-
-
-time_start = datetime.now().strftime("%Y%m%d_%H%M%S")
-
-parser = argparse.ArgumentParser()
-parser.add_argument("-o", "--model-output", help=" : Model Output File Location", default=None)
-parser.add_argument("-k", "--openai-api-key", help=" : Model", default=None)
-parser.add_argument("-j", "--judge-model", help=" : Judge Model", default="gpt-4-1106-preview")
-parser.add_argument("-t", "--threads", help=" : Thread count", default=10, type=int)
-args = parser.parse_args()
-
-if args.model_output is None:
- raise ValueError("Model Output File Location is required")
-if args.openai_api_key is None:
- raise ValueError("OpenAI API Key is required")
-
-client = OpenAI(api_key=args.openai_api_key)
-
-df_model_outputs = pd.read_json(args.model_output, orient="records", encoding="utf-8-sig", lines=True)
-df_judge_template = pd.read_json("judge_template.jsonl", orient="records", encoding="utf-8-sig", lines=True)
-
-lock = Lock()
-
-
-def create_answers(model_output, is_multi_turn: bool = False) -> Dict[str, Union[str, float]]:
- # Construct prompt from model output
- model_questions = model_output["questions"]
- model_outputs = model_output["outputs"]
- model_references = model_output["references"]
-
- prompt = f"**질문**\n{model_questions[0]}\n\n**모델 답변**\n{model_outputs[0]}"
-
- if model_references and model_references[0]:
- prompt += f"\n\n**Ground Truth**\n{model_references[0]}"
-
- if is_multi_turn:
- prompt += f"\n\n**이어지는 질문**\n{model_questions[1]}\n\n**모델 답변**\n{model_outputs[1]}"
- if model_references and model_references[1]:
- prompt += f"\n\n**Ground Truth**\n{model_references[1]}"
-
- prompt += "\n\n[[대화 종료. 평가 시작.]]"
-
- try:
- response = client.chat.completions.create(
- model=args.judge_model,
- temperature=0,
- n=1,
- messages=[
- {"role": "system", "content": df_judge_template.iloc[1 if is_multi_turn else 0]["system_prompt"]},
- {"role": "user", "content": prompt},
- ],
- )
- # Extract judge message and score using regular expressions
- content = response.choices[0].message.content
- judge_message_match = re.search(r"평가:(.*?)점수:", content, re.DOTALL)
- judge_message = judge_message_match.group(1).strip() if judge_message_match else "No judge message found"
-
- judge_score_match = re.search(r"점수:\s*(\d+(\.\d+)?)", content)
- if judge_score_match:
- judge_score = float(judge_score_match.group(1))
- else:
- raise ValueError("No score found in response")
-
- return {"judge_message": judge_message, "judge_score": judge_score}
-
- except Exception as e:
- print("Error. Retrying after 10 sec", e)
- time.sleep(10)
- return create_answers(model_output, is_multi_turn)
-
-
-def process_item(_, row):
- row = row[1]
-
- query_single = create_answers(row)
- query_multi = create_answers(row, is_multi_turn=True)
-
- row["query_single"] = query_single
- row["query_multi"] = query_multi
- row = row.to_dict()
-
- with lock:
- with open(f"judge_{time_start}.jsonl", "a", encoding="utf-8-sig") as f:
- f.write(json.dumps(row, ensure_ascii=False))
- f.write("\n")
-
-
-with ThreadPoolExecutor(max_workers=int(args.threads)) as executor:
- list(executor.map(process_item, df_model_outputs.index, df_model_outputs.iterrows()))
diff --git a/results/judge_152334H_miqu-1-70b-sf.jsonl b/results/judge_152334H_miqu-1-70b-sf.jsonl
deleted file mode 100644
index e12bec8..0000000
--- a/results/judge_152334H_miqu-1-70b-sf.jsonl
+++ /dev/null
@@ -1,42 +0,0 @@
-{"id": 14, "category": "수학(Math)", "questions": ["f(x) = 3x^3 + 2x^2 + 58을 미분하시오.", "미분한 식을 한 번 더 미분해보시오."], "outputs": ["함수 f(x) = 3x^3 + 2x^2 + 58를 미분하면,\n\nf'(x) = d(3x^3)/dx + d(2x^2)/dx + d(58)/dx\n\n= 3d(x^3)/dx + 2d(x^2)/dx + 0 (상수항은 미분하면 0)\n\n= 3(3x^2) + 2(2x)\n\n= 9x^2 + 4x\n\n따라서, 함수 f(x) = 3x^3 + 2x^2 + 58의 미분값은 f'(x) = 9x^2 + 4x입니다.", "함수 f(x) = 3x^3 + 2x^2 + 58의 미분값 f'(x) = 9x^2 + 4x를 한 번 더 미분하면,\n\nf''(x) = d(9x^2)/dx + d(4x)/dx\n\n= 9d(x^2)/dx + 4d(x)/dx\n\n= 9(2x) + 4(1)\n\n= 18x + 4\n\n따라서, 함수 f(x) = 3x^3 + 2x^2 + 58의 두 번째 미분값은 f''(x) = 18x + 4입니다."], "references": ["9x^2 + 4x", "18x + 4"], "query_single": {"judge_message": "모델이 제공한 답변은 정확하고, 미분 과정을 단계별로 잘 설명하고 있다. 또한 최종 결과도 Ground Truth와 일치한다.", "judge_score": 10.0}, "query_multi": {"judge_message": "모델이 제공한 답변은 정확하고, 미분 과정을 단계별로 설명하며 이전 대화 맥락과도 잘 호응하고 있다. Ground Truth와 일치한다.", "judge_score": 10.0}}
-{"id": 23, "category": "코딩(Coding)", "questions": ["'XSS가 무엇이고 어떻게 악용될 수 있는지'를 설명하는 웹사이트의 HTML을 작성해보세요.", "XSS를 방지하는 방법은 무엇이 있나요? 이번에는 HTML이 아닌 마크다운 형식으로 작성해주세요."], "outputs": ["먼저, XSS(Cross-Site Scripting)는 웹 애플리케이션 보안 취약점 중 하나로, 공격자가 악의적인 스크립트 코드를 웹 사이트에 삽입하여 다른 사용자를 공격하는 것을 말합니다. 이를 통해 공격자는 쿠키를 탈취하거나, 악성 소프트웨어를 설치하여 사용자의 개인 정보를 훔칠 수 있습니다.\n\nHTML 코드는 다음과 같습니다:\n\n```html\n\n\n\n \n \n XSS 취약점\n\n\n XSS(Cross-Site Scripting) 취약점
\n XSS는 웹 애플리케이션 보안 취약점 중 하나로, 공격자가 악의적인 스크립트 코드를 웹 사이트에 삽입하여 다른 사용자를 공격하는 것을 말합니다.
\n XSS 악용 사례
\n \n - 쿠키 탈취: 공격자는 악의적인 스크립트를 이용하여 사용자의 쿠키를 탈취할 수 있습니다.
\n - 악성 소프트웨어 설치: 공격자는 악의적인 스크립트를 이용하여 사용자의 컴퓨터에 악성 소프트웨어를 설치할 수 있습니다.
\n - 개인 정보 탈취: 공격자는 악의적인 스크립트를 이용하여 사용자의 개인 정보를 탈취할 수 있습니다.
\n
\n XSS 방지 방법
\n \n - 입력 값 검증: 입력 값에 대한 검증을 수행하여 악의적인 스크립트 코드가 삽입되는 것을 방지할 수 있습니다.
\n - 출력 값 에스케이프: 출력 값에 대한 에스케이프를 수행하여 악의적인 스크립트 코드가 실행되는 것을 방지할 수 있습니다.
\n - Content Security Policy: Content Security Policy를 이용하여 스크립트 실행을 제한할 수 있습니다.
\n
\n\n\n```", "XSS(Cross-Site Scripting)는 웹 애플리케이션 보안 취약점 중 하나로, 공격자가 악의적인 스크립트 코드를 웹 사이트에 삽입하여 다른 사용자를 공격하는 것을 말합니다. XSS를 방지하는 방법에는 다음과 같은 것들이 있습니다.\n\n1. **입력 값 검증**: 입력 값에 대한 검증을 수행하여 악의적인 스크립트 코드가 삽입되는 것을 방지할 수 있습니다. 예를 들어, 사용자가 입력한 값에서 ``, which would be displayed on the page and executed by anyone viewing the comments.
\n \n \n \n Types of XSS:
\n \n - Reflected XSS: The malicious script is reflected back to the user in the server's response to their request.
\n - Stored XSS: The script is stored on the server and remains persistent even after the user has left the page.
\n - DOM-based XSS: The script manipulates the Document Object Model (DOM) of the user's browser, allowing it to execute without the need for a server response.
\n
\n \n \n \n Abuse of XSS:
\n \n - Stealing sensitive data (cookies, login credentials)
\n - Phishing attacks: impersonating a trusted site to trick users into revealing personal information
\n - Website defacement: altering the appearance or content of a legitimate site
\n - Executing unauthorized actions on behalf of users, such as transferring funds or making purchases
\n
\n \n \n \n Example of Malicious Input:
\n \n <div>User Comment: <script>alert('XSS Attack!');</script></div>\n
\n When displayed without sanitization, this would result in an alert box for all visitors.
\n \n \n \n