전체 개념 논문 구현 NLP PyTorch Transformer Recommender Graph Vision GAN MWP Automata

ATHENA: Mathematical Reasoning with Thought Expansion

2023.10.31
논문 NLP MWP

부족하지만, 많은 시간 준비했던 논문을 이번 EMNLP (2023) 학회에서 main paper로서 소개하게 되었다. 이 논문은 2년 전 처음 Math Word Problem (MWP) 분야에 관심을 갖게 된 이후, 올해 4월까지 감사하게도 많은 사람들의 도움을 받아 여러번의 발전을 거쳐 완성되었다.

모델의 핵심 아이디어는 바로 Thought Expansion, 즉 생각의 확장이다. 사람의 생각이 이루어지는 방식에 대해 많은 고민과 탐구를 통해서 이러한 모델을 설계하게 되었고, 기존과 차별화되는 성과를 얻을 수 있었다.

이 포스팅에서는 논문의 주저자로서, 주제와 아키텍처에 대해 논문에 담지 못한 내용들, 그리고 어떤 영감으로부터 이러한 아키텍처를 구현하게 되었는지를 자세히 포함하여 소개하도록 하겠다.

Math Word Problem (MWP)

Math Word Problem (MWP), 우리 말로 표현하면 수학 문장제 문제는 불과 몇년 전까지만 해도 단지 수많은 NLP 분야중 하나였고, 나에게 크게 흥미가 가는 분야는 아니었다.

MWP는 수학 문제 중에서도, 자연어로 상황에 대한 묘사와 질문이 주어진다는 점이 특징이다. 가장 간단한 예시로 다음과 같은 문제가 있다.

Q) 바구니에 사과가 5개, 배가 3개 있다. 바구니에 있는 과일은 모두 몇개인가?
A) 5 + 3 = 8

BERT 이후 등장한 수많은 언어 모델들은 이보다 훨씬 더 어려운 문제들에서도 탁월한 성능을 보여주었기 때문에, 위와 같이 간단한 문제는 이런 언어모델들을 두면 아주 쉽게 풀릴 것처럼 보인다. 실제로 위보다 훨씬 복잡한 문제들이 들어있는 Math23k와 같은 데이터셋도 7~80%의 정답률을 보였고, 이제는 이런 단순한 문제풀이가 아니라 증명문제처럼 정말 복잡한 수학 문제들도 연구되기 시작하였다.

여기까지의 연구결과를 보면, 수학 분야쪽에 관심이 많은 사람이 아니라면 굳이 이런 "수학 문제"를 따로 잘 해결하는 모델을 연구할 필요성을 느끼지 못한다. 하지만 이러한 생각은 아래 논문을 보고나서 바뀌게 되었다.

Shortcut Learning in NLP

  • Patel et al. Are NLP Models really able to Solve Simple Math Word Problems? NAACL (2021). (이하 'SVAMP 논문'으로 표현)

SVAMP 논문의 자세한 내용은 해당 포스팅에 소개하였지만 간단히 말하자면, 위에서 보였던 훌륭한 정답률은 모두 'shallow heuristics'에 의존하는 것이고, 사실 NLP모델은 위의 문제처럼 사과와 배를 더하는 정말 간단한 사칙연산조차 제대로 이해하지 못했다는 것이었다.

'lexical shortcut', 'shorcut learning', 'shallow heuristics' 등의 여러 이름으로 불리고 있는 이 문제는, 비슷한 시기에 commonsense reasoning, relation extraction등 여러 다른 자연어 처리 분야에서도 제기되기 시작하였다. 대표적인 연구 중 하나가 바로 딥마인드에서 발표한 Nature 논문 Geirhos et al. Shortcut learning in deep neural networks. Nature Machine Intelligence (2020)이다.

이런 이슈들의 주요 골자는 바로 현재 딥러닝 모델들의 비약적인 성능들이 해당 태스크를 제대로 이해한 것이 아닌, 데이터셋을 만들면서 미처 고려하지 못했던 shortcut pattern으로 인해 나타났다는 이야기다. 이는 이전 포스팅 등에서도 보여주듯, 최근 ChatGPT 등의 LLM이 보여주고 있는 hallucination 문제와도 근본적으로 맞닿아 있는 문제점이다.

MWP 와 Shortcut Investigation

MWP 연구의 이점이 여기에서 드러난다. MWP는 다른 태스크들보다 이런 shortcut 문제들을 연구하는데 있어서 유리한 점이 있다. 바로 모델의 풀이과정과 정답이 "수식"으로서 아주 명확하게 표현된다는 것이다.

자연어 태스크들은 그 특성상 정답이 한정되거나, 혹은 평가가 정확하지 못하다. 컴퓨터가 우리 언어를 보고, 답이 맞는지를 확인할 수가 없기 때문이다. 그래서 대부분의 태스크는 객관식 선택지 중 고르거나, 혹은 주관식은 BLEU 스코어 등의 평가방식을 사용한다.

BLEU 등의 평가방식은 그냥 문장의 단어적인 유사도를 보지, 근본적으로 그 정답이 올바른지를 확인하는 것이 불가능하다. 모델의 정확도를 보기 위해서는 객관식 문제형태가 되어야 하는데, 이 방식은 정답의 개수가 한정적이기 때문에 결국 shortcut 형태를 피하기가 어렵다.

하지만 "수식"을 정답으로 출력하게 되면, 이처럼 정답을 객관식으로 만들 필요도 없으면서도, 답이 맞는지를 그 풀이과정까지 완벽하게 평가할 수 있다. 그래서 SVAMP처럼 모델의 추론 능력을 정확하게 평가하는 것이 가능한 것이다.

이런 관점에서 shortcut 문제를 해결하기 위해 MWP 분야에 관심갖기 시작하였고, 그 해결 방법을 단지 "수학 문제"에 특화되기 보다 좀 더 근본적으로 접근하는 방법을 연구하고자 하였다.

Shortcut에 대한 이해

이러한 shortcut은 발생하는 것일까?

사실 이미 위의 논문을 읽을 때, 나는 직관적으로 모델에 어떤 문제가 발생하는지를 바로 이해할 수 있었다. 이 현상은 이미 내 개인적인 경험에서 겪었던 일이었다.

과거에 아동 복지쪽에서 아이들을 가르치는 일을 한 적이 있다. 내 기억에서 가장 인상깊었던 것은 바로 갓 초등학교를 입학한 아주 어린 꼬마를 가르칠 때의 일이다. 나는 주로 초등학교 고학년~중등부들을 가르쳤기 때문에 이런 어린 꼬마는 처음 담당하게 되었다.

그 꼬마는 학교에서 아주 기초적인 것들은 배워, 숫자를 세어 가며 덧셈 뺄셈을 하거나 구구단도 외워서 쉬운 곱셈까지도 할 줄 아는 상태였다. 나는 위와 같은 초등학교 1학년 수준의 수학 문장제 문제집을 같이 풀며, 개념들을 하나씩 설명해 주었다. 예를 들면, "사과가 5개 있는데, 3개를 먹었으니, 5개중에 3개가 사라지겠지? 그러면 뺄셈을 하면 되는거야. 5개중에서 3개를 뺀다. 식으로는 5 - 3 = 2" 이런 식이다.

이렇게 여러 날들에 거쳐 나는 덧셈을 활용하는 법, 뺄셈을 활용하는 법, 곱셈을 활용하는 법을 모두 알려주었다. 그 애는 내가 알려준것들을 활용하며 문제를 쉽게 풀었고, 이 때까지 나는 잘못된 것을 알지 못했다.

내가 문제를 발견한 것은 바로 한 단원을 끝내고 종합문제를 풀 때였다. 그 애는 문제를 거의 제대로 풀지 못했다. 더 정확히 표현하면, 그냥 모두 곱했다.

이 때 나는 이전에 가르치며 느꼈던 위화감을 깨달았다.

첫 날에는, 덧셈의 개념을 알려주었다. 그리고 덧셈에 대한 연습문제들을 풀었다. 그 애는 문제에 나와있는 두 숫자를 더해서 답을 맞췄다.

다음날에는 뺄셈을 알려주었고, 뺄셈 연습문제들을 풀었다. 그 애는 문제에 나와있는 숫자들을 빼서 답을 구했다.

그리고 곱셈을 알려주고, 곱셈에 대한 연습문제들을 풀었다.

그 애는 당일 푼 문제들은 (계산실수를 빼면) 모두 맞췄다. 하지만, 그 것은 문제를 이해하고 있는 것이 아니었다. 아니, 심지어 문제를 읽지도 않았고 볼 수 있다.

대신, 그냥 문제에서 2개의 숫자를 찾고, (문제는 항상 2개의 숫자만 주어졌으므로) 그 2개의 숫자를 내가 그 날 알려준 연산을 사용했을 뿐이었다. 내 설명은 아마 귓등으로 날아가버렸을 것이다.

