7주차: 장문맥 처리와 효율적 추론
장문맥 처리와 효율적 추론
□ 이 주차가 놓이는 자리
- 6주차에서 사진 1장이 832토큰이 되어 입력의 95%를 차지했다. 문맥은 공짜가 아니다. 이번 주는 문맥이 길어질 때 무엇이 비싸지고 무엇이 깨지는가를 본다
- 핵심 질문은 둘이다
- 긴 문맥을 어떻게 여는가: 어텐션 비용을 줄이고, 학습 때보다 긴 위치를 다루는 방법 (위치 인코딩 확장, 어텐션 근사, 캐시)
- 열린 문맥을 모델이 실제로 쓰는가: 긴 입력의 가운데에 놓인 정보가 잘 쓰이지 않는 현상 (Lost in the Middle)
- 비용 쪽에서는 추론의 두 단계(프리필과 디코딩)와 KV 캐시를 숫자로 계산한다. 1주차의 제곱 비용과 KV 캐시, 2주차의 FlashAttention과 슬라이딩 윈도 어텐션이 여기서 다시 만난다
- 7주차는 중간고사 앞 주다. 대면 시간에는 1~7주차 개념 위계를 함께 다시 그린다
□ 이번 주가 답하는 질문
- 문맥이 2배가 되면 시간과 메모리는 각각 몇 배가 되는가 (어텐션 n², KV 캐시 n, 프리필과 디코딩)
- 긴 문맥을 감당하게 하는 방법은 어떤 갈래가 있고, 각각 무엇을 줄이는가
- 학습 때보다 긴 위치를 넣으면 왜 무너지고, 위치 보간은 그것을 어떻게 피하는가 (RoPE)
- 긴 입력의 가운데 정보는 왜 덜 쓰이는가, 질문을 앞에 두면 해결되는가 (Lost in the Middle)
- 바늘 찾기 점수가 높으면 긴 문서를 이해한다고 말할 수 있는가
- 갱신이 잦은 공공 문서에는 검색 결합과 초장문맥 중 무엇이 맞는가
□ 읽기 안내 - 이 노트의 어디와 이어지나
| 읽기 | 이 노트에서 다루는 곳 |
|---|---|
| FoLM (Xiao & Zhu, arXiv:2501.09223) 2.3 Long Sequence Modeling | 긴 문맥을 여는 다섯 갈래, RoPE, 위치 보간, 장문맥 평가 |
| FoLM 5.1 Prefilling and Decoding | 추론의 두 단계, 첫 토큰까지 시간과 토큰 간 지연 |
| Lost in the Middle (Liu 외, 2023, arXiv:2307.03172) | U자 곡선, 질문 위치, 검색 문서 수와 성능 포화 |
□ 문서와 실측에 대하여
- 실습 문서는 위키백과 「제주특별자치도」의 2026-09-11 판(판 번호 42464087) 본문이다. 판 번호를 고정했으므로 누가 실행해도 본문은 사실상 같은 글이다(위키백과의 틀이 바뀌면 글자 수가 조금 달라질 수 있다. CC BY-SA 4.0). 출처는 이 문서 아래 [문서 출처] 표에 있다
- 문서에 끼워 넣는 안내센터 출입 번호 문장은 실험용으로 지어낸 것이다. 실제 기관이나 번호가 아니다
- 본문의 숫자는 기존 노트북을 실행한 과거 기록이다. 번호 찾기 표·그림은 substring 번호 포함률 프록시이며, 이번에 추가한 strict 번호 일치 지표의 재측정값은 아님. 모델은 Qwen/Qwen3-0.6B-Base(fp32, CPU)다. 회수 결과는 탐욕 디코딩이라 같은 환경에서는 같게 나오지만, 시간은 실행 환경마다 다르다. 시간은 절대값보다 길이에 따라 늘어나는 모양으로 읽는다
- 도내 기업 데이터는 없다. 기업과 기관은 학습활동 [실무]에서 조건 상정으로만 등장한다
온라인 (2시수)
Section titled “온라인 (2시수)”강의: 긴 문맥을 여는 방법과 그 한계
Section titled “강의: 긴 문맥을 여는 방법과 그 한계”□ 읽기 준비 - 토큰으로 잰 문서 길이
- 문맥 길이는 글자 수가 아니라 토큰 수로 잰다. 한국어는 영어보다 같은 내용에 토큰이 더 든다
- 이번 실습 문서(위키백과 「제주특별자치도」 본문)는 10,556자이고, 실습 모델의 토크나이저로 7,884토큰이다. 토큰 하나에 평균 1.34자다
- 실습 모델의 최대 위치(max_position_embeddings)는 32,768이다. 이 문서를 네 번쯤 이어 붙이면 닿는 길이다
- 이번 주의 모든 숫자는 “토큰 n개”를 기준으로 읽는다
□ 긴 문맥이 비싼 이유 - 계산과 메모리
○ 계산: 어텐션 점수표는 n x n
- 1주차에서 본 대로 모든 토큰이 모든 토큰을 쳐다보면 점수표가 n x n 칸이 된다. 입력이 2배면 이 표는 4배다
- 모델 전체의 계산에는 길이에 정비례하는 부분(토큰마다 지나가는 피드포워드 층 등)도 있다. 그래서 입력이 짧을 때는 제곱 항의 몫이 작고, 입력이 길어질수록 커진다. 뒤의 실측에서 이 모양을 확인한다
○ 메모리: KV 캐시는 n에 정비례
- 한 토큰씩 생성할 때 앞 토큰들의 Key와 Value를 다시 계산하지 않으려고 층마다 저장해 둔다. 이것이 KV 캐시다(1주차의 “Key·Value 메모장”)
- 크기는 설정값만으로 정확히 계산된다. FoLM 2.3.4는 이 공간 복잡도를 O(층 수 x 헤드 수 x 헤드 차원 x 토큰 수)로 적는다
KV 캐시 = 2 (K와 V) x 층 수 x KV 헤드 수 x 헤드 차원 x 바이트 x 토큰 수
Qwen3-0.6B-Base, bf16(2바이트)토큰당 2 x 28 x 8 x 128 x 2 = 114,688바이트 = 112 KiB32,768토큰 112 KiB x 32,768 = 3.5 GiB가중치 596,049,920개 x 2바이트 = 약 1.11 GiB- 약 10,400토큰(노트북 1-3 출력 10,394)이면 KV 캐시가 가중치 크기와 같아지고, 최대 위치 32,768토큰이면 가중치의 3.15배다. 긴 문맥에서는 모델보다 캐시가 메모리를 더 먹는다. 동시에 여러 요청을 받으면 요청 수만큼 곱해진다
- 이 모델은 쿼리 헤드 16개가 KV 헤드 8개를 2개씩 나눠 쓴다(GQA, grouped-query attention). KV 헤드를 쿼리 헤드만큼 16개 두었다면(MHA) 캐시가 정확히 2배였다. 헤드를 나눠 쓰는 것 자체가 장문맥 비용을 줄이는 장치다
문맥 길이와 동시 요청 수를 바꿔 보세요. 모델 설정은 실습 모델 Qwen3-0.6B-Base의 실제 값이다.
○ 추론의 두 단계 - 프리필과 디코딩
- FoLM 5.1은 추론을 두 단계로 나눈다(표 5.1)
| 프리필 (prefilling) | 디코딩 (decoding) | |
|---|---|---|
| 토큰 처리 | 입력 토큰을 한 번에 | 출력 토큰을 하나씩 차례로 |
| 하는 일 | 입력을 읽어 KV 캐시를 만든다 | 캐시를 읽어 다음 토큰을 만든다 |
| 병목 | 계산 (compute-bound) | 메모리 읽기 (memory-bound) |
| 계산 비용 | 높다 | 매우 높다 |
- 표의 “매우 높다”는 답 전체를 만드는 비용이다. 디코딩은 출력 토큰 수만큼 단계를 되풀이하고, 생성할수록 캐시가 길어져 비용이 크게 는다. FoLM은 대부분의 경우 디코딩이 프리필보다 계산 비용이 크다고 쓴다. 여러 후보 문장을 함께 펼치는 디코딩 방법을 쓰면 더 커진다
- 왜 병목이 다른가. 프리필은 토큰 수천 개를 행렬 하나로 묶어 계산하므로 연산 장치가 바쁘다. 디코딩은 매 단계 토큰 하나를 위해 가중치 전체와 KV 캐시 전체를 메모리에서 읽어 와야 하므로, 계산보다 읽기를 기다리는 시간이 길다
- 서비스 지표도 이 둘에 대응한다(FoLM 5.1.4)
- 첫 토큰까지 시간(TTFT, time to first token): 대부분 프리필 시간이다. 문맥이 길수록 길어진다
- 토큰 간 지연(ITL, inter-token latency): 디코딩 한 단계의 시간이다. 캐시가 길수록 읽을 것이 늘어난다
○ 실측 - 입력 길이와 프리필 시간
- 실습 노트북 1-5에서 위키백과 문서 앞부분을 길이별로 잘라 프리필 시간을 쟀다(작성 환경 CPU, fp32, 1회 측정).
generate처럼 마지막 자리에서만 다음 토큰의 확률을 계산하게 했다
| 입력 길이 | 프리필 시간 | 앞 길이 대비 |
|---|---|---|
| 250토큰 | 0.24초 | |
| 500토큰 | 0.41초 | 1.7배 |
| 1,000토큰 | 0.82초 | 2.0배 |
| 2,000토큰 | 1.66초 | 2.0배 |
- 입력이 2배가 될 때 시간은 1.7배, 2.0배, 2.0배로 늘었다. 짧은 입력에서는 길이와 상관없는 고정 비용 때문에 2배보다 적게 늘고, 1,000토큰부터는 거의 길이에 정비례했다. 이 크기의 모델에서 2,000토큰까지는 피드포워드 같은 정비례 부분이 계산의 대부분이고 n² 항은 아직 작다
- 더 긴 입력은 뒤의 회수율 측정(노트북 2에서 TODO 길이를 늘린 실행)에서 보인다. 노트북은 길이마다 질문 10건(깊이 다섯 곳 x 안내센터 둘)에 걸린 시간을 합해 한 줄에 찍는다. 그것을 10으로 나눈 질문 한 건의 시간(프리필에 답 최대 6토큰 생성을 더한 것)이 입력 2,272토큰 2.2초, 4,257토큰 4.9초, 7,276토큰 9.4초였다. 2,000토큰을 넘어서자 길이보다 시간이 빠르게 늘었다(길이 1.9배에 시간 2.2배, 다시 길이 1.7배에 시간 1.9배). n² 항의 몫이 커지는 것과 맞는 모양이다. 이 시간에 든 디코딩은 첫 토큰을 프리필이 내므로 이후 최대 5토큰 x 약 0.039초(아래 2,000토큰 측정) = 0.2초 안팎이다. 다만 한 번 실행한 값이고 행 합계를 초 단위로 반올림했으므로 잡음이 섞여 있다
- 2,000토큰을 읽은 뒤 1토큰만 생성하는 데(첫 토큰까지 시간) 1.62초, 20토큰을 생성하는 데 2.37초가 걸렸다. 그 차이를 19로 나누면 이후 토큰당 약 0.039초다. 첫 토큰까지 시간이 프리필 시간(1.66초)과 거의 같다는 것도 확인된다. 이 측정처럼 입력이 길고 답이 짧으면 기다리는 시간의 대부분은 입력을 읽는 시간이다. 답이 수백 토큰으로 길어지면 디코딩 몫이 커진다
- CPU 한 번의 측정이라 절대값은 환경마다 다르다. GPU에서는 프리필이 훨씬 빨라 디코딩 쪽 비중이 커질 수 있다. 절대값보다 길이에 따라 늘어나는 모양을 읽는다
□ 긴 문맥을 여는 다섯 갈래 - FoLM 2.3
- FoLM 2.3(Long Sequence Modeling)은 긴 입력을 다루는 방법을 다섯 묶음으로 정리한다. 이름은 많아도 겨누는 곳은 셋이다. 계산(n²), 캐시(n), 위치(학습 길이)
| 갈래 (FoLM 절) | 무엇을 바꾸나 | 줄이는 것 | 이 과목에서 |
|---|---|---|---|
| 구현 최적화 (2.3.1) | 계산은 그대로, 정밀도와 메모리 왕복과 장치 분배를 바꾼다 | 시간, 메모리 | 2주차 FlashAttention |
| 효율적 구조 (2.3.2) | 모든 쌍 대신 일부만 보거나(희소), 소프트맥스를 풀어 순서대로 누적한다(선형) | 계산 n² | 2주차 슬라이딩 윈도, 1주차 상태공간모델 |
| 캐시와 메모리 (2.3.3) | 캐시를 고정 크기로 묶거나, 오래된 문맥을 요약 메모리로 옮긴다 | 캐시 n | 2주차 KV 압축 사례 |
| 헤드·층 공유 (2.3.4) | 여러 쿼리 헤드가 K, V를 나눠 쓴다(MQA, GQA) | 캐시 상수배 | 이번 주 실습 모델의 GQA |
| 위치 외삽·보간 (2.3.5) | 학습 때보다 긴 위치를 표현하는 방식을 바꾼다 | 학습 길이의 벽 | 이번 주 RoPE |
- 앞의 넷은 “긴 문맥을 감당할 수 있게” 하는 방법이고, 마지막 하나는 “긴 위치를 표현할 수 있게” 하는 방법이다. 감당할 수 있어도 위치를 표현하지 못하면 학습 길이 밖에서 모델이 무너진다
- 근사(희소, 선형, 캐시 압축)는 공짜가 아니다. 버리거나 뭉친 만큼 정보가 줄 수 있다. 2주차의 FlashAttention이 “근사가 아니라 같은 계산”이라는 점이 특별했던 이유다
□ 위치 인코딩 - RoPE와 학습 길이
○ RoPE는 위치를 회전 각도로 적는다
- 어텐션 자체는 순서를 모른다. 위치 정보가 없으면 토큰 순서를 섞어도 점수표의 행과 열이 같이 섞일 뿐 점수 값들은 그대로다. 그래서 위치 정보를 따로 넣는다
- RoPE(rotary positional embedding, FoLM 2.3.5.3)는 쿼리와 키 벡터를 위치만큼 돌린다. 벡터를 2차원씩 짝지어(차원 쌍), 위치 i의 토큰은 쌍마다 각도 i x θ만큼 회전한다
- 2차원 예로 보자. 벡터 (1, 0)을 θ = 30도로 돌리면
위치 0: 0도 -> (1.000, 0.000)위치 1: 30도 -> (0.866, 0.500)위치 2: 60도 -> (0.500, 0.866)위치 3: 90도 -> (0.000, 1.000)- 쿼리를 위치 i만큼, 키를 위치 j만큼 돌리면 둘의 내적은 각도 차 (i - j) x θ에만 달려 있다. 위치 5와 3의 쌍이나 위치 105와 103의 쌍이나 차이는 2칸, 60도로 같다. 그래서 RoPE는 절대 위치를 넣었는데 어텐션은 상대 위치를 본다
○ 차원 쌍마다 회전 속도가 다르다
- 실제 벡터는 2차원이 아니다. 실습 모델의 헤드 차원은 128이라 차원 쌍이 64개다. 쌍 k의 회전 속도 θ_k와 한 바퀴 도는 데 걸리는 토큰 수(주기) T_k는 다음과 같다(FoLM 식 2.97, 2.98)
θ_k = b^(-2(k-1)/d) d = 헤드 차원 128, b = 기저T_k = 2π x b^(2(k-1)/d) k = 1, 2, ..., 64- 실습 모델의 기저 b는 1,000,000이다. 계산하면
- 가장 빠른 쌍(k = 1)은 6.28토큰마다 한 바퀴를 돈다. 가까운 위치를 구별하는 데 쓰인다
- 가장 느린 쌍(k = 64)은 약 506만 토큰마다 한 바퀴를 돈다. 최대 위치 32,768까지 가도 2.3도밖에 돌지 않는다
- 64쌍 중 24쌍은 최대 위치 안에서 한 바퀴도 돌지 않는다
- 느린 쌍이 문제다. 학습 중 이 쌍들은 한 바퀴를 다 돌지 못해 원의 일부 각도만 봤다(최대 위치까지 k = 41은 약 334도, k = 48은 약 74도, 가장 느린 k = 64는 2.3도). 학습 길이를 넘는 위치를 넣으면 이 쌍들이 처음 보는 각도를 만든다. 빠른 쌍은 학습 중에 이미 여러 바퀴를 돌아 모든 각도를 봤으므로 문제가 적다
위치를 옮겨 보세요. 초록 호는 학습 길이(최대 위치 32,768) 안에서 그 차원 쌍이 지나간 각도 범위이고, 바늘은 지금 위치의 각도다. 바늘이 호 밖으로 나가면 빨간색이 된다. (Qwen3-0.6B-Base 설정으로 계산한 값)
○ 학습 길이 밖으로 - 외삽과 위치 보간
- 외삽(extrapolation): 학습 길이 m_l보다 긴 위치를 그대로 넣는다. 느린 쌍이 본 적 없는 각도를 받아 성능이 무너지기 쉽다
- 위치 보간(position interpolation, Chen 외 2023): 새 길이 m의 위치를 m_l / m 배로 줄여 학습한 범위 [0, m_l] 안에 넣는다(FoLM 식 2.99, 2.100). 각도가 모두 본 적 있는 범위에 들어온다. 대신 이웃한 위치의 각도 차가 줄어들므로, 짧은 추가 학습으로 적응시킨다
- 예: 32,768을 4배인 131,072로 늘리려면 위치를 1/4로 줄인다. 위치 100,000은 25,000이 된다
- 기저 늘리기(FoLM 식 2.101~2.104): 위치 대신 기저 b를 λ배 한다. 가장 느린 쌍의 주기가 위치 보간과 같아지도록 λ = (m / m_l)^(d / (d - 2))로 정한다
- 4배로 늘리면 λ = 4^(128/126) = 약 4.089. 가장 느린 쌍의 주기는 정확히 4배가 되고, 가장 빠른 쌍(k = 1)의 주기는 배율이 λ^0 = 1이라 그대로다
- 위치 보간이 모든 쌍을 똑같이 4배 늘리는 데 비해, 기저 늘리기는 느린 쌍만 많이 늘리고 빠른 쌍은 거의 건드리지 않는다. 가까운 위치를 구별하는 능력을 지키려는 것이다
- 정리하면 “모델이 128K 토큰을 받는다”는 말에는 두 층이 있다. 받을 수 있다(위치 표현과 메모리가 허락한다)와 잘 쓴다(그 안의 정보를 실제로 활용한다)는 다른 이야기다. 다음 절이 두 번째 층이다
□ 열린 문맥을 모델이 실제로 쓰는가 - Lost in the Middle
○ 실험 설계
- Liu 외(2023, arXiv:2307.03172)는 두 가지 과제로 “긴 입력 속 정보를 얼마나 잘 쓰는가”를 쟀다
- 여러 문서 질의응답: 질문 하나에 위키백과 문단 k개(10, 20, 30개)를 준다. 그중 하나만 답을 담고 나머지는 관련은 있지만 답이 없는 문단이다. 답 문서의 위치를 처음부터 끝까지 옮겨 가며 정답률을 잰다. 문서 20개가 약 4K 토큰이다
- 키-값 찾기: 무작위 문자열(UUID) 키와 값의 쌍 75, 140, 300개(약 4K, 8K, 16K 토큰)를 JSON으로 주고 키 하나의 값을 묻는다. 의미 이해 없이 같은 문자열을 찾아 옮기기만 하면 되는 가장 쉬운 형태다
- 모델은 공개 모델 2개와 상용 API 모델 4개(두 계열의 기본판과 문맥 확장판)였다
○ 결과
- U자 곡선: 답이 입력의 맨 앞(초두 편향, primacy bias)이나 맨 뒤(최신 편향, recency bias)에 있을 때 정답률이 가장 높고, 가운데로 갈수록 떨어진다
- 한 상용 모델은 답이 가운데 있을 때 정답률이 20% 넘게 떨어졌다. 같은 모델은 문서 20개, 30개 설정에서 답이 가운데 있을 때의 정답률이 문서를 하나도 주지 않고 물었을 때(closed-book, 56.1%)보다 낮았다. 답이 든 문서를 줬는데 안 준 것보다 못한 것이다
- 문맥 확장판이 더 잘 쓰는 것은 아니다: 입력이 두 판의 문맥 창에 모두 들어갈 때 기본판과 확장판의 곡선은 거의 같았다. 창을 늘리는 것과 창 안의 정보를 잘 쓰는 것은 별개다
- 키-값 찾기에서는 한 계열이 거의 완벽했지만 다른 모델들은 140쌍, 300쌍에서 가운데 위치가 무너졌다. 가장 쉬운 찾기조차 모델에 따라 U자가 나왔다
○ 왜 가운데가 꺼지는가 - 논문이 시험한 세 요인과 모델 크기
- 구조: 인코더-디코더 모델은 학습 때 본 길이 안에서는 위치 변화에 비교적 강했다. 논문은 양방향 인코더가 각 문서를 뒤에 오는 문서까지 보면서 처리하기 때문일 것으로 추정한다. 그러나 학습 길이보다 긴 입력에서는 이들도 U자가 나왔다
- 질문 위치(query-aware contextualization): 디코더 모델은 앞 토큰이 뒤를 볼 수 없어서, 질문이 문서 뒤에만 있으면 문서를 읽는 동안 무엇을 찾는지 모른다. 질문을 문서 앞과 뒤 모두에 두면 키-값 찾기는 거의 완벽해졌다(한 모델은 300쌍에서 100%, 질문을 뒤에만 둔 최악은 45.6%). 하지만 여러 문서 질의응답의 경향은 거의 바뀌지 않았다. 찾기는 고쳐졌지만 읽고 판단하는 문제는 남았다
- 지시 학습: 지시 학습을 하지 않은 바탕 모델도 U자를 보였다. 지시 학습 데이터에서 지시가 대개 입력 앞에 오기 때문만은 아니라는 뜻이다
- 모델 크기: 크기가 다른 Llama-2 모델(7B, 13B, 70B)을 비교하자 U자는 충분히 큰 모델에서만 나타났다. 7B는 최신 편향(끝 쪽이 유리)만 보였고, 13B와 70B가 U자를 보였다. 위치 편향의 모양 자체가 모델 크기에 따라 다르다
○ 실무에 주는 함의 - 문서를 더 넣으면 좋아지는가
- 같은 논문의 검색 결합 실험에서, 검색기가 가져온 문서를 20개에서 50개로 늘려도 정답률은 1~1.5% 정도만 올랐다. 검색기의 재현율은 계속 오르는데 모델 성능은 일찍 포화됐다. 문맥만 길어지고 지연과 비용이 늘었다
- 논문의 제안은 관련 문서를 앞으로 당기는 재정렬과 덜 가져오기(목록 자르기)다. 9주차 검색 결합에서 다시 다룬다
□ 실측 - 제주 문서에서 숨긴 번호 찾기
○ 측정 설계
- 위키백과 「제주특별자치도」 본문 사이사이에 가상의 안내센터 출입 번호 문장 열 개를 끼운다. “애월 안내센터의 오늘 임시 출입 번호는 7468이다.”처럼 안내센터마다 번호가 다르다
- 그중 하나(애월 또는 표선)의 번호를 묻는다. 찾을 문장은 원문 문장 개수 기준 삽입 위치 비율(0% = 맨 앞, 100% = 맨 뒤)에 놓고, 나머지 아홉 문장도 문장 개수 기준으로 흩는다. 이 비율은 토큰 위치 비율과 다를 수 있다. 비슷한 문장이 여럿이라 정확히 그 안내센터의 번호를 골라야 맞는다
- L은 위키백과의 문장별 토큰 수를 합산한 예산 상한이다. 이어 붙인 실제 본문 토큰 수와 일치하는 고정 길이가 아니다. L과 삽입 위치 다섯 곳마다 두 안내센터를 물어, 답에 정답 번호가 포함되는 비율을 substring 번호 포함률로 센다
- Lost in the Middle의 키-값 찾기와 같은 계열이다. 의미를 읽을 필요 없이 질문과 같은 글자를 찾아 번호를 옮기면 된다
○ 기존 프록시 결과 - L 예산 4,000의 가운데 문장 위치에서 두 번 번호 불일치
- 노트북을 TODO 그대로 실행하면(L = 250, 500, 1,000) 15칸 모두 substring 번호 포함률 1.0이었다. 각 응답에 해당 정답 번호가 포함되었음을 뜻하며 strict 번호 일치나 문장 의미의 정확성까지 증명하지는 않는다
- TODO 예산을 [500, 1000, 2000, 4000, 7000]으로 바꾼 과거 실행 결과다. 입력 열은 해당 L에서 마지막 질문의 입력 길이, 0~100% 열은 문장 위치별 substring 번호 포함률이다. 실제 토큰 위치 비율과 strict 점수는 당시 기록하지 않았다
| 문장별 토큰 예산 L | 마지막 입력 (토큰) | 문장 위치 0% | 25% | 50% | 75% | 100% | substring 평균 |
|---|---|---|---|---|---|---|---|
| 500 | 762 | 1.0 | 1.0 | 1.0 | 1.0 | 1.0 | 1.00 |
| 1,000 | 1,288 | 1.0 | 1.0 | 1.0 | 1.0 | 1.0 | 1.00 |
| 2,000 | 2,272 | 1.0 | 1.0 | 1.0 | 1.0 | 1.0 | 1.00 |
| 4,000 | 4,257 | 1.0 | 0.5 | 0.5 | 1.0 | 1.0 | 0.80 |
| 7,000 | 7,276 | 1.0 | 1.0 | 1.0 | 1.0 | 1.0 | 1.00 |
- 놓친 두 번은 모두 L = 4,000에서 표선을 물었을 때였다. 깊이 25%에서는 한림의 번호(3471)를, 50%에서는 애월의 번호(7468)를 답했다. 없는 번호를 지어낸 것이 아니라 비슷한 문장의 번호를 가져왔다. 가운데 쪽에서 비슷한 문장끼리 헷갈린 모양이다
- 그러나 여기서 “길수록 떨어진다”나 “U자가 나왔다”고 말할 수는 없다
- 칸마다 두 번만 물었다. 0.5는 두 번 중 한 번이라는 뜻이다
- 예산 7,000에서는 다시 모든 응답에 정답 번호가 포함되었다
- 결론을 내려면 묻는 안내센터를 늘리거나 다른 문서로 되풀이해 표본을 키워야 한다
- 이 결과는 Lost in the Middle과 어긋나는가. 그렇지 않다. 조건이 다르다
- 찾기가 쉽다: 질문의 “애월 안내센터의 오늘 임시 출입 번호”가 숨긴 문장에 글자 그대로 있다. 논문의 키-값 찾기에서도 한 계열은 거의 완벽했다. U자가 크게 나온 것은 관련 문서를 읽고 답을 판단하는 여러 문서 질의응답이었다
- 학습 길이 안이다: 가장 긴 입력도 최대 위치 32,768의 4분의 1이 안 된다
- 후보가 적다: 비슷한 문장이 열 개뿐이다. 논문의 키-값 찾기는 75~300쌍이었다
- 모델이 작다: 논문에서도 U자는 충분히 큰 모델(13B 이상)에서 나타났고 7B는 최신 편향만 보였다. 0.6B 모델에서 같은 모양을 기대할 근거는 약하다
- 그러므로 이 과거 실측이 직접 말해 주는 것은 “이 예산·삽입 조건에서 응답에 목표 번호가 포함되었다”까지다. “이 모델은 긴 문서를 이해한다”는 이 측정으로 말할 수 없다
□ 두 번호 지표와 실제 위치를 따로 기록
- 기존 프록시:
정답 번호 in 응답. 정답 7468이 응답 17468의 일부이거나 여러 번호 중 하나여도 성공 처리되는 한계 - 추가 strict 번호 일치: 응답의 숫자열이 하나만 있고, 그 숫자열이 정확한 4자리 정답과 일치할 때 성공
- 예:
7468이다는 두 지표 모두 성공.17468,7468 또는 3471은 기존 프록시만 성공 - strict도 의미 판정은 아님.
7468은 아니다처럼 단일 정답 번호를 부정하는 문장은 통과할 수 있으므로 실제 정답 검증과 구분 - 노트북은 같은 생성 응답에서 두 지표를 함께 계산·출력. strict를 위해 새로 생성하지 않으므로 지표 비교의 응답 조건 동일
GRID_RECORDS: 응답별 두 판정, L 예산, 원문 문장 위치 비율, 이어 붙인 실제 본문 토큰 수, 삽입 후 문서 토큰 수, 정답 문장의 첫 출현 토큰 index와 토큰 깊이 기록- 실제 토큰 깊이: 문서 안의 첫 출현 토큰 index / 삽입 후 문서 토큰 수. 질문·답 접두는 분모에서 제외, tokenizer offset으로 위치 확인
- 이 메타데이터 추가는 입력 문장을 변경하지 않는 관찰 장치. 위 과거 그림의 숫자를 새 strict 실측값으로 바꾸지 않기
- 그림 안의 “회수율”은 이 문서에서 구체화한 과거 substring 프록시, “깊이”는 문장 위치 비율, L은 토큰 예산으로 읽기
○ 같은 모델, 다른 채점 - 답의 첫머리를 빼면
- 노트북은 프롬프트 끝에 답의 첫머리(“애월 안내센터의 오늘 임시 출입 번호는”)를 미리 적어 둔다. 이것을 빼고
답:에서 끝내면 어떻게 될까. 노트북 3의 실측(L = 500)이다
| 프롬프트 끝 | 생성 길이 | substring 번호 포함률 (문장 위치 다섯 곳) | 문장 위치 50% 애월의 답 |
|---|---|---|---|
| 답의 첫머리를 적어 둠 | 6토큰 | 1.0 | 7468이다 |
답:에서 끝 | 8토큰 | 0.0 | 애월 안내센터의 오늘 |
답:에서 끝 | 24토큰 | 1.0 | 애월 안내센터의 오늘 임시 출입 번호는 7468이다. |
- 24토큰 출력에서는 목표 번호가 나타났고, 8토큰 출력은 질문의 첫 부분에서 끝났다. 이것은 출력 길이와 형식의 차이이며 모델의 내부 지식을 직접 관찰한 증거는 아니다. 같은 모델, 같은 문서인데 프롬프트 형식과 생성 길이에 따라 substring 번호 포함률이 0과 1 사이를 오갔다
- FoLM이 경고한 “프롬프트만 바꿔도 결과가 크게 달라진다”를 직접 본 것이다. 장문맥 점수를 비교할 때는 프롬프트 형식과 생성 길이를 같게 두었는지부터 확인한다. 5주차의 “자가 무엇을 재는가”와 같은 질문이다
□ 평가의 함정 - 찾아냈다고 이해한 것은 아니다
- 장문맥 평가에는 대략 세 가지가 쓰인다(FoLM 2.3.6.3)
- 퍼플렉시티: 간단하지만 먼 문맥보다 가까운 문맥을 얼마나 쓰는지를 주로 반영한다
- 합성 과제: 바늘 찾기(needle-in-a-haystack), 비밀번호 찾기(passkey retrieval), 복사 과제. 긴 글 속 작은 정보를 찾아내는지 본다
- 실제 긴 문서 과제: 긴 문서 요약, 긴 문서 질의응답, 코드 완성 등. 사용자의 기대와 가깝다
- FoLM이 짚는 한계
- 텍스트 조각을 정확히 찾아내도 문맥 전체를 이해했다고 할 수는 없다. 중요한 부분만 기억했을 수도, 사전학습에서 외운 답을 꺼냈을 수도 있다
- 프롬프트만 바꿔도 결과가 크게 달라진다. 그래서 향상이 장문맥 능력 덕분인지 가려내기 어렵고, 과장해서 주장할 위험이 있다
- 이번 주 실습도 바늘 찾기다. 결과가 좋게 나와도 “이 모델은 긴 문서를 이해한다”가 아니라 “이 조건에서 이 문장을 찾아냈다”까지만 말한다. 5주차의 “지표가 측정하지 못하는 것”과 같은 이야기다
- 실습 노트북으로 문장 위치별 substring 번호 포함률과 strict 번호 일치를 함께 잰다. 기본 L 예산 셋을 먼저 돌리고, TODO 예산을 늘려 프록시 곡선과 실제 토큰 위치를 기록
- 두 지표 표와 실제 본문·문서 토큰 수, 정답 토큰 위치, 1-5의 프리필 시간을 기록. 예산 증가와 실제 길이·시간·번호 지표의 변화를 구분
- 노트북 3에서 답의 첫머리를 뺐을 때 두 번호 지표의 변화를 기록하고, 부정·인용을 판정하지 못하는 한계를 한 문장으로 작성
대면 (1시수)
Section titled “대면 (1시수)”장문맥 처리 전략 비교 - 검색 결합인가, 초장문맥인가
Section titled “장문맥 처리 전략 비교 - 검색 결합인가, 초장문맥인가”□ 같은 문서를 넣는 두 가지 길
- 문서를 모델에 주는 길은 크게 둘이다
- 검색 결합: 문서를 미리 잘게 나눠 색인해 두고, 질문이 오면 관련 조각 몇 개만 꺼내 짧은 문맥으로 넣는다. 구조는 9주차에서 자세히 다룬다
- 초장문맥: 문서 전체를 긴 문맥에 그대로 넣는다. 고를 필요가 없지만 질문마다 긴 입력을 읽는다
- 어느 쪽이 “더 좋다”는 정답은 없다. 비용, 지연, 갱신 주기라는 조건이 답을 정한다
□ 비교의 근거 - 이번 주 숫자로 계산하기
- 세 조건을 이번 주 실측과 계산으로 이어 본다
- 지연: 첫 토큰까지 시간은 대부분 프리필이다. 실습 환경에서 500토큰 입력의 프리필은 0.41초, 2,000토큰은 1.66초였고(1-5 실측), 7,000토큰 문서를 넣은 질문 한 건은 9.4초가 걸렸다(노트북 2, TODO 변경 실행). 검색 결합은 짧은 입력 쪽에, 초장문맥은 긴 입력 쪽에 선다. 검색 단계 자체의 시간은 따로 더한다
- 비용(메모리): KV 캐시는 길이에 정비례한다. 실습 모델 bf16 기준 토큰당 112 KiB이므로 2,000토큰 문맥은 약 219 MiB, 32,768토큰은 3.5 GiB다. 동시 사용자가 늘면 그 수만큼 곱해진다
- 갱신 주기: 문서가 바뀌면 검색 결합은 바뀐 조각만 다시 색인한다. 초장문맥은 다음 질문부터 새 문서 전체를 다시 넣으면 된다. 같은 문서에 질문이 반복되면 문서 부분의 KV 캐시를 재사용하는 방법(접두부 캐시)이 있지만, 문서가 바뀌면 그 캐시는 버리고 다시 프리필한다
- 정확도: Lost in the Middle의 결과대로, 긴 입력에 넣었다고 모두 쓰이지는 않는다. 검색 결합도 검색이 놓친 조각은 모델이 볼 수 없다. 둘 다 실패하는 모양이 있다
□ 비교표 채우기 - 공공·행정 문서 사례
- 상정 조건: 공공데이터포털에 개방된 제주 행정정보처럼 자주 갱신되는 공공 문서(예: 공지, 시설 운영 안내, 민원 안내)를 바탕으로 주민 문의에 답하는 서비스를 만든다. 문서 묶음 전체는 수만 토큰이고, 일부가 매주 바뀐다
- 아래 표의 빈칸을 근거와 함께 채운다. 근거 칸에는 이번 주의 숫자(프리필 시간, KV 캐시 크기)나 논문 결과를 적는다
| 조건 | 검색 결합 | 초장문맥 | 이 조건에서의 선택과 근거 |
|---|---|---|---|
| 문서 묶음 크기 (수만 토큰, 모델 최대 위치 32,768) | |||
| 갱신 주기 (매주 일부 변경) | |||
| 첫 토큰까지 시간 (문의 응답) | |||
| 메모리 (동시 문의 10건) | |||
| 정답이 문서 가운데 있을 때 | |||
| 출처 제시 (어느 문서에서 왔나) |
- 채울 때 확인할 것
- 문서 묶음이 모델의 최대 위치를 넘으면 초장문맥은 애초에 성립하지 않는다. 표의 첫 줄부터 결론이 나기도 한다
- “빠르다/느리다”를 쓰지 말고 얼마나를 쓴다. 이번 주 실측 프리필 시간과 KV 캐시 계산기가 근거다
- 두 방법을 섞는 길도 있다. 검색으로 후보를 넉넉히 가져와 중간 길이 문맥에 넣고, 관련도 높은 조각을 앞에 둔다(Lost in the Middle의 재정렬 제안)
중간고사 대비 종합 리뷰 - 1~7주차 개념 위계
Section titled “중간고사 대비 종합 리뷰 - 1~7주차 개념 위계”□ 마디를 다시 그린다
- 1주차의 과목 지도는 아키텍처 -> 적응 -> 제어 -> 검색 결합 -> 시스템화로 이어진다. 7주차까지 앞 세 마디와, 그 위에 얹는 확장(멀티모달, 장문맥)을 지났다
- 앞 마디의 산출물이 다음 마디의 재료다. 위계를 거꾸로 짚어 보면 빠진 마디가 보인다
| 마디 | 주차 | 핵심 질문 | 7주차와 이어지는 곳 |
|---|---|---|---|
| 아키텍처 | 1 | Transformer는 왜 생겼고 어디가 아픈가 (제곱 비용, 상태공간모델) | 긴 문맥이 비싼 첫 번째 이유 |
| 아키텍처 | 2 | 학습 루프를 끝까지 돌리고 어텐션을 빠르게 계산하는 법 (FlashAttention, KV 압축) | 다섯 갈래의 구현 최적화와 캐시 |
| 적응 | 3 | 전부 다시 학습하지 않고 작은 부품만 학습할 수 있는가 (LoRA, QLoRA) | 위치 보간 뒤의 짧은 추가 학습도 적응이다 |
| 제어 | 4 | 가중치를 바꾸지 않고 입력만으로 동작을 바꿀 수 있는가 (문맥학습) | 입력이 길어지는 대가가 이번 주의 비용이다 |
| 제어 | 5 | 맞았는지는 무엇으로 판단하는가 (지표가 놓치는 것) | 바늘 찾기 점수가 놓치는 것 |
| 확장 | 6 | 사진과 글을 한 공간에 놓는 법 (CLIP, VLM) | 사진이 문맥을 잠식한다 |
| 확장 | 7 | 긴 문맥을 열고, 실제로 쓰게 하는 법 | 다음 마디 검색 결합의 출발점 |
○ 자가 진단 - 빠진 마디 찾기
- 각 줄의 핵심 질문에 세 문장 이내로 답해 본다. 막히는 줄이 빠진 마디다
- 막힌 마디는 그 주차의 “스스로 점검”과 “자주 하는 오해 Q&A”부터 다시 본다
- 중간고사는 이론과 실습 문제로 치른다. 채점은 수업계획서의 성적 판정 기준(표현이 달라도 개념이 맞으면 정답, 접근 설계·동작·성능 비교의 중간 단계 부분점수)을 따른다. 8주차 온라인 학습활동이 기출 유형 자가 점검이다
[이론] 위치 인코딩 확장과 어텐션 근사가 장문맥을 여는 방식, 그리고 중간 위치 정보가 소실되는 현상의 원인을 정리한다
- 다섯 갈래(FoLM 2.3)가 각각 계산 n², 캐시 n, 학습 길이 중 무엇을 겨누는지 표로 쓴다
- RoPE의 느린 차원 쌍이 학습 길이 밖에서 처음 보는 각도를 받는 이유와, 위치 보간과 기저 늘리기가 그것을 피하는 방식의 차이를 쓴다
- Lost in the Middle이 시험한 세 요인(구조, 질문 위치, 지시 학습)과 각각의 결과를 쓴다
[구현] 번호 찾기 노트북을 실행하고, 문장별 토큰 예산을 늘려 가며(TODO 한 곳) substring 프록시와 strict 번호 일치, 실제 토큰 위치를 비교한다
- 기록할 것: 예산별 두 지표, 문장 삽입 위치와 실제 토큰 위치, 실제 본문·입력 토큰 수, 프리필 시간. 기존 그림과 비교하는 곡선은 substring 프록시
- 두 번호 지표가 떨어지면 문장 위치와 실제 토큰 위치를 함께 확인하고, 다른 안내센터의 번호·긴 숫자·복수 번호 등 실패 형태를 기록한다
- 두 번호 지표가 떨어지지 않으면 그 결과와 한계도 기록. 글자 겹침과 입력 길이를 확인하되, 높은 번호 지표를 의미 이해의 증명으로 해석하지 않기
[실무] 갱신이 잦은 공공·행정 문서를 대상으로 대면 시간의 비교표를 채워 검색 결합과 초장문맥 중 무엇을 택할지 비용·지연·갱신 주기 조건에서 판단한다. 공공데이터포털의 제주 행정정보를 사례로 삼는다
- 근거 칸에는 이번 주 숫자(프리필 시간, KV 캐시 크기)와 Lost in the Middle의 결과를 쓴다
- “빠르다/느리다”가 아니라 “얼마나”를 쓴다
- 1~7주차 개념 위계를 다시 그리고, 세 문장으로 답하지 못하는 마디를 표시한다
자주 하는 오해 Q&A
Section titled “자주 하는 오해 Q&A”Q1. 문맥 창이 크면 긴 문서를 다 이해하는 것 아닌가?
창의 크기는 “받을 수 있다”는 뜻이지 “잘 쓴다”는 뜻이 아니다. Lost in the Middle에서 문맥 확장판 모델은 입력이 두 판의 창에 모두 들어갈 때 기본판과 정답률이 거의 같았고, 한 상용 모델은 답이 가운데 있으면 20% 넘게 떨어졌다. 창을 늘리는 일(위치 표현, 메모리)과 창 안의 정보를 쓰는 일은 따로 확인해야 한다.
Q2. 바늘 찾기 점수가 100%면 장문맥 능력이 검증된 것 아닌가?
아니다. 바늘 찾기는 “긴 글 속 특정 문장을 찾아 옮기는가”만 본다. 찾아냈다고 문맥 전체를 이해한 것은 아니고(FoLM 2.3.6.3), 프롬프트만 바꿔도 결과가 달라진다. 이번 주 실습에서도 찾을 문장과 질문이 글자 그대로 겹친다. 여러 문서를 읽고 판단하는 과제에서는 같은 모델이 다르게 움직일 수 있다. 5주차의 “지표가 측정하지 못하는 것”을 그대로 적용한다.
Q3. 문맥이 2배면 시간도 정확히 4배인가?
아니다. 어텐션 점수표는 n x n이라 4배가 되지만, 모델 계산에는 길이에 정비례하는 부분(피드포워드 층, 투영 층)도 크다. 실측에서 2,000토큰까지는 입력이 2배일 때 프리필 시간이 1.7~2.0배였고, 2,000토큰을 넘어서자 길이보다 빠르게 늘었다. 배율은 모델 크기, 길이, 실행 환경에 따라 다르다. 노트북 1-5와 2에서 직접 재 본다.
Q4. KV 캐시는 모델을 다시 학습시키는 것인가?
아니다. KV 캐시는 추론 중에만 쓰는 임시 메모다. 이미 계산한 앞 토큰들의 Key와 Value를 저장해 두고 다음 토큰을 만들 때 다시 쓴다. 가중치는 바뀌지 않는다. 대신 길이에 정비례해 커져서, 실습 모델은 약 10,400토큰에서 가중치 크기를 넘는다(bf16 기준).
Q5. RoPE를 쓰면 학습 길이보다 긴 입력도 그냥 되는가?
보장되지 않는다. RoPE의 느린 차원 쌍은 학습 길이 안에서 아주 조금만 돈다(실습 모델의 가장 느린 쌍은 32,768까지 2.3도). 학습 길이를 넘으면 이 쌍들이 처음 보는 각도를 만든다. 그래서 위치 보간이나 기저 늘리기로 각도를 본 적 있는 범위로 되돌리고, 짧은 추가 학습으로 적응시킨다.
Q6. 질문을 문서 앞에 두면 Lost in the Middle이 해결되는가?
일부만. 논문에서 질문을 앞뒤에 모두 두자 키-값 찾기는 거의 완벽해졌지만, 여러 문서를 읽고 답하는 과제의 경향은 거의 그대로였다. 디코더 모델은 앞 토큰이 뒤를 못 보므로 질문을 앞에 두면 “무엇을 찾을지”는 알려 줄 수 있다. 그러나 찾은 것을 읽고 판단하는 문제까지 풀어 주지는 않는다.
Q7. 그러면 긴 문맥 대신 언제나 검색 결합을 쓰면 되는가?
조건에 달렸다. 검색 결합은 문맥이 짧아 빠르고 싸며 갱신이 쉽지만, 검색이 놓친 조각은 모델이 볼 수 없다. 초장문맥은 고르는 단계가 없지만 질문마다 긴 프리필과 큰 KV 캐시를 치르고, 가운데 정보가 덜 쓰인다. 문서 크기, 갱신 주기, 응답 시간 요구를 표로 놓고 고른다. 대면 시간의 비교표가 이 판단 연습이다.
Q8. 한국어 문서는 왜 문맥을 더 빨리 채우는가?
토크나이저가 같은 내용의 한국어를 영어보다 더 많은 토큰으로 자르는 경우가 많기 때문이다. 이번 주 문서는 토큰 하나에 평균 1.34자였다. 문맥 길이, 프리필 시간, KV 캐시는 모두 토큰 수에 달려 있으므로, 같은 분량이라도 토큰이 많으면 그만큼 비싸다.
스스로 점검
Section titled “스스로 점검”- 층 28개, KV 헤드 8개, 헤드 차원 128인 모델의 bf16 KV 캐시는 토큰당 몇 바이트인가? 8,192토큰이면?
- 같은 모델에서 KV 헤드를 16개로 늘리면(MHA) KV 캐시는 몇 배가 되는가? GQA가 무엇을 아끼는지 한 문장으로 쓰자.
- 프리필과 디코딩의 병목은 각각 무엇인가? 첫 토큰까지 시간은 어느 단계와 주로 관련되는가?
- RoPE에서 위치 5의 쿼리와 위치 3의 키, 위치 105의 쿼리와 위치 103의 키의 내적이 같은 각도 차를 갖는 이유는?
- 기저 b = 1,000,000, 헤드 차원 128일 때 가장 빠른 차원 쌍의 주기는 몇 토큰인가? 가장 느린 쌍이 학습 길이 밖에서 문제가 되는 이유는?
- 학습 길이 32,768인 모델을 131,072로 늘리려 한다. 위치 보간을 쓰면 위치 65,536은 몇이 되는가?
- Lost in the Middle의 U자 곡선에서 정답률이 높은 두 위치와 그 이름은?
- 질문을 문서 앞뒤에 두는 방식이 키-값 찾기에는 크게 듣고 여러 문서 질의응답에는 거의 듣지 않은 이유를 추측해 보자.
- 기존 substring 번호 포함률이 1.0이었다. strict 번호 일치와 의미 정확성도 1.0이라고 할 수 있는가?
정답 보기
- 2 x 28 x 8 x 128 x 2 = 114,688바이트(112 KiB). 8,192토큰이면 112 KiB x 8,192 = 896 MiB
- 정확히 2배. GQA는 쿼리 헤드 여러 개가 K, V 헤드 하나를 나눠 써서 KV 캐시를 그 비율만큼 줄인다
- 프리필은 계산이 병목(입력 전체를 한 번에 행렬로 처리), 디코딩은 메모리 읽기가 병목(토큰 하나를 위해 가중치와 캐시 전체를 읽음). 첫 토큰까지 시간은 주로 프리필이다
- 내적은 두 회전 각도의 차 (i - j) x θ에만 달려 있다. 5 - 3 = 105 - 103 = 2라서 각도 차가 같다. RoPE가 상대 위치를 보게 되는 이유다
- T_1 = 2π x b^0 = 약 6.28토큰. 가장 느린 쌍은 학습 길이 안에서 아주 작은 각도만 봤으므로, 학습 길이를 넘는 위치에서 처음 보는 각도를 받는다
- 65,536 x 32,768 / 131,072 = 16,384
- 맨 앞(초두 편향, primacy bias)과 맨 뒤(최신 편향, recency bias)
- 키-값 찾기는 질문의 키와 같은 문자열을 찾기만 하면 되므로, 문서를 읽을 때 무엇을 찾는지 아는 것만으로 크게 좋아진다. 여러 문서 질의응답은 찾은 뒤 내용을 읽고 판단해야 해서, 무엇을 찾을지 아는 것만으로는 부족하다(논문 결과에 대한 해석이며 정답은 하나가 아니다)
- 알 수 있는 것은 응답에 목표 번호가 포함된 비율. 더 긴 숫자·복수 번호도 포함 판정을 통과하므로 strict 일치는 별도 계산. strict도 부정·인용 등 의미의 정확성이나 긴 문서 이해를 증명하지 못한다
이번 주 용어 정리
Section titled “이번 주 용어 정리”| 용어 | 한 줄 뜻 |
|---|---|
| 문맥 창 (context window) | 모델이 한 번에 받을 수 있는 최대 토큰 수 |
| 최대 위치 (max_position_embeddings) | 모델 설정에 적힌 위치의 상한. 실습 모델은 32,768 |
| 프리필 (prefilling) | 입력 전체를 한 번에 읽어 KV 캐시를 만드는 단계. 계산이 병목 |
| 디코딩 (decoding) | 캐시를 읽으며 출력 토큰을 하나씩 만드는 단계. 메모리 읽기가 병목 |
| 첫 토큰까지 시간 (TTFT) | 요청부터 첫 출력 토큰까지 걸린 시간. 대부분 프리필 |
| 토큰 간 지연 (ITL) | 첫 토큰 이후 토큰 하나를 더 만드는 데 걸리는 시간 |
| KV 캐시 | 앞 토큰들의 Key와 Value를 층마다 저장해 둔 추론용 메모. 길이에 정비례 |
| GQA (grouped-query attention) | 쿼리 헤드 여러 개가 K, V 헤드 하나를 나눠 쓰는 어텐션. KV 캐시를 줄인다 |
| MQA (multi-query attention) | 모든 쿼리 헤드가 K, V 헤드 하나를 함께 쓰는 극단의 공유 |
| 희소 어텐션 | 모든 쌍 대신 일부 쌍만 계산하는 어텐션 |
| 선형 어텐션 | 소프트맥스를 다른 식으로 바꿔 계산을 길이에 정비례하게 만든 어텐션 |
| RoPE | 쿼리와 키를 위치만큼 회전시켜 위치를 넣는 방식. 내적이 상대 위치에 달린다 |
| 차원 쌍 | RoPE가 함께 회전시키는 벡터의 두 차원. 쌍마다 회전 속도가 다르다 |
| 기저 (base, rope_theta) | RoPE 회전 속도를 정하는 수. 클수록 느린 쌍의 주기가 길어진다 |
| 외삽 (extrapolation) | 학습 때보다 긴 위치를 그대로 넣는 것 |
| 위치 보간 (position interpolation) | 긴 위치를 학습 범위 안으로 줄여 넣는 것 |
| 기저 늘리기 | 기저 b를 키워 느린 쌍의 주기만 많이 늘리는 확장법 |
| Lost in the Middle | 긴 입력의 가운데에 놓인 정보를 덜 쓰는 현상. U자 곡선 |
| 초두 편향 / 최신 편향 | 입력의 맨 앞 / 맨 뒤 정보를 더 잘 쓰는 경향 |
| query-aware contextualization | 질문을 문서 앞과 뒤 모두에 두는 배치 |
| 바늘 찾기 (needle-in-a-haystack) | 긴 글 속에 숨긴 문장을 찾아내는지 보는 합성 평가 |
| substring 번호 포함률 | 응답에 목표 번호 문자열이 포함되는 비율, 과거 표·그림의 프록시 |
| strict 번호 일치 | 유일한 숫자열이 정확한 4자리 정답과 일치하는 비율, 의미 판정과 구분 |
| 삽입 위치 비율 | 원문 문장 수를 기준으로 한 위치, 실제 토큰 위치와 구분 |
| L 예산 | 문장별 토큰 합의 상한, 이어 붙인 실제 본문 길이와 구분 |
| 검색 결합 | 필요한 조각만 검색해 짧은 문맥으로 넣는 방식. 9주차 |
| 접두부 캐시 | 같은 앞부분(문서)의 KV 캐시를 질문마다 재사용하는 것. 앞부분이 바뀌면 다시 만든다 |
| 자료 | 출처 | 라이선스 |
|---|---|---|
| 실습 문서 | 위키백과 「제주특별자치도」 2026-09-11 판 (판 번호 42464087), 본문 문단만 사용 | CC BY-SA 4.0 |
| 숨긴 문장 | 실험용으로 지어낸 안내센터 출입 번호 문장. 실제 기관이나 번호가 아니다 | - |
- 노트북이 실행 시점에 위키백과 API로 고정 판을 내려받는다. 문서 원본은 저장소에 담지 않는다
- 과제 보고에 문서를 인용할 때 위 표의 출처와 판 번호를 함께 적는다
실습 노트북
Section titled “실습 노트북”위키백과 「제주특별자치도」 고정 판을 내려받아, 모델 설정에서 KV 캐시와 RoPE 주기를 계산하고 프리필과 디코딩 시간을 잰다. 그다음 문서 곳곳에 가상의 안내센터 번호 문장 열 개를 숨기고 문장 위치별 substring 번호 포함률과 strict 번호 일치를 함께 잰다. 바꿀 곳은 문장별 토큰 예산 목록 한 곳이다. 실제 본문 길이·정답 토큰 깊이는 메타데이터로 확인한다. 마지막으로 답의 첫머리를 빼면 같은 모델의 점수가 어떻게 바뀌는지 본다. 메타데이터·strict 지표 추가 이전 작성 환경의 CPU 1회 실행은 처음부터 끝까지 약 1분 10초였다(모델 내려받는 시간 제외). TODO 길이를 [500, 1000, 2000, 4000, 7000]으로 바꾸면 약 4분이었다. Colab 무료 CPU에서는 이보다 더 걸릴 수 있다.