ⓒ시사IN 이정현
ⓒ시사IN 이정현

친구로부터 “너, 참 잘났다, 잘났어!”라는 말을 듣고 정말 우쭐하는 사람은 드물 것이다. ‘참’은 ‘사실이나 이치에 어긋남이 없이’란 뜻이다. ‘잘나다’의 의미는 ‘잘생기다’ ‘뛰어나다’ 등이다. 그러나 당사자를 앞에 둔 맥락에서 ‘참 잘났다’는 ‘변변치 못하거나 대수롭지 않다’는 뜻일 가능성이 크다. ‘참’과 ‘잘나다’는 긍정적 의미의 단어들이 결합해서 조소(嘲笑)의 뉘앙스를 띤 것이다.

인공지능이 자연어(사람들이 일상적으로 쓰는 언어)를 이해하기는 정말 어렵다. 인공지능은 몹시 똑똑해 보이지만 실제로 아는 것은 1(긍정)과 0(부정)밖에 없다. ‘긍정’이 두 개 결합했는데 그 결과가 때론 ‘부정’적 의미인 ‘비체계적’ 상황은 인공지능에게 익숙하지 않다. 더욱이 자연어에서는 단어의 배열 순서(어순)에 따라 문장의 의미가 바뀐다. 같은 문장이라도 외부 상황(맥락)에 따라 뜻이 달라진다. 예컨대 ‘참 잘났다’가 눈앞의 당사자를 겨냥한 말이 아니라 그 자리에 없는 다른 친구에 관한 이야기였다면 칭찬일 수 있다(“영희 그 아이, 참 잘났지?”).

자연어는 체계적이지 않으며 복잡하고 모호하다. 사람에겐 쉽지만 인공지능에겐 만만치 않은 대상이다. 언어에 비하면 ‘고양이 식별’ 따위는 식은 죽 먹기다. 그냥 고양이 이미지를 순서와 맥락에 상관없이 많이 입력해주면 된다. 언어를 이해하려면 순서와 맥락까지 알아야 한다. 이런 난관이 테크 기업들에겐 오히려 큰 기회일 수 있다. 그러나 그 필요에 따라 발전해온 부문이 바로 자연어 처리(NLP:Natural Language Processing)이다.

초기의 NLP 개발자들은 이른바 ‘규칙 기반 접근(rule-based approach)’ 방식을 채택했다. 사람이 단어·문법 등 ‘규칙’을 일일이 컴퓨터에 코딩하고, 이를 기반으로 인공지능이 자연어를 이해하는 방식이다. 그러나 자연어의 모호성과 비체계성까지 코딩에 담기는 어려웠다.

결국 NLP에도 머신러닝이 도입된다. 예컨대 특정 상품에 대한 소비자들의 반응(홈페이지 댓글, SNS 등에 올라온 자연어 묶음)을 인공지능에 입력하고 ‘긍정/부정 여부를 예측하라’고 명령한다. 물론 사람은 컴퓨터에 입력한 ‘참 맛있어요’라는 댓글이 ‘긍정’ 반응이란 것을 알고 있다. 인공지능은 자기 나름대로 구성한 ‘예측 방법’에 따라 긍정/부정을 판단해서 출력한다. 그 출력(예측)이 사실과 일치한다면(‘참 맛있어요’를 긍정 반응으로 판단), 인공지능은 자신의 기존 예측 방법을 강화한다. 틀렸다면(‘참 맛있어요’를 부정 반응으로 판단), 예측 방법을 수정한다. 이런 과정을 수없이 되풀이하면서 인공지능은 긍정/부정에 대한 예측 규칙을 익히게 된다(학습). 댓글의 어떤 특성이 긍정과 부정을 가르는지 식별하게 되었고 이에 따라 새로운 댓글에 대해서도 정확한 판단을 내릴 수 있다. 사람이 규칙을 알려준 적이 없는데도 말이다.

자연어 처리는 어떻게 작동하나?

NLP(자연어 처리)는 머신러닝을 도입한 이후 급격히 발전하게 된다. 2010년대 중반쯤엔 나름 괜찮은 음성인식 비서나 번역기, 스팸메일 필터 등이 선보이게 된다. 인공지능이 어느 정도까지는 사람과 비슷한 수준으로 자연어의 의미와 뉘앙스를 이해할 수 있게 된 것이다. 숫자만 아는 인공지능이 어떻게 언어를 인식할 수 있게 된 것일까? 그 실마리를 잡으려면 NLP가 이뤄지는 과정을 참조할 필요가 있다.

