モデル / データセット
JohnSnowLabs/spark-nlp avatar
JohnSnowLabs/spark-nlp

Spark NLP を採用する前に確認すべきこと: Spark 上のアノテーション基盤とモデル配布の実態

State of the Art Natural Language Processing

スター 4,158フォーク 744ScalaApache-2.0

ひと目でわかる

これは何?
Apache Spark 上で動く NLP アノテーションライブラリ。Scala 実装で JVM と Python の両方から使え、学習済みパイプラインをダウンロードして動かす導線が整っている。一方で、モデルの入手経路とライセンス、Spark バージョンとの対応を先に確認しないと、採用後に詰まる。
誰に向いている?
大量テキストを Spark クラスタ上で一括処理し、その結果を DataFrame として下流に流したいチームには向いている。逆に、単発の推論 API を立てたいだけ、あるいは依存を最小限にした Python スクリプトで完結させたい場合には重すぎる。
商用利用できる?
できます。Apache-2.0 は寛容なライセンスで、著作権表示とライセンス表示を残せば、使用・改変・販売が可能です。
今もメンテナンスされている?
されています。最後のコミットは 3 日前です。
何の言語で書かれている?
主に Scala です(GitHub の言語統計による)。

回答はプロジェクトの GitHub データ(最終同期:2026年9月15日)と当サイトの分析に基づくもので、法的助言ではありません。

オープンソース詳細解説

Spark NLP が埋めるのは Spark ジョブと NLP モデルの間の隙間

Spark でテキストを処理しようとすると、トークン化や固有表現抽出のような処理を DataFrame の列変換として書き直す作業が発生する。Python の NLP ライブラリを UDF で包む方法は動くが、モデルのロードやバッチ処理を自分で管理することになり、分散環境での再現性も担保しにくい。Spark NLP はこの部分を Spark の Transformer として実装し、アノテーションを列として持つ DataFrame を出力する。README は「Apache Spark の上に構築された」ライブラリだと述べており、対象は機械学習パイプラインで NLP アノテーションを分散処理したい開発者である。Scala で書かれているため、Python と R だけでなく Java、Scala、Kotlin からも同じ機能に到達できる点が、JVM 側の資産を持つ組織にとっての差になる。

アノテーションは Document から始まり複数列に展開される

README の例では、PretrainedPipeline('explain_document_dl', lang='en') をロードし、annotate(text) を呼ぶと辞書が返る。キーは entities、stem、checked、lemma、document、pos、token、ner、embeddings、sentence の 10 種類で、入力テキスト 1 件に対して複数のアノテーション列が同時に生成される構造だとわかる。つまりパイプラインは単一のモデルではなく、トークン化、品詞付与、レンマ化、固有表現抽出、埋め込みといった複数の処理を連結したもので、その連結結果がそのまま列として並ぶ。result['entities'] が ['Mona Lisa', 'Leonardo', 'Louvre', 'Paris'] を返す例が README に示されており、固有表現が文字列のリストとして取り出せる。パイプラインの中身を list(result.keys()) で確認できるため、どのアノテーションが有効かを実行時に把握できる。ここで注意したいのは、返るキーはパイプライン定義に依存するという点で、すべてのパイプラインが同じ 10 列を返すわけではない。

導入手順: Java のバージョンと Spark の対応表が最初の関門

README の Quick Start は、まず java -version で Java 8 または 11 (Oracle か OpenJDK) を確認するところから始まる。次に conda create -n sparknlp python=3.7 -y で環境を作り、conda activate sparknlp の後、pip install spark-nlp==6.4.2 pyspark==3.3.1 を実行する。README には「spark-nlp by default is based on pyspark 3.x」とあり、既定の想定が PySpark 3 系であることが明記されている。Python 側では import sparknlp の後、spark = sparknlp.start() でセッションを開始する。start() は gpu、apple_silicon、memory の 3 引数を取り、sparknlp.start(gpu=True)、sparknlp.start(apple_silicon=True)、sparknlp.start(memory="16G") の例が示されている。パッケージは実行環境ごとに分かれており、CPU は spark-nlp、GPU は spark-nlp-gpu、AArch64 (linux) は spark-nlp-aarch64、Apple Silicon は spark-nlp-silicon を選ぶ。README は M1/M2 と AArch64 を experimental なサポートと注記しているので、これらを本番基盤の前提に置くのは避けたほうがよい。

モデルは同梱されない。配布経路とライセンスが本体と別に効いてくる

ライブラリ本体のライセンスは Apache-2.0 で、リポジトリの LICENSE にもその表示がある。ただし README が掲げる「100000+ の学習済みパイプラインとモデル」「200+ 言語」は別途配布される資産であり、本体の Apache-2.0 がそのまま適用されるとは README からは読み取れない。PretrainedPipeline は名前を指定してダウンロードする仕組みなので、実行時にはネットワーク経由でモデルを取得することになる。エアギャップ環境や外部通信を制限したバッチ基盤では、この取得経路がそのまま障害になる。モデルを事前に配置する手順は README の範囲では説明されておらず、ここは導入前に自分で確認する必要がある領域だ。ライセンスについても、モデルごとに条件が異なりうるという前提で個別に確認するのが妥当で、本記事は法的助言を与えるものではない。

