
【夏休みの自由研究リレー】 Chronos-2をSageMaker AIのリアルタイム推論で使う方法を調査してみた
こんにちは、データ事業本部の鈴木です。
当記事はクラスメソッドの有志による『夏休みの自由研究リレー』 第8回のエントリです。
このブログリレーの企画は、普段からクラウドやAIを追いかけているメンバーによって、「やってみた」だけではなく「作ってみた」や「調査/研究してみた」もアウトプットしてみようという企画です。
新たな知見になることは勿論、アイデアを自社やコミュニティの発展に寄与できればと考えておりますので、お付き合い頂けますと幸いです。
では、さっそくいってみましょう。今回の記事は『 Chronos-2 を SageMaker AI の推論エンドポイントで使う方法を調査してみた』です。
Amazon の時系列基盤モデル である Chronos-2 は、AutoGluon-Cloud また SageMaker JumpStart から SageMaker をインフラにデプロイして利用できます。
この記事では AutoGluon-Cloud と JumpStart で推論エンドポイントをデプロイし、実際に推論を行うところまで試してみました。
Chronos-2 について
Chronos-2 は、ゼロショットで時系列予測ができる事前学習済みモデルです。単変量だけでなく、多変量や共変量付きの予測にも対応しています。特に Chronos-2 の強みは、複数の単変量時系列間で情報を共有し、より正確な予測を実現するクロスラーニングです。新規系列の予測に類似する系列を合わせて入力することで、コールドスタートな予測シナリオでもより正確な予測が期待されます。

(Introducing Chronos-2: From univariate to universal forecasting より2026/8/1に引用)
予測も、2025/10時点で fev-bench 時系列ベンチマークで既存の時系列基盤モデル(TSFM)を大幅に上回る性能が報告されています。
Chronos-2 の実運用でのインフラとしては、 Amazon SageMaker AI が HuggingFace ページでも紹介されています。
デプロイ方法は AutoGluon-Cloud および SageMaker Jumpstart が紹介されており、前者が推奨とされています。まずはそれぞれの仕組みからどのように SageMaker AI にデプロイできるのかを確認してみました。
事前準備
1. 検証方法の設計
有名な時系列予測ツールである Prophet の Quick Start を題材に、 過去の Peyton Manning の Wikipedia ページビュー数データから1年分の値を予測してみて予測の流れを確認しました。
以下の条件で実施しました。
- 入力は
ds(日付)とy(数値)の 2 列を使用する - データの末尾 365 日 をテストデータとしてホールドアウトする
- 学習データはその直前2年分の期間とする
- 評価指標は MAE / RMSE / MASE で比較する
- 学習データで欠損がある日は、学習データ内で線形補完する
- 推論結果の中で、テストデータに該当日がない場合は評価指標算出からは除外する
学習期間・テスト期間は以下の通りです。
| 学習期間 | 学習データ日数 | テスト期間 | テストデータ日数 |
|---|---|---|---|
| 2013-01-20 〜 2015-01-20 | 731日 | 2015-01-21 〜 2016-01-20 | 365 日 |
2. SageMaker Studio の準備
AutoGluon-Cloud 用の Python プログラム実行や SageMaker Jumpstart の操作を SageMaker Studio で行いたいため、クイックスタートで SageMaker Studio ドメインを作成しました。
やってみる
1. AutoGluon-Cloud でデプロイする
まずは、 AutoGluon-Cloud でデプロイしてみました。
Chronos-2の推奨の方法になります。
今回は SageMaker Studio から Jupyter Lab スペースを起動し、 Python プログラムを実行しました。
# AutoGluon の推論ペイロードで pyarrow が必要だったが、
# PyExtensionType エラーが起きたためバージョンを指定した。
!pip uninstall -y pyarrow
!pip install -U "autogluon.cloud>=0.5.0" "pandas[pyarrow]" "pyarrow>=17,<20"
# 共通設定
from autogluon.cloud import bootstrap
from autogluon.cloud import TimeSeriesFoundationModel, TimeSeriesEndpoint
import warnings
from pathlib import Path
import matplotlib.pyplot as plt
import pandas as pd
warnings.filterwarnings("ignore", category=FutureWarning)
INSTANCE_TYPE = "ml.c5.xlarge" # 今回は検証なのでサポートされている中で最も安価なインスタンスタイプ
REGION = "ap-northeast-1"
HISTORY_YEARS = 3 # 使用する履歴データの期間
PERIODS = 365 # 予測期間 = テスト期間(日数)
FREQ = "D"
SEASONAL_PERIOD = 7 # MASE 計算用(日次データの週次季節性)
# 必要リソースの作成、初回のみ
bootstrap()
# 検証データの読み込み
df = pd.read_csv(
"https://raw.githubusercontent.com/facebook/prophet/main/examples/example_wp_log_peyton_manning.csv"
)
df["ds"] = pd.to_datetime(df["ds"])
df = df.sort_values("ds")
# 直近 HISTORY_YEARS 年に絞る(末尾 PERIODS 日をテストにすると学習は約 2 年)
history_start = df["ds"].max() - pd.DateOffset(years=HISTORY_YEARS)
df = df[df["ds"] >= history_start].reset_index(drop=True)
# 末尾 PERIODS 日をテストデータ(評価用)に分割
df_train = df.iloc[:-PERIODS].reset_index(drop=True)
df_test = df.iloc[-PERIODS:].reset_index(drop=True)
# Chronos-2 をリアルタイムエンドポイントに新規デプロイ
model = TimeSeriesFoundationModel(model_id="chronos-2")
endpoint = model.deploy(instance_type=INSTANCE_TYPE)
# AutoGluon 形式に整形(item_id / timestamp / target)
df_chronos = df_train.rename(columns={"ds": "timestamp", "y": "target"}).copy()
df_chronos["item_id"] = "peyton_manning"
# 日付欠損があると freq を推論できないため、日次に揃える
full_idx = pd.date_range(
df_chronos["timestamp"].min(),
df_chronos["timestamp"].max(),
freq=FREQ,
)
df_chronos = (
df_chronos.set_index("timestamp")
.reindex(full_idx)
.assign(item_id=lambda d: d["item_id"].fillna("peyton_manning"))
)
df_chronos["target"] = df_chronos["target"].interpolate(limit_direction="both")
df_chronos = df_chronos.reset_index(names="timestamp")
# 推論実行
predictions = endpoint.predict(
data=df_chronos,
target="target",
id_column="item_id",
timestamp_column="timestamp",
prediction_length=PERIODS,
)
bootstrap()ではエンドポイントデプロイに必要な IAM ロールおよび S3 バケットが作成され、ローカルの設定ファイルに記録されます。
▼ローカルの設定ファイル