컴퓨터가 언어를 이해하는 과정은 인간의 그것과 완전히 다르다. 인간에게 ‘사과’라는 단어는 ‘붉거나 파란 구체로 깨물면 달고 신 즙이 배어 나오는’, 언어 외부에 존재하는 실체를 ‘가리킨다’. 그러나 인공지능에게 ‘사과’는 입력된 숫자를 더하고 곱하며 미분하며 그 값들을 수없이 결합시킨 결과다. 즉, 인공지능이 ‘사과’라는 단어를 이해(?)하려면, ‘사과’를 계산 가능한 형태로 변환해줘야 한다. 이 과정이 꽤 복잡하다.

▢ 전처리

일단 인공지능에 입력할 자연어 데이터들을 정제해줘야 한다. 단어들을 어근 형태로 축소하고(달렸다, 달린다, 달리고 있다 등을 어근인 ‘달리다’로), 오자를 교정한다. 특히 영어의 경우엔 문장에 감초처럼 자주 등장하지만 특별한 정보를 담고 있지 않은 관사와 전치사(the, a, at, in…) 등을 필터링해야 한다.

▢ 토큰화

문장을 작은 의미 단위로 쪼갠다. 단어 단위로 자르는 경우가 많다. “나는 학교에 간다”라면 ‘나는’ ‘학교에’ ‘간다’로 쪼개는 식이다. 이렇게 나뉜 단위를 각각 ‘토큰(token)’이라고 부른다. 특정 토큰이 자주 등장한다면 그 토큰이 해당 문장이나 글 전체의 의미에 중요한 영향력을 행사하는 것으로 추정할 수 있다.

▢ 토큰의 벡터화(임베딩·embedding)

토큰들을, 컴퓨터가 읽을 수 있는, 숫자 형태로 변환시킨다. ‘나는 학교에 간다’라면 토큰(‘나는’ ‘학교에’ ‘간다’)이 모두 세 개이므로 예컨대 다음의 ‘벡터’들처럼 바꿀 수 있다.

나는(1, 0, 0)

학교에(0, 1, 0)

간다(0, 0, 1)

‘벡터’는 언어 모델을 이해하는 데 결정적으로 중요한 개념이므로 짧게라도 짚고 넘어갈 필요가 있다. 예컨대 ‘동쪽으로 2m 갔다’라는 의미를 남에게 전달하려고 할 때 그냥 ‘2’라고 하면 될까? 당연히 안 된다. 그렇다면 평면(2차원) 좌표를 응용해서 (2, 0)으로 나타내면 어떨까? 원점(0, 0)에서 동쪽으로 1m씩 2회 이동하면 (2, 0)이니 말이다. 이와 마찬가지로 ‘북쪽으로 3m’는 (0, 3), ‘북쪽으로 2m 간 뒤 동쪽으로 1m’는 (1, 2)다. 이처럼 벡터는 ‘크기와 방향을 모두 가진 양’이라고 할 수 있다.

그런데 (1, 2) (2, 0) (0, 3) 등은 평면에서 동서남북으로 움직일 때에 한정된 ‘2차원’ 좌표다. 만약 위아래로도 이동할 수 있다면 어떻게 될까? 그 움직임은 (1, 2, 3) 같은 ‘3차원’ 좌표에 표시해야 한다. 여기서 1이 동쪽, 2가 북쪽이라면, 3은 ‘위’로의 이동이다. 인간으로서는 기껏해야 3차원까지만 머릿속으로 그려볼 수 있다(우리가 사는 곳은 3차원 공간이다). 그러나 수학적으로 보면 4차원, 5차원은 물론 1만 차원, 나아가 무한대 차원까지 가능하다. 인공지능은 이런 차원들에서 연산하며 학습한다.

당장 “나는 학교에 간다”란 짧은 문장만 해도 토큰이 세 개다. 그래서 각 토큰(예컨대 ‘나는’)은 3차원의 벡터(1, 0, 0)로 표시되었다. 만약 인공지능에 긴 문장이나 책 한 권을 통째로 집어넣어 학습시킨다면, 토큰 하나가 수십 차원 혹은 수천 차원의 벡터로 나타날 수도 있다는 뜻이다. 이렇게 토큰을 벡터로 변형시키는(벡터 공간에 토큰을 점이나 화살표로 찍는) 것을 ‘임베딩’이라고 부른다. 토큰들은 각자 일정한 숫자들로 나타난다. 이를 일단 ‘임베딩 수치’라고 부르자.

벡터는 자연어에 대한 머신러닝에 매우 유용하게 활용된다. 우리가 아는 벡터의 성질을 활용할 수 있기 때문이다. 벡터는 연산할 수 있다. ‘사과’라는 단어 자체는 연산할 수 없지만, ‘사과’를 벡터로 나타내면 더하고 빼며 곱할 수 있다. 벡터들 간의 거리와 각도도 측정할 수 있다. 벡터의 이런 성질을 자연어 처리에 이용한다.

일단 토큰들이 벡터화되었다면(토큰들이 각자 임베딩 수치를 갖게 되었다면), 본격적인 머신러닝에 들어갈 준비가 된 것이다. 그렇다면 머신러닝에서는 어떤 일이 벌어질까?

