https://arca.live/b/alpaca/75877323?p=1

어쩌다 이 글에서 내 프로젝트가 언급이 된 걸 봤는데, 아예 여기서 이것저것 교류하고싶어서 계정 파고 들어왔음 ㅎㅇㅎㅇ


인사 겸, 내가 진행중인 프로젝트에 대해 소개해줄게. 


일단 모델은 cl-tohoku/bert-base-japanese-v2랑 KoGPT2를 각각 인코더, 디코더로 채용한 구조로 만들었어.

작년 4월에 초기 훈련이 끝난 상태고 성능은 일단 어느정도 나오는 것으로 보임.

데이터셋은 Tatoeba에 있는 일본어-한국어 데이터셋이랑 게임에서 쓰이는 용어, 표현 같은걸 모아서 준비했음.

https://huggingface.co/sappho192/ffxiv-ja-ko-translator

그 이후에는 모델 추론을 로컬에서 편하게 돌릴 수 있도록 탈-Python화를 1년 가까이 진행하고 있었음... 


아래 움짤에 있는건 내가 예전에 개발했던 게임 채팅 번역 앱인데, 궁극적으로는 여기에 내가 훈련시킨 모델을 집어넣고 싶어서 탈-Python까지 완료하는게 정말 중요했었음. 이 부분이 정보 얻기도 힘들고 어케 진행해야할지도 막막해서 몇달 유기하고 다시 알아보고 또 유기하기를 1년 가까이 반복한 것 같다.


이 번역 앱은 5년전에 만들었고, WPF 기반에다가 Papago를 땡겨쓰고 있긴 한데, 게임 용어나 은어 같은건 해석을 잘 못하니까 전용 번역모델이 필요하다고 느끼게 되더라. 


그러다 최근 한 2주? 동안 진전이 급속도로 일어나서, 모델은 ONNX모델로 변환하고 C#에서 OnnxRuntime 기반으로 돌리는데 성공했음. 

퇴근하고 어젯밤에 집 와서 마지막 부분 구현하는데 진짜 맘속으로 기도 100번 했다... 

https://github.com/sappho192/onnx-hf-test


원래는 최대한 허깅페이스의 Optimum으로 최대한 날먹을 하고 싶었었는데, Optimum의 OnnxRuntime API도 내부적으론 PyTorch에 의존성이 있더라고... 결과적으론 [이거]로 ONNX모델로 바꾸는 것만 도움받았고 나머진 거의 다 직접 짜게됐다... 


정리해보면, 변환된 모델을 쓰려면 아래 파이프라인을 처리(구현)해야되고, 3, 4번 과정이 제일 중요했음...


1. 입력 언어의 Tokenizer

2. 인코더 데이터 준비

3. 인코더 결과를 적당히 처리해서 디코더에 입력 (최초 입력 단계)

4. 디코더에서 나온 결과를 적당히 처리해서 디코더에 다시 입력 (EOS 토큰이 나올때까지)

5. 디코더 처리가 끝나고 만들어진 토큰들을 출력 언어의 Tokenizer에 넣어 번역문 생성


HuggingFace의 Tokenizers는 Rust 구현체가 있기 때문에 이걸 DLL라이브러리로 만들어서 이용하면 날먹이 되지 않을까 싶었는데 ㅅㅂ KoGPT2는 그게 되는데 bert-japanese는 연구진이 자체적으로 토크나이저를 만든거라 안되더라고.

https://github.com/sappho192/BertJapaneseTokenizer

그래서 걔네들 소스코드 보면서 내가 직접 C# 버전으로 구현했다.

MeCab+UniDic으로 1차 분리를 하고, UniDIc에 없는 단어들은 미리 만들어둔 BPE vocabulary로 쪼개는 방식으로 토큰을 만들더라.


Rust DLL→C# 형태로 Tokenizers 라이브러리 쓰는 코드는 여기에 남겨뒀음.

https://github.com/sappho192/onnx-hf-test/tree/main/rust/decoder


인코더랑 디코더 쓰는 방법은 Netron으로 모델 입출력 구조도 확인하고 여기저기 구글링하면서 알아봤었음. 인코더는 그냥 적당히 하면 되는데 디코더의 입출력에 있는 past_key_values 값들이 Cross-Attention에 관한 값들이라 거기에 맞는 처리를 해줘야됐었음...

여기에서 시간을 제일 많이 잡아먹게 됐는데 결국 PyCharm에서 한땀한땀 Step In 디버깅 하면서 구현을 따라했다. 결국 마지막엔 이렇게 하는게 답이더라.


암튼 내가 생각하던 마일스톤까지는 이렇게 완료됐음.

앞으로의 목표는 대충 이렇다.

1. ONNX 추론 관련 코드 최적화(성능, 메모리)

아무래도 모델 크기가 크다보니 모델만 프로세스에 탑재해도 1.2GB 정도를 잡아먹는다. 그래서 최대한 모델 탑재 이외에 잡아먹는 메모리는 최소화시켜야 할 것 같아서 이래저래 최적화를 시키고 있음.

나중에 여유가 나면 양자화나 fp16 같은것도 좀 도입해보고 싶긴함. 


2. 모델 성능 개선 & 성능 객관화

작년에 훈련시켰던 모델이 어느정도 성능이 나오고 있는 것 같긴 한데, 진짜로 내가 데이터셋에 추가했던 게임 관련 용어나 대화들이 영향을 준건지를 아직 검증 못해봤음. 그리고 작년 4월 이후에 게임이 업뎃되면서 콘텐츠가 많이 생겼기 때문에 이런 부분을 FIne-tuning으로 따라잡을 수 있을지도 해봐야 할 듯함.

그리고 그 외에도 좀 찝찝한 부분들이 있긴 한데, 나중에 기회되면 다시 얘기해볼게!


3. 다른 사람들도 자신만의 모델을 쉽게 훈련할 수 있도록 제반 환경을 제공

여기 채널에 나처럼 특정 분야에 특화된 일-한 번역기를 만들고 싶은 친구들이 있을 것 같아서 생각해두고 있음.

본문에 얘기한 것들이랑 링크에 있는 리포들을 참고해도 충분히 직접 가능하긴 하지만 그래도 이것저것 단계를 간소화하고 매뉴얼도 좀 더 자세히 적어야 할 것 같아서 ㅇㅇ... 궁금한건 언제든 이슈나 여기 댓글로 물어봐도 됨



대충 이렇게 나랑 내 개인 프로젝트를 소개해봤음. 앞으로 잘 부탁해~