이번에 회사에서 새로운 기능을 런칭했다. 내려오는 데이터 량이 좀 된다. 150K 정도 

 

스테이징 서버(한국에 있다)에서 혹독한 테스트를 거쳐도 문제가 없고, 론칭후 테스트에서도 별 이상이 밝혀지지 않았다. WI-FI 환경하에서도 동작을 잘하고 

 

문제는 내 폰에서 발생했다. 참고로 나는 SKT 폰을 사용중이다. SKT 의 LTE 환경하에서는 멈춘거처럼 동작하는 것이다. 150K 다.. 다시 말하면. 그정도 데이터를 내려 봤는데 멈춘다고? 

 

개발자를 소집해서 물어봤더니 전혀 안 느리다고 한다. 내 폰을 실제로 보여주니 개발자들이 다들 당황하는 것이다. 결국 이런 저런 테스트를 통해서 내린 결론은 SKT - LTE 가 완전 개 구리다는 것이다. 국내는 별 문제가 없으나 특히 해외가

 

KT, LG, WI-FI 망에서는 아주 잘 동작한다. 이렇게 쓰는 것도 웃기다. 겨우 150K 인데.. 

 

결국 SKT 의 LTE 환경이 개선되길 바라는 것은 코로나 19가 자연적으로 사라지길 바라는 것만큼 이루어지기 힘든 바람일테니, 우리가 패킷을 다이어트 시켰다. 1/3 로 줄였더니 시간이 많이 단축 됐다. 하.. 5G 시대에 150K 때문에 이런 난리가 일어나다니.. 

 

결론은 SKT-LTE 가 해외에 있는 서버랑 연결할때 극악의 효율을 보여준다는 것이다. 해외 서비스 준비할때 이런 것도 고려해야 할 것이다. 


프론트 개발이 가능하신 개발자 분들이 제 오픈소스 프로젝트에 참여해서 프론트 엔드를 꾸며 주었군요. 모바일도 적용이 되어 있습니다. 


데모: https://chat.crazia.org/

소스: https://github.com/crazia/NM-chatbot


딥러닝 관련 과거 포스트들: 

1. AI 학 개론 (초보 개발자를 위한 정리) 

2. seq2seq 를 이용한 챗봇 (Neural Network Chatbot)

3. seq2seq 를 이용한 챗봇 - 웹버젼

4. seq2seq 를 이용한 챗봇 - 자동 진화 버젼

5. seq2seq 를 이용한 챗봇 - 형태소 분석을 추가한 버젼



큰 회사를 제외하고 일반적으로 작은 형태의 IT 회사는 다양한 형태가 존재하지만 무리하게 일반화를 굳이 하자면, CTO (Technology) 주도의 회사와 CPO (Product) 주도의 회사가 있습니다. 


쉽게 말하자면 기술 주도의 회사와 기획 주도의 회사 입니다. 각각의 장점이 확실히 존재합니다. 기술 주도는 제품이 단순하고 개발 이터레이션이 짧게 돌아가고, 기획 주도는 창의적이고 다양한 시도를 하기에 기존하고 다른 제품이 나올 확률이 높습니다. 어떤 개발 스타일을 제가 좋아하는 것은 별도로 치고도, 잘 생각해 보면 회사의 개발 방향이 이런 형태중에 한가지에 가까울 수가 있습니다. 


다만 개발자 출신으로서 생각해 보기에는 (초보) 개발자는 기술 주도의 회사가 더 편하겠지요? 아무래도 CTO 가 주도하는 사이클을 몸에 익히면 추후에 팀장이나 또는 본인이 CTO 로 나아갈 때 도움이 됩니다. 


그렇다고 기획 주도의 회사가 (초보) 개발자가 일하기 힘들기만 한 것이냐? 그렇지는 않습니다. 고난 속에서도 배우는 것이 있듯이 나중에 기획이 바꼈을 때 어떻게 기획자들과 싸워서 일정을 쟁취해야 하는지에 대해서 확실히 배울 수가 있습니다. 다만 변경되는 일정에 대한 짜증은 별도이지만요. 즉 심각하게 힘들게 하는 SI 의 대비를 미리 할 수가 있다는 것입니다. 농담 처럼 이야기 하지요 SI 에 계속 있으면 안되지만 군대 가듯이 SI 를 해 볼 필요는 있다고 말이죠. 그리고 이 바닥에서 말하듯이 개발자에게 있어 군대란 .. 


