로컬 LLM이 실제보다 멍청하게 느껴지는 이유: 어텐션 백엔드·KV 캐시·양자화 실험
Why your local LLM feels dumber than it is
TL;DR Highlight
어텐션 백엔드·KV 캐시·양자화만 바꿔도 툴 호출이 깨졌다
Who Should Read
vLLM으로 로컬 모델을 띄워 에이전트 툴 호출을 돌리는데 가끔 이상하게 실패해 원인을 찾는 백엔드 개발자
Core Mechanics
- 같은 가중치도 환경마다 결과가 다르다
- GPU 세대와 명령어 세트가 다르면 같은 weight여도 다음 토큰 계산이 달라진다.
- 저자는 vLLM 나이틀리 컨테이너에 패키지가 734개(Python 252개) 들어 있다고 짚었다.
- 어텐션 백엔드만 바꿔도 토큰이 갈린다
- Qwen3.6-27B BF16, RTX PRO 6000 Blackwell, 약 100k 토큰 프롬프트에서 Triton을 기준으로 FlashAttention 2·FlashInfer와 비교했다.
- 초반 수천 토큰은 모두 같았지만 뒤쪽 구간부터 top-1 토큰이 서로 달라졌다.
- 같은 백엔드를 반복 실행하면 logits가 비트 단위로 같아서, 차이는 랜덤 노이즈가 아니다.
- KV 캐시 양자화는 툴 호출을 깬다
- 가중치는 BF16으로 두고 KV 캐시만 양자화해도 divergence(분기)가 생겼다.
- int8은 틀어졌다가 회복했지만 int4는 회복하지 못했고, 재현 가능한 툴 호출 오류가 나왔다.
- 4비트 양자화는 툴 호출을 더 자주 망쳤다
- 5개 비교에서 INT8 W8A16이 공식 FP8(W8A8)과 NVIDIA NVFP4보다 토큰 뒤집힘이 적었다.
- NVFP4는 최하위였고, 88k 컨텍스트 즈음 토큰 뒤집힘이 약 50%였다.
- NVFP4와 AWQ W4A16은 툴 호출을 제대로 닫지 못했고 'show arp' 대신 'show run'을 실행했다.
Community Reactions
- llama.cpp의 파서 버그 사례
- Step 3.7 Flash를 llama.cpp에서 돌리다 파서가 줄바꿈 `\n`을 reasoning 블록에 포함시켜 추론 루프가 생겼다는 경험이 나왔다.
- 긴 멀티턴 에이전트 세션에서만 드러났다고 한다.
- KV 캐시는 양자화하지 말라는 의견
- 체크포인트가 양자화 KV 캐시로 학습되지 않았다면 추론 때 양자화하지 말아야 한다는 의견이 있었다.
- 어떤 댓글러는 KV 캐시 비양자화와 최고 Q8 사용을 원칙으로 삼고 느려도 정확한 쪽을 택한다고 했다.
- llama.cpp 문법 강제 덕에 일부 오류는 없다는 의견
- llama.cpp와 ik_llama.cpp는 툴 호출이 감지되면 문법을 강제해서 툴 호출 미종료는 안 생긴다는 의견이 있었다.
- 잘못된 명령어를 고르는 오류는 여전히 가능하다고 했다.
- 클라우드에도 해당하는지 궁금하다는 질문
- 낮과 저녁, 또는 하루 뒤 재개한 세션에서 품질이 달라 보이는 경험을 두고 KV 캐시 정책 영향인지 묻는 댓글이 있었다.
- 답은 달리지 않았다.
How to Apply
- KV 캐시 양자화부터 끄고 재실행하기
- 오늘 툴 호출이 간헐적으로 실패하는 로컬 서버의 KV 캐시 dtype을 BF16으로 되돌려라.
- 같은 프롬프트를 실패 케이스 5개 이상으로 재실행해 결과를 비교하라.
- 백엔드·양자화를 바꿀 때 툴 호출 회귀 테스트 돌리기
- 실제 에이전트 세션 로그를 수집해 고정 테스트 세트로 만들라.
- 어텐션 백엔드, 양자화, 텐서 병렬도를 하나씩만 바꿔 툴 호출 성공률을 비교하라.
- 샘플러 설정을 모델 카드와 맞추기
- Hugging Face 모델 카드의 temp, top-p, chat template을 서버 설정과 대조하라.
- 특히 temp가 너무 낮아 THINK 루프가 나는지 확인하라.
- 양자화 모델 카드의 지표 믿기 전에 공개 정보 확인하기
- 낮은 KLD를 내세우면 기준 체크포인트, 평가 텍스트, 컨텍스트 길이, KL 방향이 공개됐는지 먼저 보라.
- 공개되지 않았다면 그 수치로 모델을 고르지 말고 직접 워크로드로 평가하라.
Try It
# Claude나 ChatGPT에 붙여넣기 (논문 방법의 간이 버전: 툴 호출 회귀 점검표 만들기)
나는 vLLM으로 로컬 모델을 돌리며 에이전트 툴 호출을 쓴다. 아래 환경에서 툴 호출이 가끔 실패한다.
- 모델: {{모델명}}
- 양자화: {{양자화 방식}}
- KV 캐시 dtype: {{KV dtype}}
- 어텐션 백엔드: {{백엔드}}
- 텐서 병렬도: {{TP 값}}
- 실패 로그: {{실패한 툴 호출 로그}}
위 변수를 한 번에 하나씩만 바꿔 원인을 좁히는 실험 계획을 표로 만들어 줘. 각 실험마다 '바꿀 설정', '유지할 설정', '성공 기준(툴 호출 인자가 정답과 일치하는지)', '반복 횟수'를 넣어 줘.
이어서 해 볼 것: 표대로 KV 캐시를 BF16으로 되돌리는 실험부터 돌리고 결과를 붙여넣어 다음 단계를 물어보자.Terminology
관련 논문
The Judge Can Debias Itself: LLM-as-a-Judge가 스스로 편향을 고치게 하는 법
심사 프롬프트에 편향 경고를 넣거나 스스로 비판시켰더니 21개 중 20개 조합에서 정확도가 올랐다
미국 노동시간의 90%는 AI 벤치마크가 제대로 다루지 못하는 일이다
벤치마크 29개를 직업 과제에 매핑했더니 노동시간 90%가 커버 밖
Postgres 19, AI 코드 리뷰가 버그를 너무 많이 찾아 출시 연기
LLM 코드 리뷰가 버그를 쏟아내 Postgres 19가 11월로 밀리고 기능 8~10개가 빠졌다
StarSkirmish Bench v0.2: LLM이 1시간 만에 짜는 StarCraft 봇 대결
LLM에게 1시간 동안 StarCraft 봇을 짜게 했더니 GPT-6 Astra가 1위
그럴듯한 설명 하나면 멀티모달 LLM 심사위원도 속는다 (JUPE 벤치마크)
정답은 그대로 두고 설명만 붙였더니 MLLM 심사위원의 오답 거절률이 12.7~13.8%p 떨어졌다
신경망은 이미 깔끔하다: polysemanticity의 원인 재해석
뉴런을 직접 들여다봤더니 대부분 한 가지 역할이 있었다는 주장
Linus Torvalds의 첫 LLM 보조 패치 시리즈
Linus가 LLM으로 folio 조회 패치 10개를 만들어 read() 벤치가 10배 빨라졌다