GLiNER:ローカルでの判定とエンティティ抽出

開発プレビュー。 重みは Hugging Face で公開済みです。Swift モジュールはレビュー中で、speech-swift のリリースにはまだ含まれていません。

GLiNER モジュールは GLiNER2.5-Decide を MLX Swift で実行します。テキストと許可するラベルの一覧を渡すと分類スコアが得られ、人物や時刻などのエンティティのスパンも取得できます。

仕組み

DeBERTa エンコーダがテキストとスキーマをまとめて読み込みます。分類ヘッドがラベルを採点し、エンティティヘッドが元の文のスパンを特定します。ランタイムは JSON をトークン単位で生成しません。

import GLiNER
let model = try await GLiNER.fromPretrained()
let choices = try model.classify(
    "Remind me to call Dad at six PM.",
    labels: ["create_reminder", "send_message", "other"]
)
let spans = try model.extractEntities(
    "Remind me to call Dad at six PM.",
    labels: ["person", "time"]
)

重み

固定した上流リビジョン 7ee5da4c の MLX 変換を 3 種類 Hugging Face で公開しています。ランタイムは初回使用時に選択したバリアントをダウンロードし、以降はローカルキャッシュを再利用します。Python は使いません。

バリアントリポジトリ重みルーティング抽出ピークメモリ
int8 (既定)aufklarer/GLiNER2.5-Decide-340M-MLX-8bit567 MB7.6 ms8.9 ms0.85 GB
fp16aufklarer/GLiNER2.5-Decide-340M-MLX-fp16973 MB8.8 ms10.0 ms1.58 GB
fp32aufklarer/GLiNER2.5-Decide-340M-MLX1.95 GB11.1 ms12.6 ms2.55 GB

Apple M5 Pro、他の負荷なし:トークン化を含むリクエスト全体の中央値と、プロセスのピークメモリ。3 つのバリアントはいずれも 24 件の参照ケースで上流の PyTorch モデルと同じラベル・スパン・オフセットを返し、信頼度の差は 0.006 以内です。

コマンドライン

speech CLI は 2 つのタスクを speech gliner classify と speech gliner extract として提供します。ラベルはカンマ区切りで渡し、--description label=text は繰り返し指定できます。テキストを省略すると stdin から読み込みます。--variant で int8(既定)、fp16、fp32 を選び、--model-dir でダウンロードの代わりにローカルのバンドルを読み込みます。無効な引数はモデルの読み込み前に拒否されます。--json を付けると、各ラベルの確率または UTF-16 オフセット付きのスパンに加え、読み込みと推論の時間を出力します。

swift build -c release --product speech --disable-sandbox
scripts/build_mlx_metallib.sh release
.build/release/speech gliner classify "Remind me to call Dad at six PM." \
  --labels create_reminder,send_message,set_timer,other
.build/release/speech gliner extract "Remind me to call Dad at six PM." \
  --labels person,time --json

エージェント向けモデルカードは、正確な API、出力フィールド、検証済みの結果をまとめた Markdown ファイルです。

小規模なコマンドセットでの精度

手書きのルーティング例 16 件のうち 12 件、抽出例 8 件のうち 7 件が期待どおりでした。Swift 版は 24 件の参照ケースで上流の PyTorch モデルを再現し、トークン ID・ラベル・スパンが一致し、スコアの差は 0.001 以内です。これらの小さなセットは挙動と再現性の確認用で、幅広い精度ベンチマークではありません。

対応範囲と制限

精度とメモリ

FP16 は重みの保存容量を半分の 973 MB にします。INT8 はエンコーダの行列とトークン埋め込みを 64 個単位で 8 ビットに量子化し、ヘッド・正規化・活性化は FP16 のまま、ファイルは 567 MB です。ランタイムは INT8 行列をパックしたまま保持し、リクエストで使う埋め込み行だけをデコードします。

エンコーダの相対位置射影は重みだけで決まるため、リクエストごとではなく読み込み時に一度だけ計算します。オプションの GLiNER.load(from:evaluateLayers:) モードはエンコーダ層を 1 層ずつ実体化し、ピーク時の確保量を抑えます。

出典とクレジット