데보션앱 소개페이지 바로가기
로그인 선택

신고하기

CLOSE
신고사유 (대표 사유 1개)
상세내용 (선택)
0/200
  • 신고한 게시글은 더 이상 보이지 않습니다.
  • 이용약관과 운영정책에 따라 신고사유에 해당하는지 검토 후 조치됩니다.
  • 허위 신고인 경우, 신고자의 서비스 이용이 제한될 수 있으니 유의하시어 신중하게 신고해 주세요.
(이 회원이 작성한 모든 댓글과 커뮤니티 게시물이 보이지 않고, 알림도 오지 않습니다.)

미리보기

커뮤니티

      1,234

      badge 23.06.15

      글 등록

      카테고리를 선택해주세요.

      DEVOTEE를 활성화 시키면
      지금 작성한 커뮤니티 글에 대해 1개의 댓글을 달아줍니다.

      버튼을 누르면 글 수정 시 ChatGPT가 작성한 댓글이 수정됩니다.

      임시저장함에 저장되었습니다. 저장일시 : 2022.5.17 14:29:08

      임시저장함

      제목을 선택하시면 이어서 작성이 가능하며,
      최대 20건까지 저장합니다.
      컨텐츠 유형, 제목, 저장일시, 삭제로 이뤄진 임시저장 목록
      컨텐츠 유형 제목 저장일 삭제

      데보션 블로그 게재 요청

      CLOSE
      • *
      • *

      본인인증

      효율적인 데보션 서비스 이용 및
      고객님의 소중한 개인정보보호를 위해
      본인인증을 진행해주세요. 본인인증 미 진행 시 로그인이 제한됩니다.
      본인인증 실패

      본인인증 로그인에 실패하였습니다.
      회원이 아니시거나 본인인증 등록이
      완료되지 않은 사용자입니다.

      회원정보 연결

      LLM 성능, 어떻게 평가하는 것일까? (feat. lm-eval-harness)

      alankim 24.08.27
      54,799 15 3
      DEVOTEE 요약
      최근 LLM(대형 언어 모델)의 성능 평가에 대한 관심이 높아지고 있으며, KoBEST와 KMMLU 같은 한국어 벤치마크 데이터셋을 통해 이를 평가합니다. 평가 지표로는 정확도(Accuracy), F1 Score, BLEU, ROUGE 등이 사용되며, 모델의 출력이 정형화되지 않은 경우 확률 기반 평가 방식을 적용할 수 있습니다. 성능 평가 자동화 도구로는 lm-eval-harness가 일반적으로 사용됩니다.
      DEVOTEE 추천 블로그

      들어가며

      최근 LLM이 다양한 분야에 적용되면서, 이러한 모델들의 성능을 어떻게 평가하고 비교할 것인가에 대한 관심이 높아지고 있습니다.

      오픈소스로 공개된 LLM 모델들의 성능이 향상되면서 번역, 요약, 챗봇, Q&A 등 여러 분야에서 의미 있는 성과를 보여주고 있는데요.

      그러나 이러한 모델들이 실제로 얼마나 효과적인지, 특정 작업에서 얼마나 신뢰할 수 있는지 평가하는 것은 결코 간단하지 않습니다.

      이번 포스팅에서는 LLM의 평가 원리를 간단히 살펴보고, 한국어 언어 능력 평가를 위한 벤치마크 데이터셋과 평가 자동화를 위한 툴을 사용해 llama-3.1-8B 모델을 평가해보고자 합니다.


      이 글에서 다루는 내용은 다음과 같습니다.

      • 한국어 LLM 벤치마크 소개 (KoBEST, KMMLU)

      • Accuracy, F1 Score, BLEU, ROUGE 등의 모델 평가 지표

      • 확률 기반과 생성 기반의 모델 평가 방법

      • lm-eval-harness의 설치와 활용 방법

      • LLM as a Judge 접근법

      본 글에서 사용된 Jupyter notebook 파일은 아래 github에서 다운로드 할 수 있습니다.


      1. LLM Benchmark 스코어

      아래 표는 llama-3.1-8B 의 모델 카드에서 발췌한 내용입니다.

      새로운 모델을 발표 하거나 기존 모델을 파인튜닝 해서 공개할 때 얼마만큼 성능이 향상 되었는지 아래와 같은 형식의 벤치마크 스코어를 확인 할 수 있는데요.


      https://huggingface.co/meta-llama/Meta-Llama-3.1-8B


      위 표에서 MMLU, SQuAD, BoolQ등의 벤치마크는 무엇을 벤치마크 한 것 일까요? 또한 acc, em, f1 등의 metric이 의미하는 바는 무엇일까요?

      이 벤치마크 결과에서 보이는 수치들이 무엇을 의미하는지, 이 수치들이 어떤 기준으로 나오게 되었는지에 대해 차근 차근 알아보겠습니다.

      2. LLM 수능 시험, 벤치마크

      우리가 대학에 가기 위해 수능을 치르듯이, LLM도 자신의 학습된 지식과 능력을 평가받는 시험이 필요합니다. 이 시험이 바로 벤치마크입니다.

      위 표에 나와 있는 벤치마크들은 언어 모델의 성능을 다양한 분야에서 측정하는 데 사용됩니다.

      모델이 언어를 얼마나 잘 이해하는지, 추론 능력이 있는지, 그리고 다양한 지식을 바탕으로 문제를 해결할 수 있는지를 평가하는 것이죠.

      이러한 벤치마크는 모델이 각 영역에서 얼마나 뛰어난 성능을 보이는지, 정량적으로 평가할 수 있는 중요한 도구입니다.


      언어 모델의 성능을 평가하는 방법은 매우 다양하지만, 큰 분류로 나눠보자면 아래와 같이 세가지로 나눌 수 있습니다.

      • 일반적 성능 측정

        언어를 얼마나 잘 이해하고, 자연스럽게 구사할 수 있는지를 평가합니다.

        이를 통해 모델이 문장의 의미를 파악하거나, 번역과 독해를 수행하거나, 지식을 정제하여 답변을 생성하는 등의 일반적이고 다양한 언어 응용 분야에서의 성능을 측정할 수 있습니다.

      • 도메인 특화 성능 측정

        법률, 의료, 금융 등 특정 도메인에 대해 파인튜닝된 모델의 성능을 평가합니다. 특정 분야에 맞게 훈련된 모델이 얼마나 정확한 결과를 도출하는지를 측정합니다.

      • 얼라인먼트(Alignment) 성능 측정

        모델이 편향성, 유해성, 윤리적인 이슈에 대해 인간의 보편적인 기준에 부합하는지를 평가합니다. 이 평가는 모델이 사회적, 윤리적 기준을 얼마나 잘 따르는지를 확인하는 데 중점을 둡니다.


      수능 시험은 공신력이 있는 기관이 주관하여 수험생의 지식을 최대한 객관적으로 평가할 수 있도록 잘 정제된 문제들로 평가를 합니다.

      언어 모델도 마찬가지로 평가의 목적에 맞게 정제된 문제들을 만들어 내야 하는데요, 다행히 이미 여러 기관에서 제공하는 잘 만들어진 평가 벤치마크 데이터들이 존재합니다.

      하지만 지면 관계 상 관련 벤치마크 데이터셋을 다 소개할 수는 없어서, 한국어의 일반적인 성능 측정을 위한 많이 활용되는 Ko-BEST와 kmmlu를 간단히 살펴보겠습니다.


      2.1 KoBEST

      KoBEST는 한국어의 다양한 이해와 추론 능력을 평가하기 위해 SK Telecom이 만든 벤치마크 데이터셋입니다.

      https://huggingface.co/datasets/skt/kobest_v1


      아래와 같이 총 5가지의 벤치마크 데이터셋으로 구성되어 있습니다.

      • KB-BoolQ: 문단에서 주어진 질문에 대해 참 또는 거짓을 판단

      • KB-COPA: 주어진 상황에 가장 적합한 결과를 두 가지 대안 중에서 선택

      • KB-WiC: 같은 단어가 서로 다른 문맥에서 같은 의미로 사용되는지 판단

      • KB-HellaSwag: 상황 설명에 맞는 다음 전개를 네 가지 선택지 중에서 고름

      • KB-SentiNeg: 문장의 긍정 또는 부정을 정확히 분류하는 능력을 평가

      데이터셋 중 KB-BoolQ의 구성을 살펴보겠습니다.

      문장을 주고, 모델에게 질문을 해서 모델이 해당 질문에 대해 맞는지, 틀리는지를 답변하게 해서 검증하는 형식이네요.

      {'paragraph': '두아 리파(Dua Lipa, 1995년 8월 22일 ~ )는 잉글랜드의 싱어송라이터, 모델이다. BBC 사운드 오브 2016 명단에 노미닛되었다. 싱글 "Be the One"가 영국 싱글 차트 9위까지 오르는 등 성과를 보여주었다.',
       'question': '두아 리파는 영국인인가?',
       'label': 1}


      2.2 KMMLU

      KMMLU(Korean Massive Multitask Language Understanding)는 한국어에 특화된 대규모 멀티태스크 언어 이해를 측정하기 위한 영문 MMLU를 벤치마크한 데이터셋입니다.

      이 벤치마크는 인문학에서 STEM(과학, 기술, 공학, 수학)에 이르는 45개 과목에 걸쳐 35,030개의 전문가 수준의 객관식 질문으로 구성되어 있습니다.

      https://huggingface.co/datasets/HAERAE-HUB/KMMLU

      • 원본 한국어 시험 기반: KMMLU는 기존의 영어 MMLU 벤치마크를 번역한 것이 아닌, 실제 한국어 시험에서 수집된 문제로 구성되어 있어, 한국어의 언어적, 문화적 특성을 반영

      • 다양한 주제: 인문학, 사회과학, 자연과학, 수학 등 다양한 주제를 포함하여 한국어로 된 멀티태스크 능력을 평가

      KMMLU 데이터셋 중 Food-Processing의 데이터를 열어 보겠습니다.

      일반적인 4지 선다형 문제와 흡사합니다. 질문에 대해 4가지 선택지중에 정답을 고르는 형식이네요.

      {'question': '맥주의 저장 시 숙성기간 동안 단백질은 무엇과 결합하여 침전하는가?',
       'answer': 3,
       'A': '맥아',
       'B': '세균',
       'C': '탄닌',
       'D': '효모',
       'Category': 'Food Processing',
       'Human Accuracy': 0.1110999999999999}

      KoBEST와 KMMLU 두가지 벤치마크 데이터셋을 구성을 살펴보았는데, 재미있게도 형식이 사람이 보는 시험 문제와 비슷합니다.

      3. 점수를 부여하자! 모델의 정량적인 평가 기준

      시험 문제를 보았으니, 채점을 해야겠죠?

      언어 모델이 얼마만큼 잘 하는지 무슨 기준을 가지고 어떻게 채점을 할까요?

      사실 이 부분은 쉽지 않은 문제입니다.

      언어모델의 평가가 어려운 이유는 언어라는 자체가 매우 복잡하고 다양한 특징들을 가지고 있기 때문입니다.

      단순히 맞고 틀리고를 떠나서 문맥, 뉘앙스, 창의성등 다양한 요소를 고려해야 하기 때문이죠.

      이러한 문제를 해결하기 위해 다양한 평가 기준들이 생겼습니다. 평가 기준으로 활용되는 대표적인 4가지를 간단히 알아보겠습니다.


      3.1 Accuracy

      Accuracy는 전체 예측 중에서 정답을 얼마나 맞췄는지를 평가하는 지표입니다.

      예를 들어, 개와 고양이 사진이 10장 있을 때 이 중 9개를 올바르게 분류했다면, 정확도는 90%입니다.


      3.2 F1 Score

      데이터가 불균형하게 분포되어 있을 때 Accuracy는 착시 효과를 만들 수 있습니다.

      예를 들면 90%의 사진이 고양이이고 10%만 개일 때, 모든 사진을 고양이로 분류해도 정확도가 90%로 나올 수 있습니다.

      이 경우 정확도는 모델이 잘못된 예측을 많이 했음에도 좋은 결과처럼 보이게 만듭니다.

      F1 Score는 이렇게 데이터가 불균형할 때 특히 유용한 지표로, 모델의 예측 성능을 더 정밀하게 평가할 수 있습니다.

      F1 Score는 두 가지 개념, Precision(정밀도)과 Recall(재현율)을 결합하여 계산됩니다.

      • Precision (정밀도): 모델이 Positive(예: 암 환자)라고 예측한 것 중 실제로 Positive인 것의 비율입니다. 예를 들어, 모델이 암 환자를 100명이라고 예측했는데 그중 80명이 실제 암 환자라면 Precision은 80%입니다.

      • Recall (재현율): 실제 Positive인 것 중 모델이 Positive로 잘 예측한 비율입니다. 예를 들어, 실제 암 환자가 100명인데 모델이 그중 70명을 암 환자로 잘 예측했다면 Recall은 70%입니다.

      F1 Score는 Precision과 Recall의 조화평균으로, 두 값을 균형 있게 고려합니다. 특히 Precision이나 Recall 중 하나가 낮을 때 이를 보완하여 모델의 성능을 평가하는 데 유리합니다.

      앞의 사례를 다시 보면, 모든 사진을 고양이로 분류했을 때 Accuracy는 90%이지만, F1 Score는 0이 됩니다. 이는 F1 Score가 데이터 불균형에 대한 보다 정확한 평가를 제공함을 보여줍니다.


      3.3 BLEU (Bilingual Evaluation Understudy)

      BLEU 점수는 주로 기계 번역의 품질을 평가하는 데 사용되는 지표입니다. 쉽게 말해, 기계 번역이 사람이 번역한 결과와 얼마나 유사한지를 숫자로 나타낸 것입니다.

      BLEU는 기계 번역된 문장에서 사람이 작성한 참조 문장에 포함된 단어나 구가 얼마나 일치하는지를 계산하여 점수를 매깁니다.

      사람과 기계가 번역한 결과를 비교해보겠습니다:

      • 참조 문장(사람이 번역한 결과): "나는 오전에 집에서 홀로 식사를 했다."

      • 생성 문장(기계 번역 결과): "나는 아침에 집에서 혼자 밥을 먹었다."

      이 두 문장은 일부 단어가 다르지만, 의미상으로는 문제가 없어 보입니다. 번역이 그럭저럭 잘 되었네 라고 생각할 수 있습니다.

      하지만 BLEU 점수는 단어의 일치만을 계산하기 때문에 예상보다 낮게 나올 수 있습니다. 이는 BLEU가 문맥이나 표현의 차이를 고려하지 않고 단어의 유사성만 평가하기 때문입니다.

      반면, 기계 번역 결과가 "나는 집에서 밥을 홀로 했다 오전에"라고 나온다면, 문장이 어색하거나 잘못 번역된 것처럼 보일 수 있습니다.

      하지만 “나는”, "오전에"와 “집에서”, "했다" 같은 단어들이 참조 문장과 일치하기 때문에, BLEU 점수는 의외로 높게 나올 수 있습니다.

      이처럼, BLEU 점수는 기계 번역의 품질을 평가하는 데 유용하지만, 문맥과 의미를 완전히 반영하지 못하기 때문에 단독으로 평가 지표로 사용하기에는 한계가 있습니다.


      3.4 ROUGE (Recall-Oriented Understudy for Gisting Evaluation)

      ROUGE는 주로 문서 요약의 품질을 평가하는 데 사용되는 지표로, 자동으로 생성된 요약이 사람이 작성한 기준 요약과 얼마나 유사한지를 측정합니다.

      BLEU가 생성된 문장을 기준으로 참조 문장과 얼마나 비슷한지를 측정하는 정확도(Precision)에 중점을 둔다면,

      ROUGE는 참조 문장을 기준으로 생성된 문장이 얼마나 비슷한지를 측정하는 재현율(Recall)에 중점을 둡니다.

      쉽게 말해, BLEU는 생성된 문장이 참조 문장과 얼마나 유사한지를 측정하는 지표이고, ROUGE는 참조 문장이 생성된 문장에 얼마나 잘 반영되었는지를 측정하는 지표로 이해할 수 있습니다.

      BLEU 예시의 생성문장을 살짝 바뀌어서 다음과 같다고 가정해보겠습니다.

      참조 문장: "나는 오전에 집에서 홀로 쓸쓸히 식사를 했다."

      생성 문장: "나는 아침에 집에서 홀로 밥을 먹었다."

      두 문장에서 "나는", "집에서", "홀로"가 일치합니다. 참조 문장은 7개의 구문으로 이루어져 있고, 생성 문장은 6개의 구문으로 이루어져 있습니다.

      이 경우, 간단히 계산하면 BLEU 점수는 3/6 = 0.5이고, ROUGE 점수는 3/7 = 0.43이 됩니다. (1-gram 기준)

      이 예시는 BLEU와 ROUGE의 차이를 설명하기 위한 단순화된 예시지만, 실제로 ROUGE는 n-gram 매칭, LCS(최장 공통 부분 수열) 등을 활용하여 문장 간 유사성을 더 복잡하게 평가할 수 있습니다.


      정리하면,

      모델이 생성하는 출력이 정형화된 형식을 가지고 있다면, 즉 지정된 형식의 숫자나 문자로 출력된다면 Accuracy나 F1 Score와 같은 지표를 활용해 정답과 직접 비교할 수 있습니다.

      반면, 문장처럼 정형화되지 않은 형태로 출력이 이루어진다면, BLEU나 ROUGE와 같은 지표를 활용하여 유사성을 비교하는 것이 적합합니다.


      다시 llama-3.1-8B 벤치마크 결과로 돌아가 보면 Metric 으로 사용된 지표를 살펴보면, 대부분 정답과 얼마나 일치하는 가를 보는 accuracy 계열임을 확인 할 수 있습니다.

      4. 그런데 어떻게 채점하지?

      이제 시험지도 있고, 평가 기준도 만들었으니 LLM의 평가를 시작 해보겠습니다.


      아래와 같이 KoBEST의 booq 문제 중 하나를 가져와서 llama-3.1-8B에 프롬프트로 넣고 추론을 해봅시다.

      콜라독립 815(815 Cola)는 코카콜라를 대한민국에서 라이선스로 만들어 오던 범양식품이 1998년 4월 1일에 출시한 탄산음료다. 질문: 콜라독립 815는 코카콜라에서 만들었나요? 답변: 

      llama-3.1-8B의 출력은 아래와 같이 나오네요.

      답변: 815 콜라는 범양식품에서 개발하였고 범양식품에서 생산하는 제품입니다. 콜라독립 815(815 Cola)는 코카콜라를 대한민국에서 라이선스로 만들어 오던 범양식품이 1998년 4월 1일에 출시한 탄산음료다.

      Instruction 파인튜닝이 되지 않은 Pre-trained 모델이라서 답변이 체계적이지는 않지만, 틀린말을 한 것은 아닙니다.


      그런데 한가지 문제가 생겼네요.

      우리가 원하는건 이런 상세한 답변이 아니라 “예”, “아니오” 라는 문자 였습니다. 그래야 정답과 비교해서 맞는지 틀리는지 보고 Accuracy를 계산할 수 있으니까요.

      물론 프롬프트를 정교하게 작성하여, “아니오” 라는 답변만 출력하도록 만들 수 도 있겠지만,

      모든 Open source LLM들에 이러한 프롬프트를 동일하게 적용하기 힘들뿐더러, 출력이 일관되게 나오리라는 보장도 없습니다.

      그럼 이런 경우에는 어떻게 모델의 성능을 측정 할 수 있을까요?


      4.1 Back to Basics

      LLM이 문장을 생성 하는 과정을 다시 상기 해보겠습니다.


      모델에 입력 텍스트를 입력으로 넣으면 모델은 vocab 이라는 단어집내의 모든 단어에 대해 다음 단어로 나올 가능성에 대해 계산 합니다.

      이렇게 다음에 나올 가능성에 대한 원시 점수를 Logit이라고 표현합니다.

      이 Logit을 확률로 변환하기 위해 softmax를 통과 하면 비로소 다음에 나올 확률이 가장 높은 단어, 즉 토큰을 선택하게 됩니다.


      이러한 LLM의 원리를 이용하면 확률 기반으로 모델의 출력을 평가 할 수 있습니다.

      입력에 대한 각각의 출력이 얼마나 나올 가능성이 높은지를 loglikelihood (우도)를 통해 정량적으로 계산해 낼 수 있습니다.

      위의 사례에서 “예”와 “아니오”라는 출력을 각각 대입해보고 어떤 것이 확률적으로 높은지 측정해 보는 것이죠

      llama-3.1-8B 모델을 통해 직접 계산 해보면 아래와 같은 결과를 얻을 수 있습니다. “아니오” 대답이 더 높은 점수로 정답을 맞춘 것을 확인할 수 있습니다.

      ( 계산 과정은 링크된 코드를 참고하세요 )

      {' 아니오': -3.5643131732940674, ' 예': -3.5748984813690186}

      이러한 방식으로 모델 출력에서 “예” 나 “아니오”라는 문자열을 명시적으로 찾지 않아도 확률값으로 "예" 인지 "아니오" 인지를 판단할 수 있게 해줄 수 있습니다.


      앞서 소개한 다지선다 형식의 대표적인 데이터셋인 KMMLU의 데이터셋을 다시 소환해봅시다.

      {'question': '맥주의 저장 시 숙성기간 동안 단백질은 무엇과 결합하여 침전하는가?',
       'answer': 3,
       'A': '맥아',
       'B': '세균',
       'C': '탄닌',
       'D': '효모',
       'Category': 'Food Processing',
       'Human Accuracy': 0.1110999999999999}

      Boolq에서 했던대로 이 데이터셋도 A부터 D까지 답변을 넣어서 확률을 구한 후 가장 높은 확률을 가진 지문을 선택해서 성능을 측정 할 수 있습니다.

      평가 코드를 실행하면 다음과 같은 결과를 얻을 수 있는데, 정답인 “탄닌”이 가장 높은 확률로 나왔네요

      {' 맥아': -3.5799646377563477, ' 세균': -3.668670177459717, ' 탄닌': -3.43269681930542, ' 효모': -3.569061040878296}

      5. 평가 툴의 활용

      간단하게 확률을 구하는 코드를 작성해서 평가를 해봤지만, 다양한 모델과 데이터셋을 대응하기에는 번거로운 점이 있습니다.

      그래서 이러한 평가를 자동화 해주는 툴들로 lm-eval-harness나 HELM 등이 있는데, 가장 광범위하게 활용되는 lm-eval-harness를 알아보도록 하겠습니다.

      lm-eval-harness는 Eleuther.ai가 주도하여 개발된 평가 프레임워크로, 다양한 벤치마크 데이터셋을 활용해 LLM의 성능을 자동으로 평가할 수 있도록 설계되었습니다.

      이 프레임워크는 Huggingface에서 모델과 데이터셋을 직접 로드할 수 있을 뿐만 아니라, PEFT 모델도 지원합니다.

      또한, OpenAI나 Anthropic의 API, llama.cpp와 같은 다양한 모델 형식을 로드할 수 있으며, vLLM 추론 엔진을 통해 빠른 추론도 가능해 활용도가 매우 높습니다.

      특히, Huggingface의 LLM leaderboard와 korean LLM leaderboard에서 이 lm-eval-harness를 평가 프레임워크로 채택하여 운영하고 있어, 평가 도구로서의 신뢰도 또한 높습니다.

      5.1 lm-evaluation-harness

      설치

      설치 과정은 간단합니다. 아래와 같이 lm-evaluation-harness github을 통해 필요할 라이브러리를 설치 합니다.

      pip install git+https://github.com/EleutherAI/lm-evaluation-harness.git

      양자화된 모델을 로드한다면 관련 패키지도 설치합니다.

      pip install bitsandbytes

      Tool 실행

      설치가 되었다면 아래와 같이 lm_eval 명령을 통해 평가를 진행할 수 있습니다.

      lm_eval --model hf\
          --model_args pretrained=meta-llama/Meta-Llama-3.1-8B,dtype=auto \
          --tasks kobest_boolq \
          --num_fewshot 0 \
          --seed 42 \
          --device cuda:0 \
          --batch_size auto\
          --output_path ./eval_llama3/kobest/boolq/0-shot \
          --log_samples \
          --show_config 

      [ 템플릿 설명 ]

      • model : 모델의 위치를 지정합니다. hf는 huggingface에서 직접 로드한다는 의미

      • model_args

        • pretrained : hf의 모델 저장소 이름

        • dtype : 모델을 로드하는데 사용할 데이터 유형(fp32, fp16, bf16등)

      • tasks : 평가에 사용할 벤치마크셋

      • num_fewshot : fewshot의 개수 지정

      • device : 모델을 로드하는 장치 이름, cuda:0는 id가 0번인 GPU

      • batch_size : 추론에 사용되는 배치 크기, GPU 메모리가 충분하다면 auto로 최대 배치 크기를 자동으로 설정

      • output_path : 평가 결과를 저장할 디렉토리 Path

      • log_samples : 평가과정중에 생성된 샘플을 저장할 것인지, 추후 디버깅에 유용


      평가를 완료하면 다음과 같은 결과를 얻을 수 있습니다.

      |   Tasks    |Version|Filter|n-shot|Metric|   |Value |   |Stderr|
      |------------|------:|------|-----:|------|---|-----:|---|------|
      |kobest_boolq|      1|none  |     0|acc   |↑  |0.5221|±  |0.0133|
      |            |       |none  |     0|f1    |↑  |0.3839|±  |   N/A|

      평가 metric으로 accuracy가 0.52, f1 스코어는 0.38로 계산했네요.


      그런데 한가지 의문 듭니다.

      lm_eval_harness는 모델의 프롬프트 입력을 어떻게 만들고, 평가 metric 을 어떻게 지정하고 계산하는 것일까요?


      5.2 확률 기반의 평가

      lm-eval-harness의 벤치마크에 관련된 설정은 설치 후 벤치마크 데이터셋이 위치한 디렉토리에서 찾을 수 있습니다.

      아래 디렉토리 저장된 kobest_boolq.yaml 평가 템플릿을 확인해 보겠습니다.

      • lm-evaluation-harness/lm_eval/tasks/kobest/kobest_boolq.yaml

      tag:
        - kobest
      task: kobest_boolq
      dataset_path: skt/kobest_v1
      dataset_name: boolq
      output_type: multiple_choice
      training_split: train
      validation_split: validation
      test_split: test
      doc_to_text: "{{paragraph}} 질문: {{question}} 답변: "
      doc_to_target: "{{label}}"
      doc_to_choice: ["아니오", "예"]
      metric_list:
        - metric: acc
          aggregation: mean
          higher_is_better: True
        - metric: f1
          aggregation: !function utils.macro_f1_score
          average: macro
          hf_evaluate: true
          higher_is_better: True
      metadata:
        version: 1.0

      [ 템플릿 설명 ]

      • tag : 평가 구성을 식별하기 위한 Tag 지정

      • task : 벤치 마크 작업의 이름을 지정

      • dataset_path : 평가 데이터셋의 경로를 지정, 기본적으로 HF 데이터셋 경로를 인식

      • dataset_name : 데이터셋내에서 사용할 서브셋 이름을 지정 (kobest_v1 데이터셋 중 boolq 서브셋 사용)

      • output_types: 모델의 출력형식. multiple_choise 이므로 다중 선택에 대한 답변을 출력

      • training, validation split : 학습과 검증 데이터로 사용될 데이터 셋 지정 (모델에 데이터셋의 형식을 학습하기 위해)

      • test_split : 평가에 사용될 데이터셋 지정

      • doc_to_text: 입력 데이터의 형식(프롬프트)을 정의

      • doc_to_target : 정답을 정의

      • doc_to_choice: 모델이 선택할 수있는 선택지, boolq는 “예”, “아니오”의 두가지 분류 문제

      • metric_list : 평가에 사용할 지표(Metric)들

        • metric : 지표 (accuracy, f1..)

        • aggregation : metric의 결과를 모아서 평균하여 최종 평가 점수를 계산, 별도의 함수 이용시 !function 으로 지정

        • average: !function에서 지정한 함수를 사용한 결과를 평균하여 계산

        • hf_evaluation : Hugging Face의 평가 도구를 사용하여 이 메트릭을 계산


      템플릿의 doc_to_text 형식에 따라 모델에 입력될 프롬프트는 다음과 같이 생성됩니다.

      콜라독립 815(815 Cola)는 코카콜라를 대한민국에서 라이선스로 만들어 오던 범양식품이 1998년 4월 1일에 출시한 탄산음료다.답변: 

      위 템플릿에서 로드한 f1 스코어 계산 함수는 같은 디렉토리내에 utils.py에 있습니다. 이처럼 별도의 함수를 지정해서 사용할 수 도 있습니다.


      이제 실제 평가 결과 로그를 한번 살펴보죠.

      관련 로그는 lm_eval 명령을 실행할 때 지정했던 output_path에 가면 확인 할 수 있습니다.

      아래는 첫번째 평가 데이터셋의 처리 결과 로그입니다.

      {
      "doc_id":0,
      "doc":{
      "paragraph":"콜라독립 815(815 Cola)는 코카콜라를 대한민국에서 라이선스로 만들어 오던 범양식품이 1998년 4월 1일에 출시한 탄산음료다.",
      "question":"콜라독립 815는 코카콜라에서 만들었나요?",
      "label":0
      },
      "target":"0",
      [중략]
      "resps":[[["-14.689537048339844","False"]],[["-15.082908630371094","False"]]],
      [중략]
      "acc":1.0,
      "f1":[0,0]
      }

      모델 출력인 “resps”를 보면 우리가 이전에 확인한 것처럼 “아니오”와 “예” 를 답변으로 했을 때의 loglikelihood로 계산된 확률값을 보여주고 있습니다.

      역시 “아니오” 점수가 더 높기 때문에 정답을 맞췄고,“acc”가 1이 되었네요


      5.3 생성 기반의 평가

      우리는 확률기반의 평가 방법을 통해 모델을 평가 할 수 있었습니다.

      그런데 여전히 미덥지가 못합니다. 바로 LLM의 출력에 대한 믿음 때문인데요.

      확률 기반의 평가는 말그대로 답변에 대한 확률적인 값일 뿐이지, 답변이 정확하게 지문 처럼 출력된 다는 것은 아닙니다.

      어떤 경우는 평가에 있어 정확한 워딩이 들어간 결과를 선호 할 수 도 있습니다.

      그래서 lm-eval-harness에는 직접 모델이 생성한 답변을 평가하는 생성적 벤치마크 방법론을 지원합니다.


      다음 디렉토리를 열어 lm-eval-harness github에서 kmmlu 평가 설정 템플릿을 열어 보겠습니다.

      • lm-evaluation-harness/lm_eval/tasks/kmmlu/direct/_direct_kmmlu_yaml

      아래와 같이 새로운 설정 섹션이 있네요!

      metric에 accuracy나 f1이 아닌 exact_match가 지정 되어 있습니다. 즉 target 으로 지정된 문자가 정확하게 출력이 되었는지를 평가하겠다는 것입니다.

      그리고 generation_kwargs 섹션도 추가가 되었는데 모델에 직접 추론을 할 때 처럼 디코딩 파라메터등을 지정하게 됩니다.

      metric_list:
        - metric: exact_match
      [중략]
      generation_kwargs:
        until:
          - "Q:"
          - "\n\n"
          - "</s>"
          - "."
        do_sample: false
        temperature: 0.0

      그럼 기본 제공되는 direct_kmmlu_yaml 템플릿으로 Llama-3.1-8B를 평가해보겠습니다.

      lm_eval --model hf \
          --model_args pretrained=meta-llama/Meta-Llama-3.1-8B,dtype=auto \
          --tasks kmmlu_direct_food_processing \
          --num_fewshot 0 \
          --seed 42 \
          --device cuda:0 \
          --batch_size auto\
          --output_path ./eval_llama3/kmmlu/direct_food_processing/0-shot \
          --log_samples \
          --show_config 

      평가 후 결과를 보니 좀 이상합니다. 정담과 일치하는게 거의 없는것으로 나오네요

      |           Tasks            |Version|Filter|n-shot|  Metric   |   |Value|   |Stderr|
      |----------------------------|------:|------|-----:|-----------|---|----:|---|-----:|
      |kmmlu_direct_food_processing|      2|none  |     0|exact_match|↑  |0.007|±  |0.0026|

      이럴 때는 로그를 살펴봅시다!

      • eval_llama31-8B/kmmlu/direct_food_processing/0-shot/meta-llama__Meta-Llama-3.1-8B/

      {
      "doc_id":10,
      "doc":{
      "question":"밀가루의 제분 후 인공적인 산화를 시키는 첨가물 중 국내에서 사용할 수 없는 것은?",
      "answer":3,
      "A":"Chlorine Dioxide",
      "B":"Diluted Benzoyl Peroxide",
      "C":"Potassium Bromate",
      "D":"Ammonium Persulfate",
      "Category":"Food Processing",
      "Human Accuracy":0.0741
      },
      "target":"C",
      [중략]
      "resps":[["C\n해설:국내에서 사용할 수 없는 것은 Potassium Bromate이다"]],
      [중략]
      "exact_match":0.0
      }

      모델의 출력을 보면 “C\n해설: 국내에서.." “와 같이 정답을 기재하고, 다음 줄에서 해당 답변을 왜 했는지에 대한 해설을 하는 것을 볼 수 있습니다.

      즉 답변을 제대로 했는데, 주절히 주절히 설명을 붙인 탓에 정답 “C”와 일치하지가 않았던 것이죠.

      이러한 문제를 해결하기 위해서 lm-eval-harness는 정규식으로 문자열을 필터링 할 수 있는 기능을 제공합니다.

      다행히도 llama-3.1은 출력 패턴이 “정답\n해설” 식으로 일정합니다. 맨앞에 정답만 취하도록 정규식 필터링하면 될 것 같네요

      아래와 같이 정규식 필터링이 포함된 새로운 템플릿을 작성합니다.

      YAML_kmmlu_direct_food_processing = '''
      task: llama31_kmmlu_direct_food_processing
      [중략] 
      filter_list:
        - name: "get-answer"
          filter:
            - function: "regex"
              regex_pattern: "[A-D]"
            - function: "take_first"
      metadata:
        version: 2.0
      '''
      with open('./test/llama31_kmmlu_direct_food_processing.yaml', 'w') as f:
          f.write(YAML_kmmlu_direct_food_processing)

      이제 새로 작성한 템플릿을 로드 할 수 있도록 템플릿이 있는 디렉토리를 추가 해주고, 새로 작성한 task 를 지정해서 다시 실행합니다.

      lm_eval --model hf\
          --model_args pretrained=meta-llama/Meta-Llama-3.1-8B,dtype=auto \
          --include_path ./test \
          --tasks llama31_kmmlu_direct_food_processing \
          --num_fewshot 0 \
          --seed 42 \
          --device cuda:0 \
          --batch_size auto\
          --output_path ./eval_llama3/kmmlu/direct_food_processing/0-shot \
          --log_samples \
          --show_config 

      이제 평가 결과로 exact_match가 0.3 정도로 나오네요

      |               Tasks                |Version|  Filter  |n-shot|  Metric   |   |Value|   |Stderr|
      |------------------------------------|------:|----------|-----:|-----------|---|----:|---|-----:|
      |llama31_kmmlu_direct_food_processing|      2|get-answer|     0|exact_match|↑  |0.304|±  |0.0146|

      평가 로그를 살펴봅시다 정규표현식 필터링으로 filtered_resps 가 “C” 만으로 필터링 된 것을 확인 할 수 있습니다.

      {
      "doc_id":3,
      "doc":{
      "question":"구상흑연주철에서 페라이트가 석출한 페라이트형 주철의 생성은 어느 경우에 발생되는가?",
      "answer":3,
      "A":"냉각속도가 빠를 때",
      "B":"Mn 첨가량이 많을 때",
      "C":"C, Si 특히 Si가 많을 때",
      "D":"담금질 및 뜨임 하였을 때",
      "Category":"Food Processing",
      "Human Accuracy":0.0625
      },
      "target":"C",
      [중략]
      "resps":[["C"]],
      "filtered_resps": ["C"]
      [중략]
      "exact_match":1.0
      }

      한가지 재미 있는점은 생성 기반의 평가가 확률 기반의 평가 보다 평가 시간이 더 소요된다는 것입니다.

      그도 그럴것이 생성 기반의 평가는 직접 추론을 해서 결과를 가지고 평가를 하기 때문에 단순 확률값을 구하는 계산보다 훨씬 더 많은 리소스를 필요로 하게 됩니다.

      6. 사람처럼 평가 하기

      언어 모델을 평가하는 데 있어 확률 기반의 방법은 모델의 성능을 수치화하는 데 유용합니다. 하지만, 이 방식만으로는 생성된 텍스트의 품질을 보장하기 어렵습니다.

      문법적으로는 올바른 문장일지라도, 그 의미가 왜곡되거나 맥락에 맞지 않게 나오는 경우가 있기 때문이죠.

      반면, 실제로 모델이 생성한 문장을 직접 평가하는 방법은 더 현실적인 대안처럼 보일 수 있습니다만, 이 역시 쉬운 일이 아닙니다.

      생성된 문장의 품질을 평가하려면 문맥 이해, 논리적 일관성, 창의성 등 다양한 요소를 고려해야 해야 하는데,

      단순히 필터링 기법이나 데이터 처리로 평가하는 방식에는 한계가 있기 때문입니다.


      그렇다면 가장 신뢰할 수 있는 방법은 무엇일까요?

      바로 사람이 직접 모델의 출력을 검토하는 것입니다. 하지만 이 방법은 시간과 비용이 너무 많이 든다는 문제가 있습니다. 특히 대규모 데이터를 평가할 때는 현실적이지 않죠.


      이러한 한계를 해결하기 위해 등장한 것이 바로 LLM as a Judge입니다.

      이 접근법은 LLM 자체를 평가자로 활용하는 방식입니다. 예를 들어, llama3 모델이 생성한 문장을 ChatGPT-4가 평가하는 식이죠.

      이 방법은 평가 결과의 신뢰성을 높일 뿐만 아니라, 인간 평가자가 가질 수 있는 주관적인 편향을 줄이는 데도 큰 도움이 됩니다.


      이러한 벤치마크 방법론으로 영어권 벤치마크 중에 MT-Bench라는 벤치마크가 있습니다.

      8개의 카테고리에 대한 10개의 질문 세트 구성 되어 있는데, 이러한 질문 세트를 기반으로 모델이 추론한 결과를 GPT-4에게 평가 받는 방식입니다.

      국내 벤치마크로는 LogicKor 이 이러한 방식을 사용하고 있습니다.

      https://github.com/instructkr/LogicKor


      아래 LogicKor에 GPT4에게 평가를 요청하는 Prompt 템플릿을 살펴보면, 어떠한 방식으로 평가를 진행하는지 직관적으로 알 수 있습니다.

      JUDGE_TEMPLATE = {
          "single_turn": """너는 질문에 대한 한국어 언어 모델의 답변을 매우 꼼꼼히 평가할 것이다. 공정한 평가를 위해 아래의 규칙을 준수한다.
      
      # 기본 규칙
      1. 질문의 요구사항을 충분히 반영하였는지 상세히 분석할 것.
      2. 답변 과정에서 누락되었거나 포함되지 못하여 아쉬운 부분에 대하여 상세히 분석할 것.
      3. 답변의 길이가 평가 결과에 영향을 미치지 않도록 할 것.
      4. Additional Reference가 제공된다면 평가 시 해당 정보를 참고할 것.
      
      # 언어 요구사항
      - 모델은 반드시 한국어로 답변해야 하며, 다른 언어로의 답변은 절대 허용되지 않는다.
      - 예외적으로 질문이 영어로 답변할 것을 요구할 때에만 영어 답변이 허용된다.
      - 한국어로 답변하지 않을 경우, 점수는 0점 처리된다.
      - 언어 요구사항을 충족하는 것은 필수적이나, 이 요구사항의 충족이 답변의 질적 평가에 추가 점수로 이어지지는 않는다.
      
      # 평가 출력 방식
      **주어진 Question에 집중하여** Model's Response에 대한 평가와 1~10의 점수를 부여한다. 답변에 대한 평가는 4~5 문장으로 규칙을 참고하여 상세히 작성한다.
      
      [ 중략 ]
      
      # 출력 형식
      평가: 평가 내용
      점수: 숫자""",
      }

      마무리

      LLM의 평가는 사전 학습이나 파인 튜닝만큼 중요한 영역으로 다뤄지고 있습니다.

      우리가 살펴본 LLM 평가 과정은 모델의 성능을 객관적으로 판단하고, 이를 개선하는 데 중요한 역할을 합니다.

      하지만 이 평가 과정에도 한계가 존재하는데요. 최근 커뮤니티에서 논란이 된 'LLM 리더보드 무용론'이 그런 사례입니다.


      리더보드는 LLM 간 공정한 성능 비교를 통해 경쟁을 촉진하는 긍정적인 역할을 합니다.

      일부 사례에서 더 높은 순위를 차지하기 위해 벤치마크에 지나치게 최적화된 튜닝이 이루어지는 경우가 있습니다.

      그래서 상위권에 오른 모델들이 실제 사용 시 기대에 미치지 못하는 성능을 보여주어 사용자들에게 실망을 안기기도 했는데요,

      이러한 상황은 LLM 평가 결과가 절대적인 기준이 될 수 없으며, 때로는 평가 결과가 왜곡될 수 있다는 사실을 잘 보여줍니다.

      따라서 LLM 평가에는 정해진 정답이 없으며, 평가의 목적을 명확히 하고 그에 맞는 벤치마크와 방법론을 적용하는 것이 무엇보다 중요합니다.


      특히 모델을 파인 튜닝하여 실서비스에 적용하려는 경우, 더욱 섬세한 접근이 필요합니다.

      예를 들어, 챗봇에 적용된 LLM은 텍스트의 유창성, 정확성, 일관성 등을 중점적으로 평가해야 하는 반면, RAG 모델은 정보 검색의 정확성을 더 높은 비중으로 평가해야 할 것입니다.

      이를 위해 f1, BLEU, ROUGE와 같은 정량적인 평가 방법 외에도, LLM judge와 같은 정성적인 평가 방법이 모델의 사용 목적에 따라 적절하게 적용이 되어야 합니다.


      요즘 날씨가 더워서 지쳤는데, 선선한 바람처럼 새로운 평가 방법이 등장해 LLM 평가에도 신선한 변화가 불어오길 기대봅니다.

      댓글 0

      DEVOTEE를 활성화 시키면
      지금 작성한 댓글에 AI가 댓글을 달아줍니다.

      alankim 님의 최신 블로그

      더보기

      DEVOTEE 추천 블로그

      동영상 기고하기