'Shortcut Learning'이란 이와 같이 모델 뿐만 아니라, 사람에게서도 얼마든지 발생할 수 있는 문제이다. 아이가 이런 식으로 문제를 풀리라고는 나도 생각하지 못했고, 아마 그 문제집을 만든 사람도 예상하지 못했을 것이다.

그 문제집은 덧셈, 뺄셈, 곱셈을 차례대로 설명해주고 있었고, 나는 그 문제집의 과정에 맞추어서 애를 가르쳤을 뿐이다. 하지만, 그 애의 입장에서는, 첫 날에는 덧셈만 하면 됐고, 둘째 날에는 뺄셈, 셋째 날에는 곱셈만 하면 됐었다. 이 패턴은 낯선 수학적인 개념을 이해하는 것보다 훨씬 학습하기 쉬운 패턴이었다.

모델도 마찬가지다. 이런 제한된 데이터셋과 평가방식(즉, loss)으로 학습하게 된다면, 모델은 그 개념을 이해하기보다 문제의 특정 몇개 단어를 보고 예측하는 방향으로 학습하기가 훨씬 쉬운 것이다.

기존 모델의 동작 과정

이렇게 shortcut learning은 사람에게서도 충분히 나타날 수 있는 현상이다. 그리고, 여기에 학습과정이 중요하다는 것도 직관적으로 알 수 있을 것이다.

그렇다면, 현재 제시된 모델들은 어떻게 학습하고 동작할까?

설명을 위해, 아래의 예제를 활용할 것이다.

Q) 4개의 과일 바구니가 있고, 각 바구니 안에는 사과가 5개, 배가 3개씩 있다. 과일은 모두 몇개인가?
A) $4 \times (5 + 3) = 32$

덧셈과 곱셈의 개념을 이해하고 나면 정말 쉽게 풀 수 있는 예제이다. 하지만, 모델에게도 그럴까?

Sequence-to-Tree (S2T)

NLP 모델에서 가장 널리 쓰이는 sequence-to-sequence (S2S) 와 다르게, sequence-to-tree (S2T) 방식은 수식에 특화된 이진트리 구조이다. 하지만 S2S나 S2T는 근본적으로 동일한 문제점을 안고 있고, 여기에서는 편의를 위해 S2T 기준으로 설명을 진행하도록 한다.

이 연구를 처음 시작할 당시에 SOTA 성능을 기록한 모델은 바로 Graph-To-Tree (G2T) (2020) 모델이다. 이 모델은 기존 Sequence-to-Tree (S2T) 모델, 정확히는, Goal-driven Tree-Structured model (GTS)에 그래프 임베딩을 추가하면서 성능을 올린 형태이므로, 결국 S2T의 개선 모델이라고 할 수 있다.

이 방식은 기본적으로 다음과 같이 디코딩이 트리의 pre-order 순서로 진행되는 예측 모델이다.

  1. 먼저, 자연어 문제를 LSTM (혹은 PLM) 등으로 인코딩한다.
  2. Root -> Left -> Right 순으로 순회하며 트리 형태로 디코딩한다.

구체적으로 위 예제 문제로 설명하자면, S2T는 다음 순서로 수식을 예측한다.

Sequence-to-Tree

  1. 가장 먼저, root 노드를 예측한다: ×가 예측되었다.
    > 예측한 결과가 연산자이므로, 노드의 좌측과 우측에 올 각 피연산자(child)를 구해야 한다.
  2. ×의 왼쪽 child를 예측한다: 4 가 예측된다.
    > 4는 숫자이므로 더이상 탐색을 수행하지 않고 종료한다.
  3. ×의 오른쪽 child를 예측한다: +가 예측된다.
    > +는 연산자이므로, 이 +의 각 child를 구해야 한다.
  4. +의 왼쪽 child를 구한다: 5 가 예측된다.
    > 5는 숫자이므로 탐색 종료
  5. +의 오른쪽 child를 구한다: 3이 예측되된다.
    > 3은 숫자이므로 탐색 종료
  6. 모든 탐색이 종료되고, 위와 같은 트리가 만들어진다. 이 트리를 식으로 표현하면 4 × (5 + 3) 가 된다.

S2T는 이와 같이 트리를 예측하기 때문에 수식에 있어서는 S2S보다 유리하다고 볼 수 있다. S2S는 수식을 그냥 문자열 순서대로 예측해서 하나의 토큰만 실수하더라도 4 * ( + 3)과 같이 식 자체가 잘못 만들어지지만 S2T는 무조건 명확한 트리가 만들어져야 탐색이 종료되므로, 항상 유효한 수식을 만들어낸다는 장점이 있다.

여기서 pre-order를 사용하는 이유는 트리구조 자체를 정의해야 하기 때문이다. 구조를 정의하지 않은 상황에서는 어떤 자식부터 예측해야 할 지를 판단할 수가 없다.

S2T의 문제

이 S2T는 분명 이론적으로도 수식을 깔끔하게 구할 수 있고, 성능도 좋았기에 후속 연구들도 대부분 이 S2T를 기반으로 인코딩 성능을 개선하는 방향이었다. 하지만, 사람이 이런 학습방식을 갖는다고 생각하면 이 S2T는 근본적으로 원리를 배우는 것이 불가능한 모델이다. 그 이유는 다음과 같다.

우리가 S2T처럼 문제를 풀려면 다음과 같은 문제풀이 방식을 배워야 한다.

문제: 4개의 과일 바구니가 있고, 각 바구니 안에는 사과가 5개, 배가 3개씩 있다. 과일은 모두 몇개인가?

  1. 정답을 구할 때 가장 마지막에 수행될 연산은 무엇일까? : ×
  2. 그렇다면, 이 ×은 어떤 것과 연산될까? : 4
  3. 그렇다면, 4는 어떤 것과 곱해지게 될까? : +

예제가 너무 쉽기 때문에, 우리들은 위 질문들에 대답할 수는 있을 것이다.

하지만, 우리가 정말 어려운 문제를 푸는 상태이고, 복잡한 방정식들을 전개하면서 정답을 구해야 하는 상황을 생각해보자. 우리는 그 복잡한 문제에서 가장 마지막 연산을 맨 처음에 알 수 있을까?

게다가 애초에, 마지막 연산은 한 가지가 아니다. 위 문제를 (4 × 5) + (4 × 3)으로 풀 수도 있다. 이런 경우 마지막 연산은 +가 된다.

결국, S2T는 사람도 불가능한 문제풀이 방법을 학습하려는 것이다. 이렇게 보면, S2T가 원리를 배우지 못하고 shortcut을 배우는 것은 너무 당연한 결과이다.