TensorFlow、ONNX、OpenVINO、GGUF を取り込めるが、対応の深さは一様ではない

README はモデルインポートの対応先として TensorFlow、ONNX、OpenVINO、Llama.cpp (GGUF) の 4 つを挙げている。既存の学習済みモデルを Spark のパイプラインに載せ替えたい場合、フレームワークをまたいで取り込める余地があるということだ。ただし README が示すのは対応先の一覧であり、各形式についてどの演算が変換可能か、どの程度のモデルサイズまで実用的かといった粒度の情報は含まれていない。GGUF や ONNX を扱う動機は「すでにその形式のモデル資産がある」ことなので、実際に変換を試すまでは自分のモデルが通るか判断できない。ここは README の記述以上に踏み込んだ評価を当サイトは行っていない。導入検討時には、対象モデルを 1 つ選んで変換と推論を通す検証を先に済ませるべきで、対応表だけを見て計画を立てるのは危険である。

Spark を前提にしていることが、そのまま適用範囲の境界になる

このライブラリの最も大きな制約は、Apache Spark が動作前提であることだ。数万件のテキストを一括処理する用途では、分散実行と DataFrame への統合が効く。しかし、リクエストごとに 1 件のテキストを返す低レイテンシの推論サービスを立てたいだけなら、SparkSession の起動とモデルのロードという固定費がそのまま遅延になる。README の例も、テキスト 1 件を annotate する形ではあるが、その前段で sparknlp.start() を呼んでいる。単発処理のためにクラスタを立ち上げる構成は割に合わない。加えて Java 8 または 11 という実行環境の指定、PySpark 3 系という既定、experimental 扱いの Apple Silicon と AArch64 という条件が重なる。既存システムが Java 17 で動いている、あるいは Spark 4 系へ移行予定だという場合、この組み合わせが成立するかは README からは判断できない。Spark を使っていない、あるいは今後も使う予定がないチームにとっては、この依存関係そのものが採用を止める理由になる。

代替として spaCy を選ぶ場合、違いは分散の有無に集約される

Spark を前提としない選択肢として spaCy がある。どちらもトークン化、品詞付与、レンマ化、固有表現抽出をパイプラインとして提供する点は共通している。違いは実行モデルだ。spaCy は単一プロセスの Python ライブラリとして設計されており、並列化するなら複数プロセスを自前で立てるか、呼び出し側でバッチを分割することになる。Spark NLP は Spark の分散実行に乗るため、パーティション分割と集約をフレームワーク側に任せられる。逆に、Spark クラスタを持たない環境では spaCy のほうが導入の階段が低い。もう 1 つの違いは JVM への到達性で、Scala で書かれた Spark NLP は Java、Scala、Kotlin から直接呼べる。Python 中心の構成ならこの利点は働かない。処理対象が数百万件規模で、すでに Spark 基盤があるなら Spark NLP、数千件規模で単発バッチなら spaCy、という切り分けが現実的である。

バージョン更新の追従コストは Spark 側の都合に引きずられる

リリースは 6.4.0 (2026-04-07)、6.4.1 (2026-05-25)、6.4.2 (2026-06-24) と、およそ 1 か月から 2 か月間隔で並んでいる。メジャー番号が上がるときには、対応する Spark のバージョンとモデルの互換性を確認する作業が発生すると考えられる。README のパッケージ表が Apache Spark 3.0 から 3.5 までを列挙しているのに対し、Quick Start が固定するのは pyspark==3.3.1 と spark-nlp==6.4.2 の組み合わせである。この 2 つは一致しているので、まずこの組み合わせで動かし、その後に自分の Spark バージョンへ寄せる、という順序が現実的だ。更新のたびにモデルの再取得が必要になる可能性もあり、モデルをキャッシュする仕組みを自前で持っていない場合は、その分の帯域と時間を見込んでおく必要がある。

編集部の結論

大量テキストを Spark クラスタ上で一括処理し、その結果を DataFrame として下流に流したいチームには向いている。逆に、単発の推論 API を立てたいだけ、あるいは依存を最小限にした Python スクリプトで完結させたい場合には重すぎる。採用前に確認すべきは 3 点で、第一に自分の Apache Spark のバージョンに対応する Maven パッケージ (spark-nlp / spark-nlp-gpu / spark-nlp-aarch64 / spark-nlp-silicon) を選び、sparknlp.start() の引数と一致させること。第二に使いたいモデルが PretrainedPipeline で取得できるか、モデル名と lang を実際に解決して確認すること。第三に Apache-2.0 の本体と、配布モデル側の条件が同じとは限らないため、モデルごとのライセンス表記を確認すること。この 3 点が自分の環境で噛み合わないなら、採用を見送る判断は早いほうがよい。

公式情報源

  1. JohnSnowLabs/spark-nlp on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
コミュニティノート

コミュニティノート