[기획: AI 트렌드] llama.cpp가 고친 500 오류, 앞부분 공유는 첫 선택지 앞에서 멈춰야 했다
10월 31일에 닫힌 오류 보고
10월 31일, AI 모델 실행 프로그램 llama.cpp에 수정 하나가 합쳐졌습니다. 코드 변경 요청을 PR이라 하고, 관리자가 그 변경을 본 코드에 합치는 일을 머지라 합니다. 이 PR을 머지한 관리자 ngxson은 그날 오류 보고(이슈) 하나를 「완료」로 닫았습니다. 같은 날 나온 시험판 b12023에도 이 수정이 들어갔습니다.
고친 것은 /v1/systemone이라는 주소에서 나던 HTTP 500 오류입니다. HTTP 500은 서버 안에서 처리가 실패했다는 응답 번호입니다. 프로그램이 요청을 받는 이런 주소를 엔드포인트라 합니다.
/v1/systemone은 10월 초 ngxson이 llama.cpp에 처음 넣은 결정 모델용 엔드포인트입니다. 결정 모델은 글 대신 선택지마다 점수 하나를 돌려주는 AI 모델로, 우리가 앞선 글 글 대신 확률을 돌려주는 AI 모델, 같은 질문에 0.28과 0.45가 나왔다는 보고에서 다뤘습니다.
보고는 10월 13일에 올라왔고, 17일에는 제보자가 아닌 개발자 aiqubits가 수정 PR을 냈습니다. 보고 제목에 따르면 오류는 특정 서버 설정에서, 한 요청 속 두 질문의 앞부분이 같을 때 났습니다.
「질문과 선택지는 한 배치에 들어가야 한다」
제보자는 llama.cpp 서버에 결정 모델을 올리고 요청 하나를 보냈습니다. 요청에는 두 질문이 함께 쓰는 공통 내용(state) 하나와 똑같은 선택형 질문 두 개가 들어 있었습니다.
서버는 여러 요청을 동시에 처리하려고 처리 단위를 여럿 둘 수 있고, 이를 슬롯이라 합니다. 슬롯 수는 서버를 띄울 때 -np 설정으로 정합니다. 슬롯을 두 개(-np 2)로 띄운 서버에 이 요청을 보내자 HTTP 500이 돌아왔습니다. 슬롯 하나(-np 1)로 띄우면 정상 처리를 뜻하는 HTTP 200이 왔습니다.
실패한 응답에는 「질문과 그 선택지는 한 배치에 들어가야 한다」는 문구가 붙어 있었습니다. 배치는 서버가 한 번에 계산하는 입력 묶음입니다. 입력 하나가 여러 배치에 나뉘어 차례로 계산되기도 합니다.
슬롯을 네 개로 늘려도, 배치 크기를 작게 잡아도 실패했습니다. --no-cache-prompt 설정에서도 실패했습니다. 이름대로라면 앞 요청의 계산 결과를 다음 요청에 다시 쓰지 않게 하는 설정입니다. 그러니 문제는 요청과 요청 사이가 아니라, 요청 하나 안에서 생긴 것으로 보입니다(우리 판단).
llama.cpp의 결정 엔드포인트는 출력을 끝 한 곳이 아니라 중간에서도 읽는다
모델은 글을 토큰이라는 조각으로 잘라 읽습니다. llama.cpp의 기본 설정에서 글을 써 내는 생성용 계산은 입력의 마지막 토큰 위치에서만 출력을 꺼냅니다. 출력을 입력의 끝에서 읽는 셈입니다.
이 서버에는 앞부분 공유라는 최적화가 있습니다. 여러 입력의 앞부분이 같으면 그 부분을 한 번만 계산해 나눠 쓰는 방식입니다. 지문 하나에 문제 두 개가 딸린 시험지라면, 지문은 한 번 읽고 두 문제에 함께 쓰는 식입니다. 출력을 마지막 토큰에서만 읽는다면, 그 토큰만 따로 계산하면 앞부분은 어디까지 나눠 써도 됩니다(우리 판단).
엔드포인트를 처음 넣은 ngxson은 결정 모델을 두고, 기존 임베딩 모델을 감싼 것일 뿐이라고 적었습니다. 임베딩은 모델이 입력을 읽고 내놓는 숫자 묶음으로, 토큰 위치마다 하나씩 꺼낼 수 있습니다.
llama.cpp 서버에서는 결정 모델의 입력에 선택지마다 표지 토큰이 붙고, 서버는 그 표지 위치의 임베딩으로 선택지 점수를 만듭니다. 출력을 읽는 위치가 선택지 수만큼 있고, 첫 위치는 입력의 중간에 놓입니다.
제보자는 원인을 이렇게 추정했습니다. 서버는 한 요청에 묶인 질문들의 공통 앞부분을 한 번 계산해 질문별 계산에 복사합니다. 나눠 쓰는 길이의 상한은 전체 길이에서 토큰 하나를 뺀 길이뿐이었습니다. 두 질문이 똑같으면 공통 앞부분은 거의 입력 전체가 됩니다. 그래서 공통 앞부분이 첫 선택지 표지를 넘을 수 있고, 넘으면 그 표지는 앞 배치에서 계산됩니다. 그런데 점수를 응답으로 보내는 단계는 마지막 배치의 임베딩만 읽습니다. 첫 표지의 임베딩을 못 찾아 오류가 났다는 것이 제보자의 추정입니다. 실제 오류 문구의 앞부분도 「임베딩을 얻지 못했다」입니다.
토큰 하나만 따로 남기는 이 상한은, 출력을 마지막 토큰에서만 읽는다면 충분합니다(우리 판단). 수정 PR은 공유를 각 질문의 첫 출력 위치, 즉 첫 선택지 표지 앞까지로 줄였습니다. PR 설명에 따르면 그래야 선택지 표지의 임베딩이 마지막 배치에 남아 응답 단계에서 읽힙니다.
같은 엔드포인트를 지원하는 서버 프로그램 vLLM은 입력을 선택지 이름을 적을 자리(「id:」)까지 넣고, 바로 다음에 올 토큰 하나의 확률 분포에서 선택지 이름 토큰들의 확률을 읽습니다. 점수를 입력의 끝에서 읽는, 생성용 계산과 같은 방식입니다(우리 판단). 작성자는 후속 수정에서 공통 내용을 맨 앞에, 질문을 그 뒤에 두도록 순서를 바꿨고, 사유로 뒤쪽 질문의 정확도 하락을 들었습니다(작성자 보고 · 수치 없음).
성공 응답과 확률 대조는 별개의 확인
제보자는 이슈에 수정안도 적었습니다. 공통 앞부분을 각 질문의 첫 선택지 표지에서 자르는 방식으로, 머지된 수정과 방향이 같습니다. 그는 이 수정안으로 슬롯 두 개와 네 개에서 HTTP 200을 받았다고 적었습니다. 확률이 슬롯 하나일 때와 같은지는 아직 확인하지 않았다고도 적었습니다.
머지된 PR은 두 사람의 승인을 받고 자동 점검 열두 개를 통과했습니다. AI 도구가 만들었다고 밝힌 자동 코드 검토에는, 수정이 맞다는 평가와 함께 회귀 테스트가 없다는 지적이 달렸습니다. 회귀 테스트는 고친 문제가 다시 생기지 않는지 매번 자동으로 확인하는 시험입니다. 우리가 본 PR 페이지에서는 성능 측정 결과나 새로 추가된 테스트를 찾지 못했습니다.
우리가 열어 본 이슈와 PR에서는 확률이 슬롯 하나일 때와 같다는 확인 기록을 찾지 못했습니다. HTTP 200은 요청을 끝까지 처리했다는 뜻이지, 돌려준 숫자가 같다는 뜻은 아닙니다. 앞선 글에서 다룬 다른 제보자의 별개 보고에서는, 같은 요청의 확률이 단독일 때 0.28, 짧은 요청과 한 배치일 때 0.45였습니다(원인 미확정).
이번 수정으로 코드에 적힌 것은 경계 하나입니다. 앞부분은 나눠 써도 되지만, 출력을 읽는 첫 위치 앞까지만입니다. 우리는 출력을 마지막 토큰에서만 읽는다고 가정한 최적화가 들어올 때마다, 결정 모델에서는 이 경계부터 다시 따져야 한다고 봅니다(우리 판단 · 확신도 중간 · 사례 한 건). 다 고쳤는지는 HTTP 200이 아니라, 슬롯이 하나일 때와 사실상 같은(미세한 오차 범위의) 확률이 나오는지로 확인해야 합니다(우리 판단).
유의
"캐스케이드 ①(llama.cpp/v1/systemone 앞부분 공유 HTTP 500 수정 머지 10-31 · 시각 미표기 · 날짜 귀속으로 48시간 창 안) · 원천 직접 열람은 github.com뿐(이슈출처
- 기준일 = 2026년 11월 1일 오전(한국 시간).
- 이번에 원문을 직접 연 것은 아래 GitHub 페이지뿐입니다. 이슈 #30482·PR #30710·llama.h는 우리가 다시 열어 핵심 문장을 인용으로 대조했고, 나머지는 한 번 열람한 내용입니다. 요약 모델을 거쳐 내용을 돌려주는 웹 열람 도구(WebFetch)로 읽어 문단 전문을 한 줄씩 맞춰 보지는 못했습니다. GitHub 페이지의 시각은 시간대가 표기되지 않아 날짜만 적었습니다.
- 이해관계: Refract는 Anthropic의 Claude로 글을 분석하고 씁니다. 이 글이 다룬 수정 PR의 작성자는 AI 사용 여부를 묻는 항목에 「No」라고 적었습니다.
- 오류 보고(2026-10-13 등록 · 10-31 종결)·재현 조건·오류 문구·원인 추정과 확인 범위(제보자 1인) — 1차, 직접 열람 ggml-org/llama.cpp 이슈 #30482
- 수정 PR(2026-10-17 등록 · 10-31 머지)·설명 문구·승인과 자동 검토·AI 사용 공시 — 1차, 직접 열람 ggml-org/llama.cpp PR #30710
- llama.cpp 기본 출력 위치(마지막 토큰 · 임베딩은 전 위치) — 1차, 직접 열람 llama.h
- 시험판 b12023 변경 목록 — 1차, 직접 열람 llama.cpp b12023
/v1/systemone첫 도입(2026-10-02)·「임베딩 모델을 감싼 것」 발언 — 1차, 직접 열람 ggml-org/llama.cpp PR #29818- vLLM의 구현 방식과 순서 변경(작성자 자기보고 · 수치 없음) — 1차, 직접 열람 vllm-project/vllm PR #59299
- 같은 기간 vLLM 시험판(2026-10-31) 노트,
/v1/systemone관련 항목 없음 — 1차, 직접 열람 vLLM v0.33.0rc3 - 결정 모델의 출력 형식·다른 제보자의 배치 보고(제보자 1인 · 원인 미확정) — 우리 이전 글 글 대신 확률을 돌려주는 AI 모델, 같은 질문에 0.28과 0.45가 나왔다는 보고에서 인용(원출처 llama.cpp PR #30378·Ollama 문서·이슈 #30402)