S2S도 결국 마찬가지다. 식의 맨 처음 문자가 4가 올 지, (가 오는지를 모델이 미리 수 있을까?

이 문제점이 바로 잘 드러났던 것이 바로 SVAMP 논문의 문제 변형 테스트다. 아래 예시를 보면 이 MWP라는게 보기보다 쉽지 않은 태스크이고, 이런 모델로는 쉽지 않다는 것을 이해할 수 있다.

문제 변형을 통한 shortcut의 관찰

SVAMP 논문은 같은 문제를 조금씩 변형하면서 모델을 테스트했는데, 특히 질문 부분을 변형하는 부분이 중요하다. 왜냐하면, 질문만 바꾸더라도, 정답 수식이 완전히 달라지기 때문이다. 그래서 이런 변형을 활용하여 모델이 정말 원리를 이해하고 있는지를 평가하는데 사용하였다.

예를 들어서, 위의 예제를 다음과 같이 질문만 바꿀 수 있다.

문제: 4개의 과일 바구니가 있고, 각 바구니 안에는 사과가 5개, 배가 3개씩 있다. 과일은 모두 몇개인가? 답: 4 × (5 + 3)

  • 변형 1

    4개의 과일 바구니가 있고, 각 바구니 안에는 사과가 5개, 배가 3개씩 있다. 사과는 모두 몇개인가? 답: 5 × 4

  • 변형 2

    4개의 과일 바구니가 있고, 각 바구니 안에는 사과가 5개, 배가 3개씩 있다. 사과는 배보다 몇 개가 더 있나? 답: (5 - 3) × 4

  • 변형 3

    4개의 과일 바구니가 있고, 각 바구니 안에는 사과가 5개, 배가 3개씩 있다. 사과는 바구니보다 몇 개가 더 있나? 답: (4 × 5) - 4

이렇게 보면, MWP가 생각보다 모델 입장에서는 쉽지 않다는 것을 느낄 수 있다. 문제에서 몇 개의 단어나 어순만 약간 바뀌었을 뿐인데, 풀이는 완전히 달라지고 있다.

예를 들어, 변형 2와 변형 3은 질문에서 "" 와 "바구니"만 다르고 나머지는 전부 동일한 문자 구성이다. 하지만, 정답은 다음과 같이 전혀 다른 형태이다.

  • 변형 2는 뺄셈을 맨 처음에 계산하지만, 변형 3은 뺄셈을 맨 마지막에 수행한다.
    따라서 S2T는 각 문제에 대해 서로 다른 root 연산자를 예측해야 한다.
  • 변형 2와 변형 3의 공통점은 바로 식의 맨 마지막이 4로 끝난다는 것이다.
    즉, root 연산자에 상관 없이 무조건 right child는 4가 된다.

우리는 수학적인 개념을 이해하고 있기 때문에 이 식들이 어떤 과정을 통해 나왔는지를 알지만, 위와 같이 식을 유도하는 과정을 차근히 밟지 않은 모델은 이런 과정을 이해할 수 있을까?

모델 입장에서는 이 4개의 문제들을 보고,

질문에 "사과는" 이라는 글자가 들어가면 마지막에 무조건 4가 된다.

라는 공통 패턴, shortcut을 발견하는 것이 더 쉬울 것이다. 사실 4는 "바구니"의 개수지, "사과"와는 아무 상관없는데도 말이다.

심지어, 여기에는 정답 식을 labeler가 어떻게 설정하는지에 따라서도 영향을 받는다. 예를 들어, 변형 2의 식을 (4 × 5) - (4 × 3) 로 작성할 수도 있다. 이렇게 되면, 위 shortcut은 성립이 되지 않고, 또 다른 규칙을 찾아야 한다.

Shortcut을 해결하려면?

결국 현재 언어 모델 구조는 텍스트 패턴을 찾는데는 강력하지만, 어떤 원리를 습득하고 그런 원리들을 사용해서 문제를 올바르게 풀기는 쉽지 않은 형태라는 것을 직관적으로 이해할 수 있다.

이에 대한 해결은 크게 2가지 방향으로 볼 수 있다.

하나는, 바로 모든 경우의 수를 학습시키는 것이다. 예를 들어 위의 사과와 배, 바구니로 만들 수 있는 모든 변형문제를 제작하고 모델에게 학습시키는 것이다. 그러면 loss 자체가 편법으로는 수렴할 수 없게 되고, 모델은 그 원리를 찾는 방향으로 학습을 진행할 것이다 (혹은, 학습을 못해 발산하거나). 현재 LLM이 바로 이런 형태라고 할 수 있다. 모든 편법들을 막는 데이터와, 적절한 모델이 있으면, 결국 그 모델이 찾는 shortcut 자체가 정답원리에 가까워질 수밖에 없는 것이다.

하지만 우리가 표현할 수 있는 언어와 생각은 무한하고, 이를 데이터에 담는 것은 결국 근본적으로 한계가 있다. 그렇기에, 결국 근본적인 해결책은 위처럼 데이터의 확장이 아니라, 모델 구조 자체가 "원리를 배우고 사용하는 모델"이 되어야 한다는 것을 알 수 있다.

하지만 도대체 "원리를 배우고 사용하는" 모델은 어떻게 만들어야 하는 것일까?

그 해답을 제시하기 위해, 나는 다음과 같은 질문으로부터 출발하였다.

이처럼 까다로운 태스크를, 우리는 어떻게 풀고 있을까?

인간은 어떻게 생각할까?

우리들은 원리를 이해하며 문제를 푼다. 그렇기에 모든 경우를 학습하지 않아도 원리를 배우고 생각하는 법을 자연스럽게 알 수 있는 것이다.

하지만, 여기서 원리를 이해한다는 것은 정확히 무엇일까? 사람은 어떤 방법으로 원리를 이해하는 것일까?

이를 구체화하기 위해 단순히 내 직관이나 경험에 의존하는 것이 아니라, 정말 많은 인지과학이나 심리학 이론과 연구들을 살펴보며 연구를 진행하였다.

사람의 풀이 능력

먼저 우리가 문제를 푸는 과정을 자세히 살펴보자.

4개의 과일 바구니가 있고, 각 바구니 안에는 사과가 5개, 배가 3개씩 있다. 과일은 모두 몇개인가?

이런 문제를 받으면, 우리는 맨 처음 어떤 생각을 하게 될까?

일단, 문제에서 "과일"의 모든 갯수를 구하라고 했기 때문에 한번 과일의 개수를 세어 보려고 할 수 있다.

가령 첫 번째로는, 각 바구니 안에 모든 과일의 개수를 구할 수 있다. 바구니 안에는 사과와 배, 두 가지의 과일이 있으므로, 5 + 3 = 8이 된다.

우리는 한 바구니에 8개의 과일이 있는 것을 알았다. 그런데, 문제에 바구니는 총 4개라 했으므로, 우리는 총 과일의 개수를 4 × 8 = 32 를 통해 얻을 수 있다.

너무 당연한 과정이지만, 우리는 어떻게 문제를 보고 이런 풀이를 떠올린 것일까? 구체적으로, 인간의 어떠한 능력이, 어떠한 방식으로 사용되어 이렇게 문제를 푸는 것일까?

연산의 개념

가장 먼저 눈여겨봐야 할 부분은 바로 연산의 개념이다.

문제에서 우리는 다음 3가지 단서를 알고 있다.

  1. 바구니의 개수: 4
  2. 각 바구니 안의 사과 개수: 5
  3. 각 바구니 안의 배 개수: 3

첫 번째 과정에서, 우리는 "각 바구니 안의 사과 개수"와, "각 바구니 안의 배 개수"를 더했다. 그리고, "각 바구니 안의 모든 과일 개수는 8이구나" 라는 생각을 떠올릴 수 있었다.

이런 생각을 떠올리기 위해 우리는 두 가지 능력을 갖추어야 한다.

  1. 숫자 53을 더할 수 있는 능력이 있어야 한다.
  2. 두 "개수"에 대해서 덧셈을 수행한 값은 바로 "모든 개수"가 된다는 원리를 알고 있어야 한다.

여기에서 첫 번째 부분은 단순 계산이므로, 컴퓨터에게 전혀 문제되지 않는다. 말 그대로 compute 하면 된다.

모델이 어려워하는 것은 바로 두 번째, "덧셈"에 대한 이해다. 5 + 3이 바로, "각 바구니 안의 과일 개수"를 나타내는 숫자라는 것을 알아야 한다.

우리는 이러한 덧셈에 대한 개념을 어떻게 알고 있을까?

애초에, 우리는 덧셈의 과정을 눈으로 볼 수 있다. 사과 3개가 놓여져 있고, 거기에 2개를 더 놓으면 5개가 되는 과정을 본다. 우리는 이 것을 덧셈, "addition"이라고 배우고, 문제를 풀 때 이런 개념을 떠올리면서 푼다.

하지만 모델은 이런 실제 상황을 볼 수 없기에 이런 물리법칙을 알 수 없다. 장님이 설명만으로 현상을 이해하려고 하는 것과 같은 것이다. 모델 입장에서는, 사과와 배의 개수를 세는 것을 "덧셈"을 적용해야 할지, "곱셈"을 적용해야 할 지 이런 당연한 개념을 파악하기 어렵다.

심지어, 같은 연산도 여러가지 개념이 있다. 예를 들어, 어떤 두 길이를 일자로 놓을 때에도 덧셈을 사용해야 한다.

우리에게는 당연하지만, 모델에게는 이런 연산의 개념은 매우 어려운 과제가 되는 것이다.

문제 해결 능력

위에서 우리는 "사과의 개수"와 "배의 개수"를 먼저 더하고, "바구니 개수"와 곱해서 정답을 얻었다.

우리는 왜 이렇게 생각했을까? 즉, 왜 "사과의 개수"와 "배의 개수"를 더했을까?

만약 질문이 "사과의 개수와 바구니 개수의 차이"를 구하라고 했다면, 우리는 위처럼 "사과의 개수"와 "배의 개수"를 더했을까?

이와 같이 연산의 개념을 이해하더라도, 어떻게 문제를 푸냐는 또 다른 문제가 된다. 그리고 결국 질문에 대답하기 위해서는 이러한 문제해결 능력이 필요하다.

여기에서 문제해결 능력이란, 수많은 생각들 중에서 정답으로 향하는 길을 찾는 능력이라고 할 수 있다.

우리는 주어진 상황을 보고 수많은 생각을 떠올릴 수 있다. 예를 들어, 질문 없이 다음과 같이 상황만 주어진다고 한다.

4개의 과일 바구니가 있고, 각 바구니 안에는 사과가 5개, 배가 3개씩 있다.

우리는 사과와 배를 더할수도 있고, 뺄 수도 있고, 곱할수도 있고 등 수많은 생각을 할 수 있다. 우리는 연산의 개념을 알고 있기 때문에, 사과와 배를 더하면 과일개수가 된다는 것을 알 수 있고, 빼면 사과가 배보다 얼마나 더 많은지를 나타낸다는 것을 알 수 있다.

하지만 이러한 생각들 중에 문제를 풀기 위해서는 어떤 생각을 해야하는 것일까?

위에서는 질문이 주어지지 않았기 때문에, 알 수 없다. 즉, 문제를 풀기 위해 해야 하는 생각은 "질문"에 따라 달라진다는 것이다.

이 질문이란 다시 말해서, 우리의 "목표"라고 얘기할 수 있다. 그리고, 문제를 푸는 능력을 다시 말하면, 목표에 도달하는 능력이라고 표현할 수 있다.

이러한 능력을 심리학이나 인지과학 분야에서는 절차적 지식, procedural knowledge라고 말한다. 반대로 위에서의 연산에 대한 개념은 개념적 지식, conceptual knowledge라고 한다.

추론에는 이와 같이 개념적 지식과 절차적 지식이 있고, 결국 우리는 이 두 지식의 상호작용을 통해서 문제들을 해결하는 것이다. 이러한 수학에 대한 개념적 지식과 절차적 지식의 발달을 연구한 대표적인 심리학 교수로 Bethany Rittle-Johnson 교수가 있다.

인간의 사고 과정

사람은 이러한 능력, 혹은 지식을 통해 구체적으로 어떻게 생각할까?

이에 대한 대표적인 연구자는 Philip Johnson-Laird 교수로, 인간의 사고과정, 특히 추론과정에 대해 연구하였다. 이 Johnson-Laird의 개념을 일부 빌려 표현하자면, 사람의 생각을 크게 두 가지로 구분할 수 있는데 바로 목표가 없는 생각목표지향 생각이다.

위에서 질문 없이 상황만 주어졌을 때 떠올리는 생각을 목표가 없는 생각이라고 볼 수 있다. 이러한 사고 과정에는 어떤 생각도 떠올릴 수가 있다. 우리는 사과와 배의 개수를 더할수도, 서로 뺄 수도 있는 것이다. 이를 다른 말로는 연상 (Association) 이라고 한다.

반면, 목표지향 생각은 명확한 목표가 주어졌을 때 수행하는 사고 과정이다. 목표지향 생각은 답에 도달하기 위해서는 어떤 개념을 적용하는 것이 좋을지를 찾는 과정이라고 할 수 있다. 질문에 따라 사과와 배의 개수를 더해야 할 지, 아니면 빼야 할 지를 판단하는 것이다. 이를 다시 말해 추론 (Reasoning) 이라고 한다.

더 자세히 들여다보면, 추론연상의 결과물들의 부분집합으로 볼 수 있다. 우리가 떠올릴 수 있는 모든 생각들 중에서, 질문에 대답할 때 사용된 생각들인 것이다. 즉, 사과와 배의 개수를 더하기도 하고, 빼기도 했는데, 그 중에서 문제풀이에 활용된 것은 사과와 배의 개수를 더한 생각인 것이다.

이러한 관점에서, 우리는 이러한 사고과정과 지식의 관계를 정리할 수 있다. 연상개념적 지식을 사용하여 여러가지의 생각을 떠올린다. 추론절차적 지식을 사용하여, 연상된 생각 중에 목표에 필요한 생각과, 필요없는 생각을 구분한다.

ATHENA는 바로 사람의 연상추론을 활용한 모델이다. 모델은 연상과 추론을 통해 문제푸는 방법에 도달하는 과정을 학습한다. 이러한 과정을 통해, 모델은 자연스럽게 개념적 지식과 절차적 지식을 각각 활용하는 법을 습득하게 된다.

ATHENA가 이러한 원리를 습득했기 때문에, 기존 모델들보다 한번 배운 개념을 활용하는데 훨씬 강력한 모습을 보여줄 수 있는 것이다.

참고로 논문에서는 이러한 개념들에 대해 분량의 한계로 간단히만 소개하였다. 특히 이러한 심리학적인 자세한 개념들을 NLP 연구자들에게 소개하기 위해서는 여러 용어들을 소개하고 설명하는 데 많은 분량의 할당이 필요하다. 따라서 핵심이 된 심리학 개념 중 위의 연상 (association) 이라는 용어를 포함하여 많은 내용들이 논문에서는 생략되어 등장하지 않음을 밝힌다.

ATHENA

Attention-based THought Expansion Network Architecture 의 각 글자를 따 ATHENA라고 이름지었다.

이름에서도 나타나듯이, 모델의 핵심은 attention을 활용하여 생각의 확장 (thought expansion) 과정을 표현한 것이다. 그리고, 연상과 추론은 바로 이 생각의 확장과정 안에서 사용되는 도구이다.

먼저 이 사고의 확장이라는 개념을 이 연구에서 어떻게 정의하였는지 소개하도록 한다.

Thought Expansion

사람은 어떤 생각이 들었을 때, 그 생각들을 엮어서 새로운 생각을 계속 연상하고, 다시 그 생각으로부터 꼬리에 꼬리를 물며 무한히 생각을 뻗어나갈 수 있다. 이런 과정을 우리는 생각을 확장한다고 이야기할 수 있다.

우리가 문제를 푸는 것은 이렇게 생각을 뻗어나가며 정답을 찾기 위한 과정이라고 할 수 있다. 처음 보는 문제일수록 우리는 모든 경우를 탐색하는 과정이 필요하겠지만, 문제풀이 능력을 키우면 우리는 딱 필요한 과정만 거쳐서 정답에 도달할 수 있다.

문제풀이를 위한 생각의 확장이란, 이렇게 연상과 추론을 통해서 최적화된 생각으로 정답에 도달하고자 하는 과정이다. 구체적으로, 모델은 답을 찾을 때 까지 다음과 같은 과정을 반복한다.

  1. 현재까지의 생각에서 연상 가능한 모든 생각을 떠올린다.
  2. 모든 생각들 중, 추론을 통해 목표에 도달하는데 필요한 생각들을 빼고는 전부 잊는다.
  3. 답을 찾을 때 까지 위 과정을 반복한다.

이러한 추상적인 방법론으로 모델을 만든다고 하면, 다음과 같은 것들이 궁금할 수 있다.

  1. 모델의 "생각"이란 것을 어떻게 구분할 수 있을까?
  2. "연상"과 "추론"은 어떻게 이루어지는가?
  3. 어떻게 모델은 생각을 통해서 답을 찾은 것을 알까?

이에 대한 내용을 하나씩 풀어보도록 하겠다.

A Thought

이 모든 과정의 근본이 되는 단위가 바로 "생각"이다.

먼저, 일반적t인 뉴럴 모델들은 어떤 특정 길이(보통 입력 길이) 만큼의 벡터들을 가지고 어떤 연산을 수행해서 다시 특정 길이의 출력을 생성한다. 그리고 레이어마다 이러한 연산들을 반복하여 최종적인 답을 얻는다.

하지만 이러한 과정의 문제점은 이 중간의 벡터 값들이 어떤 것을 의미하는지, 즉 어떤 생각인지를 우리가 알 수 없다는 것이다.

여기에서는 각 벡터들에 대해 명확한 심볼과, 명확한 연산을 통해 생각을 정의하고, 이 생각을 우리가 의도한대로 뻗어나갈 수 있도록 하였다. 무작정 연산을 하는 네트워크와 달리, 생각의 전파 여부와 방식을 결정할 수 있는 것이다.

이 연구에서 하나의 "생각"이란, 어떤 독립적인 개념과 우리에게 구분할 수 있는 심볼을 가진 단위라고 볼 수 있다. 구체적으로 각 생각을 기호 $\theta$로 표현하고, 그 생각이 나타내는 심볼을 $\mathcal E(\theta)$ 이라고 한다.

예를 들어, 위 문제를 푼다고 하면 우리는 문제를 읽으며 다음 3개의 생각을 떠올릴 수 있을 것이다.

  1. $\theta_1$ : 바구니의 개수 $\rightarrow \mathcal E(\theta_1)=4$
  2. $\theta_2$ : 바구니 안에 들어있는 사과의 개수 $\rightarrow \mathcal E(\theta_2)=5$
  3. $\theta_3$ : 바구니 안에 들어있는 배의 개수 $\rightarrow \mathcal E(\theta_3)=3$

다시 말하면, 우리는 "수학 문제"로 한정했기 때문에, 문제에 나와있는 각 조건 (즉, 숫자) 들이 표현하고 있는 의미가 바로 각 생각이 되는 것이다.

우리는 이 생각들에 각 수학적 연산을 통해서 새로운 생각을 만들 수 있다. 예를 들어,

  1. $\theta_4=\theta_1 \times \theta_2$: 전체 바구니에 들어있는 사과의 개수
    $\rightarrow \mathcal E(\theta_4)=\mathcal E(\theta_1)\times\mathcal E(\theta_2)=4\times5$
  2. $\theta_5=\theta_2 + \theta_3$: 바구니 안에 들어있는 과일의 개수
    $\rightarrow \mathcal E(\theta_5)=\mathcal E(\theta_2)+\mathcal E(\theta_3)=5+3$

이런 식이 되는 것이다.

물론 위는 이해하기 쉽게 연산을 표현한 것이고, 엄밀한 연산 정의는 조금 더 나중에 소개하도록 한다. 여기에서 이해해야할 것은 생각이란 결국 (의미, 심볼)을 나타내는 하나의 쌍이고, 이를 조합하여 새로운 (의미, 심볼) 쌍을 생성할 수 있는 것이다.

의미의 구현

그렇다면, 여기서 "의미"는 어떻게 표현해야 할까? 나는 이 연구에서 모든 생각의 의미를 동일한 크기의 벡터로 표현하였다. 즉, 모델 구현에서 하나의 생각은 다음과 같이 모델의 히든 크기 $H$를 가진 벡터이다: $ \theta \in \R^H $.

이 정의의 전제는 계속 확장되어 나타나는 복잡한 생각들도 결국 모두 단일벡터로 표현할 수 있다는 것이다. 이 전제가 충분히 가능하리라고 보인 것은 바로 우리가 생각을 단순히 더하는 것이 아닌, 합성이 일어나기 때문이다.

예를 들어, 사과의 개수배의 개수를 더하는 생각을 했다면, 우리는 굳이 "사과", "배" 라는 정보를 기억할 필요 없이 과일 개수라는 좀 더 추상화된 정보만 갖고 있으면 된다.

이렇게 생각을 합성한다는 개념에서 살펴봤을 때 필요한 것은 어떤 최초의 생각이 있어야 한다는 것이다. 이 최초 생각은 어떻게 만들어야 할까?

Initial Thoughts

최초의 생각 (initial thoughts) 은 바로 문제 상황을 읽고, 어떤 개념을 적용하지 않고도 바로 떠올릴 수 있는 생각을 의미한다.

즉, 위 문제에서는 바구니의 개수, 바구니 안의 사과 개수, 바구니 안의 개수가 될 것이다.

여기서 문제는 바로, 우리가 문제를 언어모델로 임베딩을 했을 때는 위와 같이 임베딩 벡터가 딱 나뉘어있지 않다는 것이다. 문제로부터 "바구니의 개수"에 대한 표현과, "바구니 안 사과 개수", "바구니 안의 배의 개수" 표현을 어떻게 임베딩할 수 있을까?

나는 PLM의 [MASK] 토큰으로부터 그 힌트를 얻을 수 있었다.

BERT에서 제안된 Masked Language Modeling 기법은 [MASK] 토큰으로 가려진 원래의 토큰을 복원하기 위한 작업이다. 모델은 [MASK]를 PLM으로 인코딩한 최종 임베딩으로부터 원래 토큰을 예측하는 작업을 수행한다.

이를 자세히 생각해보면, 결국 이 [MASK]토큰이란 주어진 텍스트로부터 맥락상 [MASK] 가 가리키고 있는 토큰이 어떠한 역할 혹은 의미를 가져야 하는지를 발견하려는 토큰인 것이다.

나는 이 [MASK]의 특성을 활용하여, 각 생각의 역할이나 의미를 추출한 임베딩을 만들고자 하였다. 먼저, 다음과 같이 문제에서 나와있는 숫자들을 [MASK] 토큰으로 가린다.

[MASK]개의 과일 바구니가 있고, 각 바구니 안에는 사과가 [MASK]개, 배가 [MASK]개씩 있다. 과일은 모두 몇개인가?

이렇게 마스킹을 하고 PLM으로 인코딩을 한다면, 첫 번째 [MASK]는 "과일 바구니가 나타내는 개수를 나타내는 숫자" 라는 역할을 표현할 임베딩이 될 것이다. 마찬가지로 두 번째와 세 번째 [MASK]도 각각 그 숫자가 문제에서 표현하고 있는 역할을 나타낼 수 있는 것이다.

이렇게 [MASK]가 나타내는 있는 실제 숫자들을 따로 심볼로서 저장해놓고, [MASK]에는 그 의미만 들어있도록 한다면, 우리가 원하는 생각의 개념이 만들어질 수 있는 것이다.

물론, 여기에서 고려해야할 점은 실제 PLM이 위와 같이 생각을 잘 구분해내는가? 이다. 이는 결국, PLM의 성능에 따라 차이가 많이 나며, 특히 "동일한 [MASK]임베딩이 서로 다른 위치값을 가졌을 때 PLM이 얼마나 그 차이를 잘 인지하는가?"에 따라서 성능차이가 발생하게 된다. 아무리 문제풀이를 완벽하게 습득하더라도, 최초 생각 자체가 잘못 생성되면 문제를 풀 수 없다는 것이다.

Association

우리가 갖고있는 생각에서 새로운 생각을 만들어내는 과정을 연상이라고 하였다. 연상은 한 생각에서 뻗어나갈수도 있지만, 두 생각을 조합하여 새로운 생각을 만들 수도 있다.

수학 문제를 풀 때 필요한 연상은 바로 연산, 즉 여기에서는 사칙연산이 될 것이다.

하지만, 나는 이 사칙연산을 그대로 정의하는 대신, 좀 더 일반화시키고자 하였다. 그 주요 이유는 바로 다음과 같다.

  1. 4개의 사칙연산은 서로 완전히 독립된 개념이 아니다. 예를 들어, 뺄셈이란 음수를 더하는 개념과 같다. 즉, $a-b$는 $a+(-b)$와 정확히 같은 의미다.
  2. 특히, 덧셈과 곱셈은 그 연산을 수행할 때 생각의 순서와 무관하게 동일한 의미를 도출해야 한다. 즉, $a+b$와 $b+a$는 정확히 동일한 의미를 지녀야 한다.
  3. 이는 사람이 생각을 추상화시키는 관점에 있어서도 마찬가지 맥락을 지닌다. 우리 머릿속에서 추상화된 생각은 근본적으로 그 순서가 존재하지 않기 때문이다.

즉, 이러한 조건들을 만족시킬 수 있도록 연상 동작을 다음 두 가지로 구분하였다.

  1. Transform: 하나의 생각을 변형하여 새로운 생각을 연상한다. \(\operatorname{T}: \theta \mapsto \theta'\)
  2. Merge: 두 생각을 조합해서 새로운 생각을 연상해낸다. 입력 순서에 무관하다. \(\operatorname{M}: \theta_i, \theta_j \mapsto \theta'\)

위와 같은 생각의 연상함수로 우리는 모든 사칙연산들을 표현할 수 있다. $\operatorname{M}$으로 덧셈과 곱셈을 표현하고, $\operatorname{T}$ 로 각 연산의 역원을 표현하는 것이다. 즉, 모델에는 다음과 같이 4개의 연상 함수가 있다: $\operatorname{T}^{(-\cdot)}, \operatorname{T}^{(1/\cdot)}, \operatorname{M}^{(+)}, \operatorname{M}^{(\times)}$.

여기에서 강조하고 싶은 점은, 이 연상 함수들은 모든 생각들에 대해서 적용된다는 것이다. 일반적인 네트워크를 구성한다면 어떤 레이어의 출력 결과가 다음의 새로운 레이어로 전파되도록 하게 된다.

하지만, 우리가 생각하는 법은 순서에 따라 달라지는가? 그렇지 않다. 생각을 확장하는 개념의 원리자체는 그 생각이 어떤 생각이든 동일한 것이다. 바구니 사과의 개수바구니 배의 개수를 더하는 개념이나, 전체 바구니 안의 사과의 개수 바구니 안의 배의 개수를 더하는 것이나 결국 같다.

우리는 이렇게 개념을 적용하기 때문에 기억력이 허용하는 한 무한히 생각을 확장해 나갈 수 있다. 연상 함수도 마찬가지로, 이러한 "개념" 단위로 레이어가 존재할 뿐, 새로운 생각들에 대해서도 모두 동일한 연상을 적용하여, 메모리가 허용하는 한 무한히 생각을 확장해 나가게 되는 것이다.

이렇게 연상을 통해서 얻은 생각들을 후보 생각들, candidate thoughts 이라고 표현하였고, 이 생각들의 집합을 표기하기 위해 $\Theta$ 기호를 사용한다.

Inference

연상을 통해 현재 뻗어나갈 수 있는 모든 후보 생각 $\Theta$ 를 얻었다. 그렇다면, 이 중에서 목표에 도달하기 위해 필요한 생각들을 어떻게 구분할 수 있을까?

목표가 바로 앞에 있다면 이는 쉽게 알 수 있을 것이다. 과일의 개수를 알고 싶으면 사과와 배의 개수를 더하면 되는 것이다. 하지만 우리의 목표가 멀리 떨어져 있다면, 현재 지점에서 어떤 생각들이 필요한지 파악하기 쉽지 않다. 그렇다면 우리는 목표를 향해 어떻게 생각들을 추론해 나가야 할까?

가장 먼저 떠올릴 수 있는 것은, 목표를 단계별로 분리해야 한다는 것이다. 위의 문제에서, "모든 바구니 안의 과일 개수"를 구하기 위해서는 먼저 "각 바구니 안의 과일 개수"를 파악하는 중간 목표 (intermediate goal) 를 세우는 것이다.

여기에서 주의해야 할 것은, 바로 이 중간 목표가 단계별로 꼭 하나씩 있는 것이 아니라, 여러개가 동시에 필요할 수도 있다는 것이다.

우리의 추론과정으로 다시 돌아가서 생각해보자.

지금 설계하는 모델은 결국 연역적 추론 (deductive reasoning) 을 하는 모델이라고 이야기할 수 있다. 연역적 추론이란, 각 추론 단계 (inference step)에서, 전제 (premise) 를 기준으로 올바른 명제를 생성하여 최종적인 결론까지 도달하는 과정이다. 참고로, 한국어로는 둘 다 추론이지만, 여기에서 reasoning은 전체적인 추론 과정을 의미하고, inference 는 각 단계별 추론을 의미하는 용어이다.

이 연역적 추론의 관점에서, 위의 중간 목표들을 일종의 전제라고 볼 수 있다. 다시 말해, 어떠한 중간 목표를 전제로하여, 그 전제로부터 합당한 생각들을 유추하고, 이 과정을 반복하며 최종적인 결론까지 도달한다는 것이다.

이러한 개념을 이해했다면, 다음과 같은 구현이 필요한 것을 알 수 있다.

  1. Premise 를 어떻게 표현할 것인가?
  2. 각 단계별 premise를 어떻게 설정할 것인가?
  3. premise로부터 어떻게 생각들을 구분할 것인가?

이러한 구현이 되었다면, 결국 이 inference에서는 "목표에 도달하기 위한 생각들"을 얻을 수 있을 것이다. 이 생각들을 여기서는 합당한 생각, reasonable thoughts, 라고 표현하였고 이 생각들의 집합을 기호로 $\Theta^*$ 로 표기한다.

Implementation

위에서 생각의 확장과정을 구체적으로 살펴보았고, 어떠한 재료가 필요한 지 이해할 수 있었다. 이 과정을 어떻게 네트워크로 표현해야 효율적으로 그 결과를 얻을 수 있을까?

Attention

내가 주목한 것은 multi-head attention 이다. 특히, chain-of-thought prompting 논문으로부터 인상적인 insight를 얻을 수 있었다.

이 chain-of-thought prompting은 LLM에게 정답이 아닌, 풀이과정을 예측하도록 지시하면서 추론성능을 큰 폭으로 향상시켰고, 최근 LLM의 놀라운 언어능력들은 결국 이러한 풀이과정, chain-of-thought 예측에서 나왔다고 해도 과언이 아니다.

우리의 추론개념에서 살펴보면, 이 chain-of-thought은 결국 중간목표를 설정하고, 최종 목표에 도달하는 추론과정을 자연스럽게 파악하고 있는 것이다. 나는 LLM 모델의 구조에서 어떻게 이러한 추론과정이 구현되었을까? 에 대한 관점으로 고민하였고, 이로부터 어떤 영감을 떠올릴 수 있었다.

먼저 transformer 기반 self-attention decoder 모델이 어떻게 추론과정을 예측하는지 그 동작과정을 살펴보도록 하자.

디코더는 주어진 입력으로부터 그 다음 토큰을 autoregressive 하게 예측을 수행한다. 즉, 문제와 질문이 주어지면 일단 그 질문에 대한 처음 대답을 예측할 것이다. 여기에서 처음 대답이란 결국 최초의 조건들을 설명하는 문장인 것이다.

그 다음은, "문제"과 처음의 "조건 문장"이 입력이 되어, "그 다음 추론 문장"을 예측한다. 그리고 이렇게 예측한 "그 다음 추론 문장"은 또 다음 단계의 입력이 되는 것이다.

나는 이 과정에서 입력을 추론에서의 중간 목표, 혹은 premise로 해석하였다. 이러한 관점에서, 추론한 결과로 나온 출력들은 다음의 새로운 입력, 즉 중간목표로서의 역할을 하고 있는 것이다.

Transformer 는 이 과정이 토큰단위로 수행되었지만, 여기에서는 굳이 토큰단위가 아닌 생각을 단위로 하여 이와 같은 과정을 구현할 수 있다. 거기다가, 이렇게 추론과정이 recurrent 구조로 들어가기 때문에, transformer처럼 multi layer로 만들지 않더라도 하나의 레이어의 반복으로 충분히 그 역할을 대체할 수 있을 것으로 보았다.

이렇게 multi-head attention과 feed-forward network를 premise와 conclusion 관점에서 해석하여 아키텍처를 설계하였다.

특히 feed-forward 의 역할도 중요한데, 최근 연구들에서 이 FF가 next prediction의 key-value 맵핑을 하는 것을 보여주었다. 이러한 관점에서 보면 attention은 premise와 conclusion을 연결시키는 역할을 수행하고, feed-forward는 그 결과물을 변형하여 최종적인 결론을 얻어내는 것이라고 볼 수 있다.

Association

먼저, 앞에서 정의한 연상의 두 종류 Merge와 Transform을 정의하였다.

Transform은 어떤 하나의 생각이 새로운 생각으로 변형되는 과정이다. 즉, 이러한 단일 변형은 FF가 next prediction을 맵핑하는 과정으로 볼 수 있기에, FF 레이어로서 구현하였다. 즉, $\operatorname{T}(\theta)=\operatorname{FF}(\theta)$ 가 된다.

Merge가 바로 핵심이 되는데, 두 생각을 조합하여 새로운 생각을 만들어내야 한다. 그런데 중요한 것은, 두 생각의 순서에 무관해야 한다. 즉, 교환법칙 (commutative property) 가 성립해야 한다.

두 생각이 서로 연결되는 과정을 attention을 이용하여 표현할 수 있다. attention의 source, 즉 key에 해당하는 부분이 바로 두 생각이다. 그런데 query를 어떻게 설정해야 할까?

나의 아이디어는 바로 query를 해당 두 생각으로 두고 그 결과를 합하여 commutative 를 구현하는 것이다. 이 덧셈은 결과적으로는 간단하지만 아주 효율적이다. 왜냐하면, 일종의 residual connection과 같이 gradient를 각 생각에 그대로 전파하는 역할을 수행할 수 있기 때문이다. 따라서, 이렇게 덧셈을 한 결과물을 최종적으로 FF 로 맵핑을 수행한다. 즉, 대략 다음과 같은 식이 되는 것이다.

\[\operatorname{M}(\theta_i, \theta_j) = \operatorname{FF}({\bf{1}}^\top \operatorname{SelfAttn}([\theta_i;\theta_j])W+b)\]

여기에서 ${\bf{1}}^\top$이 바로 나온 결과물들을 모두 합하는 것이다. 식을 간단히 표현하기 위해 layer normalization과 residual connection 부분은 제외하였다.

결국 Merge 란, 현재 생각들을 가능한 모든 경우로 조합하여 후보 생각을 만드는 것이다. 즉, 모든 $(i,j)$ 조합에 대해 새로운 생각이 나올 수 있는 것이다.

Inference

이렇게 생각을 연상하고 나면, 이 생각들에 대해 추론이 핵심이다.

앞에서 추론은 premise로부터 생각들에 대해 결론을 얻는 과정으로 정의하였다. 이를 모델로서 표현하기 위해서는 먼저 premise를 정의해야 한다. 이 premise도 결국 어떤 임베딩 형태가 되어야 하고, 여기에서 이 임베딩을 premise vector라고 표현하였다.

Premise Vector

Chain-of-thought을 떠올려보면, 최초의 premise는 문제 그 자체라고 볼 수 있다. 이 문제 전체의 임베딩을 사용할 수도 있지만, 더 효율적으로 그 문장의 [CLS] 토큰을 활용하면 된다. 애초에 [CLS]토큰 자체가 그 문장 전체의 representation으로 사용되기 위해 설정한 토큰이기 때문이다. 즉, 문제를 PLM으로 인코딩한 벡터를 $X$라고 하면, 최초의 premise vector $P_0=X_{[CLS]}$ 가 된다.

Infer

이 Premise vector를 통해 이제 각 생각을 전제에 대해 판단하는 infer과정을 설계할 수 있다. 위에서 설명했듯이, 생성된 후보 생각들을 query로 두고, premise vector 를 key로 두는 것이다. 대략 아래와 같은 형태이다.

\[\operatorname{infer}(\theta) = \operatorname{Attn}(\theta, P_d)W+b\]

이렇게 얻은 임베딩에 logistic activation을 적용하면 그 생각이 유효한지 여부를 결정할 수 있다. $\sigma(\operatorname{infer}(\theta))$의 값이 1이면 그 생각을 허용한다라는 의미를 가지고, 반대로 0이면 그 생각들을 폐기하는 것이다.

Premise Update

어떤 단계 $d$ 에서 생각들을 구했다면, 다음 단계 $d+1$의 목표, 즉 새로운 premise를 설정해야 한다. 위에서의 chain-of-thoughts 의 개념을 적용하여, 현재 얻은 생각들이 새로운 목표를 반영하는데 사용된다. 여기서 중요한 점은, 기존의 premise도 유지해야 한다는 것이다. Transformer의 디코더도 입력문장부터 생성된 모든 문장까지 어텐션을 사용한다는 것을 생각해보면 쉽게 이해할 수 있다. 즉, premise 는 대략 다음과 같은 방식으로 업데이트 된다.

\[P_{d+1} = P_d \Vert \operatorname{infer}([\Theta_d^*])\]

$d$ 단계에서 합당한 생각들 $\Theta_d^*$ 의 infer 결과물을 업데이트시키는 것이다.

이 과정에서 주의해야 할 것은 이 infer의 결과물은 premise를 업데이트하는데는 사용되지만, 생각 자체가 업데이트되는 것은 아니라는 점이다. 생각의 연상은 목표와 관계가 없기 때문이다.

여기까지 모델에 대해 수식을 통해 대략적인 소개를 보여주었다. 위의 수식들은 엄밀하게는 논문의 수식과는 조금 다르고, 개념을 이해하기 편하도록 개략적인 부분만 차용하여 작성하였음을 염두해야 한다. 구체적인 레이어의 구현은 논문이나 코드를 참조하면 정확한 내용을 확인할 수 있다.

여기에서 한 가지 더 고려해야 할 점은 바로 최종 목표에 도달했는지에 대한 여부이다. 이는 $\operatorname{answer}$ 라는 함수를 사용하고, infer와 동일한 구조이지만 premise vector 대신 goal vector 를 사용한다는 측면에서만 차이가 있다.

Goal Vector

Premise 는 중간목표를 나타낼 뿐, 최종적인 목표에 도달했는지는 정의하기 어렵다. 이를 위해 goal vector를 별도로 구성하였는데, 쉽게 얘기하자면 문장의 ?에 해당하는 토큰을 goal vector로 정의하였다. 이 punctuation mark 는 질문을 적절히 임베딩하는데 유용한데, 이에 대한 자세한 설명과 분석은 논문의 appendix에 포함시켰으나 여기에서는 생략하도록 한다.

모델의 동작 과정

위 모델은 결국 연상 -> 추론의 동작을 반복하게 된다. 구체적으로는, 효율적인 구성을 위해 각 연상의 종류마다 추론을 따로 구현한다. 즉, Transform -> Infer -> Merge -> Infer -> Transform -> … 의 순서를 반복하는 것이다.

Transform -> Merge 를 바로 수행하면 모든 연산을 표현할 수 있지만, 그 후보생각이 훨씬 많아지게 된다. 하지만 그 사이에 Infer를 넣음으로서 필요한 Transform만 수행하고, 효율적으로 Merge에 필요한 것들만 추출하여 수행할 수 있는 것이다.

이 과정에서 가장 주목해야 할 것은 바로 레이어의 입력과 출력의 길이, $\Vert\Theta^*\Vert$와 $\Vert\Theta\Vert$ 가 네트워크의 판단에 따라 유동적으로 확장된다는 것이다.

일반적인 모델들을 생각해보면, 모델에는 항상 sequence 길이와 batch 길이가 미리 정해져 있고, 각 레이어의 입력과 출력의 크기는 미리 정해져 있다. 이를 잘 생각해보면, 생각을 확장하는 데 크기적으로 한계가 있기 때문에 결국 깊이를 쌓아 전파를 해야 원하는 모든 생각들이 표현된다고 이해할 수도 있다.

하지만 이 생각을 확장하는 아키텍쳐는 그 길이가 유동적으로 조절되기 때문에, 단일 레이어의 재귀적 호출만으로도 충분히 좋은 아키텍처로서 작동할 수 있는 것이다.

나는 이러한 직관으로서 각 구현을 단일 레이어로 모두 구현하였고, 재귀적인 동작을 하도록 설계하였다.

여기까지 생각을 개념화하고 확장을 표현하는 아키텍처를 인간의 사고과정에 맞추어 구상하였다. 하지만, 정말로 이 모델이 우리가 의도한 대로 연상과 추론을 수행할까? 그리고 정말 shortcut이 아닌 개념을 습득할 수 있을까?

지금까지의 연구들은 모두 단순히 데이터셋에 대한 정확도를 벤치마크로 측정하였다. 이러한 벤치마크로는 위와 같이 정말로 모델이 개념을 습득하는지를 파악하기 어렵다.

이를 정말로 파악하기 위해 새로운 실험 셋팅들을 설정했는데, 이러한 실험들을 위주로 결과를 설명하도록 한다.

One-to-Many Experiment

이 연구의 또 하나의 기여점이 바로 이 새로운 실험에 대한 셋팅이다. 단순히 SVAMP처럼 모델이 변형문제를 잘 푸는가?에서 그치지 않고, 모델이 개념을 얼마나 잘 습득하는지, 얼마나 shortcut에 의존하는지를 보고자 이렇게 새로운 실험을 설계하였다.

이 실험의 이름을 일대다 (1:N) 실험이라고 지었다. 바로, 하나를 알려주면 얼마나 그 개념을 잘 활용하나? 를 보고자 하는 실험이기 때문이다.

앞에서 변형문제에 대해서 소개하면서 개념적 지식과 절차적 지식에 대해 이야기하였다. 개념적 지식은 상황에 대한 물리법칙과 그 개념에 대한 지식이었고, 절차적 지식은 이 개념을 활용해서 목표에 도달하기 위한 지식이었다. 그리고, 우리는 눈으로 관찰하기 때문에 우리가 살고있는 이 세계의 물리적인 동작들을 개념으로서 표현하기 쉬웠지만 모델은 글로서 모든 것을 이해해야 하기 때문에 이러한 개념적 습득이 더 어렵다는 설명도 하였다.

이를 다시 얘기하면, 모델이 주어진 상황에서 어떤 물리법칙이 일어나는지를 배우지 않는다면, 아무리 뛰어난 모델이라도 문제를 풀 수 없다는 뜻이다.

예를 들어, 바구니에 사과와 배가 들어있다는 것은 사과와 배의 개수가 "덧셈"을 통해서 계산된다는 것을 말하고, 모든 바구니 안의 과일 수를 구하는 것은 바구니의 개수와 각 바구니 안의 과일수의 "곱셈"을 통해서 얻는다는 것을 배워야 한다는 것이다.

이러한 관점에서, 기존 연구의 실험들은 모델이 무엇을 배웠는지를 중요하게 고려하지 않았다. 사람의 입장에서는 그 원리가 결국 같다는 것을 알고있기 때문이다. 하지만, 모델의 입장에서는 각 "상황"에 대해서 개념을 이해하는 과정이 필요하다. 일대다 실험의 "일"은 바로 이 상황을 알려주는 것이다. 그리고 "다"는 알려준 상황에 대해서 여러가지 변형 문제를 내서, 모델이 얼마나 그 상황에서 사용되는 개념을 이해했는지를 측정하려는 것이다.

구체적으로 다음과 같이 샘플을 구분한다.

Setting

기존에 SVAMP와 UnbiasedMWP 라는 두 데이터셋은 모두 같은 상황에 대한 여러가지 질문들을 테스트셋으로 활용한다. 따라서, 이 split만 조금 변경하게 되면 쉽게 일대다 실험을 셋팅할 수 있다. 구체적으로 다음과 같이 split을 변경하는 셋팅을 진행하였다.

  1. 기존 테스트셋 문제들을 "상황"이 같은 문제들끼리 그룹으로 묶는다. 즉, 앞의 변형문제들은 모두 상황설명부분이 같고 질문만 다르기 때문에, 하나의 그룹이 되는 것이다.
  2. 각 그룹 당 한개의 문제를 랜덤으로 선택해서 training sample로 사용하고, 나머지 문제들은 테스트셋으로 사용한다.
  3. 랜덤에 대한 편차를 줄이기 위해 위 선택을 5개의 다른 랜덤시드를 통해 각각 만들어 낸다. 그리고 이렇게 만들어진 5개의 데이터셋에 대해서 각각의 성능을 측정하고 평균을 구한다.

여기에서 상황별로 그룹을 묶다보면 공통된 상황이 없는 문제들도 있다. 이 문제들은 validation set 으로 사용하였다.

이렇게 기존의 train/valid/test 변형 셋팅에서 test셋의 일부를 추가적인 train/valid 셋으로 사용한 것이다. 이와 같이 모델을 학습시키면, 모델은 확실히 그 "상황"에 대해서 배웠다. 라고 이야기할 수 있을 것이다. 그렇다면, 이렇게 배웠을 때 모델의 성능은 더 올랐을까?

Result

결론적으로 말하면, 기존 GTS, G2T등의 모델들은 이러한 배움에서 성능이 오르지 않았다. 오히려 훈련셋을 추가했는데 성능이 더 안좋아지기도 하였다. 반대로 ATHENA의 성능은 이 1의 배움으로부터 아주 큰 폭의 향상을 이룬다. 그 결과는 다음과 같다.

1을 배우지 않았을 때와 배웠을 때의 성능 변화

ATHENA의 절대적인 성능 자체도 최고 기록을 달성했지만, 그것보다 더 중요한 것은 바로 그 성능자체가 이 "1"을 배웠기 때문이라는 것이 드러난다. SVAMP를 기준으로 얘기하면, 원래 27.7을 기록했던 성능이 상황별 예제를 배우자 거의 2배에 가까이 성능이 증가하였다. UnbiasedMWP는 SVAMP보다 좀 더 복잡한 문제들로 구성되어 있는데, 기존 모델들이 1을 통해서도 거의 성능변화가 미미한 반면, ATHENA는 이러한 어려운 개념도 습득하여 유의미하게 성능 향상을 이룰 수 있었다.

또 한가지 소개하고 싶은 실험은 바로, 모델이 정말 개념을 배웠는지 아니면 shortcut을 습득했는지에 대한 측정이다.

이번에는 모델이 이 실험에서 "틀린" 문제들을 살펴보았다. 단순히, "틀린" 것에서 그치는 것이 아니라, 왜 그 문제를 틀렸는지를 찾아보려고 한 것이다.

만약 모델이 shortcut을 배워서 문제를 틀렸다면, 그 모델은 배운 샘플 그대로 식을 출력할 가능성이 높다. 예를 들어, 다음과 같은 훈련 샘플과 테스트 샘플이 있다고 하자.

훈련 샘플: 4개의 과일 바구니가 있고, 각 바구니 안에는 사과가 5개, 배가 3개씩 있다. 과일은 모두 몇개인가? 답: 4 × (5 + 3)

테스트 샘플: 4개의 과일 바구니가 있고, 각 바구니 안에는 사과가 5개, 배가 3개씩 있다. 사과는 모두 몇개인가? 답: 5 × 4

모델이 훈련샘플로 shortcut을 배웠다면, 테스트 문제에서도 4 × (5 + 3) 를 적어낼 가능성이 높다는 것이다.

틀린 문제들의 원인 분석

위 그래프에서 연한 부분이 바로 전체 틀린 문제들을 가리키고, 그 중 진한 부분이 바로 오답들 중에서 "1"의 정답을 그대로 대답한 정도를 나타낸다.

실제로 기존 모델들에 대해서 위와 같은 가설이 유의미하게 성립하고 있다는 것을 알 수 있다. 특히, ATHENA 이전에 SOTA성능을 기록한 DeductReasoner를 살펴보면, 오답 비율 자체는 기존 모델보다 적지만, 오히려 오답들 중 "1"의 답을 그대로 얘기한 정도는 오히려 더 높다. 다시 말해서, DeductReasoner는 비록 성능은 뛰어나지만, 쉽게 shortcut을 배우기도 한다는 것이다.

이 모델에 대해 참고로 조금 더 설명하자면, 이름에서도 보다시피 ATHENA처럼 연역적인 순서로 추론을 진행한 모델이다. 하지만 근본적으로 이 모델은 그 연역추론 자체를 특정 순서로 고정시킨 반면, ATHENA는 생각의 연상과 추론으로 나누어 진행했다는 점이 다르다. 이러한 측면에서, 앞에서 제시한 심리학적 개념 "연상"과 "추론"을 적용한 방법론이 실제 모델로서도 개념을 훨씬 습득하고자 하는 것으로 드러난다는 것을 보여주는 것이다.

다른 많은 실험들도 모두 ATHENA가 SOTA성능을 기록하였지만, 개인적으로 가장 유의미한 결과를 얻은 것은 바로 위의 실험들이라고 생각한다.

이 연구는 인간과 같은 추론능력을 모델로서 구현하기 위해 많은 cognitive, psychologic 이론들을 살펴보고 그 이론에 기반한 새로운 방식의 모델을 구현하였다.ㄷ 그리고 이렇게 생각을 확장하는 아키텍처가 정말로 "지식"을 습득하고, shortcut에 빠지지 않는 것을 보여주었다. 이렇게 나의 가설로부터 이러한 결론까지 이끌어내는데 수많은 과정과 노력을 거쳐서 이 결과를 이끌어낼 수 있었다. 이 연구에 도움을 주신 모든 분들에게 다시 한번 감사드리며, 마지막으로 다음 분석을 소개하며 이 포스팅을 마무리짓는다.

ATHENA는 정말로 사람처럼 생각하고 있을까?

이 연구를 통해 결국 "생각"을 임베딩하고, 그 생각을 합성해서, 최종적으로 목표에 도달하는 추론 과정을 수행하는 모델을 만들었다. 하지만, 그 "생각"은 정말로 우리의 "생각"대로 생각할까?

ATHENA의 생각은 숫자 벡터로 이루어져 있기 때문에 그 생각을 직접 알 수는 없다. 하지만, 문제와의 attention score 를 통해 그 생각을 간접적으로 들여다보고자 하였다.

이를 보여주기 위해 복잡하고 어려운 문제를 선정하였다. 특히, 모델의 실제 생각과정을 보여주기 위해, 훈련과정에 포함된 예제가 아니라, 실제 테스트에서 나온 추론 과정을 분석하였다.

여기서 한 가지 얘기하고 싶은 것은 이 문제 선정은 cherry-picking이 아니라는 점이다. 아니 정확히 말하면, 그러고 싶어도 그럴 수가 없었다. 왜냐하면, 아래 그래프는 제출 바로 전날에 생각하고 급하게 추출하고, 가공하여 만들었기 때문이다. 따라서 여러 문제들중 괜찮게 나왔는지를 따질 시간이 없었고, 그냥 기존에 논문에서 설명했던 예제를 그대로 사용했음을 여기서 밝힌다.

문제의 내용은 다음과 같다.

  • 어떤 학교에 길이가 80 미터, 너비가 40미터인 운동장이 있다. 나중에 이 학교가 리모델링을 통하여 운동장의 길이가 10미터, 너비 15미터 증가하였다. 현재 운동장의 넓이는 원래의 운동장의 넓이에 비교하면 몇 제곱미터나 증가하였는가?

우리는 이 문제를 다음과 같이 풀 것이다.

  • 원래 운동장의 넓이는 길이와 너비를 곱한, 80 × 40 이다.
  • 나중 운동장의 길이는 증가분을 더하면 80 + 10, 너비는 40 + 15이다.
  • 따라서 나중 운동장의 (80 + 10) × (40 + 15) 의 넓이가 된다.
  • 따라서 운동장은 나중 운동장에서 원래 운동장의 넓이를 빼면, ((80 + 10) × (40 + 15)) - (80 × 40) 만큼 증가하였다.

ATHENA는 이런 생각을 했을까?

ATHENA는 의 생각

위 그림의 왼쪽부분은 최초의 생각 (inital thoughts) 이고, 오른쪽 부분은 정답을 찾기 위해 확장한 생각들이다.

먼저 최초의 생각들을 보면, 1015를 나타내는 생각들이 특히 "나중에" 라는 단어에 높은 어텐션을 보였다. 특히, 10과는 다르게 15는 "너비" 라는 단어에 대한 분포차이가 있다.

즉, 문제로부터 생각들이 꽤 잘 구분되어 추출된 것을 확인할 수 있다. 다시 말하면, [MASK] 를 통한 추출이 꽤 합리적으로 동작하고 있다는 것이다.

그렇다면, 여기에서 실제 모델이 생각을 잘 할까? 먼저 눈여겨볼 점은, 오직 40 + 15 만 "너비"라는 단어에 어텐션을 보이고 있다는 것이다. 이 값은 나중 운동장의 너비값이라는 의미를 잘 지니고 있다는 것을 알 수 있다.

여기서 놀랐던 것은, 넓이를 나타내는 생각들이 모두 "제곱미터" 라는 의미를 연결짓고 있다는 것이다. 이는 앞에서 길이와 너비를 표현한 생각 80 + 1040 + 15에서는 "제곱미터"에 대해 낮은 어텐션을 보였던것과 명확하게 대비된다.

더 놀라운 것은 최종 생각에서 "비교하면" 단어와의 어텐션 점수이다. 뺄셈을 하면서 이 "비교하면" 이라는 의미가 그 이전의 생각들보다 훨씬 강화되었다. 즉, 최종적으로 얻은 답은 이 "비교하면"과 "제곱미터" 의 의미를 지니고 있는 어떤 생각이라는 것이다. 앞의 생각들과 어텐션의 분포가 많이 차이나는 것이 보이는가?

확실히, 연상을 통해서 ATHENA는 기존과 차별화된 생각을 만들어냈고, 그 생각의 의미는 가설을 세웠을 때 의도한 그대로 어느정도 담고있는 것이 보여진다.

다시 강조할 점은, 이 것이 실제 테스트과정에서의 임베딩을 분석했다는 점, 그리고 어떠한 cherry-picking도 수행하지 않고 무작위의 샘플에 대한 결과물이라는 점이다. 제출 전날 급하게 이 아이디어를 떠올려 한번 결과를 살펴봤는데, 생각보다 훨씬 결과가 의미있게 뽑혀서 정말 놀랐던 실험이었다.

물론 이 어텐션 결과를 볼 때 주의해야할 점은 이 것이 단지 하나의 샘플이라는 점, 그리고 UnbiasedMWP는 중국어 데이터셋이기 때문에 토큰들이 영어단어와 완전히 1:1로 대응하지는 않는다는 점이다. 하지만 이 결과는 번역기를 돌리고, 각 중국어 글자들의 의미를 찾아보며 최대한 문제와의 연결성을 그대로 전달하고자 하였다.