▼作成されるスタック

▼作成された IAM ロールのポリシー

リソースは CloudFormation で作成されるため、上記のような実装で行うと CloudFormation のスタック作成と IAM ロール・ S3 バケット作成に関するポリシーを SageMaker Studio の実行ロールに付与しないといけません。少し権限が強すぎるように感じる場合は、先にbootstrap()は別途行っておき、register()により設定するのがおすすめです。
from autogluon.cloud import register
SAGEMAKER_ROLE = "" # あらかじめ作成していたIAMロールARN
S3_BUCKET = "" # あらかじめ作成していたS3バケット名
register(
role=SAGEMAKER_ROLE,
bucket=S3_BUCKET,
region=REGION,
)
TimeSeriesFoundationModelのdeploy()により、 SagaMaker AI のリアルタイムエンドポイントにモデルをデプロイできました。


predict()によりデプロイしたエンドポイントにリクエストを送信し、指定した区間の予測結果を取得することができました。
▼入力系列と正解データ・予測結果を可視化したもの

▼精度指標
| MAE | RMSE | MASE |
|---|---|---|
| 0.3338 | 0.4617 | 0.8737 |
AutoGluon-Cloudのメリットは、1つのライブラリでリアルタイム推論・サーバーレス推論・バッチ変換の3つに対応できる点があります。また、入力もPandas DataFrameに対応しています。
Fine-tuning向けのAPIも用意されています。
2. SageMaker Jumpstartでデプロイする
続いて JumpStart でも Chronos-2 をデプロイしました。こちらはエンドポイントのデプロイまで UI で完結します。
SageMaker Studio のコンソールから JumpStart を開いて chronos-2 を検索・選択しました。

Deployボタンを押しました。

エンドポイントの設定では、今回はサポートされていた中で一番料金が安いml.c5.xlargeを選びました。より高いスループットを求める場合はインスタンスサイズを上げたり、アクセラレーター付きのインスタンスを選択することも可能でした。

