TimesFM: Nhà Tiên Tri Số Của Google Không Cần Train
TL;DR
- Giải quyết gì: Pipeline forecast theo từng dataset - train, validate, deploy mất tuần mới trả lời được “quý sau bán bao nhiêu?”
- Vì sao quan trọng: Hầu hết team cần con số khả dĩ hôm nay, không phải sau cuộc thi chọn mô hình - baseline tệ làm hỏng kế hoạch tồn kho, nhân sự, ngân sách
- Ai nên dùng: Data analyst, ML engineer, product team có số liệu lịch sử và cần dự báo kèm độ không chắc chắn mà không dựng job training riêng
- Khác biệt chính: Zero-shot trên chuỗi chưa từng thấy - pretrain trên 100 tỷ điểm thời gian thực, không cần fine-tune cho lần chạy đầu
- Ví dụ cụ thể: 100 ngày doanh số hàng ngày →
model.forecast(horizon=12)→ trajectory tháng tới + dải percentile 10–90 trong một lần gọi
Sếp hỏi forecast quý sau thứ Ba. Thứ Tư tôi có notebook Prophet, baseline ARIMA, và cảm giác cả ba mô hình chênh nhau vì tôi tune nhiều hơn là nghĩ.
Thứ Năm pip install timesfm, nhét cùng file CSV vào, có số trước giờ ăn trưa. Không hoàn hảo. Nhất quán, nhanh, và nói thẳng độ không chắc chắn. Với câu hỏi thứ Ba thì vậy là đủ.
TimesFM Là Gì
TimesFM là package Python từ Google Research, bọc quanh một transformer decoder-only đã pretrain - cùng họ kiến trúc với LLM, nhưng token là các patch số, không phải chữ. Cài pip install timesfm[torch] (hoặc timesfm[flax] cho JAX), load checkpoint từ Hugging Face, gọi .forecast() trên mảng NumPy thô.
Một câu junior dev nhắc lại được: TimesFM nhận giá trị lịch sử của chuỗi thời gian và dự đoán tương lai mà không cần train trên dataset cụ thể của bạn trước.
Checkpoint mới nhất là TimesFM 2.5: 200M tham số (giảm từ 500M ở bản 2.0), context tới 16k điểm, và quantile head tùy chọn cho dải uncertainty tới horizon 1.000 bước. Pretrain trên khoảng 100 tỷ điểm thời gian thực - Google Trends, Wikipedia pageviews, corpus công khai khác - nên nó đã thấy đường cong mùa vụ bán lẻ, spike traffic, decay chậm trước khi spreadsheet của bạn tới.
Ẩn Dụ
Hai người dự báo thời tiết. Người thứ nhất cần sáu tháng radar địa phương mới dám nói ngày mai. Người thứ hai đọc pattern từ mọi châu lục cả thập kỷ; bạn đưa nhiệt độ tuần rồi, cô ấy trả forecast kèm error bar.
TimesFM là người thứ hai. Không toàn tri. Không phép thuật. Nhưng cô ấy không bắt bạn chờ pipeline training mới có ý kiến.
Giá trị lịch sử → patch thành token → transformer decoder-only → patch tương lai
(CSV của bạn) (nhóm điểm) (200M params, pretrain) (điểm + quantile)
Patch quan trọng. Thay vì dự đoán từng timestep (chậm, lỗi tích lũy trên horizon dài), TimesFM dự đoán cả khối - patch input 32 điểm có thể forecast 128 điểm tiếp. Ít bước generation hơn, ít lỗi chồng lên nhau. Cùng ý tưởng làm LLM thực dụng, áp vào số.
--> // making it invisible to querySelectorAll. // // `data-cfasync="false"` keeps this rescue script executable even when // Rocket Loader is active. It rescues module scripts via two strategies: // 1. Query the DOM for type$="-module" + src (covers case A) // 2. Regex-parse the raw HTML for commented-out script tags (covers case B) // Dynamically-created scripts bypass Rocket Loader entirely. (function () { if (window.__markdyRescue) return; window.__markdyRescue = true; var rescued = false; function rescueModuleScripts() { if (rescued) return; rescued = true; var srcs = []; // Strategy 1: Rocket Loader kept the tag in DOM but changed the type. // type="module" → type="{uuid}-module" (still has src attribute) document.querySelectorAll('script[type$="-module"][src]').forEach(function (s) { srcs.push(s.src); }); // Strategy 2: Rocket Loader COMMENTED OUT the script tag entirely: // // These are invisible to querySelectorAll, so we parse the raw HTML. // We handle both attribute orderings (type-first or src-first). var html = document.documentElement.innerHTML; var reSrcFirst = //g; var reTypeFirst = //g; var m; while ((m = reSrcFirst.exec(html)) !== null) { srcs.push(m[1]); } while ((m = reTypeFirst.exec(html)) !== null) { srcs.push(m[1]); } // Re-inject each found src as a real module script. // Deduplicate first, then inject. Dynamically-created scripts bypass // Rocket Loader entirely. Modules with the same URL are only executed // once by the browser (cached), so re-injecting already-running scripts // is safe. var seen = {}; srcs.forEach(function (src) { if (seen[src]) return; seen[src] = true; var fix = document.createElement('script'); fix.type = 'module'; fix.src = src; fix.setAttribute('data-cfasync', 'false'); document.head.appendChild(fix); }); } // Rescue when user clicks the placeholder (fallback if autoplay failed). document.addEventListener('click', function (e) { var t = e.target; if (t && typeof t.closest === 'function' && t.closest('.markdy-placeholder')) { rescueModuleScripts(); } }); // Rescue automatically after a short delay for autoplay. // Only fires if initAll() never ran (no data-markdy-init on any root). setTimeout(function () { if (document.querySelector('.markdy-root:not([data-markdy-init])')) { rescueModuleScripts(); } }, 1500); }());Ví Dụ Ngắn Nhất
import numpy as np
import timesfm
# Load TimesFM 2.5 đã pretrain và compile với horizon bạn cần
model = timesfm.TimesFM_2p5_200M_torch.from_pretrained("google/timesfm-2.5-200m-pytorch")
model.compile(timesfm.ForecastConfig(max_context=1024, max_horizon=256))
# Đưa mảng 1D lịch sử; nhận forecast điểm + dải quantile
point, quantiles = model.forecast(
horizon=12,
inputs=[np.linspace(0, 1, 100)], # 100 ngày lịch sử → 12 bước tới
)
# point.shape == (1, 12)
# quantiles.shape == (1, 12, 10) - mean cộng percentile 10 đến 90
Mười hai dòng. Không train/val split. Không grid hyperparameter. Quantile head là phần hầu hết baseline bỏ qua mà planner thực sự cần.
💡 Tip: Gọi
model.compile()một lần với cap context và horizon. Đặtmax_horizonbằng cửa sổ planning để không phải compile lại mỗi lần.forecast().
Google Đã Gắn Vào Đâu
Không phải đồ chơi research trong notebook. Google đã wire TimesFM vào sản phẩm người ta đang dùng:
| Mặt | Bạn nhận được gì |
|---|---|
| BigQuery ML | Forecast cấp SQL, scale warehouse |
| Google Sheets | Nút forecast trong spreadsheet kết nối |
| Vertex Model Garden | Endpoint Docker cho pipeline agentic |
Kế hoạch nhu cầu bán lẻ là use case Google hay nhắc: cải thiện nhỏ độ chính xác forecast cũng giảm chi phí tồn kho và tăng doanh thu. Ops sống trong Sheets, data team sống trong BigQuery - cùng một mô hình, không ai phải retrain từ đầu.
Repo open-source trên GitHub (21k+ stars, Python) là lối thoát cho phần còn lại - notebook local, pipeline tùy chỉnh, fine-tune LoRA qua HuggingFace + PEFT nếu zero-shot chưa đủ.
Cách Cũ vs TimesFM
| Pipeline cổ điển (ARIMA / Prophet / DL tùy chỉnh) | TimesFM zero-shot | |
|---|---|---|
| Setup | Feature engineering, train/val, tìm hyperparameter | pip install, load checkpoint, gọi .forecast() |
| Tới forecast đầu tiên | Giờ đến tuần | Phút |
| Chuỗi mới | Retrain hoặc transfer cẩn thận | Ra lò ngay |
| Dải uncertainty | Tùy mô hình, thường gắn thêm | Có sẵn trong quantile head |
| Thắng khi | Pattern đặc thù domain, covariate phong phú | Baseline nhanh, nhiều chuỗi khác nhau, cold-start |
Khi Nào Không Dùng
Chuỗi đa biến với covariate lạ. Bản 2.5 có lại covariate qua XReg, nhưng nếu forecast phụ thuộc hàng chục regressor tương tác phức tạp, mô hình train riêng trên domain vẫn thắng.
Granularity dưới giờ trên stream IoT ồn. Corpus pretrain nghiêng daily/weekly/monthly - bán lẻ, traffic, search interest. Sensor tần số cao, jitter microsecond không phải sân nhà nó.
Khi “đủ tốt” không đủ tốt. Zero-shot gần supervised DL trên benchmark công khai (paper ICML 2024), nhưng “gần” không phải “nhất” mọi dataset. Sai số forecast trực tiếp ảnh hưởng hàng triệu tồn kho thì vẫn nên fine-tune hoặc ensemble.
GPU memory khi batch khổng lồ. 200M nhỏ so với LLM, nhưng batch hàng nghìn chuỗi context dài trên laptop vẫn muốn accelerator thật. BigQuery ML tồn tại một phần vì laptop bạn không phải warehouse.
README cũng nói thẳng: repo open này không phải sản phẩm Google được support chính thức. SLA production nằm ở Vertex và BigQuery, không nằm trong GitHub issue.
⚠️ Warning: Coi repo GitHub là lối thoát research, không phải endpoint được quản trị. Nếu sai số forecast ảnh hưởng trực tiếp tồn kho, validate zero-shot trong notebook trước, rồi chuyển sang BigQuery ML hoặc Vertex khi cần audit trail và SLA.
Điều Tôi Không Ngờ
Tôi tưởng thêm một thư viện forecast có diagram đẹp và bảng benchmark. Không ngờ có agent skill - timesfm-forecasting/SKILL.md trong repo - viết để coding agent gọi mô hình đúng API, không bịa shape. Repo Google Research hiếm khi ship kiểu đó. Có vẻ họ kỳ vọng người ta gắn vào pipeline tự động, không chỉ ablation học thuật.
Ví dụ fine-tune xuất hiện tháng 4/2026 (LoRA qua HuggingFace + PEFT). Build Flax inference nhanh hơn. Unit test trong tests/. Dự án chạy như sản phẩm, không như artifact sau paper.
Kết
Sếp vẫn nhận forecast thứ Sáu. Hai bản - Prophet và TimesFM cạnh nhau. Họp planning dùng dải quantile TimesFM, giữ Prophet làm sanity check.
Người dự báo thứ hai không thay người thứ nhất. Cô ấy chỉ làm câu hỏi thứ Ba có câu trả lời trước thứ Năm - và đó là phần lớn những gì forecast trong đời thực thực sự cần.
Tôi vẫn không dám forecast cuộc đời mình. Nhưng doanh số quý sau thì có số rồi. Tạm vậy.
google-research/timesfm · Apache-2.0 · 22k · blog
Hoang Yell
Một nhà phát triển phần mềm và là người kể chuyện kỹ thuật. Tôi dành thời gian để khám phá những repository mã nguồn mở thú vị nhất trên GitHub và trình bày chúng dưới dạng những câu chuyện dễ hiểu cho mọi người.