이 글은 Claude의 응답 품질을 간헐적으로 저하시킨 세 가지 버그에 대한 기술 보고서입니다. 아래에서는 무엇이 발생했는지, 수정에 시간이 걸린 이유, 그리고 앞으로 어떤 점을 개선하는지 설명합니다.
8월부터 9월 초 사이, 세 가지 인프라 버그가 간헐적으로 Claude의 응답 품질을 저하시켰습니다. 현재 이 문제들은 모두 해결되었으며, 이 글을 통해 그간의 경위를 설명드리고자 합니다.
8월 초, 다수의 사용자로부터 Claude의 응답 품질이 떨어졌다는 보고가 들어오기 시작했습니다. 초기 보고는 일반적인 사용자 피드백의 편차와 구분하기 어려운 수준이었습니다. 그러나 8월 말로 갈수록 보고 빈도와 지속성이 높아졌고, 이에 조사를 개시한 결과 세 가지 개별 인프라 버그를 발견하게 되었습니다.
분명히 말씀드립니다. 저희는 트래픽 수요, 시간대, 서버 부하를 이유로 모델 품질을 의도적으로 낮추지 않습니다. 사용자들이 보고한 문제의 원인은 전적으로 인프라 버그에 있었습니다.
사용자들이 Claude에 기대하는 일관된 품질을 잘 알고 있으며, 인프라 변경이 모델 출력에 영향을 미치지 않도록 매우 높은 기준을 유지하고 있습니다. 이번 사건에서는 그 기준에 미치지 못했습니다. 아래 포스트모템에서 무엇이 잘못되었는지, 왜 탐지와 해결에 예상보다 오랜 시간이 걸렸는지, 그리고 유사한 문제의 재발을 방지하기 위해 어떤 개선을 진행하고 있는지 설명하겠습니다.
통상적으로 인프라에 대해 이 정도 수준의 기술적 세부 사항을 공개하지는 않지만, 이번 문제의 범위와 복잡성을 고려해 보다 포괄적인 설명이 필요하다고 판단했습니다.
Claude는 자체 API, Amazon Bedrock, Google Cloud의 Vertex AI를 통해 수백만 명의 사용자에게 제공됩니다. 하드웨어 플랫폼으로는 AWS Trainium, NVIDIA GPU, Google TPU를 사용하며, 이를 통해 전 세계 사용자에게 서비스를 제공하는 데 필요한 처리 용량과 지리적 분산을 확보하고 있습니다.
각 하드웨어 플랫폼은 고유한 특성을 가지며 플랫폼별 최적화가 필요합니다. 이러한 차이에도 불구하고, 모델 구현체 간 엄격한 동등성 기준을 적용합니다. 어떤 플랫폼에서 요청을 처리하든 사용자가 동일한 품질의 응답을 받아야 한다는 것이 목표입니다. 이러한 복잡성 때문에 인프라 변경 시 모든 플랫폼과 구성에 걸쳐 면밀한 검증이 필요합니다.

