버트(BERT) 파인튜닝 간단하게 해보자.

작년 말에 GluonNLP 0.6버전 개발에 활발하게 참여하였는데, 그중에서 사용자들이 편리하게 사용할만한 부분에 대해 소개하기 위해 글을 써봤다. 다들 버트, 버트 하는데, 어떻게 사용할지 모를 분들에게 도움이 될 것이라 예상해 본다.

이 글은 MXNet-Gluon 기반으로 설명이 된다. 최근 훌륭한 한글 자료가 인터넷에 나왔으니 관심 있으신 분들은 먼저 참고하시길 바란다.

버트(BERT)

인간은 직접 혹은 간접 경험을 통해 특정 상황이나 문제에 대한 가장 효과적인 해결책을 찾을 수 있는 지혜를 얻을 수 있다. 그러한 이유 때문에 경험을 중요시 여기며 모든 경험을 할수는 간접 경험의 하나인 독서를 강조하곤 한다. NLP 영역에서 인기있는 기술인 언어모델 전이학습은 바로 이러한 컨셉을 적용한 학습전략이다. 언어모델이 어떠한 방식으로 사용될지 확실치 않더라도 미리 양질의 방대한 양의 학습데이터로 미리 학습을 시켜두고 이렇게 학습된 모델을 간단하게 튜닝해 다른 목적으로 활용하는 것이다.

버트(BERT)는 현존하는 가장 강력한 NLP 언어모델로 다양한 NLP테스크에서 가장 좋은 성능을 보여주고 있다.

이 글에서는 버트를 기반으로 대표적인 한글 코퍼스인 네이버 무비리뷰 분류기 성능을 높여보도록 하겠다. 이글에서는 예측 성능에 대한 이야기 보다는 얼마나 간단하게 버트를 한글 코퍼스에 활용할 수 있는지에 대해서 중점적으로 이야기해보겠다. 기존의 버트관련 좋은 글이 많이 나왔기 때문에 버트에 대한 자세한 설명은 해당글을 참고하길 바란다.

데이터 전처리

버트가 기존의 방법론 대비 활용하기 어려운 주요한 이유중에 하나는 아래와 같이 다양한 입력을 받아야되기 때문이다. 대부분 구현체들은 이들에 대한 일반화를 하지 않아 별도의 모형을 구축할때 구현이 까다롭다.

입력 데이터

버트는 입력 문장에 대해서 아래와 같은 작업을 요구한다.

  1. 각 토큰의 Vocabulary 인덱스를 추출해 이를 정해진 길이의 벡터로 생성.
  2. 두 문장 혹은 하나의 문장이 들어올 수 있기 때문에 이들을 구분하기 위한 토큰 타입 벡터 생성
  3. 유효 길이 벡터

토큰 인덱스 : ‘[CLS] is this jack ##son ##ville ? [SEP] no it is not .[SEP]’

토큰 타입: 0 0 0 0 0 0 0 0 1 1 1 1 1 1

유효길이: 14

토큰인덱스는 Token Embedding을 생성하는데 필요하고, 토큰 타입은 Sentence Embedding, 유효길이는 내부적으로 여러 연산을 하는데 필요하다. Positional Embedding은 입력의 길이 정보만 알수 있다면 학습/추론시 자동 생성 가능한 벡터이다.

GluonNLP는 위 작업을 매우 편하게 진행해주는 함수(BERTSentenceTransform)를 제공하고 있다.

먼저 적절한 버트 모델을 로딩한다(구글에서 공개한 multilingual 모델을 사용해야 한글 문제에 적용할 수 있다).

bert_base, vocabulary = nlp.model.get_model('bert_12_768_12',
                                             dataset_name='wiki_multilingual_cased',
                                             pretrained=True, ctx=ctx, use_pooler=True,
                                             use_decoder=False, use_classifier=False)