즉 처음의 논조와는 달라졌지만 (초보) 개발자가 기획 주도 회사에서 일할 때 


1. 자주 기획이 변한는 것에 대한 불만

 - 기획이 자주 변경 되는 건 당연한 일이 라고 여겨야 합니다. 

 - 잘 교육된 기획자가 아니면 아닐 수록 생각을 확정 못 시키고 자주 기획이 변경됩니다.


2. 기획이 바꼈는데도 일정을 고정할려고 하면

 - 절대 납득하고 날 새시면 안됩니다. 

 - 그 기획자에게도 기획이 바뀌면 일정이 변경된다는 것을 교육 시켜야 합니다. 그래야 그 분도 나중에 다른 개발자랑 일할 때 신경을 써 줍니다. 


3. 지속적으로 일정 관리에 대한 분위기 조성

 - 어떠한 일이 있더라도 기획이 바뀌면 일정은 무조건 변경되야 한다는 것을 모든 개발 참여자들이 인지하는 분위기를 조성해야 합니다. 

 - 그래서 개발 시작 전에 기획이 확정 되어지고 그 기획은 마일스톤 (or 스프린트) 기간 내에는 변경이 안되게 확답을 받아야 합니다. 

 - 개발 일정이 변경 되는 것에 대한 원인이 기획 변경에 있다는 것이 인지되면 기획자들도 조금 더 노력해서 기획을 확정 지으려고 합니다.


최근 회사 개발자가 확정 안되어진 기획서를 가지고 개발하는 데 짜증을 내길래 달래주다가 정리한 글입니다. 


기존의 포스트 대로 작업하면 일반적인 형태의 챗봇을 만들 수가 있지만, 한글은 교육 효과가 떨어질 수 밖에 없습니다. 실은 어마 어마한 교육 데이터가 존재한다면 이런 걱정 안하겠지만 애초에 교육 데이터가 많이 존재하지 않으니 그리고 실제로 많이 존재한다고 해도 한글은 원리상 형태소 분석을 추가해야 교육 효율이 좋아집니다. 


즉 seq2seq 방식에서는 


춘천에, 춘천에는, 춘천까지 


등등 춘천이 들어가는 단어를 전부 다르게 분류합니다. 춘천 이라는 명사에 의미를 주기가 어렵습니다. 영어라면 단어 위주로 나뉘어 지니까 이런 문제가 없지만 한글은 조사 때문에 형태소 분석이 필요합니다. 명사랑 조사를 분리시켜서 교육을 시키면 춘천 이라는 단어에 대한 교육을 시킬 수가 있기 때문에. 교육 효과가 높을 수가 있습니다. 


형태소 분석은 KoNLPy  를 씁니다. GPL 이기 때문에 나중에 상업용으로 적용하실 때는 형태소 분석 모듈을 새로 짜줘셔야 합니다. 


-- EDITED -- 

혹시라도 설치가 안되면 라이브러리 다시 링크후에 재시도 하면 됩니다. 

libmecab.so.2를 찾을 수 없는 에러가 나는 경우, 다음과 같이 할 수 있습니다.

  • 라이브러리를 다시 링크하고 확인후 재시도

    $ sudo ldconfig



저번 자동진화 웹버젼 챗봇 에 추가 설명을 하겠습니다. 처음부터 어떻게 해야 하는지 모르겠다는 평을 들었기 때문입니다. 


자연스럽게 따라하기 편하게 명령을 쭈욱 나열하겠습니다. 이 명령은 아나콘다 가 설치되어 있는 OSX(또는 우분투 머신) 기준에서 작성했습니다. Windows 는 알아서 적용하시길 바랍니다. 


$ conda create -n tensor python=3.6
$ git clone git@github.com:crazia/NM-chatbot.git
$ cd NM-chatbot
$ pip install -r requirements.txt
$ python manage.py migrate
$ python manage.py createsuperuser
$ python manage.py makedata --initial
$ python manage.py runserver


여기까지 진행하시면 자연스럽게 http://localhost:8000/admin 으로 접속해서 만들어둔 id/password 로 로그인 할 수가 있습니다. 


자동진화 웹버젼 챗봇 을 참조해서 대화 데이타를 만들어 줍니다. Admin 에서 작업하셔도 되고, http://localhost:8000 에 접속해서 나오는 대화창에 대화내용을 입력하면 자동으로 데이터베이스에 대화 내용이 저장되니 그 내용을 수정해서 작업해도 됩니다. 


이렇게 대화가 저장이 되면 


