Jev Local
September 19, 2026 · View on GitHub
文章・JSON・画像に対する質問を、Choice(選択肢)・Score(段階評価)・Noul(真偽)の確率として返すローカルAPIです。同じ/v1/systemoneを、性質の違う2つのバックエンドで提供します。
| LFM(既定) | ModernBERT | |
|---|---|---|
| モデル | LFM2.5-1.2B Instruct / LFM2.5-VL-1.6B(llama.cpp, Q8_0) | ModernBERT-Ja 310Mをcross-encoderとしてfine-tune |
| 判定方式 | 回答先頭トークンのlogprob(zero-shot) | (質問+State, 候補)ペアの採点(学習済み重みを配布) |
| 入力 | 文章・JSON・画像 | 文章・JSON |
| 強いところ | 知識・未知の分類体系・自由な指示文 | 日本語の意図・関係判定と速度。候補順に依存しない |
| 追加依存 | なし(バイナリを自動取得) | torch+transformers(別venv) |
| JGLUE test | JNLI 17% / JComQA 69% | JNLI 93% / JComQA 92%(trainで学習) |
クライアント・評価ツール・API仕橘は共通です。まずLFMで動かしてから、必要に応じてModernBERTバックエンドを追加する想定です。
Jev本体のモデル・学習・精度を再現するものではありません。 TypeSafeの/v1/systemone形式に合わせた非公式アダプターです。画像入力はローカル拡張で、公式SDKの画像互換を意味しません。APIの互換範囲を参照してください。
セットアップと起動(LFM)
Python 3.12以上とBashが必要です。自動セットアップはLinux x86_64・arm64、macOS(Apple Silicon・Intel)に対応し、WindowsではWSL2を使用します。通常実行に追加Pythonパッケージやコンパイルは不要です。
git clone https://github.com/Argos1111/jev_local.git
cd jev_local
./setup.sh --model text
./run.sh --model text
画像も入力する場合は、次の構成を選びます。
./setup.sh --model vision
./run.sh --model vision
textは文章用モデルだけ、visionはVLモデルと画像エンコーダーを取得します。選択は保存され、以後の./run.shはそのモデルを使います。両方を取得済みなら、./run.sh --model text/--model visionだけで切り替えられます。切り替える際は稼働中のサーバーをCtrl+Cで停止してから起動してください。未設定時の既定はtextです。
setup.shはGPUを検出してCUDA・ROCm・Metal版のllama.cppを選択し、選択したモデルを取得・SHA256検証します。VL構成は画像エンコーダー(mmproj F16)込みで約2.1 GBです。GPUを利用できない場合は理由を表示してCPU版に切り替えます。初回のみGitHub・Hugging Faceへのネット接続が必要です。
GPUドライバーやROCmの共有ライブラリは別途必要です。OSのパッケージは自動インストールしません。CPUに固定する場合は./setup.sh --backend cpuを使います。対応環境・手動設定・トラブルシューティングを参照してください。
Ready: http://127.0.0.1:8080が表示されたら、サーバーを動かしたまま別ターミナルから入力を送ります。 Ctrl+Cで推論サーバーとAPIの両方が停止します。Connection refusedの場合は起動状態と送信先ポートを確認してください。
ランタイムを変更せずモデルだけ追加する場合は./setup.sh --model vision --model-only(文章用は--model text)を使います。LFM_MODEL・LFM_MMPROJを設定済みの場合はそれらが優先されるため、標準モデルの選択を使う前にunset LFM_MODEL LFM_MMPROJで解除してください。
テキスト・JSONで試す
python3 systemone_client.py
python3 systemone_client.py --input examples/systemone.json --format json
python3 systemone_client.py --input examples/systemone.json --output results/my_result.json
既定のサンプルは顧客の問い合わせに対する12問です。--format jsonで生JSONを表示します。--outputの保存内容は表示形式にかかわらずJSONです。自分の入力にはexamples/systemone.jsonのstateとquestionsを書き換えてください。
画像で試す
./run.sh --model visionで起動します。画像を自分で用意し、ローカルの画像フォルダなどに置きます。画像はリポジトリに同梱していません。
python3 systemone_client.py \
--input examples/vision.json \
--image sample_pics/photo.jpg
GSS資料向けの12問と4問もあります。対応する画像を用意した場合は次のように実行できます。
python3 systemone_client.py \
--input examples/vision_gss_4.json \
--image sample_pics/20260911_image_resized.png \
--format json \
--output results/my_vision_gss_4.json
``$
**速度を優先する場合は、画像の縦横をともに512\text{px}以内に収め(縦横比を維持)、質問を4問に絞る構成を推奨します。** 今回の検証では、512 \times 286\text{px}・4問・\text{GPU}・画像エンコード再利用の組み合わせが最も速く、同じ画像の再送は中央値約98\text{ms}でした。4問は4並列の1回分に収まります。画像サイズや質問数を網羅的に比較した結果ではなく、1〜3問より4問が速いことを意味しません。縮小と質問の選定は入力前に行います(自動変換・4問制限はありません)。
- \text{PNG}/\text{JPEG}、1枚4 \text{MiB}、最大4枚。複数枚は$--image`を繰り返します。
- HTTPではトップレベルの`images`配列にbase64 data URLを渡します。[画像API仕様](docs/API.md#画像入力ローカル拡張)を参照してください。
- 大きな画像・複数画像には`CTX_SIZE=32768 ./run.sh --model vision`などでコンテキストを増やします。既定は4 slots・合計8192トークンです。
- 各質問は独立に推論し、最大4問を並列処理します。画像入力ではdecoder側の共通Stateキャッシュを使いません。
## 画像エンコードの再利用(実験機能)
同じ画像を複数質問に使う場合、画像エンコーダーの出力だけをメモリ内で再利用するオプションがあります。**Linux x86_64 / AMD ROCm向けの追加ビルド**が必要です。通常の`setup.sh`・`run.sh`だけでは有効になりません。[ビルドと起動手順](docs/IMAGE_CACHE.md)に従って準備してください。
```bash
# ビルド済みの場合。通常サーバーとは別ポートを使用する例
./run_image_cache_gpu.sh --port 18080 --backend-port 18097
このサーバーに送るクライアントでは--url http://127.0.0.1:18080を追加します。画像+stateを読み込むdecoderの処理と各質問の判定は、引き続き質問ごとに実行します。
Radeon AI PRO R9700・512×286 px画像・4問での測定例:
| 条件 | 応答時間 |
|---|---|
| 再利用なし、10回の中央値 | 358 ms |
| 初回の画像、1回計算+3回再利用(2回測定) | 192〜212 ms |
| 同じ画像を再送、10回の中央値 | 98 ms |
モデルロードを除くHTTP応答時間です。1画像での実験値で、速度や正答率を保証するものではありません。測定条件と精度上の制約も参照してください。
ModernBERTバックエンド(文章のみ)
LLMの先頭トークン判定ではなく、sbintuitions/modernbert-ja-310mを「(質問+State, 候補)ペアの採点器」としてfine-tuneし、同じAPIを提供する構成です。torch+transformersを別のvenvに導入します。候補順への依存がなく、1リクエストの全質問を1回のバッチ推論で処理します。
./setup_modernbert.sh # .venv-modernbert(torch/transformers)。GPUを自動検出
./run_modernbert.sh # 学習済み重み argos1111/modernbert-ja-310m-jev を取得して起動(初回約1.3 GB)
python3 systemone_client.py # クライアントは共通
学習済み重みはHugging Face Hubで公開しています(CC BY-SA 4.0)。推論はVRAM約2 GB、CPUでも動作します(12問で約2秒)。
自分で学習する場合は./train_modernbert.shを実行します。公開日本語データ(JGLUE train・JCoLA・JCommonsenseMorality・MASSIVE)を自動取得し、R9700で約40分、bf16でVRAM約20 GB(--pair-budget 64で約10 GB)です。models/modernbert-ja-310m-jev/ができると./run_modernbert.shはそちらを優先します。
画像入力は非対応で、imagesを含むリクエストは422を返します。JGLUEの高い数値は同じデータのtrainで学習した結果です。学習に使っていないタスクでは特性が分かれます:知識を問うタスク(ニュース分類・JMMLU)はLFMの方が高く、短い日本語の意図判定(顧客対応の手作り16例)はModernBERTの方が高い結果でした。数値と条件、学習データとライセンス、OS別の対応状況はModernBERTバックエンドを参照してください。
API
curl http://127.0.0.1:8080/v1/systemone \
-H 'Authorization: Bearer local-dev' \
-H 'Content-Type: application/json' \
--data-binary @examples/systemone.json
| 質問のtype | 得られるもの |
|---|---|
choice | 選んだ候補、候補ごとの確率、分布の集中度 |
score | 段階番号の期待値、各段階の確率、分布の集中度 |
noul | 真である確率(0〜1) |
確率は指定した候補の中で正規化した値です。confidenceは分布の集中度で、正解率として校正された値ではありません。仕組みと制約を参照してください。
フォルダ構成
api_server.py / systemone.py HTTP APIと型付き判断
jev_local.py / state_cache.py 候補確率の計算・テキストStateの再利用
image_input.py 画像の検証・data URLへの変換
systemone_client.py / display.py クライアント・結果表示
modernbert/ ModernBERT cross-encoderの学習・推論・API
scripts/ セットアップ・起動・実験ビルド
native/ 画像エンコードキャッシュとC++単体テスト
examples/ リクエストJSON
sample_pics/ ローカル入力画像(画像はGit対象外)
tests/ Python単体テスト
tools/ 動作確認・評価・速度測定
docs/ 詳細な設定・仕様・測定条件
models/ .cache/ results/ .venv*/ ローカル生成物(Git対象外)
モデル・画像・生ログ・計測結果・ビルド成果物はGitHubに含めません。公開する測定要約はdocs/にまとめています。results/内のファイルを編集しても配布コードにはならないため、再利用するスクリプトはtools/で管理します。
開発・検証
python3 -m unittest discover -s tests -v # モデル・ダウンロード不要
python3 -m tools.verify_api # 起動済みAPIの実通信確認
python3 -m tools.verify_vision # 合成画像で画像入力を確認
python3 -m tools.benchmark_jglue --output results/jglue # JGLUE test(どちらのバックエンドでも)
python3 -m tools.evaluate_heldout_tasks --output results/ho # 学習に使っていないタスクでの比較
CIではPythonテスト・シェル構文と、モデル不要のC++キャッシュテストを実行します。ModernBERTのテストも疑似エンコーダーで動くため、CIにtorchは不要です。GPU推論の確認はローカルで行います。
依存するllama.cppとLFM2.5モデル、ModernBERT-Ja(MIT)は、それぞれの配布元の利用条件に従います。ModernBERTの学習に使う公開データセット(JGLUE・JCoLA・JMMLU: CC BY-SA 4.0、JCommonsenseMorality: MIT、MASSIVE: CC BY 4.0、livedoor: CC BY-ND 2.1 JP)は実行時に取得し、リポジトリには含めません。学習済みモデルを再配布する場合はCC BY-SAの継承条件に留意してください。本プロジェクトにバイナリ・モデル重みは同梱しません。