우리가 너무나 잘 알다시피, 사람들의 언어생활(자연어)에서, 사과는 복숭아와 과일이라는 측면에서 유사하다. 또한 과일을 의미하는 단어가 나온 다음엔 ‘먹다’란 동사가 나올 가능성이 크다. 사과와 수박, 주스, 냉장고도 함께 많이 사용되는 단어다.

그렇다면 머신러닝에서는 현실의 자연어에서 유사하거나 관련성이 있는 단어 벡터들 간의 거리를 최소화하도록(=단어들의 임베딩 수치가 비슷하도록) 학습시키면 된다. 인공지능이 당초 예측한 사과의 임베딩 수치가 (7, 1)인데 복숭아는 (1, 7)이라고 치자. 유사한 단어들인데 거리가 너무 멀다. 그러나 인공지능은 사과와 복숭아 사이의 거리에 대한 자신의 예측이 현실의 언어 데이터들과 비교할 때 전혀 타당하지 않다는 것을 알게 된다.

그래서 학습을 통해 점차 〈그림 4〉처럼 복숭아의 벡터(임베딩 수치)를 사과와 가까운 위치로 계속 바꾸게 된다. 더 이상 가깝도록 바꿀 수 없는 위치가 바로 그림의 좌표(8, 3)다. 혹은 해당 벡터들 사이의 각도를 최소화하는 방향으로 학습시킬 수도 있다. 단어의 벡터가 비슷한 방향을 가리킨다면 비슷한 의미를 가지도록 만드는 작업이다. 학습이 완료되면, 유사하거나 관련 의미를 가진 단어들의 임베딩 수치가 비슷해진다. 관련성 없는 단어들의 벡터(임베딩 수치)는, 그 사이의 거리가 멀고 각도도 크게 조정된다. 이런 식으로 자연어의 패턴을 익힌 인공지능은 새로운 단어나 문장을 제시할 때 그다음 나올 단어(와 문장) 혹은 답변까지 확률적으로 예측할 수 있게 된다. 인공지능 처지에서는 새로운 단어(나 문장)의 벡터 주변에 있는 벡터들 중에서 잘 골라 출력하는 것이 사람에겐 ‘그다음 문장’이나 ‘답변’으로 받아들여지기 때문이다. 예를 들어 사람이 ‘사과를’이란 토큰을 제시하면 인공지능은 ‘먹는다’ ‘냉장고에 넣는다’ ‘수박과 함께’ 같은 다음 구절을 출력할 수 있게 된다.

잘 학습된 머신러닝 모델은 자연어의 패턴을 놀라울 정도로 비슷하게 구현한다. 예컨대, 임베딩 수치 기준으로 ‘여왕’에서 ‘왕’을 뺀 값이 ‘여자’에서 ‘남자’를 뺀 값과 거의 유사하게 나타난다고 한다(여왕-왕=여자-남자).
 

‘맥락’을 처리하는 트랜스포머의 등장

인터넷 등에서 방대한 자연어 자료들을 긁어와 머신러닝 기법으로 학습시킨 ‘언어 예측 모델’을 ‘사전 학습 모델(pre-trained model)’이라고 부른다. 많은 자연어 자료를 많은 매개변수로 학습할수록 예측 능력도 대체로 높은 경향이 있다. 더욱이 자연어의 문장을 읽을 땐 왼쪽에서 오른쪽으로, 즉 단어들을 순서대로 읽어나가기 마련이다. 해당 문장 속의 특정 단어에 눈이 닿았을 때 그 앞에 나온 단어들을 기억하고 있어야 문장 전체의 의미를 이해할 수 있다. 그래서 인공지능이 문장 속의 단어를 처리할 때 그 앞에 나오는 단어들을 ‘기억’해서 예측에 반영할 수 있는 아이디어가 언어 모델에 구현되었다. RNN(Recurrent Neural Network·순환신경망), 이를 개선한 LSTM(Long Short-Term Memory) 등이 그것이다.

그러나 2010년대 중반까지의 NLP(자연어 처리)엔 해결되지 않은 문제가 많았다. 문장에 나오는 단어들의 맥락(문맥)을 제대로 파악하지 못했다. 예컨대, 영어의 ‘bank’란 단어는 ‘예금을 수신하고 대출하는 업체’ 이외에 ‘둑’이란 의미로도 사용된다. 당시 구글이 개발한 임베딩 기법인 Word2Vec의 경우, bank가 문장 내에서 어떤 의미로 사용되든 동일한 임베딩 수치(벡터)를 출력했다고 한다. 그러니까 ‘은행에서 돈을 빌렸다’가 아니라 ‘둑에서 돈을 빌렸다’ 같은 기괴한 문장이 출력될 수 있었던 것이다.

