Claude Code 세션은 실제로 얼마나 많은 CO2를 배출할까?
요약
Claude Code 사용 시 발생하는 탄소 배출량을 추정하기 위한 방법론과 오픈 소스 프로젝트인 claude-carbon을 소개합니다. 논문 데이터를 기반으로 입력 및 출력 토큰당 에너지 소모량을 계산하여 세션별 탄소 발자국을 측정합니다.
핵심 포인트
- Claude Code 세션의 탄소 배출량을 추정하는 방법론 제시
- 출력 토큰이 입력 토큰보다 훨씬 많은 에너지를 소모함 (약 21:1 비율)
- 디코딩 단계의 낮은 하드웨어 활용도가 에너지 효율 저하의 원인
- 오픈 소스 프로젝트 claude-carbon을 통해 측정 도구 공개
저는 근무 시간의 대부분을 Claude Code 내부에서 보냅니다. 그러다 문득 이것이 물리적으로 어느 정도의 수치에 도달하는지 궁금해지기 시작했습니다. 죄책감으로서가 아니라, 세션 비용을 확인하는 것처럼 수치로 바라볼 수 있는 데이터로서 말이죠.
공식적인 답변은 없습니다. Anthropic은 다른 모든 프런티어 연구소(frontier lab)와 마찬가지로 추론(inference)당 에너지 데이터를 공개하지 않습니다. 그래서 저는 직접 추정치를 만들고, 이를 상태 표시줄(status line)에 넣었으며, 전체 프로젝트를 claude-carbon이라는 이름으로 오픈 소스화했습니다. 이 포스트는 방법론에 관한 것입니다. 즉, 숫자가 어디에서 왔는지, 무엇을 추정해야 했는지, 그리고 추정치가 가장 취약한 부분이 어디인지에 대한 내용입니다.
이 도구로 측정한 저의 지난 6개월간의 기록은 다음과 같습니다: 893회의 세션, 약 970kg CO2e. 이는 대서양을 횡단하는 편도 항공편의 일반석(economy seat) 한 좌석 정도의 양입니다. 세션 중앙값은 약 200g이며, 분포는 긴 꼬리(long tail) 형태를 보입니다. 가장 최악이었던 단일 세션은 68kg이었습니다. 저는 이 숫자들을 5배 오차 범위 내로도 맞히지 못했을 것입니다.
유일하게 측정된 데이터 포인트
모든 것은 하나의 논문에서 시작됩니다: Jegham et al. 2025, "How Hungry is AI?" (arxiv.org/abs/2505.09598). 이 논문은 AWS 상에서 다양한 모델에 대한 쿼리당 추론(inference) 에너지를 측정합니다. Claude 3.7 Sonnet에 대해 세 가지 구성(PUE 포함)을 보고합니다:
| 입력 토큰 (Input tokens) | 출력 토큰 (Output tokens) | 에너지 (Energy) |
|---|---|---|
| 100 | 300 | 0.950 Wh |
| ... |
세 개의 지점과 두 개의 미지수가 있습니다. 입력 토큰에 대한 계수 하나와 출력 토큰에 대한 계수 하나를 사용하여 원점을 지나는 최소제곱 회귀(ordinary least-squares regression)를 적용하면, 입력 토큰당 약 1.35e-4 Wh, 출력 토큰당 약 2.88e-3 Wh를 얻을 수 있습니다. 이 적합도는 실제 코딩 세션이 이루어지는 영역인 토큰 수가 많은 두 가지 구성과 1% 이내로 일치합니다.
그리드를 통해 변환하면: Jegham et al.은 위치 기반(location-based)인 AWS 지역 탄소 집약도(carbon intensity) 0.287 kgCO2e/kWh를 사용합니다. 이를 통해 다른 모든 것의 근거가 되는 두 가지 수치가 도출됩니다:
- 입력 토큰 100만 개당 39 gCO2e
- 출력 토큰 100만 개당 826 gCO2e
21:1이라는 비율은 가정이 아니라 적합도(fit)로부터 도출된 것이지만, 세 개의 측정 지점만으로는 실제 불확실성이 존재합니다. 하지만 그 방향성은 확실합니다. 출력 토큰(output tokens)에 더 많은 연산(FLOPs)이 필요해서가 아니라(토큰당 FLOPs는 유사함), 디코딩(decoding)이 훨씬 낮은 하드웨어 활용도(hardware utilization)에서 실행되기 때문입니다. 프리필(Prefill)은 전체 프롬프트를 병렬로 처리하여 연산 자원을 포화(saturate)시키지만, 각 디코딩 단계는 단일 토큰을 생성하기 위해 가중치(weights)와 KV 캐시(KV cache)를 다시 읽어야 하므로 메모리 대역폭 제한(memory-bandwidth-bound)을 받으며 토큰당 더 많은 에너지를 소모합니다. 정확한 배수는 배치 크기(batch size)와 서빙 스택(serving stack)에 따라 달라집니다.
이 결과가 틀릴 수도 있을까요? 저는 완전히 독립적인 경로(파라미터 수와 라이프사이클 모델 사용, AWS 텔레메트리 미사용)를 통해 영향을 추정하는 EcoLogits와 교차 검증을 수행했습니다. 그들의 Sonnet 범위는 출력 토큰 100만 개당 약 565~1385 gCO2e입니다. 826은 이 범위 안에 있습니다. 서로 관련 없는 두 가지 방법이 동일한 범위에 도달했다는 점은 현재 가용한 가장 강력한 확증입니다.
세 가지 모델 제품군이 외삽(extrapolated)되었으며, 이것이 얼마나 취약한지에 대하여
Sonnet만이 측정된 에너지 데이터를 가지고 있습니다. 그 외의 모든 것은 약한 신호(weak signals)로부터의 추론이므로, 제가 신뢰하는 정도에 따라 수치들의 순위를 매겨보겠습니다:
- Sonnet: 측정됨 (measured). 세 개의 데이터 포인트와 적합(fit) 결과가 있습니다. 확실한 근거입니다.
- Opus: 외삽됨 (extrapolated), Sonnet의 1.7x~5x 범위. 사용 가능한 두 가지 신호인 EcoLogits의 파라미터 가정과 Anthropic의 가격 비율 모두 약 1.7~2x 부근에 위치하며, 도구의 수치도 그 지점(2x)에 있습니다. 이 범위가 5x까지 확장되는 이유는 두 신호 모두 측정값이 아니기 때문에 오차가 위쪽으로 발생할 가능성이 높기 때문입니다.
- Haiku: 가장 불편한 수치. Jegham은 실제로 Haiku 3.5를 Sonnet보다 더 높게 측정했는데, 이는 보통 서빙 아티팩트(serving artifact, 지연 시간 최적화 서빙, 작은 배치 크기)로 해석됩니다. EcoLogits의 현대적인 Haiku 수치는 훨씬 낮습니다. 이 도구는 Sonnet의 0.5x를 사용합니다. 만약 측정값을 액면 그대로 받아들인다면, Haiku는 Sonnet과 비슷한 수준이 되며
유혹적인 지름길은 Anthropic의 과금 비율입니다: 캐시 읽기(cache reads)는 입력(input) 비용의 0.1x가 듭니다. 하지만 가격은 에너지 측정값이 아닙니다 (OpenAI는 동일한 메커니즘에 0.5x의 가격을 책정합니다). 정직한 답변은 이 비율을 직접적으로 측정하는 연구가 없다는 것이며, 따라서 저는 인접한 측정값으로부터 공학적 추정치를 도출했습니다: 생성 워크로드(generation workloads)에서 프리필(prefill)은 전체 추론 에너지의 약 3.4% 미만을 차지하며, 토큰당 디코딩(decode) 에너지는 KV 캐시(KV-cache) 크기에 따라 증가합니다. 왜냐하면 생성된 모든 토큰이 HBM에서 전체 캐시를 다시 읽기 때문입니다. 캐시된 토큰은 프리필을 건너뛰지만, 여전히 디코딩 단계의 잔여 에너지를 영원히 지불해야 합니다.
저는 방어 가능한 문서화된 범위인 0.05-0.15 내에서 0.08x를 사용합니다. 이것은 단일 설정 가능한 상수이며, 모델 전체에서 가장 큰 레버(lever)입니다. 이를 0으로 설정하는 것은 정당한 하한선이 될 수 있지만, 이는 재사용되는 100K-토큰 시스템 프롬프트가 탄소 배출이 없다고 선언하는 것과 같으며, 이는 어딘가에 있는 메모리 버스(memory bus)가 반박할 것입니다.
토큰을 세는 것 자체가 하나의 버그 찾기입니다
토큰 수는 Claude Code의 로컬 JSONL 트랜스크립트(transcripts)에서 가져옵니다. 만약 단순히 줄 단위로 message.usage를 합산한다면, 약 3배 정도 과다 계산하게 됩니다. 재개(Resumed) 및 압축된(compacted) 세션은 이전 메시지들을 동일한 파일로 다시 재생(replay)하며, 스트리밍(streaming)은 출력 수가 증가함에 따라 동일한 메시지 ID를 다시 작성합니다. 제 데이터에 따르면, 어시스턴트(assistant) 라인의 55%가 재생된 것입니다. (message.id, requestId)를 통해 중복을 제거하고, 마지막 발생 건만 유지한 다음 합산하십시오.
또 다른 함정은 Claude Code가 약 30일 후에 트랜스크립트를 삭제한다는 점입니다. 이 도구는 세션이 종료될 때 각 세션을 SQLite로 캡처하여 파생된 그램(grams) 단위가 아닌 원시 토큰 내역을 저장합니다. 따라서 계수(factor)가 수정될 때 하나의 스크립트로 전체 이력을 다시 산정할 수 있습니다. 측정값이 개선됨에 따라 배출 계수(Emission factors)는 계속 변하겠지만, 원시 토큰은 영원합니다.
조용히 깨뜨릴 수 없는 숫자들
저장소(repo) 내의 모든 요소(factor)와 가격은 골든 벡터(golden vectors)로 보호됩니다. 즉, 수작업으로 도출된 예상 출력값이 포함된 12개의 표준 세션(canonical sessions)이 존재하며, 매 푸시(push) 시 CI 환경에서 data/factors.json을 대상으로 재실행됩니다. 만약 누군가(대개 저 자신)가 벡터와 METHODOLOGY.md에 작성된 도출 과정(derivation)을 업데이트하지 않고 요소(factor)를 수정하면, 빌드는 실패합니다.
이전의 수치들을 스스로 재현하지 못하는 상황을 겪은 후 이 기능을 추가했습니다. 산술 연산(arithmetic)을 열 번 확인해도 오류를 찾아낼 수 없었는데, 산술 자체는 문제가 없었기 때문입니다. 도출 과정(derivation)이 어긋나 있었던 것입니다. 만약 여러분의 프로젝트가 수치를 제공한다면, 단순한 수학적 계산뿐만 아니라 도출 과정(derivation)을 테스트하십시오.
일상적인 모습
상태 표시줄에는 달러 옆에 실시간으로 그램(g) 단위가 표시됩니다:
claude-carbon ⌥ main | 🟢 Opus 4.7 ▓▓▓░░░░░░░ 35% | $1.72 · 101g CO₂ | Use 21% ↻13:00
제 행동에서 바뀐 점은 AI를 덜 사용하는 것이 아닙니다. 바로 모델 라우팅(model routing)입니다. 모델군(family)별 요소(factors)를 적용하면 작은 모델들이 큰 모델들보다 몇 배나 낮은 수치를 기록합니다. 정확한 비율을 인용하지는 않겠습니다. 모델군 간의 비율은 이 모델에서 가장 취약한 수치이기 때문입니다(이는 앞서 설명한 외삽(extrapolation) 결과입니다). 하지만 방향성은 확실하며, 의사 결정 시점에 눈에 보이는 수치가 나타나면 비용 표시가 이미 그러하듯 "이 작업에 정말 큰 모델이 필요한가?"라는 질문을 실질적인 고민으로 만들어 줍니다.
솔직한 한계점
추론(Inference)에만 국한됩니다: 학습 비용 분할(training amortization), 하드웨어 제조, 물 사용량은 포함되지 않았습니다. 탄소 집약도(carbon intensity)는 실시간이 아닌 그리드 평균(grid-average)이며, 단일 지역(single-region) 기준입니다. 캐시 읽기 요소(cache-read factor)는 측정된 것이 아니라 도출된 것입니다. 모든 세션 수치를 읽는 올바른 방법은 "수십 밀리그램이나 수십 킬로그램이 아니라, 수백 그램 단위"로 이해하는 것입니다.
Claude Code를 사용한다면, 설치는 한 줄로 끝나며 모든 것이 로컬(SQLite, 텔레메트리 없음, 계정 불필요)에 유지됩니다:
npx claude-carbon
리포지토리(Repo) 및 출처를 포함한 전체 방법론:
github.com/gwittebolle/claude-carbon.
만약 도출 과정에서 결함을 발견한다면, 이슈(issue)를 생성해 주세요. 골든 벡터(golden vectors) 덕분에 수정 비용은 저렴하며, 출처와 함께 수정을 받는 것이 이 방법론을 공개하는 목적입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기