Apache Camel × AI ― サービングによる推論 #1: TorchServe
リリースされたばかりのApache Camel 4.10 LTSでは、AI関連コンポーネントがさらに強化されました。なかでも、AIモデルサービングに関する3つの新しいコンポーネントが追加されています。[1]
以前の記事「Apache Camel AI ― DJLコンポーネントを使ったAIの活用方法」ではDJLコンポーネントを使ってCamelルート内でAIモデルの推論を実行する方法を紹介しましたが、4.10ではこれらの新しいコンポーネントによってCamelルートから外部のモデルサーバーを呼び出して推論を行えるようになります。
Kubeflowなどが提供するMLOpsでは、学習したモデルは最終的にモデルサーバーにデプロイされて使われることになります。サービングのコンポーネントが充実することで、Camelを使ったアプリケーションをMLOpsライフサイクルのModel Servingフェーズに容易に組み込めるようになります。
この記事では、TorchServeコンポーネントの使い方を紹介します。
TorchServeコンポーネント
TorchServeは機械学習フレームワークのPyTorchが提供するサービング機能です。Camel TorchServeコンポーネントを使うことで、TorchServeサーバーが提供するREST APIをCamelルートから呼び出せるようになります。
基本的な使い方
TorchServeの使い方の基本的な流れは、以下の通りです。
- PyTorchで学習したモデルをサーバーに登録する
- 登録したモデルのメタデータを確認する
- メタデータを元にモデルを呼び出して推論を行なう
- 使い終わったモデルをサーバーから登録解除する
Camel TorchServeコンポーネントを使う上で、実用上最も重要なのは3番目のステップですが、各ステップをどうやってCamelで実現できるかを一通り見ていきましょう。
準備
まず、Camel CLIがインストールされていなければインストールしてください。
jbang app install camel@apache/camel
インストールできたか動作確認をします。
$ camel --version
4.10.0
次に、TorchServeサーバーが必要です。最も手軽な方法はDockerイメージを使う方法です。
docker run --rm -it --name torchserve \
-p 8080:8080 -p 8081:8081 -p 8082:8082 \
pytorch/torchserve \
torchserve \
--disable-token-auth \
--enable-model-api \
--model-store /home/model-server/model-store
サーバーのヘルスチェック
TorchServeサーバーの動作確認は http://localhost:8080/ping にアクセスすることでできますが、Camel TorchServeコンポーネントを使ってCamelルートから確認することもできます。
torchserve:inference/ping
//DEPS org.apache.camel:camel-bom:4.10.0@pom
//DEPS org.apache.camel:camel-core
//DEPS org.apache.camel:camel-torchserve
import org.apache.camel.builder.RouteBuilder;
public class ping extends RouteBuilder {
@Override
public void configure() throws Exception {
from("timer:ping?period=10000")
.to("torchserve:inference/ping")
.log("Status: ${body}");
}
}
Camel CLIから以下のように実行します。
camel run ping.java
サーバーが無事立ち上がっていれば、以下のようなステータスが得られるでしょう。
Status: Healthy
モデルの管理
TorchServeには管理APIがあり、そこから基本的な使い方のステップ1、2、4に相当するモデルの管理を行えます。一方、Camel TorchServeコンポーネントもこの管理APIに対応しており、Camelルートからもそれぞれの管理操作を行えます。
モデルの登録
まず、サーバーを立ち上げただけでは何も推論に使用できるモデルがありません。
Camelを使ってモデルを登録してみましょう。ここではPyTorch Model Zooで提供されている学習済みMNIST V2モデルを使います。
torchserve:management/register?url=https://torchserve.pytorch.org/mar_files/mnist_v2.mar
torchserve:management/scale-worker?modelName=mnist_v2
//DEPS org.apache.camel:camel-bom:4.10.0@pom
//DEPS org.apache.camel:camel-core
//DEPS org.apache.camel:camel-torchserve
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.torchserve.TorchServeConstants;
import org.apache.camel.component.torchserve.client.model.ScaleWorkerOptions;
public class register_model extends RouteBuilder {
@Override
public void configure() throws Exception {
from("timer:register?repeatCount=1")
.to("torchserve:management/register?url=https://torchserve.pytorch.org/mar_files/mnist_v2.mar")
.log("Status: ${body}")
.to("direct:scale-worker");
// Set up workers for the model after registration to make it available for inference
from("direct:scale-worker")
.setHeader(TorchServeConstants.SCALE_WORKER_OPTIONS,
constant(ScaleWorkerOptions.builder().minWorker(1).maxWorker(2).build()))
.to("torchserve:management/scale-worker?modelName=mnist_v2")
.log("Status: ${body}");
}
}
Camel CLIから以下のように実行します。
camel run register_model.java
モデルが無事登録されれば、以下のようなステータスが得られるでしょう。
Status: Model "mnist_v2" Version: 2.0 registered with 0 initial workers. Use scale workers API to add workers for the model.
Status: Processing worker updates...
デフォルトバージョンの設定
通常、推論のためにはモデル名とバージョンの指定が必要です。しかし、モデルのデフォルトバージョンを設定することでバージョンを省略できるようになります。
torchserve:management/set-default?modelName=mnist_v2&modelVersion=2.0
//DEPS org.apache.camel:camel-bom:4.10.0@pom
//DEPS org.apache.camel:camel-core
//DEPS org.apache.camel:camel-torchserve
import org.apache.camel.builder.RouteBuilder;
public class set_default extends RouteBuilder {
@Override
public void configure() throws Exception {
from("timer:set-default?repeatCount=1")
.to("torchserve:management/set-default?modelName=mnist_v2&modelVersion=2.0")
.log("Status: ${body}");
}
}
Camel CLIから以下のように実行します。
camel run set_default.java
設定が無事成功すれば、以下のようなステータスが得られるでしょう。
Status: Default version successfully updated for model "mnist_v2" to "2.0"
モデル詳細の取得
すでに登録されているモデルの詳細情報を取得することもできます。
torchserve:management/describe?modelName=mnist_v2
//DEPS org.apache.camel:camel-bom:4.10.0@pom
//DEPS org.apache.camel:camel-core
//DEPS org.apache.camel:camel-torchserve
import org.apache.camel.builder.RouteBuilder;
public class describe_model extends RouteBuilder {
@Override
public void configure() throws Exception {
from("timer:describe?repeatCount=1")
.to("torchserve:management/describe?modelName=mnist_v2")
.log("${body[0]}");
}
}
Camel CLIから以下のように実行します。
camel run describe_model.java
成功すれば、以下のような結果が得られるでしょう。
ModelDetail {
modelName: mnist_v2
modelVersion: 2.0
modelUrl: https://torchserve.pytorch.org/mar_files/mnist_v2.mar
minWorkers: 1
maxWorkers: 2
batchSize: 1
maxBatchDelay: 100
status: null
workers: [Worker { id: 9000, startTime: 2025-02-10T11:08:36.160Z, gpu: false, status: READY }]
metrics: null
jobQueueStatus: JobQueueStatus { remainingCapacity: 1000, pendingRequests: 0 }
}
モデル一覧の取得
モデルサーバーに登録されているモデルの一覧を取得することもできます。
torchserve:management/list
//DEPS org.apache.camel:camel-bom:4.10.0@pom
//DEPS org.apache.camel:camel-core
//DEPS org.apache.camel:camel-torchserve
import org.apache.camel.builder.RouteBuilder;
public class list_models extends RouteBuilder {
@Override
public void configure() throws Exception {
from("timer:list?repeatCount=1")
.to("torchserve:management/list")
.log("${body.models}");
}
}
Camel CLIから以下のように実行します。
camel run list_models.java
成功すれば、以下のような結果が得られるでしょう。今回はまだ1つしかモデルを登録していないので、一覧にも1つしかモデルがありません。
[Model { modelName: mnist_v2, modelUrl: https://torchserve.pytorch.org/mar_files/mnist_v2.mar }]
モデルの登録解除
まだこのモデルで推論を行っていないので実行はしませんが、モデルを使い終わったら登録解除できます。
torchserve:management/unregister?modelName=mnist_v2
//DEPS org.apache.camel:camel-bom:4.10.0@pom
//DEPS org.apache.camel:camel-core
//DEPS org.apache.camel:camel-torchserve
import org.apache.camel.builder.RouteBuilder;
public class unregister_model extends RouteBuilder {
@Override
public void configure() throws Exception {
from("timer:unregister?repeatCount=1")
.to("torchserve:management/unregister?modelName=mnist_v2")
.log("Status: ${body}");
}
}
Camel CLIから以下のように実行します。
camel run unregister_model.java
成功すれば、以下のようなステータスが得られるでしょう。
Status: Model "mnist_v2" unregistered
推論
さて、本題の推論です。最初に基本的な使い方でも書いたように、実際のCamelルートで主に使うのはこの操作(エンドポイント)です。
この記事ではMNISTモデルを使っています。28x28のグレースケールの手書きの画像を数字として認識させるモデルです。TorchServeのGitHubリポジトリにあるテストデータを使って、それをCamelルートからTorchServeに推論させてみましょう。
MNISTによる手書き数字の認識
推論には以下のエンドポイントを使います。
torchserve:inference/predictions?modelName=mnist_v2
//DEPS org.apache.camel:camel-bom:4.10.0@pom
//DEPS org.apache.camel:camel-core
//DEPS org.apache.camel:camel-torchserve
import org.apache.camel.builder.RouteBuilder;
public class predictions extends RouteBuilder {
@Override
public void configure() throws Exception {
from("file:data?noop=true&recursive=true&include=.*\\.png")
.to("torchserve:inference/predictions?modelName=mnist_v2")
.log("${headers.camelFileName} => ${body}");
}
}
テストデータをローカルのdata/
ディレクトリにダウンロードした後、Camel CLIから以下のように実行します。
camel run predictions.java
成功すれば、以下のような結果が得られるでしょう。手書きの数字が正しく認識されていることが確認できます。
8.png => 8
9.png => 9
4.png => 4
5.png => 5
7.png => 7
6.png => 6
2.png => 2
3.png => 3
1.png => 1
0.png => 0
メトリクス
最後にTorchServeのメトリクスAPIについても触れておきましょう。TorchServeには、モデルの使用状況をPrometheus形式のメトリクスとして出力する機能もあります。
torchserve:metrics/metrics?metricsName=MemoryUsed
//DEPS org.apache.camel:camel-bom:4.10.0@pom
//DEPS org.apache.camel:camel-core
//DEPS org.apache.camel:camel-torchserve
import org.apache.camel.builder.RouteBuilder;
public class metrics extends RouteBuilder {
@Override
public void configure() throws Exception {
from("timer:metrics?period=10000")
.to("torchserve:metrics/metrics?metricsName=MemoryUsed")
.log("${body}");
}
}
Camel CLIから以下のように実行します。
camel run metrics.java
成功すれば、以下のようにPrometheus形式で指定のメトリクスが得られるでしょう。
# HELP MemoryUsed Torchserve prometheus gauge metric with unit: Megabytes
# TYPE MemoryUsed gauge
MemoryUsed{Level="Host",Hostname="6f4ed8f42a64",} 821.91796875
まとめ
最新のCamel 4.10.0 LTSリリースで使えるAIモデルサービングコンポーネントの1つ、TorchServeコンポーネントの機能を一通り見てきました。
TorchServeコンポーネントを使えば、PyTorchで学習したAIモデルをTorchServeにデプロイし、すぐにCamelアプリケーションから利用できるようになります。Camelには既に300以上のコンポーネントが用意されており、様々な外部システムやサービスを繋いだインテグレーションのアプリケーションを開発できます。PyTorchのAIモデルをそうしたアプリケーションの中に組み込んで、これまでは難しかったより創造的なAIベースのインテグレーションを構築できるようになります。
次回の記事では、残り2つのサービングコンポーネントも紹介します。
サンプルコード
今回紹介したCamel×AIのサンプルコードは、このリポジトリで公開しています。
-
Camel TorchServeコンポーネントは4.9から。 ↩︎
Discussion