$ python manage.py makedata


다시 이 명령을 실행해주면 저장된 대화록을 바탕으로 자동으로 교육자료를 만들고 교육을 시켜서 새로운 모델로 만들어진 교육자료를 지정하게 바뀝니다. 



지난 포스트 


NMT를 이용한 챗봇(console)


NMT를 이용한 챗봇(Web 버젼)


에 이어서 세번째 자동 진화 버젼입니다. 간단한 교육시스템을 추가 했습니다. 원리는 간단합니다. 


1. 챗봇을 이용하면 모든 대화의 내용이 데이터베이스에 저장됩니다. 


2. 저장된 내용을 검토해서 올바른 대답으로 올바른 대답으로 바꾸고 '검토 완료'로 상태를 바꿔서 저장




3. 이렇게 저장된 내용을 교육데이터(train) , 아직은 테스트 데이터를 따로 만들기 어렵기 때문에 교육과 train 을 같이 씁니다. 추후에 따로 분리할 예정입니다. 그리고 train 데이터로부터 단어집을 만들어 줍니다. 





4. 이렇게 만들어진 데이터를 바탕으로 교육을 시작합니다. (참고로 aws 저 사용에서 돌리니 서버가 멈출정도로 부하를 주더군요. 알아서 상황에 따라 돌리는 걸 추천합니다)


5. 기존 데이터셋을 새로 만들어진 데이터셋으로 바꾸고 서비스를 재시작 합니다. 



이것을 자동화할 수 있는 명령이 바로 


python manage.py makedata 


입니다. 물론 $PROJECT/chat/management/commands/makedata.py 파일에 필요한 내용을 채워서 돌려야 하는건 필수 입니다. 


https://github.com/crazia/NM-chatbot (소스)

https://chat.crazia.org (Live Demo)



seq2seq 를 이용해서 챗봇을 만든 시리즈중에서 3번째 입니다. 


콘솔버젼


웹버젼


에 이어서 웹버젼 을 실제 AWS 에 디플로이 한 버젼입니다. 현재는 교육 자료가 간단한 문답 6개로 이루어져 있어서 제대로 동작하지는 않지만 추후에 데이타가 많아지면 좀 제대로 대답할 듯 합니다. 


https://chat.crazia.org 에서 확인 가능합니다. Websocket 을 띄우는데 많이 애 먹었습니다 ㅋㅋ 



저번  NMT를 이용한 챗봇(Console) 에 간단하게 웹 인터페이스(web interface) 를 붙여봤습니다. 저번 버젼에서 옵션같은 것을 조정하고 환경변수에 모델이 저장된 위치를 지정하고 웹만 띄우면 되는 버젼으로 가볍게 고쳤습니다.


교육(Train) 시키고 이런 것은 저번 포스트에서 다루었기 때문에 실제로 구동하는 것만 할 줄 알면 될것 같습니다.  웹 버젼은 장고를 이용해서 작성했으면 채널을 이용해서 간단한 웹소켓을 이용하는 식으로 만들었습니다. 


저번 포스트 참조하기


다만 저반하고 달라진건 교육 시키는 방법 입니다. 저번에는 급하게 만드느라 package path 연결시키는 것을 무시했는데 이번에는 그걸 다 맞췄습니다. 


python -m core.nmt \
    --attention=scaled_luong \
    --src=req --tgt=rep \
    --vocab_prefix=/tmp/nmt_chat/vocab  \
    --train_prefix=/tmp/nmt_chat/train \
    --dev_prefix=/tmp/nmt_chat/test  \
    --test_prefix=/tmp/nmt_chat/test \
    --out_dir=/tmp/chat_model \
    --num_train_steps=12000 \
    --steps_per_stats=100 \
    --num_layers=4 \
    --num_units=128 \
    --dropout=0.2 \
    --metrics=bleu


이제 교육이 된 모델을 소유하고 있다면 ENV 에 그 내용을 추가해 줍니다. 



export OUT_DIR='POSITION FOR MODEL'



PROJECT ROOT 로 이동해서 



python manage.py runserver 



하면 서버가 띄워지고 http://localhost:8000 으로 가서 확인이 가능합니다. 


모든 소스는 


https://github.com/crazia/NM-chatbot


에서 받을수 있습니다. 


이름이 멋있는 영지식 증명(zero-knowledge proof)이 최근 뜨고 있습니다. 개념 자체는 1985년때부터 내려오고 있는데 최근 이름이 언급되는건 zcash 가 사용하는 zk-Snarks 때문 일것입니다. 


