로컬 대규모 언어 모델(LLM)은 처음에는 번개처럼 빠르게 느껴집니다. 7B 또는 13B 파라미터 모델을 로드하고 짧은 프롬프트를 입력하면, 토큰이 기분 좋은 속도로 화면에 스트리밍됩니다. 그러다 긴 코드 블록을 붙여넣거나 채팅 기록이 수십 차례의 턴으로 늘어나면, 모델은 기어가는 듯 느려지기 시작합니다. 속도 저하는 완만하게 일어나지 않습니다. 마치 절벽에서 떨어지는 것과 같습니다. 방금 전까지 GPU가 토큰을 쏟아내고 있었다면, 다음 순간 시스템 모니터에는 메모리 압박이 쌓이는 것이 보이고 생성 속도는 버벅거리기 시작합니다. 이 현상이 정확히 언제 발생할지 깔끔한 공식으로 예측할 수는 없습니다. 유일하게 믿을 수 있는 지표는 하드웨어 그 자체입니다.

Context의 숨겨진 비용

생성하는 모든 토큰은 KV cache에 상태를 추가합니다. 이 캐시는 prefill 및 generation 단계에서 계산된 key와 value를 저장하며, 모델 가중치, attention buffer, 런타임 오버헤드와 함께 메모리에 상주합니다. 12 GB 또는 16 GB VRAM을 가진 일반적인 소비자용 GPU에서, KV cache는 결국 다른 모든 요소와 공간을 두고 경쟁하게 됩니다. 전용 비디오 메모리가 가득 차면 운영체제는 에러를 내며 멈추지 않습니다. 대신 넘치는 데이터를 shared memory로 조용히 넘기며, PCIe 버스를 통해 GPU와 시스템 RAM 사이에서 데이터를 주고받습니다. 해당 버스는 파일 전송에는 빠르지만, 그래픽 카드 내부의 메모리 대역폭에 비하면 거북이 수준입니다. 그 결과는 단순한 성능 저하가 아니라, 성능의 붕괴입니다.

절벽에 도달했음을 알리는 세 가지 신호

모델이 실행되는 동안 하드웨어 모니터를 관찰하십시오. 성능 절벽에 도달하면 세 가지 명확한 신호가 나타납니다.

  • Shared VRAM 상승. GPU 드라이버가 전용 비디오 RAM에서 호스트 운영체제가 관리하는 풀로 밀어낸 메모리입니다. 이 수치가 0 위로 올라가는 순간, 한계를 넘은 것입니다.
  • System RAM 사용량 급증. 넘친 데이터는 어딘가에 안착해야 하며, 그 목적지는 바로 메인 메모리입니다. 모델이 토큰을 생성하는 동안 RAM 사용량이 늘어난다면, 데이터가 GPU에서 오프로드되고 있다는 뜻입니다.
  • Eval 속도가 절반 이하로 하락. 10% 정도의 저하는 서멀 스로틀링(thermal throttling)이나 백그라운드 프로세스 때문일 수 있습니다. 하지만 50% 이상의 급격한 하락은 병목 현상이 tensor core에서 메모리 대역폭 및 PCIe 레이턴시로 옮겨갔음을 의미합니다. 생성 속도가 두 자릿수에서 한 자릿수로 떨어지는 것을 본다면, 이미 절벽 아래로 떨어진 것입니다.

빠른 벤치마크가 당신을 속이는 이유

짧은 테스트는 잘못된 자신감을 심어줄 수 있습니다. 100개 정도의 토큰이 담긴 프롬프트로 벤치마크를 수행하고 양호한 처리량을 확인한 뒤 만족한다면, 당신은 '허니문 단계'만을 측정한 것입니다. KV cache는 거의 비어 있고, 레이어들은 긴 prefill로 인한 부하를 받지 않은 상태입니다. 실제 메모리 점유율은 모델이 상당한 양의 프롬프트를 처리하고 캐시가 실제 작업 크기만큼 채워진 후에야 드러납니다. 깊은 prefill과 긴 generation 실행을 통해 테스트해야 합니다. 컨텍스트가 실제로 축적되도록 두십시오. 그래야만 메모리 압박이 안정화되어 진정한 한계를 보여줄 것입니다.

llama.cpp로 한계점 찾기

llama.cpp를 통해 모델을 실행 중이라면, 간단한 산술 연산과 인내심 있는 테스트 실행만으로 한계점을 측정할 수 있습니다.

1. Shared memory 사용량 측정.
최소한의 프롬프트로 기본(baseline) 전용 VRAM을 기록한 다음, 긴 컨텍스트 작업을 실행하고 최대치를 기록합니다. 최대치에서 기본값을 빼면, GPU에서 shared system memory로 넘쳐흐른 양이 나옵니다.

