트랜스포머는 '기억 저장소'에서 처음부터 만들어 낼 수 있었다
You could have invented transformers from memory
TL;DR Highlight
선형층→MLP→self-attention을 기억 저장소로 보면 용량이 64→약 2,700→100만 이상
Who Should Read
트랜스포머가 왜 이런 구조인지 직관이 없어 MLP와 attention의 역할이 궁금한 LLM API 개발자
Core Mechanics
- 모든 층은 기억 저장소다
- 기억 하나는 키(조회용 벡터)와 값(꺼낼 벡터) 한 쌍이다.
- 키와 비슷한 입력을 넣으면 값이 나오는 구조를 연상 기억(associative memory)이라 부른다.
- 선형층은 외적을 더해 저장한다
- 새 기억 (k, v)를 넣을 때 가중치에 v·kᵀ를 더하면 된다.
- 조회는 모든 키와 유사도를 구해 값을 가중합하는 방식이다.
- 간섭이 커지면 기억이 묻힌다
- 조회 결과는 원하는 값(신호)에 다른 기억의 값(간섭)이 섞여 나온다.
- 간섭 대 신호 비율이 1이 될 때의 기억 개수가 용량(capacity)이다.
- 선형 저장소 용량은 키 차원만큼이다
- 키가 무작위 단위 벡터면 간섭/신호 비율이 대략 √(M/d_k)다.
- 그래서 용량은 M≈d_k이고, 직교 방향이 d_k개뿐이라 그 이상은 완벽 회상이 불가능하다.
- 선형에서 attention으로 갈수록 용량이 커진다
- 키 64차원 기준으로 약 64개에서 약 2,700개, 그리고 100만 개 이상으로 늘어난다.
- MLP는 비선형 저장소로, self-attention은 비파라메트릭 저장소로 설명된다.
Community Reactions
- 수학 표기가 장벽이라는 의견
- 선형대수를 전혀 몰라 읽기 어렵다는 독자와 수식 표기 설명이 없어 소외감을 느꼈다는 독자가 있었다.
- 읽고 나서도 트랜스포머를 직접 만들 수는 없겠다는 반응도 있었다.
- 데이터 구조를 빼서 상한선일 뿐이라는 의견
- 글은 키가 무작위라고 가정하는데 실제 데이터에는 구조가 많아 압축 여지가 크다는 지적이 있었다.
- 그래서 결론은 실제 추정치가 아니라 상·하한이며, 진짜 힘은 구조와의 상호작용에서 나온다는 의견이다.
- LLM에서 값이 무엇인지 모르겠다는 질문
- 글이 기억에서 LLM으로 이어지는 마지막 연결에서 막혔다는 독자가 있었다.
- 컨텍스트 토큰이 키라면 값은 무엇인지 묻는 질문이다.
- 저자가 요약 스레드를 공유했다는 정보
- 저자가 직접 댓글로 X(트위터) 요약 글 링크를 올렸다.
- 트랜스포머가 홉필드 네트워크처럼 한 스텝에 적절한 기억을 찾는다는 점을 좋아한다는 댓글도 있었다.
How to Apply
- 간섭 비율을 직접 시뮬레이션해 보기
- 오늘 30분 안에 무작위 단위 벡터 키 M개로 외적 저장소를 만들어 보자.
- M을 d_k=64 전후로 바꾸며 √(M/d_k)와 실제 회상 오차가 맞는지 확인하라.
- RAG 임베딩 차원과 문서 수 관계를 점검하기
- 임베딩 차원에 비해 청크 수가 매우 많은 인덱스에서 엉뚱한 문서가 섞여 나오는지 확인하라.
- 이 글의 간섭 개념으로 오검색 원인을 가설로 세우고 검색 로그와 대조하라.
- 팀 스터디에서 기억 저장소 관점으로 설명하기
- 선형층, MLP, attention을 키-값 조회 하나의 틀로 그려 팀에 공유하라.
- 글의 인터랙티브 앱과 코드를 함께 열어 M을 움직이며 보여 줘라.
Try It
# Python에서 바로 실행: 간이 버전(원문 코드가 아니라 글의 수식을 직접 옮긴 시뮬레이션)
# pip install numpy
import numpy as np
d = 64
rng = np.random.default_rng(0)
for M in [8, 32, 64, 256, 1024]:
K = rng.normal(size=(M, d))
K /= np.linalg.norm(K, axis=1, keepdims=True)
V = rng.normal(size=(M, d))
V /= np.linalg.norm(V, axis=1, keepdims=True)
W = V.T @ K
out = W @ K[0]
interference = np.linalg.norm(out - V[0])
print(M, 'interference/signal =', round(interference, 2), 'vs sqrt(M/d) =', round((M / d) ** 0.5, 2))
# 이어서 해 볼 것: 키를 서로 직교하게 만들고(M<=d) 간섭이 0에 가까워지는지 확인해 보자.Terminology
관련 논문
400년치 고문서에 AI를 돌렸더니 잊힌 운석·코뿔소·화산 폭발이 나왔다
임베딩 검색과 싼 필터 모델로 400년 고문서를 뒤져 미기록 사건 발굴
EmbeddingGemma 2: 텍스트·이미지·오디오·비디오를 한 벡터 공간에 넣는 오픈 경량 임베딩 모델
740M 오픈 모델 하나로 텍스트·이미지·오디오·비디오를 같은 벡터 공간에서 검색
RAG-NAROK: 출처를 직접 반박하는 문서로 RAG 지식베이스를 오염시키는 공격
검색된 출처를 겨냥해 반박문을 심었더니 1위 검색과 탐지 회피가 높아졌다
텍스트냐 이미지냐 둘 다냐: 멀티모달 문서 QA 입력 방식 비교
문서 QA에서 페이지 이미지가 정확도는 높지만 느려서, 질문별 라우터로 지연 30% 줄였다
MS 임원이 AI 스크래핑을 '인류 역사상 최대의 노동 도둑질'이라 불렀다는 NYT 소송 공개 문서
NYT 소송 공개 문서에서 MS·OpenAI 내부의 스크래핑 인식이 드러났다
임베딩의 보편적 기하 구조 활용: 짝 데이터 없이 임베딩 공간 간 변환
짝 데이터 없이 임베딩을 다른 모델 공간으로 옮겼고, 벡터 DB 보안 위험이 드러났다
Better Together: 강한 RAG 베이스라인 위에서 쿼리 리라이팅 조합하기
쿼리 리라이팅을 합치고 점수 낮을 때만 돌렸더니 비용 40%로 효과 절반