Milvus
Zilliz
  • Home
  • Blog
  • Pythonがなくても問題なし:Javaやその他の言語でのONNXによるモデル推論

Pythonがなくても問題なし:Javaやその他の言語でのONNXによるモデル推論

  • Engineering
May 30, 2025
Stefan Webb

ジェネレーティブAIアプリケーションの構築がかつてないほど簡単になりました。ツール、AIモデル、データセットの豊富なエコシステムにより、専門外のソフトウェアエンジニアでも印象的なチャットボットや画像ジェネレーターなどを構築できる。このツールの大部分はPython用に作られ、PyTorchの上に構築されている。しかし、本番環境でPythonにアクセスできず、Java、Golang、Rust、C++、あるいは他の言語を使う必要がある場合はどうだろうか?

ここでは、埋め込みモデルと基礎モデルの両方を含む、モデル推論に限定して説明します。Pythonを使わないモデル推論の選択肢は?最も明白な解決策は、AnthropicやMistralのようなプロバイダーのオンラインサービスを利用することです。彼らは通常、Python以外の言語用のSDKを提供しており、もしそうでなければ、単純なREST APIコールが必要になるだけです。しかし、例えばコンプライアンスやプライバシーの問題から、ソリューションを完全にローカルにしなければならない場合はどうするのだろうか?

もう一つの解決策は、ローカルでPythonサーバーを実行することだ。もともとの問題は、本番環境でPythonを実行できないことでしたので、ローカルのPythonサーバーを使うことは除外されます。関連するローカルソリューションは、おそらく同様の法的、セキュリティベース、あるいは技術的な制約を受けるでしょう。Javaや他のPython以外の言語から直接モデルを呼び出せるような、完全なソリューションが必要です。

図1:PythonがOnyxの蝶に変態する。

ONNX(Open Neural Network Exchange)とは?

ONNX(OpenNeural Network Exchange)は、ニューラルネットワークモデルの推論を実行するためのツールで構成される、プラットフォームにとらわれないエコシステムです。当初はMeta(当時はFacebook)のPyTorchチームによって開発され、さらにMicrosoft、IBM、Huawei、Intel、AMD、Arm、Qualcommが参加している。現在は、Linux Foundation for AI and Dataが所有するオープンソースプロジェクトである。ONNXは、プラットフォームに依存しないニューラルネットワークモデルを配布するための事実上の方法である。

図2:NN変換器の(部分的な)ONNX計算グラフ

ONNX」は通常、そのファイル形式を指す狭義の意味で使用します。ONNXモデル・ファイルは計算グラフを表し、しばしば数学関数のウェイト値を含み、この標準はニューラル・ネットワークの一般的な操作を定義している。PyTorchでautodiffを使用したときに作成される計算グラフと同様に考えることができます。別の観点から見ると、ONNXファイルフォーマットはニューラルネットワークの中間表現(IR)として機能し、ネイティブコードのコンパイルとよく似ています。上の図はONNX計算グラフを視覚化したものです。

図3:IRはフロントエンドとバックエンドのさまざまな組み合わせを可能にする

ONNXファイルフォーマットはONNXエコシステムの一部に過ぎず、計算グラフを操作するためのライブラリや、ONNXモデルファイルをロードして実行するためのライブラリも含まれている。これらのライブラリは、言語やプラットフォームにまたがっている。ONNXは単なるIR(中間表現言語)であるため、ネイティブコードで実行する前に、特定のハードウェアプラットフォームに特化した最適化を適用することができる。上の図は、フロントエンドとバックエンドの組み合わせを示したものです。

ONNXワークフロー

例えば、オープンソースのベクトルデータベースMilvusにデータを取り込む準備として、Javaからテキスト埋め込みモデルを呼び出すことを検討する。では、埋め込みモデルや基礎モデルをJavaから呼び出す場合、対応するモデルファイル上でONNXライブラリを使うだけでよいのでしょうか?はい、しかし、モデルとトークナイザーエンコーダー(およびファンデーションモデルのデコーダー)の両方のファイルを入手する必要があります。これらのファイルはPythonをオフラインで、つまり本番前に自分で作成することができます。

PythonからNNモデルをエクスポートする

PythonからHuggingFaceのセンテントランスフォーマライブラリを使って、一般的なテキスト埋め込みモデル、all-MiniLM-L6-v2 を開いてみよう。.txtaiのutilライブラリを介して間接的にHFライブラリを使用します。なぜなら、変換関数の後にプーリング層と正規化層もエクスポートする、文変換のラッパーが必要だからです。(これらの層は文脈依存のトークン埋め込み、つまりトランスフォーマの出力を受け取り、単一のテキスト埋め込みに変換します)。

