실전프로젝트 2주차 회고: 구현 및 내주 개발 방향

VLV·2022년 11월 20일
0

우리 조가 지향하는 서비스는 다음과 같은 조건을 만족해야 한다.

💊 외국어 번역 API를 통해 Client의 병환을 관련 전문가에게 한국어 문장 형태로 제공할 수 있습니다.
💊 위치 정보 등을 받아 Client에게 맞춤형 서비스를 제공할 수 있습니다.
💊 Cache Server를 별도로 두어, 자주 입력받는 데이터를 저장함으로써 서버 부하를 줄일 수 있습니다.
💊 환자의 병환 Description을 입력받으면 관련 분과 명을 Output하도록 Fine-tuning된 KoBERT 모델을 사용합니다.
💊 Client의 개인정보는 암호화되어 접근할 수 없어야 합니다.

이번 주는 기능하는 최소 단위의 프로그램 구현에 초점을 맞추었고, 시연 영상 주소는 다음과 같다.

항해99 nodejs-백엔드 10조 중간시연

이하는 구현 및 서비스 개선 방향에 대해 서술하였다.

첫째, KoBERT 기반 Multi label classificaiton 모델을 구현하였다. 이 모델은 하이닥 Q&A 데이터를 fine-tuning을 위해 14개 진료 과목 모두 합쳐 약 20만개를 사용하였다. hyper-parameter는 SKT-ai KoBERT 모델 공식 문서를 참조하였으며(https://github.com/SKTBrain/KoBERT/blob/master/scripts/NSMC/naver_review_classifications_pytorch_kobert.ipynb), 대부분 그대로 유지하되 input data 크기에 맞게 sequence max-length만 두배로 늘려 학습하였다(64 to 128). 학습은 colab-pro GPU 환경(P100 GPU & 25GB Ram)에서 이루어졌고, 총 학습시간은 약 4시간 30분 소요되었다.

학습 결과, 모델의 train accuracy는 약 0.78, test accuracy는 약 0.70으로, 우리 서비스가 목표로하는 accuracy 최소치인 0.90보다 상당히 낮은 수치를 보였다. accuracy를 높이기 위해 낮은 성능을 보이는 이유에 대해 원인을 찾은 결과, 모델 자체의 문제이거나 label수가 너무 많기 때문이라고 보긴 어려웠다. 동일 모델 및 유사한 hyper-parameters를 이용하여 비슷한 케이스(증상에 대한 자술 등)의 학습 데이터를 통해 미세조정한 다른 팀의 결과물을 보면, 40개가 넘는 라벨(병명 등)에 대해 약 0.90에 가까운 성능을 보인 경우도 있었기 때문이다. 그렇다면 가장 가능성이 높은 것은 데이터의 질 문제일 것이다. 여러 가능성이 있었지만 우리 팀은 가능한 경우를 크게 세 가지로 축소했다.

첫째, 데이터 전처리의 quaility 문제일 수 있다. 우리가 사용한 미세조정용 학습 데이터에는 하이닥 서비스의 UI(가령 <이전 글> 등 증상 자술이 아닌 불필요 정보들), 이미지 URI등이 섞여 있는 경우가 더러 있었는데, 이는 크롤링 코드를 개선함으로써 해결할 수 있는 문제이다.

둘째, 학습용 데이터로서 하이닥 Q&A가 부적절한 측면이 존재했을 수 있다. 하이닥 Q&A 서비스는 서비스 이용자로 하여금 자신의 글을 등록하기에 앞서 서비스 이용자가 인터넷 상담을 받기 원하는 진료 과목 및 전문의를 직접 선택할 수 있도록 하고있다. 필수적인 것은 아니지만, 서비스 이용자 측면에서 직접 유명 전문의에게 질의할 수 있다는 것은 하이닥 서비스의 메리트일 것이다. 그러나 이 데이터 날것자체는 "증상을 입력하면 관련 진료 과목 명을 출력해주는 모델"의 학습데이터로 적합하지 않을 수 있다. 서비스 사용자가 자신의 진료 과목을 선택할 때 default값은 "가정의학과", 전문의는 관련 질의 점수가 높은 순으로 나열해주고 있는데, 서비스 이용자가 자신의 증상과 맞는 진료과목을 추측하기 어려울 때 이 default 진료과목 및 가장 점수가 높은 의사를 선택할 가능성이 있다(대표성 휴리스틱, representative heuristic, 인간이 연산 리소스를 절약하기 위해 "그것"이 아닌 "그것을 대표하는 것"을 선택하려는 경향성 등). 1차병원으로서 광범위한 진료 및 전문 병원으로의 의뢰 업무도 수행할 수 있는 가정의학과를 default로 둔 것은 하이닥 서비스로써는 디테일한 장점일 수 있지만, 의도한 인공지능 모델을 만드는 데 악재일 수 있다.

셋째, 증상에 관한 분과별 Q&A 데이터셋이 전반적으로 갖는 문제일 수 있다. 즉 대중이 이해하는 진료 과목 별 진료 가능 여부, 범주 및 정도와 의사가 이해하는 것이 다르기 때문일 수 있다고 추측했다. "이런 증상에는 병원의 어떤 분과로 가야할까?" 와 같은 질문에 대중은 과거 경험, 주변의 정보, 상식 등을 바탕으로 추론하지만, 분과별 진료 기준은 의사 등 의학자들이 정한 것이다. 가령 대중의 이해하는 증상 별 진료 가능 범주와 실제로 진료 가능한 범주가 넓은 증상인 경우(감기 등), 환자는 어떤 분과로 찾아가도 좋을 것이다(Question 여러개와 Answer가 여러 개가 중첩 matching되는 경우). 또 대중이 이해하는 진료 가능 범주는 좁지만 실제 진료 가능한 범주가 넓은 경우(question 하나에 answer가 여러개인 경우), 대중이 이해하는 진료 가능 범주가 넓지만 실제 진료 가능한 분과는 적은 경우(Question 여러개에 answer가 하나인 경우)도 존재할 수 있다. 질문(증상)과 정답(진료 가능 분과)이1대 1 관계가 아닌 것이다. 보통 이는 오프라인 진료를 통해 의사의 면밀한 검사로 구체화된다. 환자 자신의 증상에 대한 자술을 전제로 하는 데이터가 가지는 한계이다.

위와 같은 추측들 중 마지막 세 번째는 데이터 셋 자체가 가지는 한계이므로, 팀 리소스를 집중해 해결할 문제가 (이번에는)아닐 것이다. 하지만 첫 번째와 두 번째 추측은 그것이 사실인지 검증하고, 우리 팀의 서비스를 개선할 필요가 있다. 따라서 하이닥 Q&A 데이터와 유사한 데이터 소스인 네이버 지식인 Q&A 서비스를 선택, 크롤링 코드를 개선하여 다시 미세조정을 실시하였다. 네이버 지식인 Q&A는 증상만 기술할 수 있을 뿐 서비스 이용자가 관련 분과 및 전문의를 선택할 수 없다. 때문에 서비스 이용자 자신이 아니라, 여러 분과를 전문한 의사들이 각자 환자가 자술한 증상을 보고 답변을 달 수 있다. 이를 보다 보장하기 위해, 서비스 이용자의 증상을 기준으로 하는 것이 아니라 분과별로 답변을 많이 단 전문의의 글을 찾아 질문과 답, 분과를 수집하였다. 그 결과, 같은 모델/hyper-parameters를 기준으로 train accuracy가 약 0.88 이상으로 증가하였다. 하이닥 데이터 기준 train accuracy 0.78 기준으로 약 12~13%의 성능 향상을 보인 것으로, 비록 label 갯수 및 데이터 사이즈가 동일하지는 않더라도, 유의한 성능 향상을 보임을 관찰할 수 있었다. 때문에 이번 주 목표로 네이버 지식인 Q&A 데이터를 하이닥 데이터와 같은 사이즈& 개선된 크롤링 코드로 크롤링한 데이터로 미세조정을 수행할 계획을 세웠다. 또한 기존의 AWS t2 micro/ ubuntu server로는 prediction by GPU가 불가능하므로, AWS SageMaker로 연산용 서버를 새로 구축, 이전할 예정이다.

이번 주에 해결한 중점 목표로 AI 성능 향상과 더불어 DB에 저장된 데이터와 Kakao map DB 사이의 데이터 최신성 보장 issue를 개선하고자 한다. 현재 우리 Web Server DB에 저장된 4만여개 이상의 병원 및 외국어 지원 약국 정보 데이터는 2021~2022년 기준 서울시 공공데이터 및 보건소 자료를 기반으로 한 것으로, Kakao Map측 DB와 시간적으로 다르기 때문에, "우리 서비스에서 추천해 준 병원을 실제로 가보니 폐업한 경우"등의 사건이 발생할 수 있다. 또, "추천 병원의 내 외국어 지원 가능 여부가 달라진 경우"등의 문제도 발생할 수 있을 것이다. 어떻게 우리 병원 정보 DB의 최신성 보장할 수 있을까? Web server DB의 최신성을 보장하는 것은 불가능하므로, 외국어 지원 가능 여부의 변경은 해결할 수 없다. 그러나 폐업 여부는 Kakao Map DB와 Web Server DB 사이의 불일치가 발생할 시 client에게 response하지 않고, 보다 후순위의 추천 병원으로 대체하여 response하는 예외처리를 구현함으로써 Kakao map으로의 추가적인 query 없이 리스크를 낮출 수 있다. 이 최신성 보장 이슈는 서비스의 전반적인 질과 부정확한 정보를 제외하는 것 사이의 이익/리스크 조절의 문제로 볼 수 있다.

사용 모듈 최종

마지막 목표로 nodejs + express로 작성한 현재 코드를 Typescript/Nest.js 기반으로 Refactoring하고자 한다. 우리 조는 서비스에 MSA 아키텍쳐를 기반으로 Docker/k8s 사용한 로드밸런싱을 적용, 서비스 부하 컨트롤 및 안정성 증대를 목표로 잡고있는데, Module단위 architecture 개발에 용이하고 자체적으로 보유한 모듈 범주도 큰 Nest.js가 뒷받침되면 이 과정이 보다 용이할 것이라고 의견을 모았기 때문이다. 또한 이번 주 멘토링 과정에서 지적해주신 부분인 예외처리 코드가 부족한 점을 개선하기 위해 Nest.js에 내장된 테스트 코드 모듈 jest로 코드 짜는 연습을 하면서 예외처리를 공부할 예정이다. 최종 서비스의 모듈 구조는 다음과 같을 것으로 예상하고 있다.


profile
커피, IT기기, 노래를 좋아해요.

0개의 댓글

관련 채용 정보