세 가지 버그가 시간적으로 겹쳐 발생한 탓에 진단이 특히 어려웠습니다. 첫 번째 버그는 8월 5일에 도입되어 Sonnet 4 요청의 약 0.8%에 영향을 미쳤습니다. 이어서 8월 25일과 26일의 배포에서 두 가지 버그가 추가로 발생했습니다.
초기 영향은 제한적이었으나, 8월 29일의 로드 밸런싱 변경으로 영향을 받는 트래픽이 증가하기 시작했습니다. 이로 인해 더 많은 사용자가 문제를 경험하는 한편 다른 사용자들은 정상적인 성능을 유지해, 상충하고 혼란스러운 보고가 뒤섞이게 되었습니다.
아래에서는 품질 저하를 초래한 세 가지 버그의 내용, 발생 시점, 해결 방법을 설명합니다.
8월 5일, 일부 Sonnet 4 요청이 출시 예정인 1M 토큰 컨텍스트 윈도우용으로 구성된 서버로 잘못 라우팅되었습니다. 이 버그는 초기에 요청의 0.8%에 영향을 미쳤습니다. 8월 29일, 정기적인 로드 밸런싱 변경으로 인해 짧은 컨텍스트 요청이 1M 컨텍스트 서버로 라우팅되는 비율이 의도치 않게 증가했습니다. 영향이 가장 심했던 8월 31일 특정 시간대에는 Sonnet 4 요청의 16%가 영향을 받았습니다.
이 기간에 요청을 보낸 Claude Code 사용자 중 약 30%가 하나 이상의 메시지가 잘못된 서버 유형으로 라우팅되어 저하된 응답을 받았습니다. Amazon Bedrock에서는 8월 12일부터 잘못 라우팅된 트래픽이 전체 Sonnet 4 요청의 최대 0.18%에 달했습니다. Google Cloud의 Vertex AI에서는 8월 27일부터 9월 16일 사이에 잘못된 라우팅이 전체 요청의 0.0004% 미만에서 발생했습니다.
다만, 일부 사용자는 더 심각한 영향을 받았는데, 이는 라우팅이 "고정(sticky)" 방식이었기 때문입니다. 한 번 잘못된 서버에서 요청이 처리되면, 이후의 후속 요청도 동일한 잘못된 서버에서 처리될 가능성이 높았습니다.
해결: 짧은 컨텍스트와 긴 컨텍스트 요청이 올바른 서버 풀로 전달되도록 라우팅 로직을 수정했습니다. 수정은 9월 4일에 배포되었으며, 자체 플랫폼과 Google Cloud Vertex AI에는 9월 16일까지, AWS Bedrock에는 9월 18일까지 롤아웃을 완료했습니다.
8월 25일, Claude API TPU 서버에 잘못된 설정이 배포되어 토큰 생성 과정에서 오류가 발생했습니다. 런타임 성능 최적화 관련 문제로 인해, 컨텍스트상 거의 생성되지 않아야 할 토큰에 높은 확률이 간헐적으로 부여되었습니다. 예를 들어, 영어 프롬프트에 대한 응답에 태국어나 중국어 문자가 삽입되거나, 코드에서 명백한 구문 오류가 발생하는 현상이었습니다. 영어로 질문한 일부 사용자에게 응답 중간에 "สวัสดี"와 같은 문자가 나타날 수 있었습니다.
이 손상은 8월 25~28일 사이의 Opus 4.1 및 Opus 4 요청, 그리고 8월 25일~9월 2일 사이의 Sonnet 4 요청에 영향을 미쳤습니다. 서드파티 플랫폼은 이 문제의 영향을 받지 않았습니다.
해결: 문제를 확인한 후 9월 2일에 해당 변경을 롤백했습니다. 배포 프로세스에 예기치 않은 문자 출력을 탐지하는 테스트를 추가했습니다.
8월 25일, Claude의 텍스트 생성 시 토큰 선택 방식을 개선하는 코드를 배포했습니다. 이 변경이 의도치 않게 XLA:TPU[1] 컴파일러에 잠재하던 버그를 촉발시켰으며, Claude Haiku 3.5 요청에 영향을 미친 것이 확인되었습니다.
Claude API의 Sonnet 4 및 Opus 3 일부에도 영향을 미쳤을 가능성이 있습니다. 서드파티 플랫폼은 이 문제의 영향을 받지 않았습니다.
해결: 먼저 Haiku 3.5에서 해당 버그를 확인하고 9월 4일에 롤백했습니다. 이후 Opus 3에서도 이 버그와 일치하는 사용자 보고를 확인하여 9월 12일에 롤백했습니다. Sonnet 4에서는 광범위한 조사에도 버그를 재현하지 못했지만, 만일에 대비하여 롤백을 진행했습니다.
동시에 (a) XLA:TPU 팀과 협력하여 컴파일러 버그 수정을 진행하고 있으며, (b) 정밀도를 강화한 정확한(exact) top-k를 사용하도록 수정을 배포했습니다. 자세한 내용은 아래 심층 분석을 참고하시기 바랍니다.
이 문제들이 얼마나 복잡했는지 보여드리기 위해, XLA 컴파일러 버그가 어떻게 발현되었고 왜 진단이 특히 까다로웠는지 설명하겠습니다.
Claude가 텍스트를 생성할 때, 가능한 모든 다음 단어에 대한 확률을 계산한 뒤 이 확률 분포에서 무작위로 샘플링합니다. 비정상적인 출력을 방지하기 위해 "top-p 샘플링"을 사용하는데, 이는 누적 확률이 임곗값(일반적으로 0.99 또는 0.999)에 도달하는 단어들만 고려하는 방식입니다. TPU에서는 모델이 여러 칩에 걸쳐 실행되며, 확률 계산이 서로 다른 위치에서 이루어집니다. 이러한 확률값을 정렬하려면 칩 간 데이터 조율이 필요하며, 이 과정이 상당히 복잡합니다.[2]
2024년 12월, TPU 구현체에서 temperature가 0일 때 가장 높은 확률의 토큰이 간헐적으로 누락되는 현상을 발견했습니다. 이 경우에 대한 우회 조치(workaround)를 배포하여 문제를 해결했습니다.

