주간 LLM 은 매주 LLM 관련 최신 연구, 논문을 다루는 시리즈 입니다.
2025.01 - 3주차는 LLM의 instruction-following 능력을 평가할 수 있는 ifeval benchmark에 대해 다룹니다.
Overview
23년 11월에 Google과 Yale Univ에서 공개한 벤치마크 데이터 셋으로, LLM의 지시사항 준수 능력을 평가하기 위해 설계된 벤치마크로 검증 가능한 지시사항(verifiable instructions)을 포함합니다. 비교적 이전에 나온 논문이지만 LLM의 Instrcution 성능이 최근 더 중요해지면서 가장 유명한 LLM leaderboard 중 하나인, open llm leaderboard v2(24.10)에 추가된 벤치마크 입니다.
총 25개의 지시문 카테고리로, 여러 카테고리를 조합해 다양한 지시문을 생성할 수 있습니다. 총 541개의 데이터 셋이 있습니다.
- No capital letters are allowed(대문자 금지), You are not allowed to use any commas in your response. (콤마 금지)
각 프롬프트는 하나 이상의 구체적인 지시사항을 제공하며, 모델 응답이 이를 얼마나 정확히 수행하는지 평가합니다.
Dataset Detail & Eval metric
Dataset Detail
key | prompt | instruction_id_list |
1000 | I am planning a trip to Japan, and I would like thee to write an itinerary for my journey in a Shakespearean style. You are not allowed to use any commas in your response. | [ "punctuation:no_comma" ] |
1258 | I have a dime. What can I do with this dime? Give me advice in the style of a President of the United States and make sure it has at least 600 words. | [ "length_constraints:number_words" ] |
1132 | Write the lyrics to a hit song by the rock band 'The Gifted and The Not Gifted'. To make it rocky, the response should be in all capital letters. The word "rock" should not appear in your response. | [ "change_case:english_capital", "keywords:forbidden_words" ] |
데이터 셋은 key, prompt, instruction_id_list, kwargs로 구성되어 있습니다. 상단 표에는 앞에 세 개의 컬럼만 가지고 왔습니다. 전체 데이터 셋을 확인하고 싶다면 아래 링크로 들어가시면 확인할 수 있습니다.
https://huggingface.co/datasets/google/IFEval
prompt에는 다양한 시나리오(계획짜기, 조언, 가사 작성)와 함께 볼드체에 해당하는 다양한 지시문이 포함되어 있습니다. instruction_id_list에서는 각 지시문의 분류와 개수를 확인할 수 있습니다.
Evaluation Metric
논문에서는 다음과 같이 총 prompt-level과 instruction-level로 평가 매트릭 나누어 소개합니다.
- Prompt-level (strict acc/loose acc): The percentage of prompts that all verifiable instructions in each prompt are followed
- Inst-level (strict acc/loose acc): The percentage of verifiable instructions that are followed.
개별 지시문으로 따랐는지 확인
위의 설명을 해석해보자면, prompt-level은 지시문을 모두 따랐는지를, inst-level은 개별 지시문을 따랐는지를 확인하는 매트릭으로 설명이 되나, 이는 직관적으로 이해하기 어렵습니다. 이해를 위해 평가 코드를 살펴보면 다음과 같이 각각의 평가 매트릭을 정의하는 것을 확인할 수 있습니다.
def process_results(doc, results):
# (..중략..)
return {
"prompt_level_strict_acc": out_strict.follow_all_instructions,
"inst_level_strict_acc": out_strict.follow_instruction_list,
"prompt_level_loose_acc": out_loose.follow_all_instructions,
"inst_level_loose_acc": out_loose.follow_instruction_list,
}
prompt-level의 경우 follow_all_instructions을, inst-level의 경우 follow_instruction_list을 가집니다. 이 두개의 차이는 다음 코드에서 확인할 수 있습니다.
def test_instruction_following_strict(inp,response,):
"""Tests response to see if instructions are followed."""
instruction_list = inp.instruction_id_list
is_following_list = []
# (..중략..)
for index, instruction_id in enumerate(instruction_list):
# (..중략..)
if response.strip() and instruction.check_following(response):
is_following_list.append(True)
else:
is_following_list.append(False)
return OutputExample(
instruction_id_list=inp.instruction_id_list,
prompt=inp.prompt,
response=response,
follow_all_instructions=all(is_following_list),
follow_instruction_list=is_following_list,
)
코드에서 확인할 수 있듯이, prompt-level의 경우, is_following_list에 저장된 값이 모두 True여야 1을, inst-level은 list를 전달받아 개별 지시문을 확인하는 것을 알 수 있습니다. 전체 코드는 아래 링크를 참고하시면 됩니다.
https://github.com/EleutherAI/lm-evaluation-harness/blob/main/lm_eval/tasks/ifeval/utils.py
이해를 위해 앞서 소개한 데이터 셋 중 key: 1132를 예시로 들자면, prompt-level의 경우 주어진 두 개의 지시문인 [ "change_case:english_capital", "keywords:forbidden_words" ]을 모두 지켜야 1점을, inst-level의 경우 개별 지시문의 수행여부를 보기 때문에 모두 지켰을 경우 1점, 하나만 지켰을 경우 0.5점, 모두 지키지 못했을 때 0점을 주게 됩니다. key 1000, 1258은 지시문이 한 개 이므로 prompt-level과 inst-level이 동일하게 점수를 부여합니다.
앞서 설명드린 내용은 prompt-level, inst-level의 strict acc에 대한 설명입니다. 그러면 loose acc는 어떻게 계산될까요? 논문에서는 다음의 방식으로 loose acc를 정의하고 있습니다.
LLM의 원본 응답을 resp라고 할 때, transform함수를 사용해 응답을 t 번 변형하여, 그 중 한 번이라도 지시문을 만족할 경우 점수를 주는 방식입니다. 변형 방식은 응답에서 흔히 사용되는 마크다운 태크(*,**) 제거, 서두/결론 제거 등이 있습니다.
최종적으로, Ifeval을 벤치마크로 사용하여 LLM을 평가할 경우 총 네개의 매트릭이 나오게 됩니다. prompt-level 보다는 inst-level이, strict-acc보다는 loose-acc가 더 높은 점수가 나오게 됩니다. 보통, 이 네 개의 평균을 ifeval의 최종 score로 사용합니다.
Practice (by lm-eval-harness)
지금까지 ifeval의 데이터 셋 구성과 평가 매트릭을 살펴봤습니다. 마지막으로, 모델의 ifeval 성능을 실제로 어떻게 확인할 수 있는지 간단한 실습을 해보겠습니다. 물론, 논문대로 스크래치부터 구현할 수도 있지만, 다양한 모델과 데이터 셋 별로 매번 짜기는 번거로운 부분이 있습니다. 그래서 이러한 평가를 자동화해주는 툴로 가장 많이 활용되는 lm-eval-harness에서 ifeval을 돌려보겠습니다. (이후의 평가 관련 실습에도 해당 툴을 계속 이용할 예정입니다)
먼저 lm-eval-harness를 github를 통해 필요한 라이브러리를 설치해줍니다. 자세한 코드, README가 궁금하시면 아래 링크를 참고하시면 됩니다.
pip install git+https://github.com/EleutherAI/lm-evaluation-harness.git
https://github.com/EleutherAI/lm-evaluation-harness
설치가 정상적으로 되었다면, 아래의 명령어로 원하는 모델의 ifeval 성능을 확인할 수 있습니다.
lm_eval --model hf\
--model_args pretrained={MODEL_NAME} \
--tasks ifeval \
--batch_size {BS} \
--output_path {OUTPUT-PATH-FOR-RESULT} \
--log_samples
평가하고 싶은 모델 이름에 {MODEL_NAME}을, 각자 환경에 맞는 batch size를 {BS}에 (몇으로 돌리실지 모르신다면, auto로 돌리시면 됩니다, 대신 시간이 오래걸립니다), 마지막의 output_path와 log_sampled은 자세한 평가 결과가 json 파일로 따로 저장될 수 있게하는 코드로 추후 디버깅에 유용합니다(추천 argument). 이 외에 argument는 아래 링크를 참고해서 사용을 원하면 추가해주시면 됩니다.
https://github.com/EleutherAI/lm-evaluation-harness/blob/main/docs/interface.md
평가가 끝나면, 다음과 같이 log에 점수가 나오게 됩니다. 위에서 소개한 총 네개의 매트릭의 결과가 출력되는 것을 확인할 수 있습니다.
References