서론
안녕하세요! AWS에서 솔루션 아키텍트(Solution Architect)를 맡고 있는 사이토 타쿠미입니다.
소매업의 수요 예측에 대한 상담을 하다 보면, 현장에서 나오는 질문은 대체로 정해져 있습니다. “다음 주에 세일을 할 건데, 그걸 고려할 수 있나요?”, “신상품이라 데이터가 없는데요?”, “SKU가 3만 개나 되는데, 전부 모델을 만들어야 하나요?”.
2025년 10월에 공개된 시계열 기반 모델(Time Series Foundation Model) Chronos-2는 이 세 가지 과제에 대응하도록 설계되었습니다. 학습 없이(Zero-shot) 작동하며, 가격이나 판촉, 공휴일 같은 **공변량(covariates)**을 입력할 수 있고, 여러 시리즈의 맥락을 한 번에 읽어 정보를 공유하는 in-context learning으로 기록이 짧은 시리즈를 보완합니다.
본 기사에서는 Walmart의 실제 매출 데이터인 M5 데이터셋을 사용하여 Chronos-2가 소매업 수요 예측에서 어느 정도까지 활용 가능한지 실측했습니다. 결론부터 말씀드리자면, 학습 없이도 계절성 나이브(Seasonal Naive)보다 20~26% 높은 정확도를 보였으며, 휴무일이나 캘린더 정보를 공변량으로 전달했을 때 매장 및 부문 레벨에서 최대 23% 추가 개선되었습니다. 모델 학습이나 특징 공학(Feature Engineering)이 필요 없고, 기존 판매 데이터와 영업 캘린더만 제공하면 됩니다. 다만, SKU × 매장처럼 일별로 매우 세밀한 단위에서는 공변량의 효과가 나타나지 않았습니다. 따라서 공변량을 어느 수준에서 사용할지 사전에 결정해 놓으면 도입 첫날부터 효과를 볼 수 있습니다.
이 글을 통해 얻는 것
- 소매업 수요 예측이 어려운 세 가지 이유와 Chronos-2가 각각 이를 어떻게 해결하는지
- M5 데이터(약 3만 시리즈)에서 공변량 유무 비교 실측 결과 및 공변량이 가장 효과적인 단위
- SKU별 예측을 합산해서는 안 되는 이유 (중앙값의 함정)
predict_df에서의 공변량 전달 방법과 SageMaker JumpStart 배포 - 도쿄 리전에서의 추론 비용 가이드와 도입 시 판단 기준
소매업 수요 예측이 어려운 세 가지 이유
1. 시리즈가 너무 많아 개별 학습이 불가능하다
SKU × 매장에 수만 개의 시리즈는 흔한 일입니다. 이번에 사용할 M5 데이터셋은 3,049 상품 × 10 매장 = 30,490개의 시리즈입니다. 시리즈마다 ARIMA나 LightGBM을 학습시키고, 특징 공학을 설계하며, 재학습 운영을 돌리는 것은 데이터 과학자가 몇 명 있어도 따라가기 힘듭니다.
2. 판촉·가격·캘린더로 수요가 움직인다
소매업 매출은 과거의 매출만으로는 결정되지 않습니다. 가격 인하, 전단지 광고(チラシ), 공휴일, 정부 지원금 지급일 등. 이것들은 미래 값이 사전에 알려져 있는 정보이며, 예측 모델에 “다음 주에는 이렇게 될 것이다”라고 가르칠 수 있느냐에 따라 정확도가 달라집니다. 초기 Chronos나 Chronos-Bolt는 과거 매출 1개만 볼 수 있었기 때문에, “다음 주 세일을 할 것”이라는 정보를 전달할 수 있는 수단이 없었습니다.
3. 안 팔리는 날이 더 많다
매장별 SKU의 경우, 하루에 판매가 0개 또는 1개인 간헐적 수요(Intermittent Demand)가 대부분입니다. M5의 CA_1 매장을 보면, 61%의 시리즈에서 매출 제로일 날이 절반 이상을 차지하며, 일일 평균 판매 수량의 중앙값은 0.74개였습니다. 이런 단위에서는 “평균적으로 몇 개 팔릴까”보다 “팔리는 날과 안 팔리는 날의 분포”가 본질적이며, 점 예측(Point Prediction) 정확도 경쟁에는 큰 의미가 없습니다.
Chronos-2가 변화시키는 것
Chronos-2는 Amazon이 개발한 시계열 기반 모델로, Apache 2.0 라이선스로 공개되었습니다. 파라미터 수는 120M(소형 버전은 28M)입니다. 초기 Chronos나 Chronos-Bolt와 달라진 점은 다음 세 가지입니다.
- Zero-shot: 자체 데이터 학습이 필요 없습니다. 기록을 전달하기만 하면 바로 예측 결과가 나옵니다. 3만 개의 시리즈가 있어도 “학습 작업(Learning Job)”이라는 개념이 사라집니다.
- 공변량 (Covariates): 과거만 알 수 있는 변수(방문객 수 등)와, 미래도 알 수 있는 변수(가격, 판촉 플래그, 공휴일, SNAP 지원금 지급일 등)를 구분하여 입력할 수 있습니다. 범주형 값도 전달 가능합니다.
- in-context learning (ICL): 여러 시리즈를 그룹으로 동시에 읽어 정보를 공유합니다. 다변량 예측(Multivariate Forecasting), 공변량 포함 예측, 관련 시리즈로부터의 학습이 이 하나의 메커니즘으로 구현되었습니다.
기술 보고서(arXiv:2510.15821)에 따르면, fev-bench의 소매 도메인 17개 태스크(Rossmann 매장 매출 등, 프로모션/휴업/공휴일 공변량 포함)에서 공변량을 사용하지 않았을 때 스킬 점수가 44.3%였던 것에 비해, 공변량을 사용했을 때는 48.6%로 보고되었습니다. Chronos-Bolt는 35.3%였습니다.
또 하나, 문맥적으로 알아두어야 할 것이 있습니다. Amazon Forecast가 2024년 7월 29일에 신규 고객 접수를 종료했습니다(공식 블로그). 기존 고객은 계속 사용할 수 있지만 새로운 기능은 추가되지 않습니다. 마이그레이션할 곳을 찾는 소매업체 고객에게 Chronos-2 + SageMaker는 유력한 선택지입니다.
검증 설계
데이터
M5 Forecasting(Walmart의 미국 3개 주 10개 매장, 2011년 1월~2016년 6월 일별 판매 수량)을 사용합니다. 공변량으로는 다음이 첨부되어 있습니다.
| 공변량 | 종류 | 내용 |
|---|
sell_price | 미래도 알려짐 | 주 단위의 판매 가격. 할인액은 여기에 나타남 |
snap | 미래도 알려짐 | SNAP(저소득층 식료품 지원) 지급일. 주별로 월 10일 |
| 이벤트 유형 | 미래도 알려짐 | Sporting / Cultural / National / Religious의 4개 플래그 |
closed | 미래도 알려짐 | 크리스마스(12/25). Walmart는 휴업으로 매출이 0임 |
데이터는 Nixtla의 공개 미러에서 datasetsforecast 패키지로 가져왔습니다.
비교할 세분화 수준 및 설정
공변량의 영향력이 세분화 수준에 따라 달라지는 것을 보기 위해, 4가지 세분화 수준으로 동일한 비교를 수행했습니다.
| 세분화 수준 | 시계열 수 | 가격 처리 |
|---|
| SKU × 매장 (CA_1 매장만) | 약 2,700 | 그대로 |
| ... | | |
| 예측 기간은 28일, 문맥은 직전 730일입니다. 예측 시작일을 4개로 정하고, 각각 크리스마스(2015-11-30 시작), 슈퍼볼(2016-01-25 시작), 부활절(2016-03-07 시작), 메모리얼 데이(2016-05-23 시작)를 포함하는 28일간을 평가 기간으로, 다음을 비교합니다. | | |
- 공변량 없음
- 캘린더만 (SNAP + 이벤트 유형)
- 가격만
- 가격 + 캘린더
- 가격 + 캘린더 + 휴업일 플래그(크리스마스를 포함하는 기간에 한함)
평가 지표는 확률 예측의 표준인 WQL(weighted quantile loss, P10~P90의 9분위점 평균)을 주로 사용하고, 참고로 MASE와 계절 나이브(전주 동요일)도 함께 제시합니다. 모델은 amazon/chronos-2를 그대로 사용했으며, 학습이나 fine-tuning은 전혀 하지 않았습니다. 실행 환경은 Apple M4 (16GB)의 MPS입니다.
코드
공변량이 있는 예측은 히스토리 데이터프레임과 미래 공변량 데이터프레임을 predict_df에 전달하기만 하면 됩니다.
import pandas as pd
from chronos import Chronos2Pipeline
pipe = Chronos2Pipeline.from_pretrained(
이러한 수준에서는 공변량(covariate)을 사용하지 않은 모델이 가장 좋았으며, 공변량을 추가했을 경우 1~3% 성능이 저하되었습니다. 크리스마스를 포함하는 기간의 휴업일 플래그 역시 차이를 만들지 못했습니다. SKU별 예측치를 합산한 매장 총합을 보면, 12월 25일의 예측치는 공변량 없음으로 2,382개, 휴업일 플래그 있음으로 2,474개였습니다. 실제 값은 0이었습니다.
이에 대한 이유는 두 가지로 생각합니다.
첫 번째는 간헐성(intermittency)입니다. 매출이 0인 날이 과반을 차지하는 시계열에서는 '휴업일 플래그가 1인 날은 매출 0'이라는 패턴을 과거 크리스마스 2회(730일의 맥락에 포함되는 것은 2회)만으로는 원리적으로 읽어내기 어렵습니다. 0인 날이 다른 곳에도 아주 많기 때문입니다.
두 번째는 가격 변동성의 부족입니다. 예측 기간 28일 동안 가격이 변경된 시계열은 평가 기간 전체를 통틀어 46~87개 시계열, 전체의 2~3%에 불과했습니다. 따라서 가격 공변량에는 '효과를 발휘할 여지'가 거의 없었고, 나머지 97%의 시계열에서는 입력 차원만 늘린 노이즈로 작용했다고 판단합니다.
반면, Chronos-2 단독 모델의 정확도는 Seasonal Naive보다 훨씬 좋았으며, MASE(Mean Absolute Scaled Error) 기준 0.77~0.89 대 1.00~1.21 (20~26% 개선)을 기록했습니다. SKU 일별 예측은 **공변량을 추가하지 않고 Chronos-2에 그대로 이력을 전달하는 것만으로 충분**하다는 결과였습니다. 공변량이 힘을 발휘한 것은 다음에서 볼 수 있는 집계 수준이었습니다.
같은 데이터를 매장 단위(10개 시계열)와 매장 × 부문(70개 시계열)으로 집계하여 예측하면 결과가 반전됩니다.

매장 레벨의 수치를 추출하면 다음과 같습니다.
| 평가 기간 | 공변량 없음 | 카렌다(Calendar)만 | 가격 + 카렌다 | + 휴업일 |
|---|---|---|---|---|
| 2015-11-30 (크리스마스) | 0.101 | 0.103 | 0.103 | 0.077 (-23%) |
| 2016-01-25 (슈퍼볼) | 0.068 | 0.064 (-6%) | 0.063 (-8%) | - |
| 2016-03-07 (부활절) | 0.054 | 0.054 | 0.054 (-1%) | - |
| 2016-05-23 (메모리얼 데이) | 0.049 | 0.046 (-7%) | 0.046 (-6%) | - |
크리스마스를 포함하는 기간을 매장 CA_1로 본 것이 다음 그림입니다. 공변량 없음 예측은 12월 25일에 평상시와 같은 수준(P50 기준 3,889개)을 보이지만, 휴업일 플래그를 전달한 예측은 당일 P50을 591개까지 낮추고 있습니다. 다만 P10은 음수 값, P90은 2,088개로 범위가 넓게 유지되어 과거 2회의 관측만으로는 '확실히 0'이라고 단정하기는 어렵습니다. 판매 수량은 음수가 될 수 없으므로, 실무에서는 분위점(quantile)을 0으로 절사하여 사용합니다.

휴업일은 '미래가 확실하게 알려지는 공변량'의 전형적인 예입니다. 모델은 과거 2회의 12월 25일에 매장 총합이 0이었다는 것을 맥락에서 읽어내어, 같은 플래그가 적용되는 미래의 날에 대입하고 있습니다. 이는 SKU 레벨에서는 포착할 수 없었던 패턴이며, **집계하면 신호가 노이즈 위로 떠오르는** 것이 명확하게 알 수 있습니다.
카렌다 공변량(SNAP 지급일 + 이벤트 유형)의 효과는 휴업일만큼 극적이지는 않지만, 4개 기간 중 2개 기간에서 6~7% 개선을 보였고, 나머지 2개 기간은 유지되거나 소폭 증가했습니다. 매장 × 부문 70개 시계열에서도 같은 경향으로, 휴업일 플래그가 12%, 카렌다가 최대 8%의 개선을 가져왔습니다. 상품 레벨(10개 매장 총합, 3,049개 시계열)은 중간적이었으며, 휴업일 플래그가 2% 개선, 나머지는 1~2% 악화되었습니다. 다음 그림은 2016-05-23 시작 기간 중 가장 많이 개선된 매장입니다. SNAP 지급일에 매출이 상승하는 형태를 카렌다 공변량이 포함된 예측이 더 정확하게 따라가고 있습니다.

한편, 가격만을 공변량으로 사용했을 경우에는 어떤 세분화 수준(granularity)에서도 개선되지 않았습니다. 매장 평균 가격은 '가격 지수'로서의 의미만 가질 뿐, 개별 상품의 할인 정보는 집계 과정에서 사라져 버립니다. 가격 공변량을 활용하려면, 상품 × 매장에서 가격 변동이 잦은 (프로모션이 많은) 카테고리로 범위를 좁혀 사용하는 것이 합리적입니다.
소매 현장에서는 'SKU별로 예측하고, 매장이나 부문의 계획은 그것을 합산한다'는 운영 방식이 자연스럽게 나옵니다. 간헐적 수요의 확률 예측으로 이를 수행하면 체계적으로 과소평가됩니다.

SKU 별 P50(중앙값)을 합산했을 경우, 28일간 총합은 실적보다 25% 낮았습니다. 매출이 '제로'인 날이 절반 이상을 차지하는 시계열의 중앙값은 0에 가깝게 떨어지므로, 이를 2,800개만큼 더해도 매장 합계를 채우기에는 부족합니다. 9개의 분위점(quantile)을 평균하여 기대값에 가깝게 만들면 과소평가는 7%까지 줄었고, 매장 수준에서 직접 예측한 P50은 실적보다 5% 정도 높은 수준이었습니다. 문제는 **합산할 경우 체계적으로 편향된다**는 것입니다. 어떤 수치가 정확한지는 별개의 문제입니다.
실무에 주는 시사점은 단순합니다. **의사결정의 세분화 수준(granularity)에서 직접 예측해야 한다**는 것입니다. 발주는 SKU × 매장의 분위점(P90으로 안전재고를 보는 등)으로, 매출 계획이나 인력 배치는 매장 또는 부문 레벨에서 직접 예측하는 식으로 사용처를 구분해야 합니다. Chronos-2는 제로샷(zero-shot)이라 시계열별 학습 비용이 없기 때문에, 여러 세분화 수준에서 예측을 돌리는 것에 심리적/운영적인 장벽이 없는 것이 이점입니다.
로컬 검증이 끝나면, 실제 운영 환경(production)에서는 SageMaker에 올립니다. Chronos-2는 JumpStart에 등록되어 있어, 모델 ID만 지정하면 실시간 추론 엔드포인트가 구축됩니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
from sagemaker.jumpstart.model import JumpStartModel
model = JumpStartModel(
model_id="pytorch-forecasting-chronos-2",
...
엔드포인트로 전달되는 페이로드(payload)는 시계열별 JSON 형태이며, 공변량은 `past_covariates`와 `future_covariates`로 나누어 전달합니다. 범주형 값(categorical value)은 문자열 그대로 전달할 수 있습니다.
payload = {
"inputs": [
{
...
지원되는 인스턴스는 GPU가 ml.g5 / g6 / g6e / g4dn의 xlarge 및 2xlarge, CPU가 ml.m5 / c5의 xlarge부터 4xlarge입니다. 야간 배치(nightly batch) 작업이라면 Batch Transform을, 불규칙한 호출이라면 Serverless Inference를 선택할 수 있지만, 둘 다 CPU 전용이며 JumpStart는 사용할 수 없습니다. 이 경우 모델 아티팩트를 직접 준비해야 하는 절차를 거칩니다 (공식 노트북에 전체 과정이 있습니다). pandas 데이터프레임에서 몇 줄만으로 배포하고 싶다면 AutoGluon-Cloud 경유 방법을 사용할 수도 있습니다.
## 비용 예상치
학습 과정이 없기 때문에, 비용은 추론 시간(inference time)에만 달려있습니다. 도쿄 리전의 실시간 추론 시간 단가(2026년 10월 기준, 온디맨드)는 다음과 같습니다.
| 인스턴스 | vCPU / 메모리 | GPU | 시간 단가 |
|---|---|---|---|
| ml.m5.xlarge | 4 / 16 GiB | 없음 | $0.298 |
| ... |
처리량 참고치로, 이번 검증 환경(Apple M4, MPS)에서는 약 2,800 시계열 × 730일의 컨텍스트를 공변량 없이 처리하는 데 16~18초가 걸렸고, 공변량이 6개 있을 때는 115~124초가 걸렸습니다. 공변량을 추가하면 시계열 수가 실질적으로 7배가 되므로 그만큼 느려집니다. 이 비율을 적용해 추정하자면, 3만 개의 시계열에 대한 야간 배치는 공변량 없이 몇 분, 있어도 30분 이내의 수준으로, ml.g5.xlarge를 1시간 가동하여 2달러가 채 안 되는 비용입니다. SageMaker 실기에서는 별도의 측정이 필요하지만, '매일 밤 3만 SKU 예측을 돌리는 것'이 몇 달러 내외로 가능한 수준이라는 점은 염두에 두시면 좋습니다.
## 소매업에서 Chronos-2를 사용할 때의 지침
이번 검증을 통해 도입 시 판단 기준을 정리했습니다.
- **의사결정의 세부 단위에서 직접 예측한다.** SKU별 예측을 합산하여 상위 계획에 사용하지 않는다. 매장 및 부문의 계획은 그 세부 단위로 예측한다.
- **공변량(Covariate)은 '확실히 아는 미래'로부터 입력한다.** 휴무일, 영업시간 변경, 공휴일 등이 있다. 이번에 가장 효과적이었던 것은 휴무일 플래그로, 매장 레벨에서 23% 개선을 보였다.
- **캘린더 계열의 공변량은 집계 단위(Aggregation Granularity)에서 효과를 본다.** SNAP이나 이벤트 유형은 매장/부문에서 6~8%의 개선을 가져왔다. SKU 일별 예측에서는 효과가 없었다.
- **가격 및 판촉은 실제 가격 변동이 있는 품목군으로 한정한다.** M5 데이터에서는 예측 기간 동안 가격이 움직이는 품목군은 2~3%에 불과하여 효과를 보지 못했다. 다만, 판촉 빈도가 높은 카테고리에서는 다른 결과가 나올 수 있다.
- **간헐적 수요(Intermittent Demand) SKU는 분포로 읽는다.** P50 대신 P90을 안전 재고 판단에, P10을 품절 위험 판단에 사용한다. 점 예측의 정확도를 추구하지 않는다.
- **먼저 공변량 없이 실행해 보고, 공변량을 하나씩 백테스트(Backtest)로 추가한다.** 성능이 떨어지면 제외한다. 제로샷(Zero-shot) 방식이므로 이러한 시행착오가 몇 분 만에 가능하다.
## 한계 및 주의사항
- **M5는 2016년 미국 Walmart의 데이터이다.** 가격 변동 빈도, SNAP과 같은 제도, 이벤트의 효과 방식은 일본 소매업과는 다르다. 특히 판촉 빈도가 높은 일본 식품 슈퍼마켓에서는 가격 공변량 평가가 달라질 수 있다.
- **공변량의 미래 값을 준비하는 운영이 필요하다.** 판촉 캘린더나 가격 계획이 시스템화되어 있지 않으면, 공변량을 입력하는 것 자체가 불가능할 수 있다. 여기가 실무상 가장 큰 벽이 되기 쉽다.
- **제로샷(Zero-shot)이라도 파인튜닝(Fine-tuning)을 배제하지 않는다.** Chronos-2는 LoRA를 이용한 파인튜닝에도 대응하며, 자체 데이터를 활용해 몇 %의 추가 개선을 노릴 수 있다. 다만, 먼저 제로샷으로 충분한지 확인한 후에 진행해도 늦지 않다.
- **크로스 러닝(Cross-learning)은 시도했으나 효과가 없었다.** SKU 레벨에서 `cross_learning=True` (배치 100)을 테스트했지만, WQL(Weight Quantization Loss?) 값에 변화가 없었다. 공식 문서에서도 '이력(History)이 짧은 시리즈에 효과적'이라고 명시하고 있어, 730일의 컨텍스트가 있는 이번 조건에서는 활용하기 어려웠다고 판단한다. 신상품의 콜드 스타트(Cold Start)는 별도로 검증이 필요하다.
- **이번 수치는 1개 매장(SKU 레벨)과 4가지 평가 기간의 결과이다.** 추세는 명확했지만, 카테고리나 계절에 따라 차이가 있을 가능성이 있다. 자체 데이터에서의 백테스트를 전제로 해야 한다.
## 요약
- Chronos-2는 제로샷으로 작동하는 시계열 기반 모델(Time Series Foundation Model)이며, 공변량과 in-context learning을 지원한다. Amazon Forecast가 신규 접수를 종료한 현시점에서 소매 수요 예측의 대안으로 유력하다.
- M5 데이터 실측 결과, 학습이 없는 Chronos-2 단독 사용만으로 계절성 나이브(Seasonal Naive) 대비 MASE에서 20~26% 우수했다.
- 매장/부문 레벨에서는 휴무일 플래그로 23%, 캘린더 공변량으로 6~8% 추가 개선을 이루었다. 영업 캘린더만 제공해도 효과를 볼 수 있다.
- SKU × 매장 일별 예측에서는 공변량 없이 사용하는 것이 가장 좋았다(공변량 사용 시 1~3% 악화). 간헐적 수요로 인해 신호 파악이 어렵고, 가격 변동이 있는 품목군도 2~3%에 그쳤다. 이 세부 단위는 Chronos-2 단독으로 사용해야 한다.
- SKU별 P50 합계는 실제 실적을 25% 하회한다. 의사결정의 세부 단위에서 직접 예측하는 것이 필요하다.
- SageMaker JumpStart에서 모델 ID를 지정하는 것만으로 배포가 가능하며, 3만 개 시리즈에 대한 야간 배치 처리는 몇 달러 수준이다.
검증 코드와 결과 JSON은 ndmxjp/chronos2-retail-m5-experiment에서 공개하고 있다.
### 논의 (Discussion)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48