http://설명이 잘 되어 있는 사이트


전 위키피디아 글 보다 위의 사이트가 더 설명이 잘 되어 있더군요. 


영지식 증명은 증명자(prover) 가 검증자(verifier) 에게 '무언가가 참'이라는 것을 증명하는 방법입니다. 단 '무언가'에 관한 어떤 정보도 노출 시키지 않습니다.



정의 보다는 예를 보면 확실하게 느껴질 수가 있습니다. 


색이 다른 두 공이 있습니다. 

내가 (prover) 맹인에게(verifier) 두 공을 주고, '두 공이 색이 다르다는 사실'을 증명 시키되 맹인에게 색을 직접적으로 언급하지 않습니다. 


맹인은 한손에 공을 한개씩 쥐고 테이블 밑으로 손을 내린 다음에 공을 위로 올려서 나에게 보이면 내가 그 공의 색을 말하지는 않지만 전꺼와 색이 같네 전꺼와 색이 다르네 라는 검증을 반복하면 할 수록 맹인은 두개의 공의 색이 정말 다르다는 것을 인식할 수가 있습니다. 


이게 블록체인에 적용이 되면 더 실용적으로 이해할 수가 있습니다. 기존 블록체인에서는 보내는 사람(sender), 받는 사람(receiver), 수량 등이 노출되어 있었습니다. 따라서 거래를 주고 받는 당사자 뿐만 아니라 그 트랜잭션을 지켜볼 수 있는 사람들도 전부 민감한 정보를 볼 수 있었죠.






위 그림에서 보듯이 트랜잭션의 센더(sender) 와 리시버(receiver) 끼리 센더가 리시버의 공개키로 내용을 암호화 해서 보내면 세상에서 리시버만 내용을 풀어볼 수가 있습니다. 그리고 이 트랜잭션을 밖에서 바라보는 사람들은 둘이 주고 받는 내용이 어떤 내용인지 알 수는 없지만 (PKI 란?   참조) 내용이 제대로 전달 되었다는 사실 여부는 알 수가 있습니다. 



최근 열심히 공부해서 간단한 챗봇을 만들 수가 있었습니다. 형태가 간단할 뿐이지 그 안에 들어 있는 Deep Learning 은 구글의 최신 NMT example 을 참조해서 만들었습니다. 


github 에 올리는 거라 대충 영어로 올렸지만 좀 자세한 설명은 여기에 남길려고 합니다. 


NMT(Neural Machine Traslation) 과 chatbot 은 원리상 거의 같습니다. seq2seq 방식으로 RNN 세팅해서 교육시키는 것 까지 동일합니다. 따라서 잘 만들어진 NMT 는 training 자료만 교체해서 챗봇으로 활용 가능합니다. 


소스는 https://github.com/crazia/NM-chatbot 에서 받을 수 있습니다. 


파이썬(python) 버젼은 3.6 이고 tensorflow 버젼은 1.8 입니다. 그 외 다른 라이브러리는 필요 없습니다. 


기본적으로 NMT 소스는 많이 복잡하고 옵션도 다양합니다. 이 소스를 기반으로 했기 때문에 트레이닝(Training)은 NMT 의 옵션과 실행을 그대로 가져갑니다. 대신 입출력을 최소한으로 간소화 시켰기 때문에 추후에 다른 방면으로 이용할 때(서비스 등을 만들때)는 chat.py 만 연구해서 떼어 붙이면 됩니다. 


챗봇을 구동 시킬려면 우선 교육을 시켜야 합니다. 그러면 교육 시키는 방법부터 알아야 합니다. 그러면 교육시키기 위한 자료들 부터 규정합니다. 



1. Train set 


교육을 시키기 위해서 필요한 자료 입니다. 챗봇은 사용자가 '질문'을 던지면 '응답'을 하는 구조로 되어야 합니다. 따라서 train.req 와 train.rep 두 파일이 필요합니다. 각각의 파일은 질문이 들어 있는 (req) 파일과 응답이 들어있는 rep 파일이 쌍으로 필요합니다. train.req 의 132 번째 줄에 있는 질문에 대한 답은 train.rep 의 132 번째 줄에 존재해야 합니다. 

당연히 훌륭한 챗봇은 이 데이타가 확실하게 많아야 합니다. 



2. Test set


