본문 바로가기

이 게시물은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다

스타트업 투자/데이터 + 테크

패스트캠퍼스 환급챌린지 27일차 : 명사구 질문 생성하기 강의 후기

by Sungwook Choi 2025. 4. 27.

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성하였습니다.

*_1. 학습 인증샷 4장 이상 포함
*_① 오늘자 날짜, 공부 시작 시각 포함 사진 1장

② 오늘자 날짜, 공부 종료 시각 포함 사진 1장

③ 1개 클립 수강 인증 사진 (강의장 목록 캡쳐, 강의 내용이 담긴 수강화면이 보이지 않도록) 1장

④ 학습 인증샷 1장 이상 (ex. 필기 촬영, 작업물, 등)

2. 학습 후기 700자 이상 (공백 제외)

  1. 명사구 질문 만들기
  2. 이전 네거티브 샘플 데이터셋으로 파인튜닝 하면, 질문이 의문문만 있어서 명사구 질문에는 취약한 모델이 됨
  3. 명사구 질문에도 잘 대응하기 위해, 명사구 질문 데이터셋을 만들고 이를 파인튜닝 하는 과정이 필요함
  4. 좋은 언어모델 (e.g. chatgpt-4o)로 활용해 질문 데이터셋을 명사구 질문 데이터셋으로 바꾸는 코드와 실행이 필요함
  5. 나머지 과정은 네거티브 샘플 훈련하는 것과 똑같은 프롬프트와 코드를 사용해서 파인튜닝 하면 됨

4번 코드

system_prompt = """당신은 주어진 질문을 명사구 형태로 바꿔서 재작성해야 합니다.

### 지시사항
1. 주어진 질문을 명사구 형태로 바꾸세요.
2. 명사구 형태로 바꿀 때 정보의 손실은 없었으면 합니다.

예시)
질문: 서울 지역의 개업변호사가 1만474명이었던 시기에 마을변호사는 몇 명이었는가?
재작성: 서울 지역의 개업변호사가 1만474명이었던 시기의 마을변호사 인원수

질문: 발베니 스토리 전시회에 도서 300여 권을 제공하는 서점이 있는 도시는?
재작성: 발베니 스토리 전시회에 도서 300여 권을 제공하는 서점이 있는 도시"""


questions = df["question"].to_list()

user_prompts = []

for question in questions:
  user_prompts.append("질문: " + question + "\n재작성:")

result_lst = []
for user_prompt in tqdm(user_prompts):
  response = client.chat.completions.create(
    model="gpt-4o",
    messages=[
          {"role": "system", "content": system_prompt},
          {"role": "user", "content": user_prompt}
      ],
    temperature=0
  )
  result_lst.append(response.choices[0].message.content)

df['question'] = result_lst

5번 코드

# 정답이 첫번째 문서에만 위치하지 않도록 문서를 섞는다.
samples = []
for context, negative_samples in zip(df['context'].to_list(), df['negative_samples'].to_list()):
  documents = [context] + list(negative_samples)
  random.shuffle(documents)
  samples.append(documents)

user_prompts = []
for sample in samples:
  user_prompt = '검색 결과:\n'
  for idx, s in enumerate(sample):
    user_prompt = user_prompt  + '문서' + str(idx + 1) + ':' + s + '\n'
    user_prompt = user_prompt + '---\n'
  user_prompts.append(user_prompt)


system_prompt = """당신은 검색된 문서부터 질문의 답변을 작성하는 언어 모델입니다.

### 지시사항
1. 질문으로부터 주어진 다수의 문서에서 답을 찾아 작성하세요.
2. 검색된 문서에 질문의 답이 없는 경우에는 질문에 대한 내용을 언급하면서 답을 찾을 수 없다고 작성하세요.
3. 답변에서 참고자료의 내용을 인용한 경우, 답변 맨 끝에 인용한 문서 id를 추가하세요. 답변에 내용을 인용한 경우에만 작성해야 합니다. 인용한 게 없다면 쓰지마세요.
4. 문서 id 값은 검색 결과에서 가져온 것이며 두 개의 대괄호로 묶어야 하며 ref라는 키워드와 함께 작성해야 합니다. 예를 들어 특정 문단이 3번, 5번 문서에서 인용했다면 다음과 같이 작성하십시오.
예시) ~~~해서 했습니다. [[ref3]], [[ref5]]
5. 주요 문장 또는 문단 뒤에 ref문서번호를 덧붙이는 것은 매우 중요합니다. 이는 반드시 지켜져야 합니다.
6. 문단 중간 중간에 인용이 들어가더라도 답변은 하나의 이어지는 평문으로 작성하십시오.
7. 주어진 문서는 검색 결과입니다. 따라서 질문과 연관없는 문서가 숨어있을 수 있으니 이를 인용하지 않도록 주의하십시오.
8. 검색 결과에 없는 내용은 답변으로 작성하지 마십시오. 가장 중요한 지시사항입니다. 따라서 인용 없이는 그 어떠한 설명도 제공할 수 없습니다.
9. 답변은 최대한 풍부하게 작성해주시기 바랍니다.
10. 검색 결과는 모두 독립적인 문서들이며 반드시 연관되어져 있거나 순서대로 이어지는 문서들이 아닙니다.
"""

user_prompt_for_answer = []
for multi_document_question, user_prompt in zip(df['question'].to_list(), user_prompts):
  user_prompt_for_answer.append('질문:' + multi_document_question + '\n' + user_prompt + '답변:')


result_lst = []
for user_prompt in tqdm(user_prompt_for_answer):
  response = client.chat.completions.create(
    model="gpt-4o",
    messages=[
          {"role": "system", "content": system_prompt},
          {"role": "user", "content": user_prompt + '답변:'}
      ],
    temperature=0
  )
  result_lst.append(response.choices[0].message.content)


# 인용 문서 번호 추출
def extract_ref_numbers(text):
    # 정규표현식을 사용하여 [[ref숫자]] 패턴 찾기
    pattern = r'\[\[ref(\d+)\]\]'

    # 모든 매치 찾기
    matches = re.findall(pattern, text)

    # 문자열을 정수로 변환하고 중복 제거 후 정렬
    unique_numbers = sorted(set(map(int, matches)))

    return unique_numbers

# 인용 번호 없는 샘플 찾아내기
for idx, extracted_ref_number in enumerate(extracted_ref_numbers):
  if len(extracted_ref_number) == 0:
    print(idx)
    print(result_lst[idx])
    print('--')

url : https://abit.ly/lisbva

댓글