이런 상황이 2017년을 기점으로 돌변한다. 구글에서 이른바 어텐션(attention) 메커니즘을 중심으로 하는 트랜스포머(transformer)라는 모델의 아이디어를 발표하면서부터다. 챗지피티가 기반한 대량 언어 모델인 GPT는 Generative Pre-trained Transformer, 즉 ‘생성형 사전 학습 트랜스포머’의 약자다. 구글의 람다, 메타의 라마, 네이버의 하이퍼클로바 등도 이름은 다르지만 모두 ‘생성형 사전 학습 트랜스포머’의 일종이라고 할 수 있다.

 

트랜스포머는 자동번역, 대화형 챗봇, 검색 등에서 NLP의 기능을 혁신적으로 강화시켰다. 최근 몇 년 사이 언어와 관련된 디지털 서비스가 대폭 개선되었다고 느꼈다면, 그것은 트랜스포머 덕분이라고 해도 과언이 아니다.

트랜스포머의 엄청난 능력은 이 모델의 일부인 어텐션 메커니즘에 기반한 것이다. ‘어텐션(attention)’은, 그 명칭(attention:주목, 주의)에서 알 수 있듯이, 문장의 전체 의미를 이해하기 위해 ‘주목’해야 할 부분을 추출해주는 기능이다. 단어와 단어 간의 관계, 즉 맥락(문맥)을 잘 찾아낸다고 이해해도 좋다. 예컨대 다음과 같은 문장이 있다고 치자.

내가 영희에게 보고서를 마구 흔들어대며 “참 잘났다, 잘났어!”라고 말하자 그는 잠시 어리둥절한 표정을 지었다.

여기서 어리둥절한 표정을 지은 ‘그’는 누구인가? ‘내’나 ‘보고서’ 혹은 ‘영희’일 것이다. 인간은 문맥(맥락)을 통해 ‘그’가 ‘영희’라는 점을 바로 알아챌 수 있다. 그러나 인공지능에겐 어려운 일이었다. 2010년대 중반까진, 그나마 이 문제를 해결할 수 있는 최첨단 기술이 RNN이었다. RNN은 문장의 앞에서부터 차례대로 하나씩 단어를 처리(process)해나간다. 그 과정에서 앞 단어들의 정보를 기억해서 다음 단어를 처리할 때 반영한다. 그러나 RNN의 기억력은 좋은 편이 아니었다. 위 문장에서 ‘그’에 도달할 시점엔 바로 앞에 있는 ‘말하자’와 ‘라고’는 뚜렷이 기억했다. 그러나 문장 전체를 이해하는 데 정말 중요한 ‘영희’에 대한 기억력은 이미 희미해져버린 상태였다.

이에 비해 트랜스포머에 포함된 어텐션 메커니즘은 ‘단어를 차례대로 하나씩 처리하며 앞 단어들을 기억’하는 것이 아니라 전체 문장을 통째로 처리한다. 단어별로 해당 단어와 다른 모든 단어들 사이의 관련성을 수치화한 뒤 이 정보들을 다음 단계로 넘기는 방법이다. 이 관련성이 바로 맥락이며 문맥이다.

위의 문장에서 ‘그’라면, ‘내’와 ‘보고서’, ‘영희’뿐 아니라 ‘잘났다’ ‘마구’ ‘흔들어대며’ ‘잠시’ 등 문장의 다른 모든 단어들과 크든 작든 관련성을 가진다. 이런 관련성들을 수치화하면, ‘그’는 자신과 다른 모든 단어들 사이의 관계를 반영한 정보가 된다. ‘그’뿐 아니라 다른 모든 단어들도 같은 방식으로 처리된다. ‘한 톨의 먼지가 전 우주를 품고 있다’라는 말이 있는데, 어텐션 메커니즘으로 처리되는 각각의 단어는 자신과 전체 문장 사이의 관계에 대한 정보를 안고 있다. 이 같은 ‘관계에 대한 정보’ 덕분에 트랜스포머는 ‘그’를 처리할 때 앞에 나오는 모든 단어들을 기억할 뿐 아니라 문장의 초엽에 나오는 ‘영희’에게 주목(attention)할 수 있게 된다. 아무리 ‘그’와 ‘영희’가 멀리 떨어져 있다고 하더라도 말이다. RNN에서처럼 짧은 기억력 때문에 고민할 필요가 없다.

어텐션 메커니즘이야말로 최근 나온 챗지피티나 DeepL(딥엘·번역기) 같은 NLP 관련 프로그램들이 문맥을 잘 이해하는 것처럼 보이는 비결이라고 할 수 있다.

기자명 이종태 기자 다른기사 보기 peeker@sisain.co.kr
저작권자 © 시사IN 무단전재 및 재배포 금지
이 기사를 공유합니다
관련 기사