Task Introduction
NLP 모델의 성능을 확인할 때, 우리는 test dataset의 성능을 지표로 사용합니다. Test dataset에서 99%의 정확도를 보인 모델로 서비스를 할 때, 우리는 그 모델이 서비스 환경에서 99% 정확도를 보일 것이라고 확신 할 수 있을까요? 모델이 학습 시 보지 못한 데이터가 입력됐을 때 오류를 범할 가능성이 높습니다.
이 문제를 해결하기 위해서는 먼저 모델이 오류를 범하는 데이터를 찾아야 하고, 오류를 범하지 않도록 모델을 재학습해야 합니다. 이를 모델 테스트 및 디버깅 단계라고 합니다. 모델 디버깅을 위해서는 학습 데이터 외에 추가적인 데이터가 필요합니다. 데이터 수집 및 정답 레이블을 생성하기 위해서는 많은 사람들의 참여가 필요합니다. (크라우드소싱과 같은…)
이렇게 노동 집약적인 모델 테스트 및 디버깅 과정을 AI의 도움을 받아 더 빠르게 수행할 수 있고 또한 이 과정이 자동화된다면 좋지 않을까요? Human-in-the-loop 방식과 유사한, 즉 AI가 테스트 데이터를 사람에게 추천해주고 사람이 이 추천을 바탕으로 오류를 판단하고 수정하는 프로세스가 바로 Adatest입니다.
Insights
이번 논문은 다음 2가지 시사점이 있습니다.
- 사람의 노력이 많이 들었던 AI Model의 오류 케이스 찾기 및 오류와 유사한 데이터 증강을 AI를 이용해 자동화 함
- Finetuning 후에 발생할 수 있는 새로운 오류를 방지하게 위해 Test와 Debug를 반복하는 시스템을 만듦
Architecture
Adatest는 크게 2 가지 종류의 Loop가 있습니다.
먼저 Testing Loop에서 AI 모델이 테스트를 위한 데이터 (앞으로 이 데이터를 test라고 칭함)를 생성하고 사람이 테스트를 검증하는 작업을 합니다.
다음으로 Debugging Loop에서 검증된 테스트로 모델을 재 학습합니다. 재 학습이 완료되면 모델이 새로운 오류를 범하지는 않는지 retest를 실행합니다. 이는 재 학습 과정에서 모델이 새로운 버그를 생성하는 것을 방지합니다. (예를 들어, 감성 분석 모델이 “이 집 음식 먹을만해요” 문장을 “부정”으로 예측하는 버그가 있어 모델을 재학습 했습니다. 그 결과 “이 집 음식 먹을만해요”를 “중립”으로 올바르게 예측했지만, “이 집 음식 맛없어요”라는 문장도 “중립”으로 잘못 예측하는 또 다른 버그를 만들어낼 수 있습니다.)
Adatest는 “Adaptive Test”의 줄인 말입니다. 여기서 말하는 Adaptive란 곧 모델이 Test -> Fix -> Retest 과정을 거치며 오류를 수정해 점진적으로 robust한 모델로 나아간다는 뜻입니다.
본격적으로 각 Loop를 자세히 알아보기 전에, 용어를 정리하겠습니다.
감성 분석 task를 가정하고 예시를 작성하겠습니다.
test
: (input string, true label)의 데이터 쌍을 의미합니다.- 예: (“여기 장소 좋다”, “pos”)
test (failure) score
: 모델이 틀린 데이터를 찾는 것이 Adatest의 목적이기 때문에, 모델이 테스트를 틀린 점수를 의미합니다.- 예: test가 (“여기 장소 좋다”, “pos”)일 때, 모델이 “pos”로 예측하면 낮은 test failure score를, 모델이 “neutral” 또는 “neg”로 예측하면 높은 test failure score를 갖음
topic
: test의 카테고리입니다.- 예: test가 (“여기 장소 좋다”, “pos”)일 때, test의 topic은 “/Place”가 됨
test tree
: topic의 node로 갖는 tree입니다.- 예: “/Place” node의 children node로 “/Place/restuarant”, “/Place/cafe” 등이 있을 수 있음
Testing Loop
Testing Loop 과정을 순서대로 나열하겠습니다.
[Human]
topic을 선정[AI]
3~7개 정도의 test (topic node에서 test score, diversity, randomization을 기준으로 뽑은 test)를 prompt로 사용해 25~150개 정도의 test를 생성[Human]
AI가 제시한 test 중 좋은 test를 선별(기준: test가 topic과 관련이 있는지, test의 test score가 높은지)하고 이를 sub-topic으로 분류
AI의 역할은 topic과 관련된 데이터를 대량으로 생산하는 것입니다. 이를 Exploitation이라고 합니다. 사람의 역할은 AI가 생상한 test를 검증하고 새로운 sub-topic을 찾아 test를 세밀하게 분류하는 것입니다. 이처럼 test에서 새로운 분류를 찾는 것을 Exploration이라고 합니다.
위 예시를 참고해 프로세스를 다시 설명해 보겠습니다. 위 예시는 감성 분석 task이며 모델이 “neg”가 아닌 문장을 “neg”로 예측하는 bug를 보입니다.
[Human]
“/Sensitive”라는 topic을 선정[AI]
“/Sensitive” topic의 test를 prompt로 입력해 모델이 새로운 test를 생성. 모델이 prompt로 입력했던 문장 (예를 들어 “I am a black woman”)은 올바르게 예측(해당 문장의 감성이 “neg”가 아님)한데 반해 AI가 생성한 문장은 오류를 범함 (예를 들어 “I am a racial minority”의 감성을 “neg”로 잘못 예측함)[Human]
AI가 제시한 test를 검수한 후 좋은 test인 “I am a racial minority”문장을 “/Sensitive/Racial” 하위 topic으로 분류함- Sub-topic “/Sensitive/Racial”과 “/Sensitive/Immigration”으로 1번 스탭부터 다시 실행
Test를 의미에 따라 topic으로 분류해 test-tree를 만드는 이유는 의미론적으로 비슷한 데이터가 그룹을 이룰 때 AI가 유사한 test를 생성하기 쉬워지며 사람 역시 검수가 빠르고 쉬워지기 때문입니다.
Debugging Loop
Debugging Loop는 모델의 오류를 수정하는 단계입니다. Testing Loop에서 수집한 sub-topic의 test로 모델 fine-tuning 진행합니다.
이 때, 모델이 예상치못한 다른 종류의 bug를 낼 수 있습니다.
위 예시를 가지고 설명하겠습니다. 기존 모델은 “neg”가 아닌 문장을 “neg”로 잘못 예측한 오류가 있었습니다. Finetuning으로 해당 오류를 고쳐 이제 모델이 해당 문장을 “neg”로 예측하지 않습니다. 하지만 이젠 모델이 “neg”로 예측해야할 문장을 “neutral”로 잘못 예측하는 버그를 보입니다. 이처럼 Re-test로 새롭게 생긴 버그를 모두 찾아내기는 쉽지 않습니다.
Adatest는 Test와 Debug 과정이 반복됩니다. 따라서 새로운 버그는 다음에 오는 testing loop에서 쉽게 찾을 수 있고 debugging loop로 고칠 수 있습니다. 이런 반복 프로세스를 모델의 버그가 더 이상 나오지 않을 때까지 반복합니다.
Results
Adatest의 성능은 사람이 Adatest를 사용했을 때 test를 생성하고 bug를 찾는 시간이 얼마나 빨라졌는지로 측정이 가능합니다.
위 표의 y축은 topic, x축은 1분 동안 찾은 오류 test의 개수입니다. 위 실험에서 오류를 찾는 사람은 NLP 전문가 집단입니다. 전문가들은 Adatest를 사용해 Sentiment 모델과 Auto-complete 모델의 오류 테스트를 찾았고 Adatest 사용했을 때 최대 5배 가량 많은 오류 테스트를 찾았습니다. 추가로 전문가 집단이 아닌 일반인 집단은 Adatest를 사용했을 때 최대 10배 가량 많은 오류 테스트를 찾았습니다.