근본 원인은 혼합 정밀도(mixed precision) 연산에 있었습니다. 모델은 다음 토큰 확률을 bf16(16비트 부동소수점)으로 계산합니다. 그런데 벡터 프로세서는 fp32 네이티브이기 때문에, TPU 컴파일러(XLA)가 일부 연산을 fp32(32비트)로 변환하여 런타임 성능을 최적화할 수 있습니다. 이 최적화 패스는 xla_allow_excess_precision 플래그로 제어되며, 기본값은 true입니다.
이로 인해 불일치가 발생했습니다. 가장 높은 확률의 토큰에 대해 동일한 결과를 내야 하는 연산들이 서로 다른 정밀도 수준에서 실행되었고, 정밀도 차이로 인해 어떤 토큰이 최고 확률인지에 대한 판단이 엇갈렸습니다. 그 결과, 최고 확률 토큰이 고려 대상에서 완전히 사라지는 경우가 발생했습니다.
8월 26일, 정밀도 문제를 수정하고 top-p 임곗값 경계에서의 확률 처리 방식을 개선하기 위해 샘플링 코드를 새로 작성하여 배포했습니다. 그러나 이 문제들을 수정하는 과정에서 더 까다로운 문제가 드러났습니다.

xla_allow_excess_precision 플래그의 정상 동작이었습니다.수정 과정에서 근본 원인이 해결되었다고 판단하여 12월의 우회 조치를 제거했습니다. 그런데 이것이 근사 top-k(approximate top-k) 연산에 잠재하던 더 깊은 버그를 노출시켰습니다. 근사 top-k는 최고 확률 토큰을 빠르게 찾기 위한 성능 최적화 기법입니다.[3] 이 근사 연산은 특정 배치 크기와 모델 구성에서만 완전히 잘못된 결과를 반환했으며, 12월의 우회 조치가 의도치 않게 이 문제를 가리고 있었던 것입니다.

