시리즈: "LLM의 대안을 만들 수 있을까? 8개월간의 실험, 200번의 실패, 그리고 하나의 벽" 1
요약
LLM의 긴 대화 세션 비용을 절감하기 위해 대화 기록을 압축된 메모리 상태로 교체하는 실험 과정을 다룹니다. 자체 합성 평가에서는 성공했으나 외부 벤치마크에서 실패하며, 평가 방식의 설계 오류와 메모리 유형의 중요성을 강조합니다.
핵심 포인트
- 압축된 메모리 상태를 통한 LLM 세션 비용 절감 시도
- 합성 평가(Synthetic Eval)가 실제 성능을 보장하지 못하는 위험성
- 정확한 정보 보존을 위한 전용 메모리 및 결정론적 가드 필요성
- 로컬 평가와 외부 벤치마크 간의 성능 격차 발생 원인 분석
저는 간단한 가설을 테스트했습니다: 전체 대화 기록(transcript)을 압축된 메모리 상태(compact memory state)로 교체함으로써, 답변의 정확도를 유지하면서도 긴 LLM 세션을 더 저렴하게 만들 수 있을까?
제가 직접 만든 합성 평가(synthetic eval)에서는 시스템이 30/30을 기록하며 통과했습니다. 하지만 장기 대화 메모리(long-term conversational memory)에 대한 외부 벤치마크에서는 점수가 0.13으로 폭락했습니다. 이 실패는 하나의 잘못된 프롬프트(prompt) 때문에 발생한 것이 아니었습니다. 그것은 보존되는 메모리의 유형에서 기인했습니다. 로컬 평가(local eval)는 정확한 사실(exact facts)을 테스트한 반면, LoCoMo는 일화적 기억(episodic memory)을 테스트했습니다.
여러 번의 실패한 접근 방식 끝에, 하나의 좁은 아키텍처(architecture)가 살아남았습니다: 추가 전용 메모리(append-only memory)와 정확한 필드, 특히 날짜를 위한 결정론적 가드(deterministic guards)를 결합하는 방식입니다. 이것은 범용 메모리는 아니지만, 200개의 QA에 대해 60%의 쿼리당 비용 절감과 94%의 유지율이라는 정직한 결과를 만들어냈습니다.
주요 교훈: 합성 평가(synthetic evals)는 회귀 테스트(regression tests)로서는 유용하지만, 증거로 사용하기에는 위험합니다. 만약 평가가 테스트 중인 메커니즘을 중심으로 작성된다면, 시스템은 가장 증명력이 낮은 부분에서 오히려 강력해 보일 수 있습니다.
1. 문제점
긴 LLM 세션은 비용이 많이 듭니다. 모든 새로운 요청이 이전의 전체 대화 기록을 전달받는다면, 비용은 대화 길이에 따라 증가합니다. 명백한 엔지니어링적 대응은 히스토리를 압축된 상태로 압축하고, 모델에게 해당 상태와 가장 최근의 대화 턴(turns)을 제공하는 것입니다.
가설은 다음과 같았습니다:
압축된 세션 상태(Compact session state)는 답변의 정확도를 잃지 않으면서 프롬프트/컨텍스트(prompt/context) 사용량을 줄일 수 있다.
이는 매력적입니다. 더 작은 프롬프트, 더 긴 세션, 더 저렴한 에이전트(agents), 그리고 불필요한 컨텍스트의 감소를 약속합니다. 하지만 여기에는 함정이 숨어 있습니다. 만약 상태가 잘못된 유형의 정보를 압축한다면, 그것은 메모리를 최적화하는 것이 아니라 데이터를 삭제하는 것이 됩니다.
2. 로컬 평가는 좋아 보였다
저는 제가 만든 30개의 사례 코퍼스(corpus)로 시작했습니다. 여기에는 다음이 포함되었습니다:
- 정확한 사실(exact facts);
- 지원 노트(support notes);
- CRM 스타일의 노트;
- 코딩 세션;
- RAG 방식의 컨텍스트(RAG-like context);
- 혼합 언어 사실;
- 선호도 및 결정 사항;
- 부정적인 짧은 컨텍스트 사례.
예시:
{
"id": "exact_authorization_code",
"question": "인증 코드는 무엇입니까? 코드만 답변하세요."
...
이 코퍼스(corpus) 상에서 시스템은 좋아 보였습니다. 하지만 처음 나타난 꽤 괜찮은 수치들은 드라이 런(dry-run) 결과였습니다. 드라이 런은 모델을 호출하지 않습니다. 즉, 설계 단계에서 이미 정답이 기대되는 파편들과 일치하도록 만들어진 상태입니다. 이 모드는 파이프라인(pipeline)을 점검하는 데는 유용하지만, 품질에 대한 증거는 아닙니다.
체커(checker)의 아티팩트(artifacts)와 혼합 언어 격차를 수정한 후 진행한 첫 번째 전체 실제 모델 실행 결과는 다음과 같았습니다:
corpus: 30 cases
noise: +40 turns
accuracy: 1.000 (30/30)
...
이는 드라이 런보다 강력한 결과였습니다. 하지만 핵심적인 문제는 남아 있었습니다. 바로 코퍼스(corpus)가 제가 만든 것이라는 점입니다. 코퍼스는 해당 메커니즘이 이미 잘 보존하고 있는 것들을 중심으로 작성되었습니다.
3. 합성된 30/30 결과가 충분하지 않았던 이유
로컬 평가(local eval)는 주로 정확한 사실과 지속적인 결정 사항들을 테스트했습니다:
- 코드(codes);
- 엄격한 형식의 날짜(dates in strict formats);
- ID;
- 파일 경로(file paths);
- 명시적인 선호도(explicit preferences);
- 짧은 규칙(short rules);
- "잊지 말 것"에 해당하는 사실들.
이는 회귀 테스트(regression testing)에는 중요합니다. 하지만 이것이 장기적인 대화 기억(long-term conversational memory)과 동일한 것은 아닙니다.
실제 대화 기억은 종종 다음과 같은 것들을 요구합니다:
- 어떤 일이 언제 일어났는지;
- 특정 세션과 관련하여 "어제"가 무엇을 의미했는지;
- 여러 대화에 걸친 이벤트들이 어떻게 연결되는지;
- 누가 무엇을 말했는지;
- 두 사람이 공통적으로 가진 것은 무엇인지;
- 질문에 명시되지 않았더라도 답변을 위해 필요한 사실이 무엇인지.
저의 로컬 평가는 제가 이미 압축하는 방법을 알고 있는 유형의 기억만을 테스트했습니다. 외부 벤치마크(external benchmark)는 제가 자신의 메커니즘에 맞춰 형성하지 않은 것들을 테스트했습니다.
4. LoCoMo가 주장을 깨뜨리다
외부 검증을 위해 저는 LoCoMo를 사용했습니다. LoCoMo는 매우 장기적인 대화 기억을 위한 벤치마크입니다. LoCoMo 대화는 평균 약 300턴, 9K 토큰, 최대 35개 세션으로 구성됩니다. 이는 질의응답(QA), 이벤트 요약, 그리고 다중 세션 대화 이해를 통해 장기 기억을 테스트합니다.
첫 번째 결과는 가혹했습니다:
raw : 8/15 = 0.53
projected_facts : 2/15 = 0.13
projected_hybrid : 2/15 = 0.13
최적화된 상태(optimized state)는 원본 컨텍스트(raw context)가 보존했던 정답의 약 4분의 1만을 유지했습니다. 컨텍스트 저장(context saving) 자체는 94-99%로 매우 훌륭해 보였습니다.
그것은 최적화가 아니었습니다. 필요한 정보의 삭제였습니다.
대화 라인에 세션 타임스탬프(session timestamps)를 추가한 후, 원본 베이스라인(raw baseline)이 개선되었습니다:
raw : 0.80
projected_hybrid : 0.20
retained_vs_raw : 0.25
따라서 베이스라인이 좋아졌음에도 문제는 사라지지 않았습니다. 투영된 상태(projected state)가 필요한 메모리 유형(memory type)을 보존하지 못하고 있다는 사실이 더욱 명확해졌습니다.
중요한 방법론적 주의 사항이 있습니다. 초기 0.13 수치는 엄격한 부분 문자열/토큰 검사기(substring/token checker)를 사용했습니다. 이러한 검사기는 의미론적으로 올바른 날짜 답변을 놓칠 수 있습니다. 예를 들어, 정답(gold answer)은 2023년 5월 25일 이전의 일요일이지만, 모델은 2023년 5월 20일이라고 답변할 수 있습니다.
하지만 그 격차는 검사기 오류로 치부하기에는 너무 컸습니다. 원본(raw)은 8개의 정답을 맞혔지만, 투영된 상태(projected)는 2개에 그쳤습니다.
5. 무엇이 실패했는가
LoCoMo 이후, 세 가지 실패가 드러났습니다.
5.1 정적 사실(Static Facts)은 에피소드 기억(Episodic Memory)이 아니다
초기 상태는 다음과 같은 정확한 사실들을 잘 보존했습니다:
- 코드(codes);
- 경로(paths);
- ID;
- 엄격한 날짜(strict dates);
- 명시적인 사용자 결정(explicit user decisions);
- 선호도(preferences);
- 제약 조건(constraints).
하지만 다음과 같은 것들은 제대로 보존하지 못했습니다:
- 이벤트 순서(event sequence);
- 상대적 날짜(relative dates);
- 세션 날짜 기준의 "어제(yesterday)";
- 공유된 관심사(shared interests);
- 멀티홉 링크(multi-hop links);
- 증거-이웃 컨텍스트(evidence-neighbor context).
LoCoMo가 요구한 것은 에피소드 기억(episodic memory)이었습니다. 즉, 누가 무엇을, 언제, 어디서 했는지, 그리고 그것이 세션 전반에 걸쳐 어떻게 연결되는지에 대한 것이었습니다.
5.2 어휘적 검색(Lexical Retrieval)만으로는 부족했다
저는 검색 방식(retrieval-style)의 접근법도 테스트했습니다. 모든 것을 하나의 상태로 압축하는 대신, 각 질문에 대해 관련 청크(chunks)를 선택하는 방식입니다.
결과:
append_full : 32/60 = 0.533, query saving 45.89%
append_retrieved : 25/60 = 0.417, query saving 90.73%
append_retrieved가 경제성 측면에서는 더 좋아 보였지만, 품질은 떨어졌습니다. 이유는 간단합니다. 질문과 증거(evidence)가 단어를 공유하지 않을 때 어휘적 중첩(lexical overlap)은 실패하기 때문입니다.
전형적인 실패 사례:
- "Caroline가 무엇을 연구했나요?"라는 질문은
adoption agencies를 검색하지 못했습니다. - 공유된 스트레스(shared-destress) 질문은
dance를 검색하지 못했습니다. - 무술(martial-arts) 질문은
Kickboxing, Taekwondo를 검색하지 못했습니다. - 시간적(temporal) 질문과 멀티홉(multi-hop) 질문은 더 자주 실패했습니다.
5.3 날짜(Dates)는 별도의 실패 범주였습니다
200개의 QA(질의응답) 테스트 결과, 주요 격차는 시간적(temporal) 범주에 집중되었습니다:
raw : 126/200 = 0.63
append-only : 111/200 = 0.56
retention : 88%
...
이러한 구분은 중요했습니다. 메모리가 일률적으로 나빴던 것이 아닙니다. 시간적 닻(temporal anchors)이 문제였습니다.
진단이 정확하면, 해결책도 정확할 수 있습니다.
6. 시도의 사다리 (Ladder of Attempts)
첫 번째 실패에서 최종 결과로 바로 도약할 수는 없었습니다. 여러 접근 방식이 특정 이유로 인해 폐기되었습니다.
| 접근 방식 | 결과 | 실패 또는 범위 축소 이유 |
|---|---|---|
| 텍스트 압축 (text compression) / 투영된 상태 (projected state) | 2/15 = 0.13 | 정확한 사실은 유지했으나, 에피소드 기억 (episodic memory)을 상실함 |
| ... |
이 표가 실제 연구의 이야기입니다. 유용한 메커니즘은 추측으로 찾아낸 것이 아닙니다. 더 그럴듯해 보이는 메커니즘들이 먼저 탈락했기에 살아남은 것입니다.
7. 살아남은 것
살아남은 설계에는 두 가지 제약 조건이 있었습니다.
첫째: 전체 상태를 다시 요약(re-summarize)하지 마십시오.
둘째: 정확한 필드들을 결정론적(deterministically)으로 보호하십시오.
추가 전용(append-only) 규칙은 간단합니다:
- 새로운 대화(exchange)만 압축합니다.
- 압축된 청크(chunk)를 동결(freeze)합니다.
- 이를 메모리에 추가(append)합니다.
- 오래된 청크를 절대 다시 압축하지 않습니다.
이것이 중요한 이유: 만약 오래된 사실들이 압축기를 반복해서 통과하게 되면, 작은 손실들이 누적됩니다. 각 대화가 한 번만 압축되고 동결된다면, 손실이 같은 방식으로 복리처럼 쌓일 수 없습니다.
초기 append-only 결과는 raw 방식보다 훨씬 좋아 보였습니다: 6개의 대화에서 103% 유지율(retention)을 기록했습니다. 그것은 소표본에 의한 인위적인 결과(artifact)였습니다. 200개의 QA 테스트에서 유지율은 88%로 떨어졌습니다. 이는 유용한 정보였습니다. 아키텍처가 도움이 되었다는 점은 보여주었지만, 시간적 격차(temporal gap)는 여전히 실재한다는 것을 나타냈기 때문입니다.
8. 데이트-가드 (Date-Guard)
해결책은 결정론적인 날짜 보호(deterministic date protection)였습니다.
아이디어는 다음과 같습니다:
- 절대적 시간 표현 (absolute time expressions) 추출;
- 상대적 시간 표현 (relative time expressions) 추출;
- 상대적 표현에 세션 날짜 (session date) 부착;
- 이러한 시간 앵커 (time anchors)를 압축된 상태 (compressed state)에 추가.
이는 LLM에게 날짜를 주의해서 다루라고 요구하는 것이 아닙니다. 선택의 여지를 없애는 것입니다. 압축기 (compressor)는 산문을 단축할 수 있지만, 날짜 앵커는 명시적인 필드 (explicit fields)로서 살아남습니다.
200개의 QA 설정에 대한 결과:
가드 미사용 (without guard):
유지율 (retention) 88%
시간적 오류 (temporal cat) 79%
...
날짜가 별도로 보호되면서 산문 압축기 (prose compressor)가 더 공격적으로 작동할 수 있게 되었기에 절약 효율이 향상되었습니다.
최종적인 솔직한 수치:
추가 전용(append-only) + 날짜 가드(date-guard): 94% 유지율, 쿼리당 60% 절약
이것은 해결된 메모리 (solved memory)가 아닙니다. LLM 컨텍스트 (context)에 대한 보편적인 대안도 아닙니다. 이것은 좁은 범위의 결과입니다: 추가 전용 압축 (append-only compression)과 특정 필드에 대한 결정론적 보호 (deterministic protection)의 조합입니다.
9. 비용 및 범위 (Cost and Scope)
이 메커니즘은 짧은 대화에는 유용하지 않습니다.
짧은 세션에서는 고정된 오버헤드 (fixed overhead)가 절약분보다 커질 수 있습니다:
추가된 노이즈 교환 0회: 예측 결과가 원본(raw)보다 나쁨
추가된 노이즈 교환 1회: 예측 결과가 여전히 대개 더 나쁨
또 다른 중요한 차이점은 컨텍스트 윈도우 (context-window) 절약과 API 비용 (API-cost) 절약은 동일한 지표가 아니라는 점입니다.
실제 제공업체(provider)를 대상으로 한 스모크 테스트 (smoke test) 결과는 다음과 같습니다:
원본 대비 컨텍스트 윈도우 절약 백분율 (context_window_saved_pct_vs_raw_estimate): 14.61
원본 대비 제공업체 총 비용 절약 백분율 (provider_total_saved_pct_vs_raw): -2.83
최종 프롬프트는 더 작아졌지만, 준비 과정에서 추가적인 호출 (calls)이 발생했기 때문에 전체 제공업체 비용은 더 나빠졌습니다.
60개의 QA에 대한 추가 전용 (append-only) 전체 적용 시:
원본 대비 쿼리 절약 백분율 (query_saved_pct_vs_raw) : 45.89%
원본 대비 제품 절약 백분율 (product_saved_pct_vs_raw) : 23.92%
손익분기점 쿼리 수 (break_even_queries) : 28.72
...
따라서 이 메커니즘은 설정 비용을 분할 상환 (amortized)할 수 있는 긴 세션에서만 흥미로운 주제가 됩니다.
10. 교훈 (Lessons)
교훈 1: 합성 평가 (Synthetic eval) 그 자체로는 증거가 될 수 없다
합성 평가는 회귀 테스트 (regression)에는 유용합니다. 하지만 일반화 (generalization)에 대한 증거로는 약합니다.
만약 저자가 자신의 메커니즘에 맞춰 평가를 작성한다면, 시스템은 저자의 사각지대 (blind spots)를 맞춤으로써 통과할 수 있습니다.
교훈 2: 압축률 (Compression ratio)은 유지율 (retention) 없이는 허영 지표 (vanity metric)일 뿐이다
99% 컨텍스트 절약 (context saving)은 답변 유지율 (answer retention)이 무너진다면 아무런 의미가 없습니다.
핵심 지표는 "얼마나 많이 삭제했는가?"가 아니라 "얼마나 많은 정확한 동작이 살아남았는가?"입니다.
교훈 3: 메모리는 단일한 개념이 아니다
정확한 사실 (Exact facts), 선호도 (preferences), 에피소드 사건 (episodic events), 시간적 닻 (temporal anchors), 다단계 관계 (multi-hop relations) 및 출처 근거 (source evidence)는 서로 다른 메모리 유형입니다.
압축기 (compressor)는 하나를 보존하면서 다른 하나를 파괴할 수 있습니다.
교훈 4: 결정론적 가드 (Deterministic guards)가 중요하다
일부 필드는 생성형 요약 (generative summary)에 맡겨서는 안 됩니다:
- 날짜 (dates);
- 금액 (amounts);
- ID (IDs);
- 코드 (codes);
- 이름 (names);
- 상태 (statuses);
- 경로 (paths);
- 제약 조건 (constraints).
만약 특정 필드를 잃는 것이 정확성을 해친다면, 이를 결정론적 (deterministically)으로 추출하여 명시적으로 보존하십시오.
교훈 5: 작은 샘플은 거짓말을 한다
6개의 대화에 대한 103% 유지율 (retention) 결과는 매우 흥미로워 보였습니다. 하지만 200개의 QA (질의응답)로 늘어나자 88%가 되었습니다. 유용한 신호는 낙관적인 숫자가 아니라, 손실이 어디에서 발생했는지를 보여주는 카테고리별 분석이었습니다.
11. 한계점 (Limitations)
이것은 학술적인 벤치마크 논문이 아닙니다.
한계점:
- 하나의 주요 외부 대화 메모리 벤치마크 사용;
- 200-QA 실행 전의 작고 중간 규모의 QA 슬라이스 사용;
- 통계적 유의성 (statistical significance) 분석 부재;
- 초기 일부 측정에서 엄격한 부분 문자열 확인 (substring checking) 사용;
- LLM-판사 (LLM-judge) 확인 방식은 한 문제를 해결하지만 다른 문제를 야기함;
- 최종
94%/60%결과는 안정적인 주장으로 취급되기 전에 압축된 부록 표와 함께 발표되어야 함.
이 결과는 공학 연구 노트 (engineering research note)로 읽는 것이 가장 적절합니다. 즉, 광범위한 주장의 실패, 국소적인 진단, 그리고 더 엄격한 테스트를 견뎌낸 더 좁은 범위의 메커니즘에 대한 기록입니다.
12. 결론 (Conclusion)
로컬 평가 (local eval)는 다음과 같이 말했습니다:
30/30
외부 벤치마크 (external benchmark)는 다음과 같이 말했습니다:
0.13
최종적으로 살아남은 메커니즘은 다음과 같이 말했습니다:
94% 유지율 (retention) / 쿼리당 60% 절약 (saving)
중요한 결과는 이것이 "메모리 문제를 해결했다"는 것이 아닙니다. 해결하지 못했습니다.
중요한 결과는 외부 벤치마크가 시스템으로 하여금 자체 평가를 통해 거짓말하는 것을 멈추게 만들었다는 점입니다. 유용한 아키텍처 (architecture)는 원래의 성공 사례가 실패한 후에야 비로소 나타났습니다.
참고 문헌 (References)
참고 문헌 (References)
- LoCoMo: "Evaluating Very Long-Term Conversational Memory of LLM Agents" — https://arxiv.org/abs/2402.17753
- Lost in the Middle: "How Language Models Use Long Contexts" — https://arxiv.org/abs/2307.03172
- "Investigating Data Contamination in Modern Benchmarks for Large Language Models" — https://arxiv.org/abs/2311.09783
- "Data Contamination Quiz: A Tool to Detect and Estimate Contamination in Large Language Models" — https://arxiv.org/abs/2311.06233
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기