교육이 잘 됐는지 확인하기 위해서 필요한 자료입니다. train 에 있는 내용을 발췌해서 써도 되고 아니면 한번 train 에 있는 단어들을 이용해서 적당히 만들어서 써도 됩니다. 



3. Dev set


Test set 하고 다른 케이스의 Test 를 정리해도 되지만 같은 것을 써도 무방합니다. 



4. Vocabulary file


교육과 테스트 전 과정에서 쓰이는 단어집이 필요합니다. 따라서 train.req 와 train.rep 에서 쓰이는 모든 단어를 모아서 단어집으로 가지고 있는 것이 좋습니다. 기본적으로 NMT 는 통역이라 각각의 과정에서 쓰이는 단어집이 다릅니다. (영어-> 베트남 이라면 영어 단어집 하고 베트남 단어집이 따로 존재) 하지만 챗봇은 같은 언어 이기 때문에 굳이 다를 필요는 없을 것이라고 판단했습니다. 


이 단어집을 쉽게 만들어줄 수 있는 파일이 존재해서 그냥 가져다가 조금 바꿔 줬습니다. 


$PROJECT/bin/generate_vocab < train.file > vocab.req
cp vocab.req vocab.rep


이와 같이 하면 단어집을 쉽게 만들어 줄 수 있습니다. 



5. 이 모든 파일을 한 디렉토리에 모아 둡니다. 


mkdir -p /tmp/nmt_chat
cp train.req train.rep test.req test.rep vocab.req vocab.rep /tmp/nmt_chat



이제 교육 시키기 위한 모든 자료가 준비 됐으니 교육을 시키면 됩니다. 



   $PROJECT/python nmt.py \
    --attention=scaled_luong \
    --src=req --tgt=rep \
    --vocab_prefix=/tmp/nmt_chat/vocab  \
    --train_prefix=/tmp/nmt_chat/train \
    --dev_prefix=/tmp/nmt_chat/test  \
    --test_prefix=/tmp/nmt_chat/test \
        --out_dir=/tmp/chat_model \
    --num_train_steps=12000 \
    --steps_per_stats=100 \
    --num_layers=4 \
    --num_units=128 \
    --dropout=0.2 \
    --metrics=bleu


여기에서 신경 써야할 몇가지 사안들을 지적하겠습니다. 


attention 알고리즘을 선택해야 효율이 좋아지기 때문에 꼭 선택을 해줘야 합니다. 

src 와 tgt 는 내가 이용하는 파일의 확장자들입니다. 저는 req 와 rep 를 썼기 때문에 그걸 지정해 준것입니다. 

vocab_prefix 는 단어장으로 써야할 파일의 파일명입니다. (확장자는 req 와 rep)

train_prefix 는 교육시킬때 써야할 파일의 파일명입니다. 여기서는 train 이라고 씁니다. 

dev_prefix 와 test_prefix 는 테스트 할때 쓸 파일의 파일명입니다. 여기서는 test 라고 만든것을 써줍니다. 


정말 중요한 out_dir 입니다. 교육시킨 결과물이 저장되는 곳입니다. 그리고 이후에 실행할 때 교육된 정보값을 가져오기 위해서도 입력해야 합니다. 


num_train_steps 얼마만큼 교육을 시킬것인가 하는것입니다. RNN 은 제대로 효과를 볼려면 꽤 많은 횟수로 교육을 시켜야 합니다. 

steps_per_stats 몇번 마다 로그를 남길것인가 하는것입니다. 체크포인트(checkpoint: 교육 결과 저장이 10x steps_per_stats 마다 일어납니다)

num_layers 는 RNN 을 몇 계층으로 할 것인지 입력하는 것입니다. 간단한 건 2 계층, 시스템이 허용된다면 8 계층에서 가장 최적의 효과를 보였다고 벤치마크는 말합니다. 

num_units 는 네트워크 사이즈 입니다. 

dropout 은 Deep Learning 에서 교육중 건너뛰고(?) 얼마만큼 교육시킬건지 지정해 주는 수치 입니다. 교육자료가 많을 때 사용하면 좋습니다. 


너무나 당연하지만 gpu 버젼으로 교육시키면 효과가 훨씬 좋습니다. 저는 개발은 OSX 에서 하지만 교육은 제 PC 에서 합니다. nvdia 그래픽 카드를 소유하고 있어서..


이제 모든 교육이 끝났으니까 챗봇을 구동하면 됩니다. 


챗봇 구동시키기



python chat.py --out_dir=/tmp/chat_model


+ Recent posts