컨텍스트 길이를 늘리기 어려운 이유
더 긴 컨텍스트 윈도는 그저 돌리면 되는 손잡이처럼 들립니다. 그 아래에서는 텍스트보다 빠르게 커지는 비용과, 얇게 퍼지는 어텐션과 싸웁니다.
**컨텍스트 윈도(context window)**는 언어 모델이 한 번에 받아들일 수 있는 텍스트의 양입니다. 프롬프트, 문서들, 지금까지의 대화 같은 것이죠. 클수록 좋은 것은 당연합니다. 공간이 넓을수록 보고서 한 편, 긴 코드베이스, 혹은 대화 이력 전체를 빠뜨림 없이 모델에 넣을 수 있으니까요. 그러면 왜 모든 모델의 윈도를 그냥 거대하게 만들지 않을까요? 내부를 들여다보면 길이는 공짜 매개변수가 아니기 때문입니다. 길이는 이 모델들을 작동하게 만드는 바로 그 메커니즘과 싸우며, 그 비용은 텍스트보다 빠르게 커집니다. 이 글은 컨텍스트를 늘리는 것이 단지 메모리를 더 할당하는 문제가 아니라 진정으로 왜 어려운지에 관한 것입니다.
사실 두 개의 문제가 포개져 있습니다. 비용의 문제와 품질의 문제죠. 둘 다 풀려야 하고, 둘은 서로 다른 방향으로 잡아당깁니다.
길이를 비싸게 만드는 메커니즘
대부분의 현대 언어 모델은 어텐션(attention) 위에 세워집니다. 각 토큰이 다른 토큰들을 살펴 무엇이 관련 있는지 알아내게 하는 메커니즘이죠. 어텐션은 이 모델들에 힘을 주는 바로 그것입니다. 입력의 모든 조각이, 원칙적으로 다른 모든 조각과 관계 맺을 수 있습니다.
그 구절, 즉 모든 조각이 다른 모든 조각과, 가 또한 문제의 근원입니다. 표준 형태의 어텐션에서 작업량은 토큰 쌍의 개수에 비례해 커집니다. 입력 길이를 두 배로 하면 작업이 두 배가 되는 게 아니라 대략 네 배가 됩니다. 쌍의 개수가 길이의 제곱으로 커지기 때문이죠. 이것이 그 유명한 어텐션의 이차(quadratic) 비용이며, 긴 컨텍스트가 비싼 핵심 이유입니다.
직관은 단순합니다. N개의 사물이 있고 각각이 다른 모든 것을 고려해야 한다면, 계산할 관계가 N 곱하기 N 차수만큼 있습니다. N을 열 배로 키우면 관계는 백 배로 커집니다. 열 배 긴 윈도는 처리하는 데 열 배보다 훨씬 더 큰 비용이 들 수 있습니다. 어텐션에서 길이는 선형 비용이 아닙니다.
연산 문제 위에 얹힌 메모리 문제
비용은 연산만의 문제가 아닙니다. 메모리의 문제이기도 합니다. 텍스트를 효율적으로 처리하고, 특히 생성하기 위해, 모델은 이미 본 토큰들의 중간 표현을 붙들어 둡니다. 흔히 **키-밸류 캐시(key-value cache)**라 불리는 진행 중인 저장소죠. 이 캐시 덕분에 모델은 새 토큰마다 모든 것을 처음부터 다시 계산하지 않아도 됩니다.
문제는 이 저장소가 컨텍스트 길이에 따라 커진다는 것입니다. 윈도가 길수록 모델이 빠른 메모리에 한꺼번에 붙들고 있어야 할 양이 늘어납니다. 매우 긴 컨텍스트에서는 이 메모리 사용량이 구속 제약이 될 수 있습니다. 연산에 대한 인내심이 바닥나기 전에 컨텍스트를 담을 공간이 먼저 바닥나는 것이죠. 그래서 긴 컨텍스트는 두 가지 희소한 자원을 동시에 압박합니다. 모든 것을 관계 맺을 연산과, 모든 것을 담을 메모리를요. 긴 컨텍스트 시스템을 설계하는 일은 대체로 두 전선 모두에서 벌이는 싸움입니다.
더 조용한 문제: 어텐션이 얇게 퍼진다
비용을 치르고 윈도를 거대하게 만들었다고 합시다. 두 번째의 더 미묘한 문제가 나타나는데, 비용이 아니라 품질에 관한 것입니다. 어텐션은 입력에 걸쳐 초점을 분배함으로써 작동합니다. 주의를 둘 것이 몇 개뿐일 때는 초점이 집중됩니다. 아주 많을 때는 그 초점이 전부에 걸쳐 퍼져야 하고, 정말로 관련 있는 조각들이 무관한 것들의 바다 속에 희석될 수 있습니다.
그래서 긴 컨텍스트는 정작 중요한 그 하나의 세부를 모델이 찾아 쓰는 일을 더 어렵게 만들 수 있습니다. 그 세부가 엄밀히는 거기 있는데도요. 정보는 윈도 안에 있지만, 윈도 안의 다른 모든 것과 어텐션을 두고 경쟁합니다. 건초 더미가 커진다고 바늘을 찾기 쉬워지지는 않습니다. 오히려 묻어 버릴 수 있죠.
이것이 매우 긴 윈도를 가진 모델이 그 윈도를 자동으로 잘 쓰지는 못하는 이유입니다. 긴 입력을 담아낼 수 있는 것과 그것을 효과적으로 추론해 낼 수 있는 것 사이에는 실제 차이가 있습니다. 전자는 용량에 관한 것이고, 후자는 고려할 것이 그토록 많을 때 어텐션이 여전히 중요한 것을 골라낼 수 있는지에 관한 것입니다.
중간에서 길을 잃다
이 품질 문제의 특히 잘 알려진 형태는, 정보가 긴 컨텍스트의 어디에 자리하느냐에 따라 모델이 그것을 고르지 않게 쓰는 경향입니다. 긴 입력의 처음과 끝 근처의 자료는 가운데 묻힌 자료보다 더 미덥게 쓰이는 경우가 많습니다. 결정적인 사실을 긴 문서의 한가운데 두면, 모델은 그것을 읽고도 사실상 간과할 수 있습니다.
이 패턴, 때로 모델이 컨텍스트의 중간에서 더 약하다고 묘사되는 이 패턴은, 긴 윈도가 균일하고 완벽한 기억이 아님을 일깨워 줍니다. 그것은 강점과 약점의 고유한 지형을 지닌 어텐션의 폭입니다. 이를 아는 것은 긴 컨텍스트를 쓰는 방식을 바꿉니다. 모든 위치가 동등하다고 가정하는 대신, 가장 중요한 자료를 모델이 가장 잘 주의를 두는 곳에 배치하는 것은 그 바탕 동작에서 곧바로 따라 나오는 실용적 지렛대입니다.
왜 그냥 더 긴 텍스트로 훈련할 수는 없는가
해결책은 그냥 모델을 매우 긴 예시로 다룰 줄 알게 될 때까지 훈련하는 것이라고 생각할지도 모릅니다. 도움이 되지만 공짜로 오지는 않습니다. 긴 시퀀스로 훈련하는 것은 같은 이차 비용을 물려받으므로, 긴 컨텍스트를 쓰는 것이 비싼 바로 그 방식으로 비쌉니다. 그리고 주로 짧은 텍스트로 훈련된 모델은, 훈련에서 본 그 무엇보다 훨씬 긴 입력을 갑자기 보면 우아하게 일반화하지 못할 수 있습니다. 위치와 관련성에 대한 감각이 익숙한 길이를 넘어서면 저하될 수 있죠. 따라서 컨텍스트를 늘리는 것은 켜는 스위치가 아닙니다. 훈련과 서빙 양쪽에서 의도적으로 구축하고 값을 치러야 하는 속성입니다.
이 분야가 한계를 밀어붙이는 방법
장애물이 실재하기에, 긴 컨텍스트에 관한 작업의 상당 부분은 이를 힘으로 밀어붙이기보다 규칙을 바꾸는 것입니다. 그 방향들은 수식 없이도 직관적입니다.
- 더 저렴한 어텐션. 큰 연구 노력은 모든 쌍을 다 계산하는 것을 피함으로써, 어텐션을 근사해 그 비용이 길이에 따라 이차가 아니라 선형에 가깝게 커지도록 하는 것을 목표로 합니다. 약간의 정확성을 내주고 많은 확장성을 얻는 것이 되풀이되는 주제입니다.
- 메모리 사용량 줄이기. 키-밸류 캐시를 압축하거나 아끼는 기법은 같은 메모리에 더 긴 컨텍스트가 들어가게 해, 문제의 메모리 측면을 공략합니다.
- 모든 것을 담는 대신 검색하기. 말뭉치 전체를 윈도에 욱여넣는 대신, 관련 있는 조각만 가져와 넣습니다. 실제 컨텍스트를 작게 유지함으로써 길이 문제를 비껴가는 것이죠. 검색 증강(retrieval-augmented) 접근의 바탕 전략입니다.
각 길은 거래를 합니다. 더 저렴한 어텐션은 약간의 정밀도를 포기하고, 압축은 약간의 충실도를 포기하며, 검색은 모든 것이 한꺼번에 존재한다는 보장을 포기합니다. 공짜 점심은 없고, 서로 다른 흥정만 있습니다.
정리
컨텍스트 길이를 늘리기 어려운 이유는, 이 모델들 뒤의 지배적 메커니즘인 어텐션이 입력의 제곱에 따라 커지는 작업 비용을 치르는 한편, 효율적으로 돌리는 데 필요한 키-밸류 캐시도 길이에 따라 커지기 때문입니다. 그래서 더 긴 윈도는 텍스트가 커지는 것보다 빠르게 연산과 메모리 모두를 압박합니다. 그리고 그 값을 치르더라도, 더 긴 컨텍스트는 어텐션을 더 얇게 퍼뜨리고 중간을 덜 미덥게 쓰므로, 더 많은 텍스트를 담는 것과 그것을 잘 추론하는 것은 같지 않습니다. 최전선은 흥정을 바꿈으로써 나아갑니다. 더 저렴한 어텐션, 더 날렵한 메모리, 혹은 중요한 것만 검색하기. 각각이 도달 범위를 위해 무언가를 내줍니다. 더 큰 윈도는 결코 그저 더 큰 숫자가 아닙니다. 복리로 불어나는 비용과의 싸움입니다.