ds = gluon.data.SimpleDataset([['나 보기가 역겨워', '김소월']])
tok = nlp.data.BERTTokenizer(vocab=vocabulary, lower=False)
trans = nlp.data.BERTSentenceTransform(tok, max_seq_length=10)
list(ds.transform(trans)
[(array([    2,  8982,  9356, 47869,  9566,     3,  8935, 22333, 38851,
             3], dtype=int32),
  array(10, dtype=int32),
  array([0, 0, 0, 0, 0, 0, 1, 1, 1, 1], dtype=int32))]

입력에 대한 전처리 부분을 제외하고 우리가 진행해야 될 부분은 무비리뷰에 대한 긍/부정 레이블을 처리하는 것이다. 모든 학습 데이터는 배치단위로 입/출력이 정의되기 때문에 입력 데이터 처리와 레이블 처리를 동시에 배치 출력하기 위해 Dataset 클래스를 정의하면 아래와 같다. Dataset 클래스는 PyTorch의 Dataset과 동일한 형태를 띈다.

class BERTDataset(Dataset):
    def __init__(self, dataset, sent_idx, label_idx, bert_tokenizer, max_len,
                 pad, pair):
        transform = nlp.data.BERTSentenceTransform(
            bert_tokenizer, max_seq_length=max_len, pad=pad, pair=pair)
        sent_dataset = gluon.data.SimpleDataset([[
            i[sent_idx],
        ] for i in dataset])
        self.sentences = sent_dataset.transform(transform)
        self.labels = gluon.data.SimpleDataset(
            [np.array(np.int32(i[label_idx])) for i in dataset])

    def __getitem__(self, i):
        return (self.sentences[i] + (self.labels[i], ))

    def __len__(self):
        return (len(self.labels))

위에서 로딩한 버트 모델은 인코더 부분이다. 인코더 위에 분류기를 붙여야 긍/부정을 학습할 수 있을 것이다. 버트 논문에서는 하나의 문장이 입력될때 분류기는 아래와 같이 구성하는걸 제안하고 있다.

모든 버트 모델은 첫 클래스 레이블을 pooler 라고 네이밍 하고 있고 이 pooler 결과를 받아 FC(fully connected) 레이어 하나를 추가해 간단하게 구성한다.

class BERTClassifier(nn.Block):
    def __init__(self,
                 bert,
                 num_classes=2,
                 dropout=None,
                 prefix=None,
                 params=None):
        super(BERTClassifier, self).__init__(prefix=prefix, params=params)
        self.bert = bert
        with self.name_scope():
            self.classifier = nn.HybridSequential(prefix=prefix)
            if dropout:
                self.classifier.add(nn.Dropout(rate=dropout))
            self.classifier.add(nn.Dense(units=num_classes))

    def forward(self, inputs, token_types, valid_length=None):
        _, pooler_out = self.bert(inputs, token_types, valid_length)
        return self.classifier(pooler_out)                               

나머지 부분은 일반적인 학습 모듈과 크게 다르지 않다. 아래는 학습 로그를 찍어본 것이다.

[Epoch 1 Batch 50/2344] loss=8.4847, lr=0.0000026681, acc=0.556
[Epoch 1 Batch 100/2344] loss=7.6343, lr=0.0000053362, acc=0.612
….
[Epoch 1 Batch 2250/2344] loss=4.5963, lr=0.0000422197, acc=0.805
[Epoch 1 Batch 2300/2344] loss=4.2460, lr=0.0000419234, acc=0.806
Test Acc : 0.84662
[Epoch 2 Batch 50/2344] loss=4.4179, lr=0.0000413664, acc=0.846
[Epoch 2 Batch 100/2344] loss=4.4742, lr=0.0000410702, acc=0.843
….
[Epoch 2 Batch 2200/2344] loss=3.4934, lr=0.0000286265, acc=0.869
[Epoch 2 Batch 2250/2344] loss=3.5244, lr=0.0000283302, acc=0.869
[Epoch 2 Batch 2300/2344] loss=3.1572, lr=0.0000280339, acc=0.869
Test Acc : 0.86312
[Epoch 3 Batch 50/2344] loss=3.4649, lr=0.0000274769, acc=0.885
[Epoch 3 Batch 100/2344] loss=3.4550, lr=0.0000271806, acc=0.885
….
[Epoch 3 Batch 2250/2344] loss=2.8383, lr=0.0000144406, acc=0.901
[Epoch 3 Batch 2300/2344] loss=2.4659, lr=0.0000141443, acc=0.901
Test Acc : 0.86686
[Epoch 4 Batch 50/2344] loss=2.6485, lr=0.0000135873, acc=0.919
[Epoch 4 Batch 100/2344] loss=2.6904, lr=0.0000132911, acc=0.916
….
[Epoch 4 Batch 2250/2344] loss=2.3454, lr=0.0000005511, acc=0.924
[Epoch 4 Batch 2300/2344] loss=2.0258, lr=0.0000002548, acc=0.925
Test Acc : 0.87136

성능

일반적으로 네이버 무비 리뷰 문제로 모델을 생성시 83~85% 정도의 정확도를 보인다고 알려져 있다. 간단하게 4 에폭 파인튜닝 후 최종 성능은 0.871이다. 물론 더 학습할 경우 성능이 오를 가능성이 있으니 좀더 학습해 보는 것도 괜찮을 것이다.

테스크(한국어) 특화 pre-training의 필요성

위 성능은 테스크 특화의 아무런 튜닝을 하지 않은 상황에서 좋은 성능이나, 버트를 쓰지 않아도 달성 가능한 성능(fasttext + LSTM + Attention)으로 고무적인 성능은 아니다. 이런 성능의 주된 이유는 한국어 특화된 버트 모형을 사용하지 않아서이다. 필자의 경험으로 한국어만 학습한 버트 모형을 해당 문제에 적용했을때 이 문제에서 0.90 이상의 정확도를 보임을 경험했고, 학습(pre-training)을 지속할수록 성능이 올라갈 수 있음을 확인했다. 이는 자신의 테스크에 잘 동작하는 버트 모형의 학습(pre-training)이 필요할 수 있음을 시사하고 있고, 아직 공개적인 한국어 버트모델이 나오지 않은 상황에서 더 필요한 작업이라 볼 수 있다.

마치며

이 글에서는 GluonNLP에서 제공하는 버트 모형을 이용해 간단하게 한국어 관련 모델을 학습해 봤다. GluonNLP는 버트를 간단하게 로딩하는 인터페이스를 제공하고 있고, 이들이 요구하는 형태로 데이터를 전처리 하는 API를 제공하고 있어 활용하기 복잡한 버트 모형을 다양한 문제에 간단하게 활용 가능하게 한다. 이곳에서 활용한 전체 코드는 여기에 공개해 두었다.

DMLC 맴버로 초청받다.

지난 2월 온전히 1개월을 모두 뉴질랜드 가족여행에 쏱아 붓고 있던 중 뉴질랜드 푸카키 호수 마운트 쿡 빙하 아래 있던 (전화도 잘 터지지 않던)오지 캠핑장에서 작은 메일을 받았다. DMLC에 초대를 하고 싶다는 메일이었다.

DMLC(Distributed (Deep) Machine Learning Community )

DMLC는 대표적으로 데이터 사이언스를 한다면 알고 있을 xgboost를 만든 개발자 집단이라 보면 된다. xgboost는 지금도 그렇지만 케글과 같은 대회에서 우승자들이 많이 사용했던 트리 기반의 앙상블 머신러닝 패키지다. 이 이외에 gluon-nlp, gluon-cv 등과 같은 딥러닝패키지들이 존재하고 있다. 몇몇 관련 프로젝트를 Amazon에서 지원하고 있기 때문에 다수의 Amazon 개발자들이 참여하고 있는 상황이다.

DMLC의 맴버가 된다는건 이러한 커뮤니티가 필요할때 서포팅을 받거나 줄 수 있게 되었다는 걸 의미한다.

어떻게 초대를 받았나?

NLP를 해본 사람들은 알겠지만 그 특유의 전처리 로직의 다양성 덕분에 코드의 유지도 힘들 뿐더러 연구 재현도 잘 안된다 이런 고충을 해결하고자 만들어진게 gluon-nlp다. 개인적인 취미 혹은 연구, 학습 목적으로 gluon-nlp를 자주 사용해왔고, 그러다 보니 자연스럽게 코드레벨에 접근하는 경우가 많아서 이미 코드 레벨의 이해도는 어느정도 준비된 상황이었다. 무엇보다 이 프로젝트 코드의 퀄리티가 상당히 좋아서 코드 읽는 재미가 있다.
다른 NLP패키지도 많지만, gluon-nlp를 선택해 사용한 이유는 이 패키지의 목표가 다수의 NLP 모델과 전처리 로직을 재현성 가능하게 만들어가는데 초점을 맞추고 있어서이다. 딥러닝 프레임웍 코드가 달라지는데, 모든 커뮤니티 서포팅 기반의 딥러닝 모델 구현체들이 재현성을 유지하는건 힘들다. 물론 gluon-nlp도 커뮤니티 서포팅 기반이나 AWS의 풀타임 엔지니어들이 핵심적인 부분을 차지하고 있고, 이러한 모델 재현성 관리가 AWS 클라우드 기반 모델 개발에 반드시 필요할 것이라는 예상을 해서이다. 클라우드 사용자들이 마음 편하게 모델을 가져다 쓰기만 할 수 있는 환경을 NLP에서도 만들어 두는게 필요할 것이다.

여튼 gluon-nlp를 사용하는 재미, 읽는 재미가 충만한 상태였으며, 패키지의 목적도 너무 맘에 들어 2018년 말까지 코드 컨트리뷰션을 하고자 계획했다.

물론 이 컨트리뷰션의 동기는 DMLC 맴버가 되는게 아니였다. 어떻게 이런걸 기대했겠나? 하지만 아래에 언급한 몇몇 이슈를 제기하고 코드를 컨트리뷰션하고 여러 기술적인 논쟁을 거치며 맴버가 될 수 있었다.

첫번째 이슈 제기

구글이 BERT 코드를 공개한 이후 몇몇 딥러닝 프레임웍 커뮤니티에서 BERT를 포팅해서 사용할 수 있게 하였다. 물론 gluon-nlp에서도 발빠르게 이를 지원했는데, 재현성 측면에서 검증이 제대로 되지 않았다는 판단이 들었다(물론 TensorFlow, PyTorch 버전의 BERT 역시 GLUE의 모든 테스크에 대해서 성능 재현코드가 없는 상태였고, 지금도 여전히 그렇다). 그래서 이에 대한 이슈를 제기했다. 결국 다른 곳에 없는 코드를 구현해야 되는 이슈였다.

GLUE에서 소개한 데이터 기반의 테스트 프레임은 BERT 뿐만 아니라 앞으로 많은 모델에서 사용될 것이기 때문에 이 부분에 대한 구현은 매우 중요해졌고, 이 코드의 베이스 코드를 컨트리뷰트 하게 되었다.

두번째 이슈

연말에 업무 때문에 BERT를 학습해야 되었는데, 마침 해당 이슈(BERT 학습셋 생성 모듈)가 gluon-nlp에 등록이 되어 있어서 함께 진행했다.

“어 회사 업무로 오픈소스 컨트리뷰션 해도 되나요?”

위와 같은 질문이 나올 수 있는데, 해당 업무는 리더의 승인을 얻어서 진행했다. 설득의 포인트는 “코드 리뷰”였다.

구글의 공개된 코드 베이스로 진행해서 큰 어려움은 없었으나, tfrecord에 대한 대안 모듈에 대한 이슈 등으로 gluon-nlp 커뮤니티 내에서 논의가 있었다. 결국 회사에서 쓸 모듈과 gluon-nlp에 컨트리뷰트 한 모듈을 달리 구축했다. 이 작업을 하면서 대용량의 학습셋을 어떻게 구축하는게 최적인지 많은 혜안을 얻을 수 있었고 이 고민 덕분에 학습셋 확장과 멀티 노드 딥러닝 학습을 하는데 큰 도움이 되었다.

결국 회사에서 딥러닝 트레이닝에 쓸 코드를 만드는데 훌륭한 외부 엔지니어의 리뷰를 받을 수 있었던 것이고, 결과적으로 많은 시행착오를 줄일 수 있었다.

딥러닝 코드는 버그를 발견하기 어렵고 디버깅 하기 쉽지 않아서 이런 리뷰를 받는건 일반적인 소프트웨어 개발에서의 리뷰보다 큰 도움을 준다.

몇몇 도움 그리고 merge
BERT MaskedLM 모듈 등의 버그를 다른 사람의 코드를 리뷰해주면서 고칠 수 있게 도움을 줬다. 물론 이런 과정을 통해 내 생각과 의견을 검증할 수 있었다.

이와 같은 작업들을 2018년 12월 말 크리스마스 ~ 연말 휴가 즈음에 진행했는데, 크리스마스 휴가는 스타벅스에서 코딩하면서 보냈고, 연말 역시 다수의 git 브랜치를 오가며 코딩하기 여념이 없었다. 1월에 업무가 바빠지면서 주중엔 신경 쓰지 못하다가 패키지 릴리즈 포커스를 받게 되어 주말작업을 통해 마침내 master에 머지 되었다.

오픈소스로 공인 실력을 키우자

필자가 만나는 모든 역량있는 개발자들이게 오픈소스 개발에 기회가 되면 참여하라고 이야기한다. 그 이유는 개인의 성장과 경력 관리에 있다. 개발자에게 오픈소스 개발 실적은 흡사 영어 공인 성적표와 같은 의미라 생각한다.

하지만 이 과정이 쉽지 않고, 무엇보다 시간이 많이 소요된다. 따라서 두가지 방안이 존재한다.

  1. 오픈소스에 투자할 시간을 늘린다.
  2. 실력을 키운다.

일단 두 가지 조건중 최소 하나 이상 충족되지 않으면 오픈소스 기여는 쉽지 않다. 재밋는 사실은 기여하면 할 수록 1번의 중요성이 적어진다는 것이다. 이는 개인의 실력이 늘어난다는 것을 의미한다.

1번조차 어려운 분들에게는 일단 워라벨이 어느정도 보장될 수 있는 업무나 직장으로 옮기라 추천하고 싶다. 🙂 잠을 줄여서 하겠다라면 말리진 않겠지만 반드시 건강이 상하게 되니 주의해야 된다.

GitHub은 코드로 말하고 답하는 SNS다. 모든 컨트리뷰트가 로깅되고 코드에 기억된다. 코드 한줄에 많은 고민과 질타가 함축되고 이를 통해 배우게 된다. 여길 방문하는 많은 분들도 이런 경험을 해보시길 추천드린다.

난 항상 딥러닝 모델 혹은 프레임웍에 문제가 있을때 도움받거나 줄 수 있는 동료풀이 있다고 이야기한다. 그 동료는 회사의 동료들도 포함이겠지만 이 보다 더 많은 딥러닝 개발자가 있는 DMLC를 염두에 둔 것이다.

데이터 과학자에서 AI 연구자로 들어서며…

2018년 9월에 5년 넘게 몸담았던 DT조직에서 AI 조직으로 옮기면서 AI 연구자로 새로운 직무를 시작했다. 그동안 이러한 소식을 블로그에 올리지 못한것은 이 발걸음에 불확실함과 기대, 불안이 공존해 있었기 때문이었다. 4개월이 지나고 어느정도 바쁜 적응의 시간을 보내고 펜을 들어 그 소회를 고백해 보고자 한다.

데이터 분석, 기술, 문화

AI 연구자가 되기 전에 6년 넘게 데이터 분석 업무를 해왔다. 그 이전엔 검색 엔지니어 였고, 엔지니어에서 데이터 사이언티스트로 넘어가게 된 이유와 방법은 이전에 밝힌 바 있다.

첫 4년은 데이터 분석에서 기술적인 부분(통계학, 머신러닝 등)에 많은 관심을 가졌다. 실제 이 기간에 통계학 학사 학위부터 시작해 박사 학위를 시작한것도 이 때문이라고 이야기 할 수 있다. 현란한 기계학습 기법, 시각화 방법론(심지어 시각화 책까지 썼다.)에 심취해 있었고, 이러한 방법론이 이 분야의 거의 전부라 생각했었다. 많은 업무에서 단맛도 많이 봤고, 쓴맛도 많이 봤다. 쓴맛을 본 이유가 모두 기술이 부족해서라 생각했던 시절이었다.

이 기간에 수행했던 일들을 대략적으로 요약하면 아래와 같다(필자의 링크드인에서 발췌한 것이다).

  • Data analysis and modeling with MNO(mobile network operator) related data and problems.
  • Build many kind of Machine Learning model and apply them to real problems.
  • 2015 market top data analyst in SKT.
  • Research on detection of customer life event changes with bootstrap sampling on interesting duration.
  • Experience on handling high-cardinality customer behavior data to apply Machine Learning Model.
  • Apply Bayesian Churn prediction model which better performance than legacy model.
  • Forecasting mobile traffic usage for infra investment.
  • Forecasting number of daily incoming calls on customer center for optimal operation.
  • Fee product analysis for optimal product usage based on Quantile Regression analysis.
  • Anomaly detection about leakage of personal information on the agency.(find system error and case of Illegal usage)
  • Develop credit scoring model for postpaid phone billing(both personal and corporation). Enhances discrimination of every grades and define optimal sales policy for each credit grade. Model uses not only billing history but also Telco specific customer behavior features.
  • Based on high-dimensional behavioral attributes to pursue a differentiated with legacy credit score model.
  • Develop scoring model for new business.
  • Researching heavily on behavior data to make it use it for marketing and new business purposes.
  • Customer Targeting Model for services using both behavior and contextual features which can improve performance more than 3 times better than control group.
  • Build customer job prediction model with behavior features for targeting and new business.
  • Apply scoring model using Deep Neural Network, improving performance over AUC +0.05 compare with traditional machine learning algorithms.
  • Apply online learning with TensorFlow(Deep Stacked Network) to reduce concept drift of changing market situation.
  • Make use of high dimension data on prediction model using AutoEncoder, it improve prediction performance.

최근까지 2년은 딥러닝에 심취하면서 모델링 자동화 그리고 관리 자동화를 위한 시스템을 개발했다. 그리고 현재 많은 조직에서 그렇게 만들어진 시스템을 사용하고 있다. 이 시스템은 직접 데이터 분석 모델링을 하면서 편하게 사용할 수 있는 시스템을 만들기 위함이 컸는데 이 때문에 그 어디에도 없는 시스템이 되었다.

2년 동안 모델링 플랫폼 개발과 딥러닝 리서치에 집중 하면서 지난 4년 동안 해왔던 데이터 분석 업무에 대해서 한걸음 떨어져서 볼 수 있는 기회가 되었다. 그동안 왜 업무에 데이터 기반 의사결정을 적용하는데 몇몇은 실패를 했고 성공을 했는지….

먼저 밝힐것은 그 이유가 ‘기술’하고는 크게 관련이 없었다는 것이다. 랜덤포리스트를 사용하든 딥러닝을 사용하든 기술은 그걸 사용하는 모델러의 만족도 그 이상도 이하도 아니였다. 결국 가장 큰 이유는 비즈니스 자체 그리고 그 주변의 환경 그리고 그들 사이에 있는 사람이었다.

모델은 필요 없어요, 제가 직접 쓸 레버를 주세요.

데이터 기반으로 업무를 최적화 하자고 딥러닝 모델을 개발해서 업무 담당자에게 가져가면 아래와 같은 반응을 보일 것이다.

딥러닝은 해석 불가능해서 사용하기 어려워요.

사실 위 반응은 사용하기 싫다는 표현을 애둘러서 이야기 한 것일 가능성이 70% 이상인데, 순진한 모델러는 딥러닝 모델에 Lime 같은걸 어렵게 적용해서 다시 가져가지만 믿을 수 없다며 담당자는 소극적으로 대하게 된다. 이 쯤되면 모델러는 테스트를 하자고 제안하게 되는데, 대부분의 경우 기존 방법의 1~2% 정도 성능 차이를 내고 적용 리소스 대비 효과가 적다며 클로징 하게 된다.

위 일화엔 두가지 업무 적인 특징이 존재할 것이다. 첫번째는 이미 비즈니스 로직이 오랜 시간이 지나면서 사람이 컨트롤 할 수 있는 수준으로 최적화 되었을 것이다. 모델로 자동화를 하지 않아도 사람이 직접 해도 될 정도인 것이다. 만일 자동화가 절실한 다 대 다를 연결해주는 로직이라면(예를 들어 온라인 광고) 안할 이유가 없다. 두번째는 현업 담당자는 새로운 레버를 원한다는 것이다. 현업 담당자가 원하는 건 대부분 자신이 몰랐던 속성(레버) 한, 두개이다. 모든 데이터 기반으로 하고 있는 블랙박스 모형은 원하지 않는다. 무엇보다 자신이 컨트롤 하기 어려워 지게 되면 필요에 따라 메트릭을 생성하는데 어려움을 겪게 되고 이는 곧 자신의 성과에 영향을 미치게 될 것이기 때문이다.

이러한 상황에 1~2%의 성능 차이도 큰 비용의 차이를 가져오는 영역을 찾아서 데이터 기반으로 개선하는건 좋은 접근 방법이나 이 역시 많은 노력과 시간이 필요하며 현업 담당자가 단순한 레버 활용으로 땡겨낼 수 있는 성과일 가능성이 높다. 이러한 경우도 최소 5% 이상의 성능 차이는 보여줘야 되는데 상당히 어려운 일이다.

레버 뿐만 아니라 브레이크, 핸들까지 줄께요..

이러한 상황에서 가장 좋은 접근 방법은 담당자에게 그들이 원하는 도구를 만들어 주는 것이다. 이쯤되면 분석, 모델을 넘어 개발이 된다. 분석, 모델링을 넘어서 도구까지 만들어줄 생각까지 염두에 두고 커뮤니케이션 하는건 담당자와 지속적관 관계를 유지하고 데이터 기반 업무 의사결정을 유도할 수 있게 하는 큰 디딤돌이 된다. 어떠한 담당자도 처음보는 괴상한 모델러가 와서 자신의 모든 업무를 자동화 시킨다고 설레발 치는걸 좋아할 수 없다. 레버는 물론 브레이크, 핸들까지 만들어 줄 생각으로 접근하고, 지속적 점진적으로 감동,개선시켜야 된다. 누가 데이터 과학자를 섹시한 직업이라 했나? 이미 섹시한 사람만이 데이터 과학자로 성공할 가능성이 높다.

저런 고민 하고 싶지 않고 분석 모델링만 하고 싶어요.

프로세스…. 사람을 변화시키는건 매우 어렵다. 얼마나 어려우면 IBM에서는 사람을 해고하고 새로 채용하는게 프로세스를 개선하는 가장 빠른 방법이라 하겠나. 아마도 그걸 아는 분들은 저런 고민을 하고 싶지 않을 것이다. 그렇다면 저런 고민 하지 않고 순수한 분석, 모델링을 할 수 있는 곳은 어디일까?

앞서 이미 비즈니스 로직이 사람에 최적화 되어 자동화에 대한 니즈가 없다고 언급했다. 반대로 비즈니스 로직이 복잡해 담당자의 의사결정 자동화가 절실한 분야에 가라고 조언하고 싶다. e커머스, 온라인 광고 등등 온라인 서비스 회사는 매칭 경우의 수가 Many-to-Many여서 자동화가 필수이다. 이러한 영역에서 크리티컬한 의사 결정의 영역은 모두 머신러닝 모델이 수행하고 있다. 초단위로 모델을 관리하고 A/B 테스트를 상시로 구동하고 있으니, 기술을 뽐내고 갈고 닦기 좋은 영역이다.

그러니 좌절하거나 실망하지 말아요.

비즈니스 데이터 분석을 한다는건 상당한 불확실성의 영역에서 과학을 하는 것이다. 사실 이미 그 일이 성공할지 실패할지 본인의 실력과는 크게 상관없이 이미 정해져 있는 경우가 많다. 그렇다고 잘 될 분석만 가려서 할 수도 없고 누군가는 해야 될 상황이 대부분이다. 따라서 본인이 최선을 다하고 정말 뭐 할것 없이 수많은 시도를 했음에도 일이 더 이상 진행되지 않는다고 자신에 대해 실망하거나 자책하지 않았으면 좋겠다. 이런 상황에 데이터 분석 조직 리더는 분석가를 질책, 책망하기 보다는 같이 고민해주고 담당자가 직접 풀기 어려운 조직레벨의 이슈를 해결해 주거나 분석 방향을 조절 및 제안해 주는데 집중 해야되며, 특히 잘 될 업무, 실패할 수 있으나 잠재력이 있는 업무 등을 리더가 잘 구분해 분석가들의 업무 스트레스/성과를 잘 조절해주려는 노력이 필요하다.

데이터 분석은 뒤로하고… AI 연구자로…

비즈니스 데이터 분석을 해오면서 느낀 한계와 가능성은 전적으로 내 개인적인 경험이고 나름의 결론이라 모든 경우의 결론이라 할 수 없는것에 주의했으면 한다. 하지만 사람, 문화, 업무를 변화하시키는게 업무의 본질임은 많은 비즈니스 데이터 분석가들이 공감하는 부분이라 생각하며, 그 미션이 생각보다 쉽지 않다라는 것은 많은 경험자들의 공통 의견이라 생각한다.

앞서 언급한 데이터 분석 업무에 대한 나름의 결론을 장시간을 투자해 얻었고 더 할만한 영역도 없었으며, 조직 초기부터 참여하여 이제는 조직이 안정화된 업무를 하고 있어 스스로 하산해도 될 거란 판단이 들었다(참고로 몸담았던 DT 조직은 현재 국내 최고의 데이터 과학자 조직으로 인정받고 있다). 그러면서 취미로 하던 딥러닝 연구를 더 깊이 하기 위해 조직 이동을 하게 되었다.

필자가 왜 AI 연구자가 되었는지 이유는 아래 세가지다.

  • 데이터 분석/모델링은 많이 했고 나름의 결론도 냈어요. (이제 그만…)
  • 딥러닝 기술연마/연구를 계속 하고 싶어요(논문도 쓰고..).
  • 딥러닝 기술 기반으로 신기한 AI 서비스를 만들고 싶어요.

AI 연구에서 엔지니어링 스킬은 생각보다 중요

조직 이동전에는 연구에 엔지니어링 스킬이 어느정도 필요할지 감을 잡지 못했다. 지금은 엔지니어링 스킬이 연구를 위해 가장 필요한 체력적인 부분이라는 것에 100% 공감하고 있다. 축구 선수로 치면 체력이 좋아야 슛을 많이 시도할 수 있는 것과 같다.

이 측면에서 볼때 경력있는 엔지니어가 AI 연구에 적합한건 당연한 것이라 생각한다. 그동안 엔지니어링 스킬을 다져온걸 큰 다행이라 생각하고 있고, 지금 이 시간 휴일에도 이 기술을 딥러닝 기술과 함께 연마하고 있다. 개발을 수년간 지속적으로 해왔지만 지금도 연구를 위해 부족하다고 느끼는 부분이 있을 정도다.

기업의 AI 연구자로서..

생각해보면 AI 연구는 정말 어려운 것이다. 코딩도 (정확하게) 잘 해야되고, 학습 시간도 오래걸려(BERT는 8 GPU로 1달 학습해야됨. 1년에 12번 테스트만 해야 될까?) 최적화도 시켜야되며 이러한 과정을 수백번 반복되야 쓸만한 연구 결과 1개가 나오니 말이다. 그래서 요즘엔 회사에서 지속적인 AI연구를 할 수 있는 방법은 뭐가 될까를 고민하고 있다. 그리고 그 연구 방향이 회사에 도움이 되는 방향과 맥을 같이해야 된다는 (어찌보면 당연한) 스스로의 결론에 이르럿고, 이러한 생각을 가지고 한해를 시작하고 있다. 아마도 1년이 지나면 이러한 생각, 행동의 정답을 볼 수 있지 않을까 한다.