-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Chronicles #15
Comments
Ideas 💡On neuro-symbolic approach나중에 -> rules + distributed hypothesis를 동시에 할 수 있는 방법은 없나? On allowing a set of EF's rather than only one
즉 set을 출력하는 것이 되어야 한다. 무엇이 정답인지는 사용자가 알아서 맥락에 맞춰서 판단하도록 하면된다.
On writing conjugation algorithms on my own
아니다. 굳이 이럴 필요 없음. On programmatically populating rules
|
예를 들면 이런 존대의 체계를 따르는 것 (Brown, 2011) |
---|
그리고 특수 존대형도, 이미 누군가 열심히 분석해 놓은게 있다면, 마다할 필요가 없다.
동사의 존대형 (Brown, 2011) |
---|
명사의 존대형 (Brown, 2011) |
---|
On adding static typing to the build workflow
Github Actions 워크 플로우에 mypy
를 사용한 static type check를 넣어도 좋을듯!
On using BERT for neuro-symbolic approach
이미 학습된 버트를 그대로 사용하는 것은 불가능하다. BPE, WordPiece는 morpheme-aware하지 않기 때문. 꼭 형태소를 보존해야하나? 물론 subword 토큰에 맞춰서 정규표현식을 만드는 것이 가능은 할 것. 하지만 보다 더 정확한 정규표현식은 품사 정보를 추가했을 때 가능하다. 형태소
만을 쓰기보단 형태소/품사
를 패턴으로 써야 동음이의어 등의 문제를 피해갈 수 있다. 흔히 쓰이는 subword tokenizers는 학습되는 토크나이저므로, 학습에 쓰인 데이터가 다르면 토크나이징 규칙도 다르다. 그래서 골치 아프다. kiwi
같은 pos tagger가 있어도 토큰 정렬이 안되기 때문에 나로썬 무용지물이다.
그래서 만약 neuro-symbolic 접근에 버트를 사용하고 싶다면, 내가 직접 kiwi
+ transformers
라이브러리의 결합으로 "KiwiBERT
"를 사전학습 시키는 수 밖에 없다. OOV 문제로 인해 분명 성능은 떨어지겠지만, 규칙으로 크게 보완할 수 있다면 차라리 나을수도 있다. 앞서 언급한 이유로 인해 다른 KoBERT는 형태소/품사
규칙으로 보완하는게 쉽지가 않으니까.
그런데 문제가 있다. attention_mask
, token_type_ids
텐서를 구축하려면 어쩔 수 없이 tokenizers
의 Tokenizer
가 필요하다. Tokenizer
의 규칙은 kiwi
로 대체하되, BERT 사전학습에 필요한 텐서 구축은 그대로 가져가는 방법은 없을까?
konlpy
와 BertTokenizer
를 결합하려고 시도한 분은 있다. 최종 결과를 보면 이렇게 나온다:
compose(bert_wordpiece_tokenizer.encode(sent_ko).tokens)
# ['신종', '코로나바이러스', '감염증', '(', '코로나', '##1', '##9', ')', '사태', '##가', '심각', '##합', '##니다']
compose(konlpy_bert_wordpiece_tokenizer.encode(sent_ko, add_special_tokens=False).tokens)
# ['신종', '코로나바이러스', '감염증', '(', '코로나', '19', ')', '사태', '가', '심각', '하', 'ᄇ니다']
compose(konlpy_bert_tokenizer.tokenize(sent_ko))
# ['신종', '코로나바이러스', '감염증', '(', '코로나', '19', ')', '사태', '가', '심각', '하', 'ᄇ니다']
트릭은 pre_tokenizer
로 konlpy
를 설정하는 것. 나도 저걸 비스무리하게 따라한다면, pre_tokenizer
로 kiwi
를 설정하고,
decode
를 overide 해서 kiwi.join()
을 집어넣으면, 얼추 비스무리하게 만들 수 있을 것 같다는 생각이 든다.
이건 politely에서 하지말고, 따로 리포를 만들어서 해야할듯. 그 리포는 우선 politely에서 실험 & 평가 후, 즉 검증을 거친 후 공개하는 편이 나을 것.
이미 카카오에서 morpheme-aware tokenization을 시도했었다. 하지만 가중치를 사용하는 방법이 그리 간편하지는 않다. KiwiBERT
를 만든다면 -> pip3 install kiwipiepy
만 선행되면 바로 huggingface에서 쓸 수 있도록 만들면, morpheme-aware language model의 접근성도 늘리고 좋을듯!
잠시만. 생각이 달라졌다. 굳이 kiwiBERT
를 만들필요는 없다. 조금의 전처리만 거친다면, kiwi tokenization 결과 <-> subword tokenization 결과를 대응시키는게 가능하긴 할 것이다. 기존의 BERT를 사용할 수 있을 것. variable-length 문제야 뭐.. k 개의 마스크로 해결할 수 있을 것 같기도 하고.
On the name of the new approach: "neuro-symbolic" or "guided"
Neuro-symbolic은 이름이 너무... 과대포장하는 느낌이다. 차라리 Guided Masked Language Modeling with Regex가 나을 것 같다.
왜 guided? BERTopic의 이 문서를 보면서 그런 생각이 들었다 |
---|
내가 하고자하는 것도 특정 맥락이 주어졌을 때, 빈칸에 들어갈 후보군을 미리 정해주는 것이라고 볼 수 있으니. 어쩌면 guided라는 말이 더 적절할 수도 있다.
기존에는 BERT를 fine-tuning하지 않고 그대로 사용할 생각만 했었는데. 규칙을 설정해두고 파인튜닝을 하는 방법도 고려해볼만한하다. 재밌을 것 같다. 정해진 규칙을 벗어나지 않는 선에서 모호한 부분을 보완해줄 수 있을 것이다. 아, 이거 빨리 데이터 구축하고 실험해보고 싶다.
On adding two tokens to `mask`
먹+(어) -> 드+시+어요
"어"가 "시+어요"로 바뀌어야 한다. 토큰이 하나만 들어가면 되는게 아니다.
On mlm vs. generation
Style Transfer는 어차피 대부분... MLM보단 generation으로 해결한다 - (seq2seq).
그렇다면 나도 generation으로 접근하는 편이 낫지 않을까?
On the problems with subword tokenizer
일단 토크나이저라는 문제가 있으니까.... 우선 SkipGram으로 실험을 해보는 편이 나을 것 같다.
장기적으로는 symbolic rule로 장규표현식을 쓰는 것이 목표다. 하지만 첫단추는 word-level LM으로 접근해보자.
On the problems with subword tokenizer
Regular expression을 쓴다고는 해도, 여전히 inductive reasoning만 가능하다.
Inductive reasoning을 도와주는 도구니까. 그런데.. deductive reasoning도 가능하다고 볼 수 있는걸까?
On using language models
언어모델을 어떻게 써야할까? kiwi
의 접근과 비슷한 접근을 하면 될 것 같다.
>> kiwi.analyze('테스트입니다.', top_n=5)
[([Token(form='테스트', tag='NNG', start=0, len=3), Token(form='이', tag='VCP', start=3, len=1), Token(form='ᆸ니다', tag='EF', start=4, len=2)], -25.217018127441406),
([Token(form='테스트입니', tag='NNG', start=0, len=5), Token(form='다', tag='EC', start=5, len=1)], -40.741905212402344),
([Token(form='테스트입니', tag='NNG', start=0, len=5), Token(form='다', tag='MAG', start=5, len=1)], -41.81024932861328),
([Token(form='테스트입니', tag='NNG', start=0, len=5), Token(form='다', tag='EF', start=5, len=1)], -42.300254821777344),
([Token(form='테스트', tag='NNG', start=0, len=3), Token(form='입', tag='NNG', start=3, len=1), Token(form='니다', tag='EF', start=4, len=2)], -45.86524200439453)
]
kiwi
를 보면, 우선 가능한 모든 문장의 후보군을 만든다. 그러고 나서 각 문장 중 어떤 것이 가장 "자연스러운"지 , 그 점수를 부여한다. 나도 그런식으로 접근하면 된다. 모든 후보군을 만든다음에, koGPT
로 각 문장의 점수를 부여하자. 이렇게 하면.. 토크나이저가 호환되지 않는 문제는 해결되긴한다. 연산량이 늘긴하겠지만. 아무래도 fine-tuning이 필요하긴하다. Formality 데이터 구축 사례를 찾아보고, GPT게열 모델을 그 데이터에 맞게 fine-tuning해보자.
굉장히 computationally intensive할 것 같다. 하지만 규칙만 잘 설정하면,
크게 걱정할 일은 없다.
- 일단 정규표현식으로 모든 문장 후보를 뽑는다. (
permute
사용하기) - 각 문장의 "naturalness"를 계산
- 가장 점수가 높은 것을 출력
- 원하면 모든 후보를 다 열람해볼수도 있음.
어떤 규칙이 가치있는 규칙일까?
사과가 나무에서 떨어진다는 규칙을 발견했다. 아무도 관심을 가지지 않는다. 하지만 "두 물체 사이에는 반드시 중력이 작용한다"는 보편적인 규칙 을 발견한 뉴턴은 지금까지도 전설적인 과학자로 촉망받는다. 모든 규칙이 다 가치가 있는 것이 아니다. 최소한의 규칙으로 최대한의 사례를 설명하는 규칙이 가치가 있다. 지구와 사과사이에 중력이 작용하기에 사과는 지구로 떨어진다. 달과 지구 사이에도 중력이 작용하기에 달도 계속 지구로 떨어지고 있다. 하지만 중력은 거리의 세제곱에 반비례하기에 멀리 떨어져 공전하고 있는 달의 중력은 원심력과 평형을 이루고, 이 때문에 하늘에 떠있는 것처럼보인다. 어찌됐든 두 사례 모두, 중력이라는 보편적인 규칙으로 설명가능하다. 규칙의 구체성보단 규칙의 범용성이 높을수록 규칙으로서의 가치가 있다.
그게 "사고절약의 원리"이다. 필요 이상으로 복잡해지면 안된다. 타당함이 비슷하다면 가능하면 더 단순한, 범용성이 높은 이론(규칙)이 우선시 되어야 한다. 물론 단순함이 타당함을 의미하지는 않는다. 창조론이 진화론보다 더 단순하다고 해서 더 타당한 것은 아니다. "신이 모든 것을 만들었어요"라는 주장보다야 복잡하지만, 창조론과는 달리 진화론은 주장을 뒷받침하는 과학적 근거가 존재한다. 하지만 뒷받침하는 근거가 비슷하다면, 보통 더 단순한 쪽이 더 정답에 가깝다. 그게 사고절약의 원리, aka 오캄의 면도날이다. 나는 왜 이런 theoretical mumbo-jumbo를 늘어놓고 있나? 지금 politely/politely/honorifics.yaml Lines 1 to 28 in a9fce8f
내 규칙에는 범용성이 없다. "사과는 나무에서 떨어진다", "이파리도 나무에서 떨어진다", "야구공을 던지면 다시 떨어진다" 만 늘어놓고 있다. 물론 그런 사례만 수천개 수십억개를 모으면 힘겹게 힘겹게 if-else로 가득한 중력 시뮬레이터 A를 만들 수 있을 것이다. 하지만 A 를 기술력이 높은 시뮬레이터라고 보기엔 부적절하다. 그냥 노가다로 때운 기술이 더 적절한 표현이다. 기술력은 그런면에서, 위 규칙보단, 현재
최소한의 규칙으로 최대한의 사례를 설명하는 규칙이다. 보편적인 규칙을 찾을 수 있다면, 왜 굳이 머신러닝이 필요할까?
하지만 자연어는 물리처럼 딱 떨어지지 않는다. "중력이론"이 애매모호하게 작용할 때가 있다. 예를 들어, 위 규칙을 바탕으로 print(styler(["저는 쓰레기를 주워요."], 3))
print(styler(["자, 같이 쓰레기를 주워요."], 3))
>>> [저는 쓰레기를 줍습니다.]
>>> [자, 같이 쓰레기를 줍습니다.] 첫번째는 맞지만, 두번째는 틀리다. 두번째는 권유가 아닌 청유이므로, 아쉽게도 우리의 "중력이론"으로는 설명할 수 없는, 애매모호한 사례가 나와버렸다. 이 문제를 어떻게 해결해야할까? 또 규칙을 추가할까? " 그러기 시작할 때 머신러닝을 써야한다. "어? 나 지금 예외처리만 10번째 인가?" 싶을 때, 우리는 기술력을 유지하기 위해 직접 예외를 처리하는 것을 것을 중단해야한다. 대신 머신러닝 모델이 알아서 "청유를 하는 경우 예외처리는 머신러닝으로 해결해야 기술력을 유지할 수 있다. 결론
|
|
v1.1
open
There were more versions of
v1.x
butv1.1
is the only one that I started to keep track of with the issue. So there is unfortunatelyv1.1
only for this branch for versions. We are moving tokhaiii
anyways, so this shouldn't be a big problem.v2.1
open
As for this branch of versions, we are moving away from
kiwi
to usekhaiii
. We are moving away fromkiwi
becausekiwi
makes more problems than it solves problems. This is mainly because it does not preserve the original lexicons:kiwi
does not preserve the original lexiconsHere,
Tuner
distorts the completely fine가까우니까
into가깝으니까
, when it does need to do that. This is becausekiwi
does not preserve a given text and just lemmatizes everything. Yeah, it does returnstart
andend
indices, but these would be very often inaccurate (e.g. overlapping indices).In contrast,
khaiii
does preserve the lexicons as well as lemmatize them at the same time.So we are moving to
khaiii
.This is the first version of using
khaiii
. What should we do?explore_ khaiii_honorify.py
#16Tuner
class to usekhaiii
#18__call__
to functions and write unit tests forTuner
#20preprocess
,apply_honorifics
,apply_abbreviations
,apply_irregulars
,postprocess
v.2.1
on streamlit #22khaiii
?v2.2
open
Here, we refine the rules to cover "chunks".
e.g. allows the rules to cover patterns with more than one morphemes.
honorifics.yaml
pattern #31v2.2
v2.3
open
Politetune
was meant to be used as a study aid for L2 learners of Korean. It therefore needs explanation forthe reasons for the output. Display the linage of the steps you take. Plus, from here on out, the
Tuner
is robustly tested with function-by-function testsExplainer
#33v2.3
v2.4
open
As for this version, the rules aren't significantly changed, but the explanations for rules get some updates.
for instance, the question "What is your visibility?" should change to:
and the reasons for each case are refined:
plus, you should fix some errors in formatting the explanations.
v2.4
v2.5
open
__call__
#47soynlp
'sconjugate
function in conjunction withconjugations.yaml
#49v2.5
v2.6
open
We need rigorous test cases to decide whether or not to write conjugations myself, or keep using soynlp's conjugate function.
거라
&너라
지원 추가하기 #53르
불규칙 by positive 해결하기 #56여
불규칙 오류 해결하기 #58?
인식못하는 문제 해결하기 #54main_demo.py
에서 발생하는 오류를 테스트로 옮기기 #62ㄴ대요
지원하기 #64더웁니다
해결하기 #68v2.6.1
open
v2.6.2
open
라
종결어미 지원하기 #74hangul.py
에 정리하기 #78@log
decorator #84v3.0.0
open
Scorer
with Word2Vec #105v3.1.0
open
Styler
against a Korean Wikipedia article #90debug
parameter to__call__
#93preprocess
#97v3.2.2
test_conjugate...
tests #100v3.2.3
add_rules
(with descriptions) #109v3.3.1
lm_search
withGPT2Scorer
#111The text was updated successfully, but these errors were encountered: