처음에 이름을 근사하게 네이밍해서 계속 쓰다보면, 동료분들도 마치 프로덕트를 부르는 것처럼 고유명사가 된 듯 사용하시게 될때 기분이 되게 좋더라구요. 그래서 이번 프로젝트명도 나름대로 네이밍을 해서 가려고 합니다.
사실 미리 데이터셋을 리서치하고, 모아뒀는데요. 그 중 Smilegate AI에서 공개한 unsmile 데이터셋의 이름에서 착안해보자고 고민하던 중 Frown 이라는 단어를 찾았어요.
"얼굴을 찡그리다, 눈살을 찌푸리다, 인상쓰다, 미간에 주름지다"
이러한 의미를 지니고 있다고 해요. 게시글이나 댓글에서 저질스러운 글 보면 뭔가 맞서 싸우고 싶고, 적극적으로 나서서 신고도 하고 싶은 수준은 아니지만 뭔가 "왜 저래; 저렇게까지 과민반응 할 필요 있나?" 수준으로 눈살이 찌푸려지는 그런 느낌..?에 적절한 단어인 것 같아서 이 단어를 선택해서 쓰고자 해요.
결론적으로 프로젝트 이름은 Korean-Frown-Sentence-Classifier(KFSC) ! 나름 근사하지 않나요? ㅋㅋㅋㅋ
깃허브 레포도 해당 이름으로 생성했습니다.
키포인트는 저희 회사의 커뮤니티 웹서비스를 운영하시는 관리자분들의 노고를 줄이는 것이라고 생각이 됩니다. 그렇다면 관리자분들의 "노고는 어디에서 오느냐?"를 리스트업 해보았습니다. 사실 미리 회사에서 미팅도 하고, 대화도 하면서 알게된 사실이에요.
해서 제가 24시간 누군가가 대신 실시간으로 올라오는 텍스트들이 커뮤니티의 정책에 위반되지 여부를 모니터링을 해주고 이를 리포팅해주는 무언가가 있다면, 관리자 입장에서는 검토할 게시글의 수가 줄어드니 아무래도 관리자의 노고를 줄이는 목적으로써는 좋은 방향이라는 생각이 들었어요.
그리고 마지막 부분도 고려해야 하는 중요한 사항인데, 아무리 만든 AI 모델의 성능이 뛰어나도 모델의 예측만 믿고 자동적으로 제재를 가하도록 할 수는 없고, 관리자의 손을 한번 타기는 해야한다! 에요. 요부분에서 저는 성능적으로 매우 뛰어난 모델이 필요한 상황은 아니고, 당장 관리자의 노고를 줄일 수 있는 추가적인 정보가 필요한 수준의 문제 상황이라고 받아들였습니다.(요 포인트에서 모델 평가 성능에 대한 부담도 좀 줄어들었습니다.ㅋㅋ 개꿀)
문제가 얼추 정의가 된 것 같아요. 이제 조금 더 디테일한 방향성을 잡아보면 좋을 것 같아요. (물론 실제로는 더 많은 부분이 감안되고, 더 많은 구성원들의 의견들을 수용하게 됩니다.)
나이브하게 문제 정의와 함께 아래와 같이 앞으로 만들 것에 대한 윤곽이 잡힌 느낌이에요.
관리자를 대신해서 24시간 신규로 등록되는 게시글/댓글이 질 나쁜 문장인지 구별해 주는 무언가를 만들자 !
원래라면, 꼭 AI가 아니라도 해결할 수 있는 방법을 찾아볼거에요. 이를테면 룰 베이스로 처리할 수 있을까? 타 기업에서 스팸 필터나 욕설 필터의 사례는 어떤 것들이 있을까? 부터 리서치해보고, 고민해 볼 것 같습니다. 그러나 저는 개인 토이 프로젝트이므로 AI로 해결할거임 ㅅㄱ
자 이제 현실적인 부분을 좀 고려해볼 필요가 있을 것 같아요. 일단 떠오르는건 아래 3가지 정도가 떠오르네요.
일단 시간적인 부분은 그래도 개인 프로젝트보다는 업무가 당연히 더 우선순위가 높기 마련이고, 심지어는 제 개인 생활이 개인 프로젝트보다 우선순위가 높습니다. 그래서 할애할 시간 총량이 적을 것 같습니다.
제가 발전이 없는 이유죠..그래서 갓성비를 많이 따져보기로 했습니다.
첫째, 한정된 시간을 어떻게 효율적으로 쓸 수 있을까?에 대한 부분인데, 사실 AI를 활용한 문제 해결에서는 데이터 수집, 전처리, 검수의 과정에서 90% 이상의 시간을 먹지 싶습니다. 현직의 많은 분들이 공감하실 것 같아요. 그래서 이 부분은 리서치한 여러 회사와 연구자분들께서 공개해주신 질 좋은 데이터셋을 기준으로 저희의 상황에 맞게 라벨, 클래스 등을 개조하는 방향으로 하는 것이 시간 관계상 효율적일 것이란 생각이 들어요.
모델의 측면에서는 스크래치로 사전 학습부터 진행하기에는 너무 시간이 많이들 것 같아요. GPU와 모델 크기, 하이퍼파라미터에 따라 다르지만, 십수일이 소요될 수 있어요. 그래서 저는 우선적으로는 사전 학습된 모델을 활용해서 fine-tuning 후 전이 학습하는 방향으로 실험을 진행해보려고 해요.
얻어 걸리면, 여기서 좋은 성능이 나오는거고 아니면 실제 저희 회사 서비스에서 추출한 텍스트들을 모아서 사전 학습도 고려해봐야죠 모..
둘째, 학습 & 평가를 위한 GPU 머신 확보 ! 아무래도 다다익GPU다 보니 좋은 GPU가 많을수록 좋지만, 제겐 그 정도의 여유가 없네요...다행히 회사에서 이러한 자기계발에 활용되는 인프라 비용을 무제한 지원해줍니다!
그래도 워낙 GPU 머신이 비싸기 때문에..눈치가 보이지 않는 선에서 V100 1개 정도?에 해당하는 AWS EC2 인스턴스를 빌려서 사용하려고해요.
셋째, 저희의 상황은 웹상에서 펼쳐지는 훈민정음의 위대함을 품고 있는 한국 문장들이 많다는 점입니다. 웹상에서의 한국 문장들은 신조어, 줄임말, 띄워쓰기 노상관 등 여러 이슈를 포함하고 있어 아주 복잡합니다. 그래서 이러한 상황이 반영되어 있는 데이터셋이 필요해요. 그런데 다행히 많은 기업과 연구자분들께서 AI 생태계를 위해서 공개를 해주신 데이터셋이 많습니다. 심지어 현재 진행하고자하는 downstream task에도 딱 맞는 데이터셋도 있어요!
이런 데이터셋을 적절히 잘 병합하고 정제해서 저희 상황에 맞는 학습, 평가용 데이터셋으로 개조해서 사용할 예정입니다. 저는 미리 관련 데이터셋을 리서치를 해두었기 때문에 진행하면서 하나씩 출처에 대해서 공유드리도록 하겠습니다.
문장의 경우에는 하나의 문장에 여러 성격이 담길 수 있잖아요 ? 예컨대 아래와 같은 경우에요.
태극기 늙은 멍멍이들 오래 살아야 민주당 장기 집권하지ㅋㅋ
이런 경우 정치성향 + 연령비하라는 2가지 성격이 모두 포함되어 있기 때문에 이런 것들도 반영을 해줄 필요가 있습니다. 그래서 저는 태스크는 Multi-label classification으로 진행하도록 하겠습니다.
Multi-class classification의 경우는 classifier 하나의 확률 높은 클래스를 뽑아낸다면, Multi-label classification의 경우 중복 답안을 허용하면서, 여러 정답을 뽑아낼 수 있다는게 차이점입니다. 위의 예시에서 Multi-class classifier는 정치성향 or 연령비하 중 하나의 확률이 높게 나올 것 이고, Multi-label classifier는 정치성향과 연령비하 두 가지 모두 높은 확률이 나오게되는 느낌입니다.
저희 회사의 커뮤니티 서비스의 경우 게임 관련 웹서비스이다보니, 유저들로부터 나오는 발화들이 많습니다. 따라서 한국어의 문법적인 요소가 잘 지켜지지 않고, 게임 관련 특수용어들도 많이 등장해요. 이러한 상황이 고려된 PLM(Pretrained Language Model)을 찾아야 성능적으로 이득을 많이보고, 삽질의 시간을 줄일 수 있을 것 같아요.
과거에 BERT 파생 모델들을 사용해본적이 있었는데, 이때 알고 있었던 모델들의 깃허브를 다시 찾아들어가봤어요. 역시나 갓갓 연구자분들.. 많은 릴리스와 업데이트를 해주셨더라구요! 그 중에서도 저희 상황과 가장 잘 맞겠다고 생각한 모델은 KcELECTRA 입니다. (이준범님께 무한한 감사를..🙏)
KcELECTRA는 댓글이 많은 뉴스 혹은 기사들의 댓글과 대댓글을 수집해서 사전 학습을 진행했다고 합니다. 이말은 즉슨 유저들이 발화한 웹상의 글들도 수집해서 사전학습되었기 때문에 더더욱 저희 웹서비스 상황과 부합하다고 생각이 들어요!
ELECTRA는 구글에서 발표한 모델인데요. 기존 BERT의 문제점은 사전 학습의 MLM 과정에서 실제 마스킹하는 비율이 전체 토큰의 15%라는 부분! 그럼 전체 말뭉치 중에서 실제 학습에 참여하는 비율이 15% 밖에 안되는 비효율적이란 문제가 있었대요. 그리고 MLM의 경우 [MASK] 토큰으로 치환하고, 이를 모델이 맞추며 최적화가 되는 과정을 거치는데, 실제 fine-tuning해서 downstream task에서 활용될 때에는 [MASK] 토큰을 사용하지 않으니, 사전 학습과 실제 태크스 적용사이에 토큰 불일치 문제도 있다고 하네요. 그래서 이를 해결한게 ELECTRA래요. 어쨋든 버트의 어떤 문제를 해결해서 장점이 있다!라는 것 아니겠어요? 그럼 그걸로 굿!
자세한 내용은 논문 읽어보세요! 저는 안읽어봤어요! 모르면서 어케쓰냐구여? 그냥 몸으로 부딪히고 때우는거죠모ㅋㅋㅋ 모르는게 나오면 그때 공부하죠 모..일단 저는 똑똑하신 구글 리서처 분들과 KcELECTRA 사전 학습해주신 분께 감사드리는 마음으로 실마리가 보이는 문제 해결하는데 집중해 볼래요. 여러분들은 저처럼 되지 마세요 미래가 깜깜합니다..
심지어 최근에 데이터를 더 모아서 사전학습된 것도 공유해주셨음...
심지어 readme도 한국어로 기깔나게 정리 잘되어 있음...
심지어 fine-tuning 예제 코드와 샘플도 있음...
심지어 huggingface 통해서 쉽게 사용할 수 있도록 사용성도 고려해주셨음...
심지어 말뭉치 데이터셋도 공유해주셧음 !!!!!
안쓸이유 없쬬?(반박시 님말이 맞음...)
너무 고마우신분..(이준범님께 다시 한번 감사를..🙏)
조금 걱정되는 부분은 모델이 무겁다!? 정도입니다. BERT 모델 자체가 일단 가벼운 모델은 아니에요! 하지만 늘 그렇듯 방법은 있죠. 일단 만들어서 테스트해보고, 실제 서비스 접목시 성능상 이슈가 있다면, 더 가벼운 PLM 모델을 찾아서 사용해볼 수도 있을 것 같고..하드웨어로 밀어 붙혀도 좋을 것 같고..tensorRT로 추론 속도를 가속해봐도 좋을 것 같고..뭐 나중일이니 생각을 멈출게요..ㅋㅋ 어쨋든 방법은 있다!
기본적으로는 KcELECTRA 사전 학습 모델을 불러와서 Multi-label classification task에 맞도록 fine-tuning 하고, 이후 공수한 데이터로 전이 학습한다가 될 것 같습니다.
사실 가져다 쓰는 수준이기 때문에 설계랄 것도 없을 것 같습니다. fine-tuning시에 마지막 classifier에서 class 개수만 맞춰주면 될 것 같다고 생각이되요. 그래서 이 부분은 데이터셋 구축에서 결정이 날 것 같습니다.
Layer를 새로 쌓는 등 모델 네크워크를 더 복잡하게 가져가는 등의 실험은 진행하지 않을 예정이에요. 정말로 fine-tuning 만하고 바로 전이 학습을 진행해서 성능을 확인해보려고해요.(문제 정의할때 성능보다는 관리자의 노고를 하루 빨리 줄여드리는게 더 중요한 포인트니까요.) 하이퍼파라미터 튜닝 등도 learning rate를 조정해보는 정도로 하고, 예제에서 주어진 값이나 사전 학습시 사용했던 하이퍼파라미터를 그대로 사용할 예정이에요. optimizer도 마찬가지이구요. 조금 달라지는게 있다면, 저희 GPU 메모리가 감당 가능한 배치 크기 조절 정도가 있을 것 같네요.
다음은 드디어 데이터셋 구축!
끝.
Good Job!