from txtai.pipeline import HFOnnx

path = “sentence-transformers/all-MiniLM-L6-v2” onnx_model = HFOnnx() model = onnx_model(path, “pooling”, “model.onnx”, True)

HuggingFace モデルハブからsentence-transformers/all-MiniLM-L6-v2 を ONNX としてエクスポートし、タスクをテキスト埋め込みと指定し、モデルの量子化を有効にするようにライブラリに指示する。onnx_model() を呼び出すと、モデルがまだローカルに存在しない場合、モデルハブからモデルをダウンロードし、3つのレイヤーをONNXに変換し、それらの計算グラフを結合する。

これでJavaで推論を実行する準備ができただろうか?それほど速くはない。モデルは、埋め込みたいテキストのトークン化に対応するトークンのリスト(複数のサンプルの場合はリストのリスト)を入力する。したがって、本番前にすべてのトークン化を実行できない限り、Java内からトークナイザを実行する必要があります。

これにはいくつかの選択肢があります。ひとつは、問題のモデルのトークナイザをJavaまたは他の言語で実装するか、実装を見つけ、Javaから静的または動的にリンクされたライブラリとして呼び出すことです。より簡単な解決策は、モデルのONNXファイルを使用するのと同じように、トークナイザをONNXファイルに変換してJavaから使用することです。

しかし、プレーンなONNXには、トークナイザーの計算グラフを実装するのに必要な操作は含まれていません。このため、Microsoft社はONNXRuntime-ExtensionsというONNXを補強するライブラリを作成した。ONNXRuntime-Extensionsは、テキスト・トークナイザーだけでなく、あらゆるデータの前処理と後処理に役立つ操作を定義しています。

ここでは、私たちのトークナイザーをONNXファイルとしてエクスポートする方法を説明します:

from onnxruntime_extensions import gen_processing_models
from sentence_transformers import SentenceTransformer

embedding_model = SentenceTransformer(‘all-MiniLM-L6-v2’) tok_encode, _ = gen_processing_models(embedding_model.tokenizer, pre_kwargs={})

onnx_tokenizer_path = “tokenizer.onnx” with open(tokenizer_path, “wb”) as f: f.write(tok_encode.SerializeToString())

文の埋め込みにはデコーダーは必要ないので、トークナイザーのデコーダーは破棄しました。これで、テキストをトークン化するためのtokenizer.onnx と、トークンの文字列を埋め込むためのmodel.onnx の2つのファイルができました。

Javaでのモデル推論

Javaからモデルを実行するのは、今や簡単なことだ。以下は、完全な例からのコードの重要な行の一部です:

// Imports required for Java/ONNX integration
import ai.onnxruntime.*;
import ai.onnxruntime.extensions.*;

// Set up inference sessions for tokenizer and model var env = OrtEnvironment.getEnvironment();

var sess_opt = new OrtSession.SessionOptions(); sess_opt.registerCustomOpLibrary(OrtxPackage.getLibraryPath());

var tokenizer = env.createSession(“app/tokenizer.onnx”, sess_opt); var model = env.createSession(“app/model.onnx”, sess_opt);

// Perform inference and extract text embeddings into native Java var results = session.run(inputs).get(“embeddings”); float[][] embeddings = (float[][]) results.get().getValue();

完全な動作例は、リソースセクションにあります。

まとめ

この記事では、HuggingFaceのモデルハブからオープンソースのモデルをエクスポートし、Python以外の言語から直接使用することが可能であることを見てきました。しかし、いくつかの注意点があります:

第一に、ONNXライブラリとランタイム拡張機能は、さまざまなレベルの機能をサポートしています。将来のSDKアップデートがリリースされるまで、すべての言語ですべてのモデルを使用することはできないかもしれません。Python、C++、Java、JavaScript用のONNXランタイム・ライブラリが最も包括的です。

第二に、HuggingFaceハブには事前にエクスポートされたONNXが含まれているが、これらのモデルには最終的なプーリングと正規化レイヤーは含まれていない。torch.onnx を直接使うつもりなら、sentence-transformers がどのように機能するか知っておくべきである。

とはいえ、ONNXは主要な業界リーダーの支持を得ており、クロスプラットフォームのジェネレーティブAIの摩擦のない手段となる軌道に乗っている。

リソース

    Try Managed Milvus for Free

    Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.

    Get Started

    Like the article? Spread the word

    続けて読む