한 문장으로 이 프로젝트가 뭘 하는지부터.
TimesFM = "한 번 배워 두면 어떤 시계열이든 추가 학습 없이 미래를 그려 주는 예측 전문 모델." 보통 시계열 예측은 데이터셋마다 모델을 처음부터 새로 학습시켜야 한다. TimesFM은 그 발상을 뒤집어, 언어모델(GPT)처럼 거대한 시계열 말뭉치로 미리 사전학습해 두고, 실제로는 model.forecast(...) 한 번 호출로 끝낸다. 매출, 웹 트래픽, 전력 수요, 기온, 환자 바이탈, 주가 — 도메인을 가리지 않고 같은 모델 하나가 처리한다.
기존 방식(ARIMA·Prophet·LSTM)은 데이터셋마다 그 데이터만 보고 처음부터 모델을 학습시킨다 — 새 가게가 생길 때마다 점원을 새로 뽑아 처음부터 교육하는 셈이다.
TimesFM은 반대다. 이미 수많은 그래프의 '오르내리는 버릇'을 통째로 익힌 베테랑 예보관을 데려와, 처음 보는 그래프라도 "이건 이렇게 흘러가겠네" 하고 바로 그려 준다. 교육 시간(학습)이 0이다.
한 가지 짚을 것 — TimesFM은 구글 내부 제품에도 들어가 있다(BigQuery ML의 SQL 예측, Connected Google Sheets의 시트 예측, Vertex Model Garden의 도커 엔드포인트). 다만 이 오픈소스 저장소 자체는 "구글의 공식 지원 제품은 아니다"라고 README가 못 박는다. 즉 연구·학습·실험용으로 자유롭게 쓰되, 프로덕션 SLA를 기대하는 물건은 아니다.
TrendShift 일간 3위 — 별 2만 개를 끌어모은 이유.
2023~2026년은 "예측마저 파운데이션 모델이 한다"는 흐름이 자리 잡은 시기다. 글(GPT)·이미지(확산모델)에 이어, 시계열도 "데이터셋마다 새로 학습"에서 "한 모델로 제로샷 예측"으로 무게중심이 옮겨갔다. TimesFM은 그 흐름의 대표 주자다. 이유를 다섯으로 정리한다.
가장 큰 매력. 예측을 하려고 GPU를 몇 시간씩 돌려 모델을 학습시킬 필요가 없다. 체크포인트(약 800MB~2GB)를 한 번 내려받고 from_pretrained(...) → compile(...) → forecast(...) 세 줄이면, 수천 개 시계열을 한 번에 배치로 예측한다.
마케팅 구호가 아니라 수치가 받쳐 준다. 저장소 문서에 따르면 TimesFM 2.0은 세일즈포스의 종합 시계열 벤치마크 GIFT-Eval에서 집계 MASE·CRPS 기준 최상위를 기록했고, 2.0(500M)은 1.0 대비 "최대 25% 더 정확"하다고 밝힌다. '제로샷인데 학습형 모델보다 잘한다'는 점이 핵심이다.
「A decoder-only foundation model for time-series forecasting」(arXiv 2310.10688)이 ICML 2024에 실린, 출처가 분명한 연구다. 구글 클라우드(BigQuery)·시트에 실제 탑재됐다는 사실이 "장난감이 아니라 검증된 설계"라는 신호가 된다.
최신 2.5 버전은 파라미터를 500M → 200M으로 줄이면서도 문맥 길이는 2,048 → 16,384로 8배 늘렸다. 더 작은 모델이 더 긴 과거를 본다. 덕분에 CPU만 있는 노트북에서도 돌릴 수 있을 만큼 문턱이 낮아졌다(7번 섹션 참고).
"내일 매출은 100"이라는 한 점만 주는 게 아니라, "80~130 사이일 확률이 높다"는 분위수(불확실성 구간)까지 내놓는다. 2.5는 연속 분위수 헤드로 이 구간을 더 정확히 보정했고, 가격·휴일 같은 외부 변수(공변량)도 끼워 넣을 수 있다.
| 접근법 | 학습 방식 | 한계 / 강점 |
|---|---|---|
| ARIMA · Prophet | 시계열 1개마다 파라미터를 매번 추정 | 계절성·차수를 사람이 튜닝. 수천 개 시계열엔 손이 너무 많이 감. |
| LSTM · TFT 등 딥러닝 | 데이터셋마다 처음부터 학습(GPU 수 시간) | 잘 맞지만, 새 데이터셋마다 학습 루프·라벨 분할·튜닝 반복. |
| TimesFM | 한 번 사전학습 → 제로샷 | 불러서 forecast() 호출이 끝. 도메인 불문 한 모델로 처리. |
새 예측 과제를 받았을 때, 모델을 학습시키기 전에 "일단 TimesFM으로 제로샷을 돌려 기준선부터 잡는" 워크플로가 강력하다. 5분이면 꽤 좋은 예측이 나오므로, 그보다 잘하는 전용 모델을 만들 가치가 있는지 판단하는 출발점이 된다.
제로샷이 늘 1등은 아니다. 규칙이 아주 강한 도메인(전용 데이터가 충분한 곳)에서는 그 데이터로 학습한 전용 모델이 더 정확할 수 있다. 또 과거에 전혀 없던 충격(코로나 같은 구조 변화)·아주 불규칙한 데이터는 어떤 모델도 어렵다. TimesFM은 '강력한 출발점'이지, '모든 예측의 정답'은 아니다. 필요하면 LoRA로 미세조정하는 길도 열려 있다.
pyproject.toml · 소스 트리에서 직접 확인한 실제 구성.
TimesFM은 의외로 설치가 가볍다. 핵심 의존성은 numpy·huggingface_hub·safetensors 셋뿐이고, 무거운 딥러닝 백엔드(PyTorch 또는 JAX)는 '엑스트라(extras)'로 골라서 깐다. 같은 모델을 PyTorch / JAX(Flax) / HuggingFace Transformers 세 가지 런타임으로 쓸 수 있는 게 특징이다.
| 구성요소 | 무엇 | 역할 |
|---|---|---|
| Python 3.10+ | 런타임 | 패키지명 timesfm. 3.12+ 권장. |
| numpy ≥1.26 | 수치 연산 | 입력 시계열은 numpy 배열. 모든 입출력의 기본 자료형. |
| huggingface_hub | 체크포인트 다운로드 | from_pretrained("google/...")가 허브에서 가중치를 받아옴(첫 호출 시 ~/.cache). |
| safetensors | 가중치 파일 포맷 | 안전·고속 텐서 저장 포맷. load_file로 읽어 load_state_dict. |
| 설치 명령 | 백엔드 | 언제 |
|---|---|---|
pip install timesfm[torch] | PyTorch ≥2.0 | 가장 일반적. CUDA GPU·Apple Silicon(MPS)·CPU 다 지원. |
pip install timesfm[flax] | JAX/Flax | 추론 속도가 더 빠른 경로. flax·optax·einshape·jax[cuda] 동반. |
pip install timesfm[xreg] | JAX + scikit-learn | 공변량(외부 변수) 예측에 필요한 XReg 선형모델 라이브러리. |
| 버전 | 파라미터 / 문맥 | 특징 |
|---|---|---|
| 2.5 (최신) | 200M / 최대 16,384 | 연속 분위수 헤드(+30M 옵션), frequency 플래그 제거, 새 예측 플래그들. |
| 2.0 | 500M / 2,048 | 실험적 분위수 헤드 10개, frequency 지시자, GIFT-Eval 최상위. |
| 1.0 | 200M / 512~2,048 | 최초 공개판. 점예측 위주(분위수 미보정). v1/에 보관. |
패키지[옵션] 형태로, 기본 설치엔 빼고 필요할 때만 까는 추가 의존성 묶음. timesfm[torch]는 "TimesFM + PyTorch까지"라는 뜻. 무거운 백엔드를 강제로 깔지 않아 설치가 가볍다.과거값 한 줄이 미래 예측이 되어 나오기까지 — 데이터의 여정.
TimesFM의 핵심 아이디어는 한 문장이다 — "시계열을 토막(패치)으로 잘라 단어처럼 다루는 디코더 전용 트랜스포머." GPT가 글을 토큰(단어 조각)으로 잘라 다음 토큰을 예측하듯, TimesFM은 시계열을 32개 시점씩 묶은 '패치'로 잘라 다음 패치를 예측한다. 먼저 숲(전체 그림)을 보고, 그다음 흐름 한 줄기를 끝까지 따라가 보자.
model.forecast(horizon=12, inputs=[...])실제 코드 호출 하나가 내부에서 어떤 순서로 도는지, 핵심 5%(해피패스)만 따라간다.
① 입력 정리 (NaN·길이). 들어온 시계열에서 앞쪽 결측(NaN)은 잘라내고, 중간 결측은 선형 보간한다. 문맥 한도(2.5는 16,384)보다 길면 뒤쪽(최신) 부분만 남기고, 짧으면 앞을 0으로 채운 뒤 마스크로 가린다. → "최근 데이터가 가장 중요"라는 가정이 코드에 박혀 있다.
② 패칭 + RevIN 정규화. 길이 context를 context/32개의 32짜리 패치로 reshape한다. 패치마다 평균·표준편차를 구해 정규화(RevIN)해서 모델에 넣고, 출력은 다시 역정규화한다. → 매출이 100단위든 100만 단위든 모델이 같은 눈높이로 보게 만드는 장치.
# timesfm_2p5_torch.py 의 decode() 핵심 (개념 요약)
patched_inputs = reshape(inputs, (batch, -1, 32)) # 32개씩 토막
x = revin(patched_inputs, reverse=False) # 정규화하고 들어감
h = stacked_transformers(tokenizer(x)) # 임베딩→트랜스포머
out_patch = point_head(h) # 한 번에 128시점 예측
y = revin(out_patch, reverse=True) # 역정규화로 원래 스케일 복원
③ 트랜스포머 통과. 임베딩된 패치들이 20층 디코더를 지난다. causal mask(인과 마스크) 덕에 각 패치는 자기보다 과거 패치만 본다 — 미래를 훔쳐보지 않는다. RoPE(회전 위치 인코딩)로 "몇 번째 패치인지" 위치 감각을 넣는다.
④ 두 헤드로 출력. 점예측 헤드는 다음 128개 시점(=출력 패치 길이)을 한 번에 내놓고, 분위수 헤드는 같은 구간의 10개 분위를 내놓는다. 결과는 항상 (점예측, 분위수예측) 튜플.
⑤ 긴 horizon은 자기회귀로 이어붙임. 한 번에 128시점까지만 나오므로, 더 긴 예측이 필요하면 방금 뽑은 중앙값(median) 예측을 다시 입력 뒤에 붙여 모델을 또 돌린다. (horizon-1)//128번 반복해 원하는 길이까지 늘린다 — GPT가 단어를 하나씩 이어 쓰며 문장을 완성하는 것과 똑같은 원리.
가장 중요한 결정. 시점 하나하나를 토큰으로 쓰면 시퀀스가 너무 길어지고 비효율적이다. TimesFM은 32개 시점을 한 패치로 묶어 입력 토큰을 만든다(입력 패치 32, 출력 패치 128). 토큰 수가 1/32로 줄어 긴 문맥(16k)을 감당할 수 있고, 한 번에 128시점을 예측해 빠르다.
서로 다른 시계열은 단위가 제각각(원, 명, ℃…)이다. RevIN(Reversible Instance Normalization, 되돌릴 수 있는 인스턴스 정규화)은 입력을 평균 0·표준편차 1로 맞춰 넣고, 출력에서 그 변환을 정확히 되돌린다. 모델은 '모양(패턴)'에만 집중하고, '크기(스케일)'는 정규화가 책임진다.
2.5는 점예측뿐 아니라 분위수(10·20·…·90%)로 불확실성 구간을 준다. 게다가 켜고 끌 수 있는 '예측 플래그'들이 품질을 보정한다.
model.compile(timesfm.ForecastConfig(
max_context=1024, max_horizon=256,
normalize_inputs=True, # 입력 z-정규화
use_continuous_quantile_head=True,# 연속 분위수(구간 보정)
force_flip_invariance=True, # 뒤집어도 같은 결과 보장
infer_is_positive=True, # 음수 못 나오게(수요·가격)
fix_quantile_crossing=True, # q10≤…≤q90 순서 강제
))
force_flip_invariance가 재미있다. "입력에 a를 곱하고 b를 더하면 예측도 똑같이 a배+b" 라는 성질을, a가 음수일 때까지 보장하려고 입력 X와 -X를 둘 다 예측해 평균낸다. 대칭성을 코드로 강제한 영리한 트릭이다.
저장소를 열었을 때 어디부터 봐야 하는가 — 2단 구조(최신 vs 보관).
처음 저장소를 열면 헷갈릴 수 있는 핵심 하나 — 최신 2.5 코드는 src/timesfm/에, 옛 1.0/2.0 코드는 v1/에 따로 보관돼 있다. 공부할 땐 src/timesfm/를 먼저 보면 된다.
| 위치 | 역할 |
|---|---|
src/timesfm/ | 지금 설치되는 패키지. 새로 공부·사용한다면 여기만 봐도 된다. |
timesfm_2p5/*_torch.py | 실제 추론 로직의 심장. decode()에 패칭·자기회귀가 들어 있다. |
torch/ · flax/ | 같은 레이어(트랜스포머·RMSNorm·RevIN)를 두 백엔드로 각각 구현. |
timesfm-forecasting/ | 코드가 아니라 '사용 설명서 + 실행 스크립트'. 가장 빠르게 손에 익히는 길. |
v1/ | 옛 버전·미세조정(LoRA)·벤치마크 재현. 논문 결과를 직접 돌려보고 싶을 때. |
이 레포에서 실제로 무엇을 배울 수 있는가 — 기술별 + 실습 아이디어.
이미지(ViT)·오디오·시계열 같은 연속 데이터를 트랜스포머에 넣는 보편 기술이 패칭이다. TimesFM에서 "32개 묶어 1토큰" 코드를 읽으면, 왜 토큰 수가 줄고 긴 문맥이 가능한지 몸으로 이해된다.
실습 아이디어: 사인파 시계열을 만들어 patch_len을 16/32/64로 바꿔가며 예측 정확도·속도를 비교해 본다.
RoPE·RMSNorm·QK-norm·SwiGLU·fused QKV — 요즘 LLM의 표준 레시피가 src/timesfm/torch/transformer.py에 그대로 들어 있다. "LLM 구조를 다른 도메인에 옮기면 어떻게 되는지"의 살아있는 교본이다.
실습 아이디어: transformer.py에서 RoPE 적용부와 scaled_dot_product_attention 호출을 찾아, 텍스트 GPT 구현과 한 줄씩 대조해 본다.
긴 horizon을 만들 때 "예측을 다시 입력에 붙여 반복"하는 루프와, 매번 다시 계산하지 않으려는 KV 캐시(DecodeCache)가 들어 있다. GPT의 토큰 생성과 정확히 같은 메커니즘을 시계열로 본다.
실습 아이디어: horizon=128 vs 512로 호출해 디코드 스텝 수가 어떻게 달라지는지(=(horizon-1)//128) 로그로 확인.
같은 모델을 PyTorch·Flax로 각각 구현하면서 configs.py의 프레임워크 무관 설정 dataclass로 공통 스펙을 분리했다. "엔진은 달라도 설계도는 하나"라는 추상화 패턴을 배우기 좋다.
실습 아이디어: torch 백엔드와 flax 백엔드로 같은 입력을 예측해, 결과가 (거의) 같은지·속도가 어떻게 다른지 비교.
timesfm-forecasting/examples/finetuning/는 HuggingFace Transformers + PEFT(LoRA)로 파운데이션 모델을 내 데이터에 살짝 적응시키는 표준 패턴을 보여준다. "제로샷이 부족할 때 다음 카드"를 손에 익힌다.
실습 아이디어: 공개 데이터(예: 항공 승객 수)로 제로샷 vs LoRA 미세조정 후 오차(MASE)를 비교.
내 컴퓨터로 돌릴 수 있나? — 2.5는 의외로 가볍다.
좋은 소식 — 2.5(200M)는 GPU가 없어도 돈다. CPU에선 느릴 뿐(5~20배), 못 돌리는 건 아니다. 저장소의 system_requirements.md 기준 대략의 그림은 이렇다.
| 항목 | 2.5 (200M) | 2.0 (500M) |
|---|---|---|
| 모델 가중치 | ~800 MB | ~2 GB |
| RAM(작은 배치) | ~1.5 GB | ~3.5 GB |
| GPU VRAM(배치 32~256) | ~1.2 ~ 2.5 GB | ≥8 GB 권장 |
| 디스크 다운로드 | ~1 GB | ~2 GB |
대략의 메모리 공식은 RAM ≈ 가중치 + 0.5GB + (0.2MB × 시계열수 × 문맥/1000). 즉 시계열 개수와 문맥 길이를 늘릴수록 메모리가 는다. 환경별 가이드:
| 환경 | 설정 권장 | 속도(대략) |
|---|---|---|
| CPU 4~8GB | 2.5만, batch 4, 문맥 512 | 100시점당 2~5초 |
| CPU 16GB / GPU 4~8GB | batch 32~64, 문맥 1024 | GPU 0.5~1초/시계열 |
| GPU 16GB+ / Apple Silicon 32GB+ | batch 128~256, 문맥 4096+ | 0.1~0.3초/시계열 |
OS는 리눅스(CUDA 최적)·macOS 13+(MPS)·Windows 11+WSL2를 지원한다. 실행 전 python scripts/check_system.py로 사전점검하면, RAM 4GB 미만은 경고·2GB 미만은 차단해 준다. 모든 예제는 속도 팁으로 torch.set_float32_matmul_precision("high")를 켠다.
예측 정확도엔 보통 충분한 과거(문맥)가 크게 기여한다. 메모리가 허락하면 문맥을 늘리고, 대신 한 번에 처리하는 시계열 수(batch)를 줄여 균형을 맞추면 된다. compile() 때 max_context는 32의 배수, max_horizon은 128의 배수여야 한다(아니면 자동 올림).
난이도별로 — 손으로 돌려봐야 진짜 내 것이 된다.
먼저 '복사만 하면 OK'인 기본 호출부터. 아래 다섯 줄이 TimesFM 예측의 전부다.
import torch, numpy as np, timesfm
torch.set_float32_matmul_precision("high")
# ① 체크포인트 로드(첫 실행 때 자동 다운로드)
model = timesfm.TimesFM_2p5_200M_torch.from_pretrained("google/timesfm-2.5-200m-pytorch")
# ② 예측 설정으로 컴파일(이걸 빼면 RuntimeError)
model.compile(timesfm.ForecastConfig(max_context=1024, max_horizon=256, normalize_inputs=True))
# ③ 과거값을 넣고 horizon(미래 길이)만큼 예측
point, quantile = model.forecast(horizon=12, inputs=[np.sin(np.linspace(0,20,100))])
print(point.shape) # (1, 12) : 점예측
print(quantile.shape) # (1, 12, 10): 평균 + 10~90% 분위
아무 시계열 CSV(일별 매출·방문자수 등)를 준비해 timesfm-forecasting/scripts/forecast_csv.py --horizon 30 --value-cols 매출로 30일 예측을 뽑아 본다. 코드 한 줄 안 짜고 결과를 그래프로 본다.
quantile 출력에서 10%·50%·90% 분위를 뽑아, 중앙선 + 음영 밴드로 그린다. ⚠️ 인덱스 함정 주의 — 0번=평균, 1번=10%, 5번=중앙값, 9번=90%. 이상탐지 예제(examples/anomaly-detection)가 참고가 된다.
같은 데이터로 max_context를 256 / 1024 / 4096으로 바꿔 예측 오차(MASE·MAPE)를 비교한다. "과거를 더 많이 보면 정말 더 정확한가?"를 직접 측정해 본다.
pip install timesfm[xreg] 후 forecast_with_covariates()로 '가격'·'휴일' 같은 변수를 함께 넣어, 변수 유무에 따른 예측 차이를 본다(examples/covariates-forecasting).
examples/finetuning/의 PEFT(LoRA) 예제로, 제로샷이 약했던 데이터에 모델을 살짝 적응시킨다. 미세조정 전후의 오차를 비교해 "언제 미세조정이 값을 하는가"를 판단해 본다.
TimesFM을 발판으로 시계열+트랜스포머를 제대로 — 6주 계획.
| 주차 | 주제 | 학습 자료 / 할 일 |
|---|---|---|
| 1주차 | 시계열 예측 기초 | 정상성·계절성·MASE/MAPE 지표 개념. ARIMA·Prophet으로 베이스라인 한 번 만들어 보기. |
| 2주차 | TimesFM 제로샷 손에 익히기 | 이 문서 + 공식 README 예제. forecast()·forecast_csv.py로 여러 데이터 예측. |
| 3주차 | 트랜스포머 핵심 | "Attention Is All You Need" + 디코더 전용(GPT) 구조. self-attention·causal mask 이해. |
| 4주차 | 최신 LLM 부품 | RoPE·RMSNorm·SwiGLU·KV 캐시. src/timesfm/torch/transformer.py를 직접 읽기. |
| 5주차 | 패칭 & 정규화 | PatchTST·RevIN 논문. "연속 신호를 토큰으로" 패러다임을 시계열·비전 양쪽에서. |
| 6주차 | 미세조정 & 평가 | LoRA(PEFT) 예제 실행 + GIFT-Eval 벤치마크로 제로샷 vs 미세조정 비교. |
문서·코드에 자주 나오는 용어 — 한 줄 정의.
| 용어 | 의미 |
|---|---|
| Foundation Model | 방대한 데이터로 사전학습해 여러 과제에 재사용하는 기반 모델(시계열판 GPT). |
| Zero-shot | 추가 학습 없이 처음 보는 데이터를 바로 예측. |
| Context / Horizon | context=모델이 보는 과거 길이, horizon=예측할 미래 길이. |
| Patch(패치) | 시점 여러 개(입력 32·출력 128)를 묶은 토큰 단위. |
| Decoder-only | 과거→미래 한 방향으로 다음 것을 예측하는 GPT형 구조. |
| RevIN | 되돌릴 수 있는 인스턴스 정규화. 입력 스케일을 맞췄다가 출력에서 복원. |
| Quantile(분위수) | 예측의 분포/구간. 0번=평균, 5번=중앙값(점예측), 9번=90%분위. |
| Autoregressive | 예측을 다시 입력에 붙여 반복 생성(긴 horizon 처리). |
| Covariate(공변량) | 예측에 도움 주는 외부 변수(가격·휴일·날씨 등). XReg로 결합. |
| Flip-invariance | 입력을 a배+b 하면 예측도 a배+b. 음수 a까지 보장하는 2.5 플래그. |
| MASE / CRPS | 시계열 예측 정확도 지표. 낮을수록 좋음(점·확률 예측 평가). |
| LoRA / PEFT | 큰 모델을 적은 자원으로 미세조정하는 기법(일부 가중치만 학습). |
원문으로 더 깊이 — 공식 소스 위주.
timesfm-forecasting/ (SKILL.md · forecast_csv.py · check_system.py)