이 버그의 동작은 극도로 비일관적이었습니다. 앞뒤에 어떤 연산이 실행되느냐, 디버깅 도구가 활성화되어 있느냐와 같은 무관한 요인에 따라 동작이 달라졌습니다. 동일한 프롬프트라도 한 요청에서는 완벽하게 동작하고 다음 요청에서는 실패할 수 있었습니다.
조사 과정에서 정확한(exact) top-k 연산이 과거와 달리 성능 페널티가 크지 않다는 사실도 발견했습니다. 이에 근사 top-k에서 정확한 top-k로 전환하고, 일부 추가 연산도 fp32 정밀도로 표준화했습니다.[4] 모델 품질은 타협할 수 없으므로, 소폭의 효율성 감소는 감수하기로 했습니다.
기존 검증 프로세스는 벤치마크, 안전성 평가, 성능 지표에 의존합니다. 엔지니어링 팀은 수동 검수(spot check)를 수행하고, 소규모 "카나리(canary)" 그룹에 먼저 배포하는 방식을 사용합니다.
이번 문제들은 더 일찍 파악했어야 할 치명적인 허점을 드러냈습니다. 실행한 평가가 사용자들이 보고하는 품질 저하를 포착하지 못했는데, 이는 부분적으로 Claude가 개별 오류에서 잘 복구하는 경향이 있기 때문입니다. 내부 개인정보 보호 정책도 보고 조사에 어려움을 더했습니다. 내부 개인정보 보호 및 보안 통제 정책에 따라 엔지니어가 사용자와 Claude 간의 상호작용에 접근할 수 있는 방법과 시점이 제한되며, 특히 피드백으로 보고되지 않은 상호작용의 경우 더욱 그렇습니다. 이는 사용자 프라이버시를 보호하지만, 버그를 식별하거나 재현하는 데 필요한 문제 상호작용을 엔지니어가 확인하지 못하게 하는 요인이 됩니다.
각 버그가 서로 다른 플랫폼에서 서로 다른 증상을 서로 다른 비율로 발생시켰습니다. 이로 인해 단일 원인을 특정하기 어려운 혼란스러운 보고가 뒤섞였고, 무작위적이고 비일관적인 품질 저하처럼 보였습니다.
더 근본적으로는, 노이즈가 많은 평가에 지나치게 의존한 문제가 있었습니다. 온라인에서 부정적인 보고가 증가하고 있다는 것은 인지하고 있었지만, 이를 최근의 개별 변경 사항과 명확하게 연결할 방법이 부족했습니다. 8월 29일에 부정적 보고가 급증했을 때, 이를 통상적인 로드 밸런싱 변경과 즉시 연결 짓지 못했습니다.
인프라를 지속적으로 개선하는 동시에, Claude를 서빙하는 모든 플랫폼에서 위와 같은 버그를 평가하고 예방하는 방식도 개선하고 있습니다. 주요 변경 사항은 다음과 같습니다.
평가와 모니터링은 중요합니다. 하지만 이번 사건을 통해, Claude의 응답이 평소 수준에 미치지 못할 때 사용자로부터 지속적인 신호를 받는 것 역시 필수적이라는 점을 깨달았습니다. 사용자들이 보고한 구체적인 변화 사례, 예기치 않은 동작 사례, 다양한 사용 사례에서 관찰된 패턴은 모두 문제를 분리하는 데 큰 도움이 되었습니다.
사용자 여러분의 직접적인 피드백은 여전히 매우 소중합니다. Claude Code에서 /bug 명령어를 사용하거나, Claude 앱의 "좋지 않아요(thumbs down)" 버튼을 통해 피드백을 보내주실 수 있습니다. 개발자와 연구자들은 내부 테스트를 보완하는 새롭고 창의적인 모델 품질 평가 방법을 만들어 주시기도 합니다. 공유하고 싶은 평가 방법이 있다면 [email protected]으로 연락해 주세요.
커뮤니티의 이러한 기여에 항상 감사드립니다.
글: Sam McAllister. Stuart Ritchie, Jonathan Gray, Kashyap Murali, Brennan Saeta, Oliver Rausch, Alex Palcuie를 비롯한 많은 분들께 감사드립니다.
[1] XLA:TPU는 XLA 고수준 최적화 언어(주로 JAX를 사용해 작성)를 TPU 기계어 명령으로 변환하는 최적화 컴파일러입니다.
[2] 모델 크기가 단일 칩에 담기에는 너무 크기 때문에 수십 개 이상의 칩에 분산 배치됩니다. 따라서 정렬 연산도 분산 정렬로 수행됩니다. TPU는 GPU나 Trainium과 마찬가지로 CPU와는 다른 성능 특성을 가지므로, 순차(serial) 알고리즘 대신 벡터화된 연산을 활용한 별도의 구현 기법이 필요합니다.
[3] 근사 연산을 사용한 이유는 상당한 성능 향상을 가져다주었기 때문입니다. 이 근사법은 가장 낮은 확률의 토큰에서 약간의 부정확성을 허용하는 방식으로 동작하며, 정상적인 경우에는 품질에 영향을 미치지 않습니다. 다만 이번 버그로 인해 가장 높은 확률의 토큰이 누락되는 문제가 발생한 것입니다.
[4] 현재 수정된 정확한 top-k 구현은 top-p 임곗값 근처의 토큰 포함 여부에 미세한 차이를 만들 수 있으며, 드문 경우 top-p 값을 재조정하면 도움이 될 수 있습니다.