유아를 돌볼 수 있다면, LLM을 프로덕션 환경에 배포할 수 있습니다
요약
LLM을 프로덕션 환경에 배포할 때, 제공업체의 내부 업데이트나 모델의 드리프트(drift)로 인해 과거 데이터가 무효화되는 심각한 문제를 겪을 수 있습니다. 이러한 문제는 단순히 파라미터 조정이나 버전 고정만으로는 해결하기 어렵습니다. 따라서 LLM 시스템은 비결정론적(non-deterministic) 특성을 고려하여, '보정 세트(calibration set)'와 같은 인간이 검증한 작은 홀드아웃 세트를 정기적으로 재실행하고 그 결과를 비교하는 방식으로 설계해야 합니다.
핵심 포인트
- LLM의 프로덕션 배포는 모델 제공업체의 내부 업데이트로 인해 예측 불가능하게 변할 수 있습니다 (모델 드리프트).
- 단순히 파라미터를 조정하거나 버전을 고정하는 방식으로는 LLM의 근본적인 비결정론적 특성을 해결하기 어렵습니다.
- 시스템 안정성을 확보하려면, '보정 세트(calibration set)'라는 인간이 검증한 작은 홀드아웃 데이터셋을 보유하고 정기적으로 재실행하여 모델의 변화를 감지해야 합니다.
- LLM-as-judge와 같은 평가 시스템 역시 드리프트될 수 있으므로, 기준점(anchor) 역할을 할 안정적인 비교 세트가 필수적입니다.
- Temperature zero 설정은 단일 버전 내에서는 결정론적으로 보이지만, 버전 간의 큰 변화에 대해서는 아무런 보호 장치가 되지 못합니다.
몇 년 전, 저는 들어오는 제품 리뷰를 1~10점 척도로 점수화하는 시계열 파이프라인 (time-series pipeline)을 운영하고 있었습니다. 점수를 매기는 주체는 LLM이었습니다. 리뷰는 지속적으로 들어왔고, 평점은 제품 팀이 매주 월요일 아침에 확인하는 대시보드로 흘러 들어갔습니다. 몇 달 동안 모든 것이 깔끔하게 작동했습니다. 그러던 어느 월요일, 차트에 계단 모양의 변화가 생겼습니다. 지난주 리뷰 평균은 6.4였는데, 이번 주 평균은 7.6이었습니다. 동일한 제품이었고, 동일한 고객들이었습니다. 제가 다시 읽어본 리뷰 자체는 일 년 내내 받아왔던 것들과 구별할 수 없을 정도로 똑같았습니다. 모델이 변한 것이었습니다. 제공업체가 가중치 (weights)에 대해 조용한 업데이트를 진행했고, 지난주에 6.4에 해당하는 점수를 주었던 LLM이 이제 동일한 내용에 대해 7.6에 해당하는 점수를 주고 있었던 것입니다. 해당 대시보드의 모든 과거 비교 데이터는 소리 없이 무효화되었습니다. 정리하는 데 일주일이 걸렸습니다. 더 어려운 대화는 우리의 보고서가 애초에 얼마나 실제에 기반하고 있었는가에 대한 것이었습니다.
이러한 종류의 실패는 프로덕션 (production) 환경에서 LLM이 보이는 기본 동작입니다. 더 엄격한 파라미터 (parameters)를 사용하거나 버전을 고정 (pinned versions)하여 이를 엔지니어링으로 해결하려는 시도는 패배할 수밖에 없는 싸움입니다. 우리의 과업은 이를 고려하여 설계하는 것입니다. 저는 이 교훈을 두 번 배웠습니다. 한 번은 리뷰 파이프라인을 통해서였고, 한 번은 두 아이를 키우면서였습니다.
비결정론 (non-determinism)에 대해 어린 자녀를 둔 부모들이 이미 알고 있는 것
만약 당신이 유아기를 겪어보았다면, 당신은 그것을 실험이라고 부르지 않았을 뿐 이미 수백 번은 그 실험을 수행해 본 셈입니다. 지난 일주일 내내 싸 온 도시락이 매일 빈 그릇으로 돌아왔는데, 화요일에는 갑자기 온 힘을 다해 식탁 밖으로 밀쳐집니다. 여섯 밤 연속으로 효과가 있었던 잠자리 동화가 일곱 번째 밤에는 통하지 않습니다. 베이비시터가 확실하다고 장담했던 낮잠 루틴은 당신이 그것을 "규칙"이라고 부르기 시작하는 순간 깨져버립니다. 경험 많은 부모들은 결국 아이에게 결정론 (determinism)을 강요하는 것을 그만둡니다. 패턴과 추세는 여전히 중요합니다. 하지만 개별적인 입력 (input)이 반드시 개별적인 출력 (output)을 만들어낼 것이라고 기대하는 것을 멈추고, 변동성 (variance)과 싸우는 대신 이를 흡수하는 시스템을 구축하게 됩니다.
이것은 AI 엔지니어들이 보통 첫 번째 보정 회귀 (calibration regression)를 겪은 후에 수행하는 것과 동일한 변화입니다. LLM-as-judge (판사로서의 LLM) 또한 드리프트 (drift)될 수 있습니다. 리뷰 파이프라인을 통해 저는 판사가 시스템에서 가장 취약한 요소가 될 수 있다는 것을 배웠습니다. 평가받는 모델이 드리프트될 수 있습니다. 평가를 수행하는 모델 또한 드리프트될 수 있습니다. 기준이 될 안정적인 무언가가 없다면, 당신은 어느 쪽이 움직였는지 알 수 없습니다. 효과적인 패턴은 인간이 검증한 점수가 알려진 작은 홀드아웃 세트 (held-out set)를 보유하는 것이며, 정기적인 주기 (cadence)로 이를 다시 실행하는 습관을 갖는 것입니다. 이를 보정 세트 (calibration set)라고 부릅시다. 20개에서 50개 정도의 예시라면 충분합니다. 당신은 먼저 보정 세트의 점수를 다시 매깁니다. 만약 다른 변경 사항이 없는데 평균 점수가 6.4에서 7.6으로 급등한다면, 데이터가 아니라 판사가 움직였다는 것을 알게 됩니다. 그 기준점 (anchor)이 없다면, 동일한 진단을 내리기 위해 개별 리뷰를 몇 주 동안 읽고 무엇이 변했는지에 대해 논쟁해야 합니다. 이것이 바로 AgentControl의 오프라인 평가 (offline evaluations)가 제 역할을 하는 지점입니다. 보정 세트를 데이터셋 (dataset)으로 업로드하고, 판사를 지정한 뒤, 정기적인 주기 또는 어떠한 변동 사항의 변경 전에도 다시 실행하면 됩니다. 제가 고생하며 배워야 했던 규율, 즉 판사를 고정하고, 입력값을 비교 가능하게 유지하며, 단일 응답보다는 분포 (distribution)를 관찰하는 것이, 누군가 실행하는 것을 기억해야 하는 스크립트 대신 구성 (configuration)의 속성이 됩니다. 육아 버전으로 비유하자면 문틀에 그려진 연필 자국과 같습니다. 문틀은 움직이지 않습니다. 몇 달마다 아이를 신발을 벗기고 벽에 등을 대게 하여 문틀에 세웁니다. 만약 선이 3인치나 올라갔는데 아이가 운동화를 신고 있다는 것을 깨닫는다면, 그 무엇도 믿기 전에 신발을 벗기고 다시 측정해야 합니다. 문틀은 당신의 홀드아웃 세트입니다. 신발을 벗는 규칙은 재실행 (re-runs)을 비교 가능하게 유지하는 규율입니다.
Temperature zero는 안심할 수 있는 담요입니다. 온도를 0으로 설정하면 모델이 결정론적 (deterministic)이 될 것이라고 느껴집니다. 단일 모델 버전 내에서는 대체로 그렇습니다. 문제는 버전 내에서의 결정론적 특성이 버전 간에는 아무런 이득을 주지 못한다는 점입니다.
제 리뷰 파이프라인(reviews pipeline)은 내내 Temperature zero 상태로 실행되고 있었습니다. 제공업체의 내부적인 교체(swap)는 상관하지 않았습니다. 판사(judge)가 바뀌었고, 탐욕적 샘플링(greedy sampling)은 이전과 동일한 잘못된 확신을 가지고 새롭게 변화된 점수들을 계속해서 생성해냈습니다. Temperature zero는 테스트 중에 관찰할 수 있는 분산(variance)을 압축하여, 당신이 더 안전하다고 느끼게 만듭니다. 하지만 이는 실제로 프로덕션(production) 환경을 망가뜨리는 분산에 대해서는 아무런 조치도 취하지 못합니다. 모델이 매번 다른 유효한 출력을 생성할 수 있다고 가정하고 설계하십시오. 결국 그렇게 될 것이기 때문입니다.
Happy path를 만들기 전에 fallback을 구축하십시오. 마지막 단계는 시간 관계상 가장 자주 생략되곤 하며, 바로 그렇기 때문에 중요합니다. 새로운 기능을 잘 수행하는 모델을 출시하기 전에, 모델이 그 기능을 제대로 수행하지 못하거나, 느리게 수행하거나, 혹은 아예 수행하지 못할 때 작동할 경로를 먼저 출시하십시오. 알려진 잘못된 입력(known-bad inputs)에 대해 캐시된 응답(cached response)을 반환하는 형태의 LLM 엔드포인트(endpoint)를 예로 들면, 다음과 같은 것들이 있습니다: 기본 모델이 인라인 체크(inline check)를 통과하지 못할 때 트래픽을 넘겨받을 수 있도록 기본 모델 뒤에 배치된 보조 모델, 에러율이 임계값(threshold)을 넘으면 모델을 완전히 우회하는 서킷 브레이커(circuit breaker), 그리고 사용자에게 스택 트레이스(stack trace)를 반환하는 대신 실패 사례를 캡처하는 로깅 경로(logging path) 등이 있습니다. 이 중 어느 것도 생소한 것이 아닙니다. 이 모든 것은 모델이 어느 시점에는 오작동할 것이라고 가정하며, 오작동할 때 '좋은 동작'이 무엇인지를 정의합니다.
이와 동일한 아이디어의 더 강력한 버전은 fallback을 정적(static)인 대신 적응형(adaptive)으로 만드는 것입니다. 정적 fallback은 무언가 잘못되었다는 것을 사람이 인지하고 레버를 당겨야 합니다. 적응형 시스템은 프로덕션 신호(production signal) 자체를 관찰하며 사람의 개입 없이 전환을 수행합니다. 이것이 바로 설정 기반(configuration-driven) LLM 툴링(tooling)이 구축된 목적입니다. LaunchDarkly의 AgentControl을 사용하면, 모델 변형(model variations)이 코드가 아닌 설정으로서 존재하며, 배포 없이도 모델 간에 트래픽을 전환할 수 있습니다. 또한 보호된 롤아웃(guarded rollout)을 통해 온라인 평가 점수나 당신이 중요하게 생각하는 AgentControl 지표를 변형의 진행, 일시 중지, 또는 롤백 여부와 직접 연결할 수 있습니다. 판사가 점수가 임계값을 넘어 퇴보하는 것을 감지하면, 롤아웃은 스스로 되돌아갑니다.
폴백 (Fallback)은 더 이상 누군가가 문제가 생겼을 때를 대비해 작성해 둔 코드 조각이 아니게 됩니다. 그것은 스스로를 감시하는 아키텍처 (Architecture)가 됩니다. 부모들은 이미 이런 방식으로 운영합니다. 식료품점에서 아이가 울며 떼를 쓰는 상황은 반드시 발생합니다. 오전 11시에는 학교에서 "미열이 있다"며 전화가 올 것입니다. 당신은 가방 안에 미리 챙겨둔 간식이 있고, 문자로 연락할 수 있는 예비 베이비시터가 있습니다. 폴백 (Fallback)이 곧 아키텍처 (Architecture)입니다. 해피 패스 (Happy path)는 보너스일 뿐입니다. 저에게 무엇이 변했는가 하면, 리뷰 파이프라인 (Reviews pipeline) 사고 이후 제 업무 방식이 바뀌었습니다. 저는 모든 API 응답에서 반환되는 모델 버전 (Model version)을 기록하기 시작했습니다. 캘리브레이션 세트 (Calibration set)를 구축했습니다. 단 한 번의 평가 (Eval) 실행 결과를 판결로 신뢰하는 것을 그만두었습니다. 이제는 지루한 폴백 (Fallback) 경로가 인상적인 데모 (Demo) 경로보다 먼저 배포됩니다. 이 중 어느 것도 대안적인 방식보다 어렵지 않습니다. 이는 대부분, 어린 아이를 키우는 모든 부모가 이미 알고 있는 사실을 아키텍처 (Architecture) 단계에서 수용하는 문제입니다. 흥미로운 측정 단위는 샘플 (Sample)이 아니라 분포 (Distribution)입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기