2. RAM 차이(delta) 계산.
시스템 RAM에 대해서도 동일하게 뺍니다. 긴 작업 중의 최대 RAM 사용량에서 기본 RAM 사용량을 뺍니다. 이 수치는 비디오 카드에서 메인 메모리로 얼마나 많은 데이터가 밀려났는지를 정확히 알려줍니다. 버스를 가로지르는 데이터 누출량을 수치화하는 것입니다.

3. Eval 속도 붕괴 시간 측정.
기본 tokens-per-second 속도와 모델이 긴 문서를 처리한 후의 속도를 비교합니다. 컨텍스트가 신선할 때는 초당 17개의 토큰을 거침없이 생성하다가, 캐시가 비대해진 후에는 초당 2개만 생성하는 모습을 볼 수도 있습니다. 이 15토큰의 차이가 바로 위험을 알리는 '탄광 속의 카나리아'입니다.

임계점 삼각 측량

곡선을 정확하게 그리려면 단 하나의 데이터 포인트에 안주하지 마십시오. 16,000 토큰, 32,000 토큰, 65,000 토큰에서 각각 세 번의 별도 테스트를 수행하십시오. 두 개의 점은 선을 암시할 수 있지만, 두 개의 점은 그저 추측일 뿐입니다. 세 번째 점이 있어야 현재 보고 있는 것이 측정 노이즈인지 아니면 실제 메모리 월(memory wall)인지 증명할 수 있습니다. 각 실행 결과 사이의 차이를 빼서, 모델, 양자화 레이어, GPU의 특정 조합에서 토큰 1,000개가 추가될 때마다 추가로 소비되는 메모리가 얼마인지 계산하십시오.

기울기를 구했다면 이를 바탕으로 예측할 수 있습니다. 토큰당 메모리 소모량을 구한 뒤, 이를 목표 컨텍스트 길이에 곱하고, 단위 변환을 위해 1024로 나눈 다음, 그 결과값을 기본 모델의 VRAM 부하에 더하십시오. 공식은 다음과 같습니다.

모델 VRAM 부하 + (토큰 수 × 토큰당 메모리 ÷ 1024) = 이론적 VRAM 사용량

이 예측은 예언이 아닙니다. 실제 동작에서 도출된 지표입니다. 전체 프로덕션 실행을 결정하기 전에 한계치를 추정하는 용도로 사용하십시오.

이론적 공식이 실패하는 이유와 양자화가 해결할 수 있는 것

교과서적인 공식은 로컬 추론의 복잡한 현실을 무시합니다. 아키텍처마다 어텐션 버퍼를 할당하는 방식이 다릅니다. 운영 체제는 디스플레이 드라이버, 컴포지터, CUDA 컨텍스트를 위해 VRAM을 예약합니다. 드라이버 버전에 따라 공유 메모리를 사용하는 공격성도 달라집니다. 이론적인 방정식은 브라우저에 탭이 가득 열려 있는 오후 2시, 당신의 컴퓨터에서 실제로 사용 가능한 VRAM이 얼마인지 알 수 없습니다. 특정 하드웨어에서 모델을 직접 실행하고 수치를 확인해야 합니다.

양자화는 부분적인 해결책을 제공합니다. KV 캐시를 f16에서 q8_0로 변경하면 정밀도를 거의 모든 실무 작업에 충분할 정도로 유지하면서도 메모리 점유량을 절반으로 줄일 수 있습니다. 이러한 변화는 여유 공간(headroom)을 확보해 줍니다. 하지만 면죄부를 주는 것은 아닙니다. 캐시는 입력되는 토큰마다 여전히 선형적으로 증가합니다. 결국 줄어든 크기조차 가용 전용 메모리를 초과하게 되고, 시스템 RAM으로의 스필오버(spillover)가 시작됩니다. 이 압박은 컨텍스트 창이 제한되거나 데이터 흐름이 멈출 때만 중단됩니다.

핵심 요약

마케팅 자료, 파라미터 수, 혹은 대략적인 계산을 믿지 마십시오. 모델을 로드하십시오. 시스템 모니터를 여십시오. 65,000 토큰 스레드를 실행하고, RAM이 상승하는 것을 지켜보며, 초당 토큰 수를 측정하십시오. 당신의 특정 화면, 당신의 특정 GPU에 나타나는 숫자만이 유일하게 의미 있는 숫자입니다. 컨텍스트는 언제나 승리합니다. 당신의 역할은 당신의 기기에서 컨텍스트가 정확히 언제 승리하는지 아는 것입니다.