必要であれば Adcanced setting から IAM Role やネットワーク設定もできましたが、今回は特に要件はないのでデフォルトとしました。

ページ下部にあるDeployボタンを押してデプロイしました。
しばらくすると、 Endpoints からエンドポイントがデプロイされたことが確認できました。

JupyterLab スペースを起動し、 Jupyter Notebook から Python で推論を実行しました。
Chronos-2 は事前学習済みモデルなので、対象系列をエンドポイントへ送りました。
import json
import warnings
from pathlib import Path
import boto3
import matplotlib.pyplot as plt
import pandas as pd
# 続く検証で使うためimport
from prophet import Prophet
warnings.filterwarnings("ignore", category=FutureWarning)
ENDPOINT_NAME = "" # デプロイしたエンドポイント
REGION = "ap-northeast-1"
HISTORY_YEARS = 3 # 使用する履歴データの期間
PERIODS = 365 # 予測期間 = テスト期間(日数)
FREQ = "D"
SEASONAL_PERIOD = 7 # MASE 計算用(日次データの週次季節性)
# 学習・テストデータの用意
df = pd.read_csv(
"https://raw.githubusercontent.com/facebook/prophet/main/examples/example_wp_log_peyton_manning.csv"
)
df["ds"] = pd.to_datetime(df["ds"])
df = df.sort_values("ds")
# 直近 HISTORY_YEARS 年に絞る(末尾 PERIODS 日をテストにすると学習は約 2 年)
history_start = df["ds"].max() - pd.DateOffset(years=HISTORY_YEARS)
df = df[df["ds"] >= history_start].reset_index(drop=True)
# 末尾 PERIODS 日をテストデータ(評価用)に分割
df_train = df.iloc[:-PERIODS].reset_index(drop=True)
df_test = df.iloc[-PERIODS:].reset_index(drop=True)
print(f"全体: {df['ds'].min().date()} 〜 {df['ds'].max().date()} ({len(df)} 日)")
print(f"Train: {df_train['ds'].min().date()} 〜 {df_train['ds'].max().date()} ({len(df_train)} 日)")
print(f"Test: {df_test['ds'].min().date()} 〜 {df_test['ds'].max().date()} ({len(df_test)} 日)")
df_train.head()
# Chronos-2での推論実行
client = boto3.client("sagemaker-runtime", region_name=REGION)
payload = {
"inputs": [
{
"target": df_train["y"].tolist(),
"item_id": "peyton_manning",
"start": df_train["ds"].iloc[0].strftime("%Y-%m-%d"),
}
],
"parameters": {
"prediction_length": PERIODS,
"freq": FREQ,
"quantile_levels": [0.1, 0.5, 0.9],
},
}
response = client.invoke_endpoint(
EndpointName=ENDPOINT_NAME,
ContentType="application/json",
Body=json.dumps(payload),
)
result = json.loads(response["Body"].read().decode("utf-8"))
▼入力系列と正解データ・予測結果を可視化したもの

▼精度指標
| MAE | RMSE | MASE |
|---|---|---|
| 0.3394 | 0.4644 | 0.8852 |
Jumpstart の場合、 UI から簡単に操作できるのが大きなメリットです。操作も簡単で分かりやすかったです。とりあえず boto3 からリクエストを送るような際にも相性が良いです。性能も検証時点では大きく異なることはありませんでした。
最後に
Chronos-2 を SageMaker JumpStart と AutoGluon-Cloud からSageMaker AI リアルタイム推論のエンドポイントにデプロイし、推論を行うまでの動線を確認しました。
Chronos-2 で初めて時系列基盤モデルを利用しましたが、 SageMaker AI のおかげで非常に簡単に利用ができて驚きました。カスタマイズが不要であればモデルの学習も必要なく、モデルを管理する必要もないのは時系列予測をシステムに組み込む上で非常に強力な強みと思います。データがまだ十分に集まっていないコールドスタートな場面でも強みを発揮しそうです。
以上、『夏休みの自由研究リレー』の第8回のエントリ『Chronos-2を SageMaker AI の推論エンドポイントで使う方法を調査してみた』でした。
次回は川中子さんの「5年分の睡眠トラッキングデータを統計とGeminiで分析してみる」の予定です。お楽しみに!!










