Fractale-350M-base: 긴 컨텍스트 대신 학습된 행동으로서의 메모리, 완전 오픈 소스 연구 공개
Fractale-350M-base: memory as trained behaviour instead of long context, a fully open research release
핵심 요약
긴 컨텍스트 대신 8개의 벡터를 통해 메모리를 관리하는 350M 파라미터 기반 모델 Fractale-350M-base가 공개되었습니다.
- 메모리 구조 — 512 토큰마다 8개의 벡터를 생성하여 가중치로 활용하는 방식임
- 학습 방식 — 10B 토큰으로 사전 학습되었으며 긴 컨텍스트 대신 메모리 의존성을 강화함
- 연구 공개 — 모델 가중치, 학습 로그, 재현 스크립트가 모두 오픈 소스로 제공됨
- 향후 계획 — 메모리 활용 능력을 극대화하기 위한 SFT 및 RL 학습을 진행할 예정임
이거 연구 프로젝트 관련해서 예전에 올렸던 글 기억하는 사람 있을 거다. fast-weight memory를 학습시키는 내용이었고, 논문이랑 전체 연구 로그는 github.com/kkuette/thought-bank에 다 있다. 이번엔 그 후속작이다. 시리즈의 첫 번째 공개 모델이 나왔다.
간단히 상황 설명하자면, 나 혼자 연구하고 있고 97M 파라미터 이하 모델들은 전부 RTX 3090 한 대로 돌렸다. 구현이나 글 쓰는 건 Claude랑 같이 작업했는데, 방향 잡고 판단하는 건 전부 내 몫이다.
이게 뭐냐면. Fractale-350M-base는 386M 파라미터짜리 베이스 모델이다. 10B 토큰(코드 + 영어 웹 데이터)으로 밑바닥부터 사전 학습시켰는데, 핵심 아이디어는 딱 하나다. 모델의 유일한 장기 기억 장치가 자기 자신에게 기록하는 8개의 벡터라는 거다. 512 토큰 단위로 요약(gist) 벡터를 하나씩 만들고, 가장 오래된 건 FIFO 방식으로 밀어낸다. 이 저장소는 fast weights로 다시 읽히는데, 각 슬롯이 하이퍼넷을 거쳐서 토큰 스트림이 통과하는 작은 low-rank MLP로 확장되는 구조다. 검색(retrieval)도 아니고, 저장된 텍스트에 어텐션을 거는 것도 아니다. 기억 자체가 포워드 패스의 일부가 되는 셈이다.
컨텍스트 윈도우는 일부러 아주 작게(512 토큰 단위) 잡았다. 각 단위가 별개의 포워드 패스라서, 현재 단위보다 이전의 정보는 오직 그 8개의 벡터를 통해서만 예측에 반영될 수 있다. 사전 학습 목표 자체가 이 저장소를 중요하게 만들도록 설계됐다. 문서의 다음번, 한 번도 본 적 없는 단위를 오직 저장소 정보만 가지고(입력값 없음) 예측해야 하니까.
측정 가능한 것들. GAP = CE(저장소 초기화) - CE(저장소 유지)를 검증용 문서에서 계산해 봤다. 최종 체크포인트에서 코드 데이터는 +9.4 nats(초기화 시 CE 12.9 vs 유지 시 3.45), 웹 데이터는 +7.3 nats가 나왔다. 2개에서 8개 단위까지 기록했을 때 성능 저하(FIFO 절벽 현상) 없이 일정하게 유지됐다. 학습이 진행될수록 격차는 양쪽에서 벌어졌는데, 저장소만 쓰는 쪽은 계속 날카로워진 반면 저장소 안 쓰는 쪽은 성능이 떨어졌다. 즉, 학습이 진행될수록 모델이 자기 기억에 더 의존하게 됐다는 뜻이다. 더 작은 규모에서 정밀하게 테스트해 봐도, 내용은 큐(cue)로 호출 가능하고 2000 스텝 이상 지나도 기억이 살아있으며, docstring을 코드로 양방향 전송하는 것도 가능하다. 논문(3M 규모 메커니즘, Zenodo에 DOI 있음)을 보면, 13개 토큰만 보여줘도 학습한 적 없는 규칙을 0.79~1.00 정확도로 수행한다. 반면 테스트 타임 학습은 자기 예제에만 끼워 맞추느라 아무것도 전송 못 하면서 비용은 138배나 더 든다.
이게 아닌 것들. 이건 베이스 모델이지 챗봇이 아니다. 인스트럭션 튜닝도 안 했고, 얼라인먼트도 안 했다. 10B 토큰으로 학습한 386M 모델이니 딱 그 정도의 유창함만 기대해라. 저장소는 요약(gist) 정보(도메인, 말투, 구조, 언급된 사실 등)를 담는 거지, 텍스트를 그대로 외우는 게 아니다. 3번째 줄 인용해 보라고 하면 못 한다. 그리고 GAP은 모델을 기억 장치 없이 돌렸을 때와 비교한 거지, 같은 연산량의 어텐션 모델이랑 비교한 게 아니다. 그 '스틸맨(steelman)' 모델(예전에 언급했던 gated-DeltaNet)은 연구 저장소에 올려뒀다.
재밌는 점: 기억 장치가 내 손에 쥐고 있는 상태값이라는 거다.
from fractale import BankSession
sess = BankSession.from_pretrained("fractale-lm/Fractale-350M-base")
sess.read(open("long_doc.txt").read()) # any length, no growing prompt
print(sess.continuation(32)) # predicted from the 8 notes ALONE
print(sess.continuation(32, use_bank=False)) # amnesic control: the difference IS the memory
sess.save_bank("doc.bank") # a few kB; restore tomorrow, or transplant into another session

