지출 한도를 넘어: Azure의 LLM 워크로드를 위한 AI 비용 거버넌스 엔지니어링
요약
Azure 환경에서 LLM 워크로드의 비용을 효과적으로 관리하기 위한 거버넌스 전략을 다룹니다. 단순한 지출 한도 설정을 넘어, 토큰 소비를 아키텍처 관점에서 관측하고 제어하는 엔지니어링 접근법을 제안합니다.
핵심 포인트
- 단순 지출 한도 설정은 서비스 장애를 유발하는 실패한 전략임
- 비용 관리는 재무 팀이 아닌 아키텍트의 엔지니어링 영역임
- 토큰 소비를 일급 관측 가능성 지표로 만들어야 함
- Azure 네이티브 메트릭의 한계를 극복하기 위한 커스텀 텔레메트리 구축 필요
비용을 아끼기 위해 프로덕션 워크로드(production workload)를 중단시키는 지출 한도(spend cap)는 거버넌스가 아닙니다. 그것은 당신이 예약해 두고 잊어버린 장애(outage)일 뿐입니다.
누군가가 리소스 그룹(resource group)에 월간 예산을 설정해 둡니다. 화요일에 트래픽이 급증합니다. 한도가 작동하여 Azure OpenAI 배포가 응답을 멈추고, 이제 당신의 온콜 엔지니어(on-call engineer)는 프로모션 기간 동안 왜 결제 요약이 429 오류를 반환했는지 제품 소유자(product owner)에게 설명하고 있습니다. 당신은 몇 백 달러를 아꼈지만, 대신 장애(incident)를 샀습니다.
이것이 제가 보는 대부분의 ai cost governance azure 관행의 상태입니다. 이미 급증한 청구서에 경고 임계값(alert threshold)을 덧붙여 놓은 상태 말이죠. 그것은 질병이 존재한다는 사실만 알려줄 뿐, 치료하는 데에는 아무런 도움이 되지 않습니다.
지출 한도는 전략이 아니라 실패의 신호입니다
과다 지출은 증상입니다. 진짜 질병은 아키텍처적으로 인지되지 않은 토큰 소비(token consumption)입니다. 모든 요청이 프런티어 모델(frontier model)로 라우팅되고, 아무도 6개월 동안 읽지 않은 시스템 프롬프트(system prompts)가 있으며, 무한히 커지는 RAG 컨텍스트(RAG context), 그리고 어떤 기능이 얼마를 사용했는지 말할 방법이 없는 상태를 의미합니다.
예산 경고는 피해가 발생한 후에야 울립니다. Azure Cost Management가 당신에게 이메일을 보낼 때쯤이면, 토큰은 이미 소진되었고 청구서는 확정되었습니다. 당신은 불이 난 사진을 보고 있는 것과 같습니다.
이것이 비용이 별도의 FinOps 팀이 소유한 재무 대시보드가 아닌, 아키텍트(architects)의 영역이어야 하는 이유입니다. 어떤 모델이 어떤 요청을 처리할지, 프롬프트가 어떻게 구조화될지, 그리고 프로비전된 용량(provisioned capacity)을 구매할지 결정하는 사람들이 바로 청구 금액을 결정하는 사람들입니다. 재무 팀은 숫자를 보고할 수 있지만, 오직 엔지니어링만이 그 숫자를 바꿀 수 있습니다.
만약 당신의 첫 번째 비용 제어 수단이 경고 임계값이라면, 당신은 모니터링(monitoring)을 하고 있는 것이지 거버넌스(governance)를 하고 있는 것이 아닙니다.
토큰을 일급 관측 가능성 지표(first-class observability metric)로 만드세요
귀속(attribute)시킬 수 없는 것은 관리할 수 없습니다. 그리고 대부분의 팀이 너무 늦게 발견하는 구조적인 문제가 있습니다. 바로 Azure의 네이티브 메트릭(native metrics)은 중요한 요소에 비용을 귀속시킬 수 없다는 점입니다.
Azure OpenAI는 ProcessedPromptTokens 및 TotalTokens와 같은 메트릭(metrics)을 방출하며, 이를 모델 이름, 버전 및 API 이름별로 차원화(dimension)합니다. 하지만 테넌트(tenant), 기능(feature) 또는 사용자 흐름(user flow)별로는 결코 차원화하지 않습니다. Azure Monitor 로그 수집 문서에 따르면, 커스텀 텔레메트리(custom telemetry)는 사용자가 직접 제공해야 합니다. 이는 당신이 놓친 포털 설정의 문제가 아닙니다. 리소스 수준의 메트릭 스키마(metric schema)는 구조적으로 "어떤 기능이 이 비용을 사용했는가"라는 질문에 답할 수 없습니다.
따라서 직접 파이프라인을 구축해야 합니다. SDK 호출 지점을 래핑(wrap)하세요. API가 모든 완료(completion) 시 이미 반환하는 usage 객체를 캡처하고, 자체적인 차원(기능 ID, 테넌트 ID, 흐름 이름, 모델 ID)을 부착한 다음, 로그 수집 API(Logs Ingestion API)와 데이터 수집 규칙(data collection rule)을 통해 Log Analytics 커스텀 테이블로 전송하십시오. 만약 배포 단계 앞에 API Management(APIM)를 배치했다면, 게이트웨이의 APIM 정책에서 동일한 필드를 추출하십시오.
포털의 Azure OpenAI 사용 메트릭은 리소스 수준에서 집계됩니다. 기능별 및 테넌트별 귀속(attribution)을 위해서는 애플리케이션 계층에서 직접 계측(instrumentation)을 수행해야 합니다. 라우팅 임계값, 프롬프트 트리밍(prompt trimming), PTU 크기 산정 등 이 이후의 모든 거버넌스 결정은 이를 구축하기 전까지는 추측에 불과합니다.
토큰이 귀속되면 요청당 비용(cost-per-request), 기능당 비용(cost-per-feature), 테넌트당 비용(cost-per-tenant)은 쿼리 가능한 실제 숫자가 됩니다. 이것이 제대로 수행된 ai cost management azure의 중추입니다. 파이프라인 메커니즘에 대해서는 AI 워크로드를 위한 Azure Monitor 계측에서 더 자세히 다룹니다.
모든 토큰을 이를 소비한 흐름에 태깅하십시오. 그렇지 않으면 눈을 감고 최적화를 하는 것과 같습니다.
지능형 모델 라우팅은 핵심 레버입니다
모든 호출을 프런티어 모델(frontier model)로 기본 설정하는 것을 중단하십시오. 대부분의 프로덕션 LLM 트래픽은 어렵지 않습니다. 분류(classification), 추출(extraction), 짧은 요약(short summarization) 및 라우팅 결정에는 GPT-4급 모델이 필요하지 않으며, 이러한 작업에 프런티어 토큰 가격을 지불하는 것이 피할 수 있는 지출 중 가장 큰 비중을 차지하는 부분입니다.
라우팅 계층 (routing layer)을 구축하세요. 들어오는 요청의 복잡도를 점수화하여, 쉬운 요청은 작고 저렴한 모델로 보내고, 정말 어려운 작업에만 비싼 모델을 예약해 두는 방식입니다. 여기에 캐스케이드 (cascade)를 추가하세요. 만약 작은 모델의 답변이 신뢰도(confidence) 또는 검증(validation) 체크를 통과하지 못하면, 더 큰 모델로 에스컬레이션 (escalate)합니다.
다음은 공개 가격 페이지에서 가져온 모델 경제성 (model economics)입니다. 이 수치들을 고정된 숫자가 아닌 계층 (tiers)으로 취급하십시오.
| 모델 계층 (Model tier) | 상대적 토큰 가격 | 최적의 워크로드 (Best-fit workload) |
|---|---|---|
| Small / mini (예: GPT-4o mini 급) | 가장 낮음 | 분류 (Classification), 추출 (extraction), 라우팅 (routing), 짧은 결정론적 작업 (short deterministic tasks) |
| ... |
모델별 토큰 가격은 변경될 수 있으며 지역마다 다르므로, 모든 수치를 Azure OpenAI Service 가격 페이지와 대조하여 확인하십시오.
이제 솔직한 이야기를 해보겠습니다. 라우팅은 흔히 LLM 비용의 60~80%를 절감한다고 인용됩니다. 이는 업계 표준 입력을 사용한 예시적인 범위일 뿐이며, 귀하의 트래픽에 맞춰 조정해야 하며 실제 결과는 달라질 수 있습니다. 수치가 달라지는 이유는 캐스케이드 세금 (cascade tax) 때문입니다. 에스컬레이션된 요청은 작은 모델 호출 비용과 프런티어 (frontier) 모델 호출 비용을 모두 지불해야 하며, 지연 시간 (latency) 또한 최대치가 아닌 합산 방식으로 늘어납니다. 순 절감액은 전적으로 에스컬레이션 비율 (escalation rate)에 달려 있으며, 에스컬레이션 비율은 레이블이 지정된 평가 세트 (labeled eval set)를 기준으로 복잡도 임계값 (complexity threshold)을 얼마나 잘 조정했느냐에 달려 있습니다. 귀하의 워크로드에 모두 적용되는 Microsoft 발행 임계값은 존재하지 않습니다.
따라서 토큰당 가격이 아니라 순 비용 (net cost)을 측정하십시오. 요청의 70%를 에스컬레이션하는 캐스케이드는 모든 것을 프런티어 모델로 직접 보내는 것보다 비용이 더 많이 듭니다.
이것이 바로 가장 높은 레버리지를 가진 **azure llm cost optimization (Azure LLM 비용 최적화)**입니다. 단 하나의 프롬프트를 튜닝하기 전에 라우팅 계층을 먼저 설계하십시오.
프롬프트 및 컨텍스트 예산 엔지니어링 (Engineer the prompt and context budget)
라우팅 이후, 다음으로 발생하는 낭비의 원인은 각 호출 내부의 토큰 팽창(token bloat)입니다. 이는 세 가지 곳에 숨어 있습니다: 점진적으로 비대해진 시스템 프롬프트(system prompts), 세 개의 청크만으로도 답변이 가능한데 20개의 청크를 검색해 오는 RAG 컨텍스트(RAG context), 그리고 캐싱 없이 매 요청마다 재전송되는 동일한 접두사(prefixes)입니다.
이 세 가지를 모두 해결하십시오. Azure OpenAI 프롬프트 캐싱 (prompt caching)을 사용하여 프롬프트의 정적(static) 부분을 할인받으십시오. 검색된 청크를 재순위화(reranking)하고 관련성 기준을 통과하는 것만 유지함으로써 컨텍스트를 다듬으십시오. 모델이 즉시 파싱하여 버리게 될 산문(prose)을 출력하지 않도록 구조화된 JSON 출력을 요청하십시오.
프롬프트 캐싱은 정적 접두사가 크고 안정적일 때만 도움이 됩니다. 동적(dynamic) 성격이 강한 프롬프트는 할인을 받지 못합니다. 캐시 가능한 콘텐츠를 앞부분에 배치하여 프롬프트 순서를 정하십시오. 즉, 시스템 지침(system instructions)과 고정된 컨텍스트를 먼저 두고, 가변적인 사용자 턴(user turn)을 마지막에 두어야 합니다. 그렇지 않으면 캐시는 아무런 효과가 없습니다.
본능적으로는 컨텍스트 창(context window)을 임의로 추측한 토큰 수로 제한하려 할 것입니다. 그러지 마십시오. **Azure 토큰 사용량 최적화 (Token usage optimization azure)**는 고정된 숫자가 아니라 검색 관련성(retrieval relevance)에 따라 다듬을 때 작동합니다. 만약 세 개의 청크가 질문에 답할 수 있다면, 여덟 개가 예산에 맞는지 여부와 상관없이 여덟 개를 보내는 것은 낭비입니다. 만약 쿼리에 진정으로 열 개가 필요하다면, 다섯 개로 강제 제한하는 것은 답변의 질을 떨어뜨리고 재시도(retry)를 유발하며, 이는 절약한 토큰보다 더 많은 비용을 발생시킵니다.
컨텍스트 창을 임의로 추측한 고정 토큰 수가 아니라, 검색 관련성에 따라 다듬으십시오.
PTU vs. PAYG: 소비 모델 자체를 관리하십시오
Azure OpenAI 워크로드에서 단일 비용 결정 중 가장 큰 비중을 차지하는 것은 프롬프트가 아닙니다. 그것은 조달(procurement)입니다.
두 가지 소비 모델(consumption models)이 있습니다. 종량제(Pay-as-you-go, PAYG)는 약정 없이 토큰당 비용을 청구합니다. PTU 문서에 설명된 프로비저닝된 처리량 단위(Provisioned Throughput Units, PTU)는 일정 기간 동안 고정된 가격으로 전용 용량(dedicated capacity)을 예약합니다. 지속적이고 높으며 예측 가능한 부하(load) 상황에서는 PTU가 토큰당 비용이 더 저렴할 수 있으며 제어 가능한 지연 시간(latency)을 제공합니다. 급증하거나 초기 단계의 트래픽 상황에서는 유휴 상태일 때 비용이 발생하지 않는 PAYG가 유리합니다.
두 모델 사이에는 안정적인 수치적 교차점(crossover)이 존재하지 않습니다. 최소 PTU 증분, PTU당 토큰 비율, 할인율은 모두 가격 정책에 따라 변하며 모델과 지역(region)마다 다릅니다. 고정된 손익분기점 토큰 수를 제시하는 사람은 이미 만료된 수치를 말하고 있는 것입니다. 따라서 임계값(threshold)을 암기하지 마세요. 방법론을 익히십시오.
최고치에 대한 추측이 아니라 측정된 트래픽 백분위수(percentiles)를 기준으로 적정 규모(right-size)를 결정하세요. 이전에 구축한 속성 파이프라인(attribution pipeline)에서 실제 분당 토큰 처리량(throughput)을 추출하고, 일주일에 한 번 발생하는 급증(spike)보다는 지속적인 부하를 살펴보며, 트래픽이 실제로 유지되는 수준에 맞춰 PTU 규모를 정하십시오. 자신의 데이터를 바탕으로 Azure OpenAI Studio의 용량 계산기(capacity calculator)를 통해 해당 수치들을 실행해 보세요.
PTU 용량은 지역 및 모델 버전별로 상이하며 온디맨드(on demand)로 보장되지 않습니다. 용량은 비용뿐만 아니라 제약 사항(constraint)이기도 합니다. 프로비저닝할 수 없는 약정을 설계하지 마십시오. 설계를 진행하기 전에 사용하려는 정확한 모델 버전과 지역의 가용성(availability)을 확인하십시오.
이것이 조달(procurement) 계층에서의 **Azure OpenAI 비용 제어(cost control)**입니다. 트래픽 분포에 따라 소비 모델을 선택한 다음, 그 안에서 프롬프트를 최적화하십시오. 존재하지 않는 트래픽을 위해 용량을 예약하는 것은 과도하게 긴 프롬프트를 사용하는 것보다 돈을 더 빨리 태워버립니다.
CI/CD 경로에 거버넌스 내재화하기
위의 모든 사항은 설계 결정(design decision)입니다. 아무런 강제성이 없는 설계 결정은 두 번의 스프린트(sprint) 이내에 다시 기본값으로 돌아가 버립니다. 누군가 기능을 추가하면서, "일단 출시하기 위해" 최첨단 모델(frontier model)을 지정하고, 라우팅 계층(routing layer)을 건너뛰며, 프롬프트 길이를 두 배로 늘려버립니다. 인보이스(invoice)가 나오기 전까지는 아무도 알아차리지 못합니다.
그러므로 배포 전에 이를 강제하십시오. 토큰 비용을 다른 모든 회귀(regression) 테스트와 동일하게 취급하십시오.
허용 목록(allowlist) 및 태깅(tagging) 강제에는 Azure Policy가 적합한 도구입니다. Azure Policy 문서에서 필요한 거부(deny) 및 감사(audit) 효과를 다루고 있습니다. 이것은 코드형 정책(policy-as-code)이며, 여러분의 아키텍트들은 이미 이를 작성하는 방법을 알고 있습니다.
배포 전에 강제되는 비용 규율이 거버넌스(governance)입니다. 인보이스를 보고 나서야 발견하는 것은 후회일 뿐입니다.
핵심 입장
거버넌스는 청구서가 급증한 후에 추가하는 알림(alert)이 아닙니다. 그것은 설계 단계에서 확정하는 아키텍처이며, 다섯 가지의 핵심 구성 요소(load-bearing parts)를 가집니다: 자체 텔레메트리(telemetry)에서 모든 토큰에 속성을 부여하고, 질문에 답할 수 있는 가장 저렴한 모델로 요청을 라우팅하며, 관련성에 따라 컨텍스트(context) 예산을 책정하고, 측정된 트래픽 분포에 따라 PTU 또는 PAYG를 선택하며, 이 모든 것을 배포 전 CI/CD 단계에서 강제하는 것입니다.
속성 부여(attribution) 계층을 건너뛰면 나머지 네 가지는 추측의 영역이 됩니다. 왜냐하면 Azure의 기본 메트릭(native metrics)은 구조적으로 어떤 기능이 비용을 지출했는지 알려줄 수 없기 때문입니다. 이것이 벤더들이 판매하는 "AI를 위한 FinOps"가 얼버무리는 부분이며, 하위의 모든 과정이 엔지니어링이 될지 아니면 보여주기식 연극(theater)이 될지를 결정하는 부분입니다. 이것이 바로 우리가 Azure에서의 AI 거버넌스를 생각하는 방식에서 이를 아키텍처 문제로 다루는 이유이기도 합니다.
여기에 여러분이 즉시 실행할 수 있는 구체적인 다음 단계가 있습니다. 이번 주에 운영 중인 엔드포인트(endpoint) 하나를 선택하십시오. 해당 엔드포인트의 SDK 호출을 래핑(wrap)하여 usage 객체에 기능 태그(feature tag)를 포함해 Log Analytics로 내보내고, 요청당 비용이 오늘 설정한 수치를 초과할 경우 실패하는 빌드 어설션(build assertion)을 하나 작성하십시오. 엔드포인트 하나, 예산 하나, 게이트(gate) 하나. 이것이 인보이스를 지켜보기만 하는 것과 이를 거버넌스하는 것의 차이입니다.
이 기사는 원래 az365.ai에 게시되었습니다. 저는 Alex Pechenizkiy이며, Microsoft AI 스택에 대해 정직하고 벤더 중립적인 분석을 작성하는 Azure 및 Power Platform 솔루션 아키텍트입니다. 더 많은 내용은 az365.ai에서 확인하실 수 있습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기