手元の PC で完結するローカル LLM ― RAG と複数モデルのクロスチェックで、外部に出せない文書を読み込み・推敲・点検する(Ollama+Open WebUI/CPU/GPU 対応・Windows)
目次
- はじめに
- 前提知識(用語の整理)
- 動作確認用モデル:LFM2.5-1.2B-Instruct
- 主要 Python パッケージ、埋め込みモデル
- Ollama、LFM2.5-1.2B-Instruct モデルのインストール
- 演習 1.Ollama の動作確認(CUI)
- LFM2.5-1.2B-Instruct による動作確認の準備
- gemma4:e2b-it-qat・gemma4:12b-it-qat モデルのインストール(任意で 26b-a4b-it-qat)
- 発展(任意):Docling による図表・数式を含む文書の高精度抽出(Docker + docling-serve)
- 付録:他のモデルを試す・推論ツールの選択
【概要】 大規模言語モデル(LLM)は、入力された文に続く次のトークンを確率的に予測する仕組みであり、出力に誤りを含む可能性がある。出力の品質は、プロンプトの構成と思考モードのオン・オフに依存する。RAG(検索拡張生成)は、LLM が既存資料を検索し、その結果を踏まえて応答を生成することで、固有情報や最新情報を要する質問への対応力を高める仕組みである。ローカル運用、複数モデルの併用、複数段階の判定により、応答の精度と情報セキュリティを高めることができる。
スライド資料
[PDF], [パワーポイント] (同じ内容, クリックしてダウンロード)
動画
はじめに
本手順は、Windows 上でローカル LLM 環境を 2 段階で構築し、インストール後の基本動作およびプロンプト戦略の試行を行う。基盤は Ollama、フロントエンドは Open WebUI(Python 3.12。Open WebUI の公式ドキュメントは互換性の観点から Python 3.11 を推奨しているため、新規に環境を用意する場合は 3.11 を選んでもよい。その場合は本手順中の Python312 を Python311 に読み替える)である。Ollama には、コンテキスト長 262144 トークンおよび KV キャッシュ q8_0 を設定する。KV キャッシュはモデルが過去のトークンの中間表現を保持する領域であり、q8_0 はこの領域を 8 ビット整数に量子化してメモリ使用量を低減する設定である。これらの設定は最初のインストール時に一度だけ行い、以降の段階でも引き継がれる。
本手順で用いるモデルは、いずれも CPU のみの PC や少 VRAM の GPU でも動作する点が共通する。
- 最初は、最軽量の動作確認用モデル LFM2.5-1.2B-Instruct(パラメータ数約 1.2B、GGUF の Q4_K_M 量子化で約 731MB、VRAM 目安 1〜2GB)と、埋め込みモデル bge-m3 を導入する。ディスク 15GB /メモリ 16GB の環境を前提とし、インストール完了の確認、Ollama・Open WebUI の動作検証、RAG(検索拡張生成)の基礎概念(文書解析・埋め込みベクトル・検索拡張生成)の体験、および予備的なプロンプト戦略の試行を実施する。
- 次は、一段上のモデル gemma4:e2b-it-qat(Gemma 4 シリーズのエッジデバイス向け E2B モデル、ダウンロード容量約 4.3GB)と、上位の gemma4:12b-it-qat(同シリーズの 12B モデル、約 7.2GB)を追加する。さらにメモリに余裕がある場合は、最上位の選択肢として gemma4:26b-a4b-it-qat(同シリーズの 26B クラスの MoE モデル、約 16GB)も利用できる。演習では、複数モデルのクロスチェック・冊子横断検出・二段プロンプト戦略・教科書品質チェック・長文機密文書の矛盾検出を扱う。いずれも QAT(Quantization-Aware Training、量子化を考慮した学習)によって軽量化され、ライセンスは Apache 2.0、テキストに加えて画像入力にも対応し、思考モード(reasoning)を備える。E2B の「E」は有効パラメータ(effective parameters)を表し、有効 2.3B(埋め込みを含めると 5.1B)、35 層、語彙数 262K、コンテキスト長 128K(131072 トークン)で、Google 公表のベンチマークでは MMLU Pro 60.0%、多言語ベンチマーク MMMLU 67.4% である。12B(総パラメータ約 11.95B)はコンテキスト長 256K(262144 トークン)で、同ベンチマークの MMLU Pro は 77.2%、MMMLU は 83.4% である。26B A4B(総パラメータ 25.2B、推論時の活性パラメータ 3.8B の MoE)はコンテキスト長 256K で、MMLU Pro 82.6%、MMMLU 86.3% と、規模が上がるほど数値が高い。各モデルは事前学習データ・規模・構造が異なるため誤り傾向の相関が低く、併用することで誤りの見逃しを減らせる。
前提知識(用語の整理)
本節では、本手順を読み進めるうえで前提となる基本概念を整理する。
LLM(大規模言語モデル)とは
LLM(Large Language Model、大規模言語モデル)は、大量のテキストを学習したニューラルネットワークであり、対話・要約・翻訳などを行う。入力テキストをトークン(語や記号の単位。文字や単語の断片に相当する単位)に分割し、入力された文に続く次のトークンを確率的に予測することで文章を生成する。モデルの規模はパラメータ数(例:1.2B=12 億)で表される。この仕組み上、出力は確率に基づく予測であり、事実と異なる内容(ハルシネーション:もっともらしいが事実でない出力)を含む可能性がある。出力の品質は、入力するプロンプトの構成と、思考モード(応答前に内部で推論過程を生成する機能。演習 8 以降で扱う)のオン・オフに依存する。
学習と推論
学習はモデルのパラメータを更新する工程、推論は学習済みモデルに入力を与えて出力(応答)を得る工程である。学習はさらに、ゼロから大規模データで行う事前学習と、既存モデルを追加データで微調整するファインチューニング(FT)に分かれる。LoRA(Low-Rank Adaptation)は FT の代表的な手法で、元モデルの重みを凍結し、少量の追加パラメータのみを学習することでメモリと時間を削減する。本手順では学習・FT は扱わず、学習済みモデルによる推論のみを行う。
量子化と GGUF
量子化は、モデル内部の重みパラメータを低ビット精度(例:16 ビットから 4 ビット、あるいは 32 ビット浮動小数点を 4 ビット整数)に圧縮し、ファイルサイズと必要メモリを削減する技術である。精度はある程度低下するが、CPU や少 VRAM の GPU でも実行可能になる。GGUF(GGML Universal File)は llama.cpp 系ツールで用いる量子化済みモデルの標準ファイル形式である。Q4_K_M は 4 ビット量子化の代表的な品質設定(量子化形式の一種)で、4 ビットを基本としつつ重要な層のみ精度を保つ方式であり、サイズと精度のバランスが取れている。
Hugging Face(HF)Hub
モデルとデータセットの共有プラットフォーム。モデルは「組織名/モデル名」の形式(例:LiquidAI/LFM2.5-1.2B-Instruct)で識別される。本手順のコマンドおよびコード中に登場するモデル ID(埋め込みモデルの BAAI/bge-m3、reranker の BAAI/bge-reranker-v2-m3 等)は HF Hub 上のものである。
GPU の利用(CUDA 等)について
本手順の推論エンジンである Ollama は、GPU があれば自動的に検出して利用する(NVIDIA GPU では CUDA、Apple Silicon の Mac では Metal、対応 GPU が無い場合は CPU で実行)。利用者が CUDA を明示的に設定する必要はなく、GPU ドライバが導入されていれば自動で使われる。なお、演習 6 で用いる sentence-transformers は、内部で機械学習フレームワーク PyTorch を利用する(こちらも GPU があれば自動で利用する)。Ollama 自体は PyTorch を使わず、後述の llama.cpp を基盤とする。
API サーバ / OpenAI 互換 API
HTTP 経由でモデルに問い合わせる仕組みを提供するサーバを API サーバと呼ぶ。OpenAI 互換 API は OpenAI 社の API 仕様に揃えたインターフェースであり、これを採用するサーバには既存の OpenAI クライアント(Python の openai ライブラリ等)をそのまま利用できる。Ollama も OpenAI 互換 API を提供する。
ローカル運用とは
ローカル運用とは、外部のサーバへデータを送信せず、手元のマシン内で推論を完結させる運用形態である。入力した文書やプロンプトが外部に送信されないため、情報セキュリティの面で利点がある。機密文書を外部の生成 AI サービスに送れない場面でも、ローカル運用なら安全に扱える。
本手順で用いる 2 つの基盤ソフトウェア
- Ollama:LLM の推論を実行するバックエンド(推論エンジン)である。モデルのダウンロード、メモリへのロード、推論の実行を担う。ローカル API サーバ機能を持ち、API サーバは既定でポート 11434 で待ち受ける。各ツールの関係は次の「推論ツールの全体像」で示す。
- Open WebUI:ユーザの操作を受け取り、ブラウザに結果を表示するフロントエンドである。HTTP 経由で Ollama に問い合わせる構造であり、フロントエンド(操作・表示側)とバックエンド(推論側)が分離されている。
推論ツールの全体像
本手順の基盤となる推論ツールの関係は次のとおり。
- llama.cpp:C++ 実装の推論エンジン本体。量子化(GGUF 形式)によりモデルサイズを削減し、CPU でも実行できる。GPU があれば CUDA/Metal 等を直接利用する。Ollama の基盤となる。
- Ollama:llama.cpp 系。ローカル API サーバ+モデル管理。数行の Python コードでモデルを呼び出せ、モデルは自動的にダウンロードされる。本手順ではこれを使用する。
このほかの推論ツール(GUI 中心の LM Studio、高スループット向けの vLLM 等)は本手順では扱わないが、用途に応じた選択肢として付録で触れる。
RAG とは
RAG(Retrieval-Augmented Generation、検索拡張生成)は、ユーザの質問に応じて、事前に登録した資料から関連箇所を検索し、その検索結果を文脈として LLM に渡したうえで応答を生成する仕組みである。これにより、LLM が学習していない固有情報や最新情報を要する質問への対応力が向上する。
コンテキスト長について
コンテキスト長とは、LLM が一度に処理できる入力+出力のトークン数の上限である。本手順では、最上位モデル gemma4:12b-it-qat のコンテキスト長上限である 262144 トークンを基準に設定する。設定値がモデル側の上限を超える場合は推論時に自動でモデル上限へ丸められるため、上限が 128K(131072 トークン)の gemma4:e2b-it-qat でも、上限がより小さい LFM2.5-1.2B-Instruct でも、同じ設定のまま支障なく動作する。この設定は最初のインストールで一度だけ行う。
動作確認用モデル:LFM2.5-1.2B-Instruct
本手順では、まずツールの動作確認に Liquid AI 社の LFM2.5-1.2B を使用する。パラメータ数約 1.2B と軽量で動作が速く、日本語を含む多言語(英語、アラビア語、中国語、フランス語、ドイツ語、日本語、韓国語、スペイン語)の 8 言語に対応する。本手順では、対話用に調整された LFM2.5-1.2B-Instruct を基本に用いる。
主な仕様は次のとおりである。用途は会話・要約・翻訳などの軽量な多言語タスク全般、対応言語は上記の 8 言語、VRAM 目安は Q4_K_M 量子化時で約 1〜2GB(モデルファイル約 731MB)である。少 VRAM の GPU や CPU のみの PC でも動作する点が、本手順の動作確認用モデルとして適している。
公式情報:https://www.liquid.ai/blog/introducing-lfm2-5-the-next-generation-of-on-device-ai
主要 Python パッケージ、埋め込みモデル
本手順で導入する主要 Python パッケージや埋め込みモデルの役割は次のとおり。
- open-webui:UI 本体である。インストール時に依存パッケージ(FastAPI、ChromaDB、sentence-transformers 等)が一括導入される。
- docling:PDF・Word・PowerPoint 文書を解析するパーサである。演習 5 では Python から直接呼び出して文書解析を体験する。Open WebUI と連携させて RAG の抽出エンジンとして使う場合は、別途 docling-serve を起動して接続する(後述の発展節を参照)。日本語 PDF、レイアウト付き文書、表・図・数式を含む文書の抽出精度が、デフォルト抽出エンジンより向上する。
- bge-m3:BAAI(北京智源人工知能研究院)が公開した多言語の埋め込みモデル(テキストを、意味を表す数値ベクトルに変換するモデル)。日本語・英語を含む 100 以上の言語と最大 8192 トークンの入力に対応する。1 回のエンコードで、Dense ベクトル(文全体の意味を 1 本のベクトルで表現)、Sparse ベクトル(語彙ごとの重みを持つ高次元かつ大半が 0 のベクトル)、Multi-Vector(トークンごとに 1 本ずつベクトルを出力する形式。ColBERT で用いられる方式)の 3 種類を同時に出力できる。Dense ベクトルは 1024 次元である。本手順では、埋め込みモデルとして
bge-m3に統一し、RAG の埋め込み(Ollama 経由、演習 7)と、埋め込みの基礎を学ぶ演習(sentence-transformers 経由、演習 6)の双方で用いる。 - bge-reranker-v2-m3:BAAI が公開した多言語の reranker(検索で得た候補を、質問との関連度で再順位付けするモデル)。bge-m3 と同系統で多言語性能が高く、日本語・英語混在の検索結果の再順位付けに適する。本手順では Open WebUI の Reranking Model として用いる(演習 4)。
本手順の RAG は、文書解析を Docling、意味検索の埋め込みを bge-m3、検索結果の再順位付けを bge-reranker-v2-m3 が担う三層構成である。日本語・英語に加え、数式・化学式・方程式・図・図中テキスト・グラフ・表を含む文書を扱う場合、これらを機械可読なテキスト(Markdown の表記法、OCR による図中テキスト等)へ変換するのは前段の Docling の役割であり、埋め込みモデルと reranker はその変換後のテキストを扱う。図表・数式を含む文書を高精度に扱うには、後述の発展節(Docling + docling-serve)の導入が要となる。
Python 3.12 のインストール
Pythonのインストールを行い、Pythonのプログラムを実行する環境を整える。扱う環境は、Windows搭載パソコンである。金子研究室では、Python 3.12.10を推奨する。
[Windows での Python 3.12 のインストール手順を見るには、ここをクリック]
Windows での Python 3.12 のインストール
以下のいずれかの方法でPython 3.12をインストールする。Pythonがインストール済みの場合、この手順は不要である。
方法 1:winget によるインストール
【インストールコマンドの実行方法】
管理者権限でコマンドプロンプトを起動する(手順:Windowsキーまたはスタートメニュー → cmd と入力 → 右クリック → 「管理者として実行」)。そして、コマンド全体をコマンドプロンプトにコピー&ペーストする。
--scope machine を指定することで、システム全体(全ユーザー向け)にインストールされる。このオプションの実行には管理者権限が必要である。インストール完了後、コマンドプロンプトを再起動するとPATHが反映される。
REM Python 3.12 をシステム領域にインストール
winget install --id Python.Python.3.12 -e --scope machine --silent --accept-source-agreements --accept-package-agreements --override "/quiet InstallAllUsers=1 PrependPath=1 Include_test=0 Include_pip=1 Include_launcher=1 InstallLauncherAllUsers=1 TargetDir=\"C:\Program Files\Python312\""
REM Python と Scripts を PATH 先頭に追加
powershell -NoProfile -Command "$p='C:\Program Files\Python312'; $s=\"$p\Scripts\"; $c=[Environment]::GetEnvironmentVariable('Path','Machine'); if((Test-Path $p) -and (';'+$c+';' -notlike \"*;$p;*\") -and (';'+$c+';' -notlike \"*;$s;*\")){[Environment]::SetEnvironmentVariable('Path',\"$p;$s;$c\",'Machine')}"
方法 2:インストーラーによるインストール
- Python公式サイト(https://www.python.org/downloads/)にアクセスし、「Download Python 3.x.x」ボタンからWindows用インストーラーをダウンロードする。
- ダウンロードしたインストーラーを実行する。
- 初期画面の下部に表示される「Add python.exe to PATH」にチェックを入れてから「Customize installation」を選択する。このチェックを入れ忘れると、コマンドプロンプトから
pythonコマンドを実行できない。 - 「Install Python 3.xx for all users」にチェックを入れ、「Install」をクリックする。
インストールの確認
コマンドプロンプトで以下を実行する。
python --version
バージョン番号(例:Python 3.12.x)が表示されればインストール成功である。「'python' は、内部コマンドまたは外部コマンドとして認識されていません。」と表示される場合は、インストールが正常に完了していない。
Python の開発環境 Visual Studio Code のインストールと Python 用の設定
Python の開発環境Visual Studio Code(プログラムを編集するソフトウェア。以下、VS Code)を整える。
[Windows での Visual Studio Code のインストールと Python 用の設定手順を見るには、ここをクリック]
Windows での Visual Studio Code のインストールと Python 用の設定手順
1. VS Code と拡張機能のインストール
以下のコマンドにより,既存の VS Code を削除し,全ユーザー共有の設定で再インストールしたうえで,拡張機能(VS Code に機能を追加するソフトウェア)をまとめて導入する.
【インストールコマンドの実行方法】
管理者権限でコマンドプロンプトを起動する(手順:Windows キーまたはスタートメニュー → cmd と入力 → 右クリック → 「管理者として実行」)。そして,コマンド全体をコマンドプロンプトにコピー&ペーストする。
インストールコマンド
REM ============================================================
REM Microsoft Visual Studio Code
REM ============================================================
winget uninstall -e --id Microsoft.VisualStudioCode --silent --disable-interactivity --accept-source-agreements
rmdir /s /q C:\ProgramData\vscode-extensions 2>nul
rmdir /s /q "%APPDATA%\Code" 2>nul
rmdir /s /q "%USERPROFILE%\.vscode" 2>nul
rmdir /s /q "%LOCALAPPDATA%\Microsoft\vscode-update" 2>nul
REM VS Code をシステム領域に新規インストール
winget install --scope machine --id Microsoft.VisualStudioCode -e --silent --accept-source-agreements --accept-package-agreements
REM 全ユーザー共有の拡張機能フォルダ
mkdir C:\ProgramData\vscode-extensions 2>nul
icacls "C:\ProgramData\vscode-extensions" /grant "Everyone:(OI)(CI)M" /T
REM スタートメニューのショートカットを --extensions-dir 付きで再作成
rmdir /s /q "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Visual Studio Code" 2>nul
del "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Visual Studio Code.lnk" 2>nul
powershell -NoProfile -Command "$s=New-Object -ComObject WScript.Shell; $lnk=$s.CreateShortcut('C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Visual Studio Code.lnk'); $lnk.TargetPath='C:\Program Files\Microsoft VS Code\Code.exe'; $lnk.Arguments='--extensions-dir \"C:\ProgramData\vscode-extensions\"'; $lnk.Save()"
REM ショートカットの検証
powershell -NoProfile -Command "$s=New-Object -ComObject WScript.Shell; $lnk=$s.CreateShortcut('C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Visual Studio Code.lnk'); Write-Host 'TargetPath:' $lnk.TargetPath; Write-Host 'Arguments:' $lnk.Arguments"
REM ファイル / フォルダ右クリックの「Code で開く」を登録
reg add "HKLM\SOFTWARE\Classes\*\shell\VSCode\command" /ve /d "\"C:\Program Files\Microsoft VS Code\Code.exe\" --extensions-dir \"C:\ProgramData\vscode-extensions\" \"%1\"" /f
reg add "HKLM\SOFTWARE\Classes\Directory\shell\VSCode\command" /ve /d "\"C:\Program Files\Microsoft VS Code\Code.exe\" --extensions-dir \"C:\ProgramData\vscode-extensions\" \"%1\"" /f
reg add "HKLM\SOFTWARE\Classes\Directory\Background\shell\VSCode\command" /ve /d "\"C:\Program Files\Microsoft VS Code\Code.exe\" --extensions-dir \"C:\ProgramData\vscode-extensions\" \"%V\"" /f
REM --extensions-dir 付きで起動する code.cmd ラッパを作成
REM (%* を echo で書くと対話的 cmd で失われるため、PowerShell で [char]37+'*' を書き出す)
powershell -NoProfile -Command "$pct=[char]37; $q=[char]34; $c='@echo off'+[char]13+[char]10+$q+'C:\Program Files\Microsoft VS Code\bin\code.cmd'+$q+' --extensions-dir '+$q+'C:\ProgramData\vscode-extensions'+$q+' '+$pct+'*'+[char]13+[char]10; [IO.File]::WriteAllText('C:\ProgramData\vscode-extensions\vscode.cmd',$c,[Text.Encoding]::ASCII)"
REM 拡張機能のインストール
set "CODE=C:\Program Files\Microsoft VS Code\bin\code.cmd"
"%CODE%" --extensions-dir "C:\ProgramData\vscode-extensions" --uninstall-extension GitHub.copilot
"%CODE%" --extensions-dir "C:\ProgramData\vscode-extensions" --uninstall-extension GitHub.copilot-chat
"%CODE%" --extensions-dir "C:\ProgramData\vscode-extensions" --install-extension ms-python.python
"%CODE%" --extensions-dir "C:\ProgramData\vscode-extensions" --install-extension ms-python.vscode-pylance
"%CODE%" --extensions-dir "C:\ProgramData\vscode-extensions" --install-extension ms-python.debugpy
"%CODE%" --extensions-dir "C:\ProgramData\vscode-extensions" --install-extension MS-CEINTL.vscode-language-pack-ja
"%CODE%" --extensions-dir "C:\ProgramData\vscode-extensions" --install-extension saoudrizwan.claude-dev
"%CODE%" --extensions-dir "C:\ProgramData\vscode-extensions" --install-extension rust-lang.rust-analyzer
"%CODE%" --extensions-dir "C:\ProgramData\vscode-extensions" --install-extension tamasfe.even-better-toml
"%CODE%" --extensions-dir "C:\ProgramData\vscode-extensions" --install-extension anthropic.claude-code
"%CODE%" --extensions-dir "C:\ProgramData\vscode-extensions" --install-extension almenon.arepl
"%CODE%" --extensions-dir "C:\ProgramData\vscode-extensions" --list-extensions --show-versions
echo === セットアップ完了 ===
2. Python インタプリタの選択
同一マシンに複数の Python がインストールされている場合,VS Code で使用する Python 本体(インタプリタ:Python プログラムを解釈・実行するソフトウェア)を選択する必要がある.
- コマンドパレット(コマンド名で機能を呼び出す VS Code の入力欄)を開く(
Ctrl+Shift+P) Python: Select Interpreterと入力する
- 表示される一覧から,使用する Python(例:
C:\Program Files\Python312\python.exe)を選択する.
Python プログラム実行手順
[Windows での Python プログラム実行手順を見るには、ここをクリック]
Windows での Python 実行手順(Visual Studio Codeを使用)
プログラムファイルの作成と保存
- 左サイドバーの「エクスプローラー」アイコン(
Ctrl+Shift+E)をクリックする
- 「NO FOLDER OPENED」(作業対象フォルダが未選択の状態)と表示される場合は,「Open Folder」をクリックし,プログラムを保存するフォルダを選択する
続いて「フォルダを信用するか」を確認する画面(フォルダ内のコードを実行してよいか確認する VS Code の仕組み)が表示されるので,チェックして Yes を選択する
- フォルダ名の右側に表示される「新しいファイル」アイコンをクリックする
- ファイル名(例:
aitask.py.ファイル名は何でも良い)を入力しEnterを押す.拡張子は.py(Python ファイルを示す拡張子)とする
- 実行したいコードを選択し,
Ctrl+Cでコピーする.VS Code のエディタ領域にCtrl+Vで貼り付ける Ctrl+Sで保存する
プログラムの実行
- エディタ右上の三角形「▷」アイコン(Run Python File:現在開いている Python ファイルを実行するボタン)をクリックする.または,エディタ上で右クリックし「ターミナルで Python ファイルを実行」を選択する
- VS Code 下部のターミナル(コマンドの入出力を表示する画面)に,実行結果(
print関数の出力等)が表示される
- tkinter(Python 標準の GUI ライブラリ)のファイル選択ダイアログを使うプログラムを実行した場合は,ダイアログが開くので対象画像を選択する
- VS Code 下部のターミナルで実行結果を確認する.OpenCV ウィンドウ(OpenCV が画像を表示するために開く専用ウィンドウ)が開いた場合はそちらも確認する.OpenCV ウィンドウは,マウスクリックでウィンドウをアクティブ(操作対象の状態)にしてからキーを押すと終了する
Ollama、LFM2.5-1.2B-Instruct モデルのインストール
まず最軽量の動作確認用モデル LFM2.5-1.2B-Instruct(約 731MB)で、Ollama および Open WebUI の動作を確認する。あわせて、本手順で使う設定(コンテキスト長 262144、KV キャッシュ q8_0、Flash Attention)をこの段階で一度だけ設定する。
ハードウェアの前提
- LFM2.5-1.2B-Instruct:ディスク空き容量 15GB 以上、メモリ搭載量 16GB 以上(モデル本体約 731MB、VRAM 目安 1〜2GB + Open WebUI 等)。少 VRAM の GPU や CPU のみの PC でも動作する。
- 推論時のメモリ占有は 1 モデル分(モデル切替時に Ollama が自動でアンロードおよびロードを行う)。
ハードウェア要件(メモリ量、GPU の必要性)の事前確定は難しい。新規に PC を準備する前に、現有の機器で本手順を試行し、性能面の問題の有無を確認したうえで、本格運用のハードウェアを決定する。
【インストールコマンドの実行方法】
管理者権限でコマンドプロンプトを起動する(手順:Windows キーまたはスタートメニュー → cmd と入力 → 右クリック → 「管理者として実行」)。winget の --scope machine オプションでシステム全体にインストールするには、管理者権限が必要である。実行時はコマンド全体をコマンドプロンプトにコピー&ペーストする。
REM ============================================================
REM 管理者権限チェック
net session >nul 2>&1
if errorlevel 1 ( echo [エラー] 管理者権限で実行してください & pause & exit /b 1 )
REM winget パッケージ一覧のローカルキャッシュを更新
winget source update
REM === 1. Ollama 環境変数を Machine スコープで事前設定 ===
REM インストール前に設定することで、Ollama 起動時から正しい設定が読み込まれる
REM これらの設定は一度だけ行い、以降の段階でも引き継がれる
powershell -NoProfile -Command "[System.Environment]::SetEnvironmentVariable('OLLAMA_FLASH_ATTENTION', '1', 'Machine')"
powershell -NoProfile -Command "[System.Environment]::SetEnvironmentVariable('OLLAMA_KV_CACHE_TYPE', 'q8_0', 'Machine')"
REM コンテキスト長:最上位モデル gemma4:12b-it-qat の上限 262144 に設定する
REM 設定値がモデル側の上限を超える場合は推論時にモデル上限へ自動で丸められるため、
REM 軽量モデルの段階でもこの設定のまま支障なく動作する
powershell -NoProfile -Command "[System.Environment]::SetEnvironmentVariable('OLLAMA_CONTEXT_LENGTH', '262144', 'Machine')"
powershell -NoProfile -Command "[System.Environment]::SetEnvironmentVariable('OLLAMA_MODELS', 'C:\Ollama\models', 'Machine')"
set "OLLAMA_FLASH_ATTENTION=1"
set "OLLAMA_KV_CACHE_TYPE=q8_0"
set "OLLAMA_CONTEXT_LENGTH=262144"
set "OLLAMA_MODELS=C:\Ollama\models"
REM === 2. 既存の Ollama プロセスを停止(ファイルロック解除のため) ===
taskkill /IM ollama.exe /F >nul 2>&1
taskkill /IM "ollama app.exe" /F >nul 2>&1
REM === 3. モデルフォルダの作成と権限設定 ===
if not exist "C:\Ollama\models" mkdir "C:\Ollama\models"
icacls "C:\Ollama\models" /grant *S-1-5-32-545:(OI)(CI)(M) /T /C
REM === 4. 既存モデルの移動(ユーザープロファイルに残っている場合) ===
REM Ollama 停止状態で実行するためファイルロックが起きない
if exist "%USERPROFILE%\.ollama\models" robocopy "%USERPROFILE%\.ollama\models" "C:\Ollama\models" /E /MOVE
if exist "%USERPROFILE%\.ollama\models" rd /s /q "%USERPROFILE%\.ollama\models"
REM === 5. winget パッケージ一覧のローカルキャッシュを更新 ===
winget source update
REM === 6. Ollama のインストール(Inno Setup) ===
winget uninstall --id Ollama.Ollama -e --silent --disable-interactivity --accept-source-agreements
REM uninstall 後にプロセスが残ることがあるため再度停止
taskkill /IM ollama.exe /F >nul 2>&1
taskkill /IM "ollama app.exe" /F >nul 2>&1
winget install --id Ollama.Ollama -e --silent --disable-interactivity --force --accept-source-agreements --accept-package-agreements --custom "/DIR=C:\Ollama"
winget upgrade --id Ollama.Ollama -e --silent --disable-interactivity --force --accept-source-agreements --accept-package-agreements --custom "/DIR=C:\Ollama"
REM === 7. Ollama のパス設定(システム PATH に未登録の場合のみ追加) ===
powershell -NoProfile -Command "$p='C:\Ollama'; $c=[Environment]::GetEnvironmentVariable('Path','Machine'); if((Test-Path $p) -and (';'+$c+';' -notlike \"*;$p;*\")){[Environment]::SetEnvironmentVariable('Path',\"$c;$p\",'Machine')}"
REM Ollama のパスを現在のセッションに反映
set "PATH=C:\Ollama;%PATH%"
REM === 8. Ollama サービスの起動(モデルダウンロードの前に必要) ===
where ollama >nul 2>&1
if errorlevel 1 echo Ollama のパスが見つかりません。再起動後に再実行してください。 & exit /b 1
tasklist /fi "imagename eq ollama.exe" | find "ollama.exe" 2>&1
if errorlevel 1 start "" "C:\Ollama\ollama.exe" serve & timeout /t 10 /nobreak
REM === 9. モデルのダウンロード(パラメータ数約 1.2B、Q4_K_M 量子化で約 731MB) ===
REM Liquid AI が Ollama 公式ライブラリに登録したタグを使用する
echo LFM2.5-1.2B-Instruct モデルをダウンロード中...
ollama pull LiquidAI/lfm2.5-1.2b-instruct
echo モデルダウンロード完了
REM === 10. 埋め込みモデルのダウンロード(RAG 演習で使用) ===
REM bge-m3:日本語・英語を含む多言語の埋め込みモデル
echo bge-m3 埋め込みモデルをダウンロード中...
ollama pull bge-m3
echo 埋め込みモデルダウンロード完了
REM === 11. Git のインストール ===
winget install --scope machine --id Git.Git -e --silent --disable-interactivity --force --accept-source-agreements --accept-package-agreements --override "/VERYSILENT /NORESTART /NOCANCEL /SP- /CLOSEAPPLICATIONS /RESTARTAPPLICATIONS /COMPONENTS=""icons,ext\reg\shellhere,assoc,assoc_sh"" /o:PathOption=Cmd /o:CRLFOption=CRLFCommitAsIs /o:BashTerminalOption=MinTTY /o:DefaultBranchOption=main /o:EditorOption=VIM /o:SSHOption=OpenSSH /o:UseCredentialManager=Enabled /o:PerformanceTweaksFSCache=Enabled /o:EnableSymlinks=Disabled /o:EnableFSMonitor=Disabled"
REM Git のパスを現在のセッションに反映
set "PATH=C:\Program Files\Git\cmd;%PATH%"
REM === 12. スタートメニュー ショートカット作成 ===
REM LFM2.5-1.2B-Instruct 起動ショートカット(CUI で質問・応答を行う)
powershell -NoProfile -Command "$s=New-Object -ComObject WScript.Shell; $l=$s.CreateShortcut([Environment]::GetFolderPath('CommonPrograms')+'\Ollama LFM2.5 1.2B.lnk'); $l.TargetPath='cmd.exe'; $l.Arguments='/k \"start cmd /k ollama serve ^& timeout /t 3 /nobreak ^>nul ^& ollama run LiquidAI/lfm2.5-1.2b-instruct\"'; $l.Save()"
echo インストール完了
演習 1.Ollama の動作確認(CUI)
Ollama 自体が動作することを確認する。あわせて、LLM のローカル実行(外部サーバへの送信を伴わず、手元のマシン内で完結する推論)を体験する。
手順
- スタートメニューから「Ollama LFM2.5 1.2B」を実行する。実行直後にコマンドプロンプトのウィンドウが 2 つ起動する(1 つは
ollama serve用、もう 1 つはチャット用)。 - チャット用ウィンドウにプロンプト記号
>>>が表示されたら、質問を入力する(例:「日本の首都はどこですか?」、「おもしろい映画を教えて」)。 - 応答が返ることを確認する。
/byeを入力して終了する。
ヒント
- 初回起動時は、モデルのメモリへのロードに時間を要する(LFM2.5-1.2B-Instruct は軽量のため比較的短時間で完了する)。
- 応答の生成中に中断する場合は Ctrl+C を押す。
ollama serve用ウィンドウは閉じずに残しておく(閉じると、次回起動時に再度起動を待つ必要が生じる)。サーバに接続できない場合は、別のコマンドプロンプトでollama serveを実行してサーバを起動してから、再度モデルを実行する。
考察ポイント
- モデルが質問に対して応答を返すか(応答内容の正確性は本演習では問わない。本演習の目的は応答経路の動作確認である)。
- 応答が返るまでの時間が、初回ロードと 2 回目以降でどう異なるか。
LFM2.5-1.2B-Instruct による動作確認の準備
次のインストールコマンドにより、Open WebUI を導入する。コンテキスト長・KV キャッシュ・Flash Attention・埋め込みモデルは前段のインストールで設定・導入済みのため、本段階では再設定しない。sentence-transformers は open-webui パッケージの依存として同梱される。
【インストールコマンドの実行方法】
管理者権限でコマンドプロンプトを起動する(手順:Windows キーまたはスタートメニュー → cmd と入力 → 右クリック → 「管理者として実行」)。実行時はコマンド全体をコマンドプロンプトにコピー&ペーストする。
インストールコマンド
REM ============================================================
REM 管理者権限チェック
net session >nul 2>&1
if errorlevel 1 ( echo [エラー] 管理者権限で実行してください & pause & exit /b 1 )
REM === 1. Ollama サービスの起動確認 ===
tasklist /fi "imagename eq ollama.exe" | find /I "ollama.exe" >nul 2>&1
if errorlevel 1 ( start "" "C:\Ollama\ollama.exe" serve & timeout /t 10 /nobreak >nul )
REM === 2. Open WebUI のインストール ===
REM open-webui パッケージにより、依存パッケージ(FastAPI、ChromaDB、
REM sentence-transformers 等)が一括インストールされる
python -m pip install --no-user --upgrade pip
python -m pip install --no-user --upgrade open-webui
python -m pip uninstall -y open-webui
python -m pip install --user --upgrade open-webui
REM === 3. sentence-transformers のバージョン確認 ===
REM open-webui の依存として導入された sentence-transformers のインポート可否を確認する
python -c "import sentence_transformers; print('sentence-transformers version:', sentence_transformers.__version__)"
注:図表・数式を含む文書を Open WebUI の RAG で高精度に扱うための Docling(docling-serve)の導入は、後述の発展節で別途行う。演習 5 で Docling を Python から直接呼び出す場合は、その演習内で docling パッケージを個別に導入する。
演習 2.インストール完了の確認
インストールが正しく完了し、各コマンドおよび主要パッケージが利用可能であることを確認する。
手順
新しいコマンドプロンプト(管理者権限不要)を起動し、以下のコマンドを順に実行する。新しく開く理由は、インストールで設定された PATH や環境変数の最新値を読み込ませるためである。
REM Ollama のバージョン表示
ollama --version
REM 登録済みモデルの一覧
REM LFM2.5-1.2B-Instruct および bge-m3 が表示されることを確認
ollama list
REM Python のバージョン表示(3.12 系であることを確認)
python --version
REM 主要 Python パッケージのインポート可否確認
python -c "import open_webui; print('open-webui OK')"
python -c "import sentence_transformers; print('sentence-transformers OK')"
REM open-webui 実行ファイルの絶対パス表示
where open-webui
REM 設定済み環境変数の確認
echo OLLAMA_MODELS=%OLLAMA_MODELS%
echo OLLAMA_CONTEXT_LENGTH=%OLLAMA_CONTEXT_LENGTH%
echo OLLAMA_FLASH_ATTENTION=%OLLAMA_FLASH_ATTENTION%
echo OLLAMA_KV_CACHE_TYPE=%OLLAMA_KV_CACHE_TYPE%
ヒント
whereは、実行ファイルの絶対パスを表示する Windows のコマンドである。- 環境変数の
echo出力で%OLLAMA_MODELS%のように変数名そのままが表示される場合、その変数が現在のセッションに未反映であることを示す。コマンドプロンプトを開き直して再確認する。
考察ポイント
ollama listの出力に LFM2.5-1.2B-Instruct(例:LiquidAI/lfm2.5-1.2b-instruct)とbge-m3の両方が含まれているか。where open-webuiが Python 3.12 の Scripts フォルダ配下のパス(例:C:\Program Files\Python312\Scripts\open-webui.exe)を返すか。python --versionがPython 3.12.xを返すか。- 2 つのパッケージ(open-webui、sentence-transformers)のインポートが成功するか。
OLLAMA_CONTEXT_LENGTHが262144となっているか。
演習 3.Open WebUI の動作検証(ブラウザ)
Open WebUI(フロントエンド)から Ollama(バックエンド)の LLM を呼び出す経路が機能することを確認する。本構成はフロントエンドとバックエンドが分離されており、Open WebUI は HTTP 経由で Ollama に問い合わせる。本演習で、この分離構成の動作を確認する。
手順
- 通常のコマンドプロンプトを開いて以下を実行する。「管理者として実行」しないこと。
%USERPROFILE%\AppData\Roaming\Python\Python312\Scripts\open-webui servePython312は Python 3.12 を表す。Python 3.12 以外のバージョンをインストールしている場合は、この部分を読み替える。 - 起動には初回 30 秒〜1 分かかる。コマンドプロンプトに
Uvicorn running on http://0.0.0.0:8080と表示された後、自動でブラウザがhttp://localhost:8080を開く。 - 初回アクセス時は管理者アカウント作成画面が表示される。氏名・メールアドレス・パスワードを入力してアカウントを作成する。
- ログイン後、画面左上のモデル選択ドロップダウン(モデル名、または「Select a model」と表示されている箇所)を開く。
- LFM2.5-1.2B-Instruct が選択肢に表示されることを確認する。
- LFM2.5-1.2B-Instruct を選択し、画面下部のチャット入力欄に質問(例:「日本の首都はどこか。」)を入力して送信する。
- 応答が返ることを確認する。
ヒント
- ブラウザが自動で開かない場合は、手動で
http://localhost:8080を開く。 - 管理者アカウントのメールアドレスは Open WebUI 内のローカル認証用であり、外部送信は行われない(実在しないメールアドレスでも作成できる)。
- モデルがドロップダウンに表示されない場合、
ollama serveが起動しているか確認する。起動していない場合は、スタートメニューの「Ollama LFM2.5 1.2B」を一度実行してから再度確認する。
考察ポイント
- ブラウザで
http://localhost:8080にアクセスできるか。 - モデル選択ドロップダウンに LFM2.5-1.2B-Instruct が表示されるか。
- 選択したモデルから応答が返るか。
- 同じモデルを CUI(演習 1)とブラウザ UI(本演習)で呼び出した場合、応答内容に差があるか。同じモデルでも、UI 経由ではシステムプロンプトや既定パラメータ(温度等)が異なる場合があり、応答に差が出ることがある。
演習 4.Open WebUI の初期設定(PDF 読み込み・RAG のための準備)
PDF・Office 文書の読み込みおよび RAG(教科書・学習指導要領との照合)に向けた初期設定を行う。設定を済ませておけば、機能を有効化した時点で動作する。
手順
- 画面右上のユーザーアイコン(または左下のアカウント名)をクリックし、「管理者パネル(Admin Panel)」を開く。
- 「設定(Settings)」タブを開き、左側のメニューから「ドキュメント(Documents)」を選択する。
- 埋め込みモデルの設定:
- 「Embedding Model Engine」を
Ollamaに設定する(sentence-transformers を直接使用せず、Ollama 経由で埋め込みを行う構成とする)。 - 「Embedding Model」に
bge-m3を入力する。
- 「Embedding Model Engine」を
- Hybrid 検索および Reranker の設定:
- 「Enable Hybrid Search」をオンにする。
- 「Reranking Model」に
BAAI/bge-reranker-v2-m3を入力する(Hugging Face から自動ダウンロードされる。初回は数百 MB のダウンロードが発生する)。 - 「Top K」を
5〜10の範囲で設定する(Top K は、再順位付け後に LLM に渡す上位件数)。
- チャンクの設定:
- 「Chunk Size」を
1000〜1500トークンに設定する。 - 「Chunk Overlap」を
100〜200トークンに設定する。
- 「Chunk Size」を
- 「Content Extraction Engine」は当面
Default(Open WebUI 内蔵)のままとする。表・図・数式を含む文書を高精度に扱う段階で、後述の発展節に従ってDocling(docling-serve)へ切り替える。 - 「保存(Save)」を押す。
ヒント
- Hybrid 検索は、ベクトル検索(意味的な類似度に基づく検索)とキーワード検索を併用する検索方式である。
- Reranker は、検索で得られた候補を再順位付けするモデルである。本手順では bge-m3(埋め込み)と同系統の bge-reranker-v2-m3 を用いる。
- チャンクは、長文を埋め込み計算のために分割した単位である。Chunk Overlap はチャンク間の重複量であり、重複によってチャンク境界で文脈が途切れることを防ぐ。
考察ポイント
- 「Embedding Model」に
bge-m3が設定されているか。 - 「Save」操作後にエラーメッセージが表示されないか。
演習 5.Docling による文書の構造化抽出(文書解析の基礎)
RAG パイプラインの前段にあたる「文書解析」を体験する。Docling は、PDF や Word 文書を、本文・見出し・段落・表などの構造を保持したまま機械可読な形式(Markdown 等)に変換する Python パッケージである。RAG では、検索対象の文書をどの粒度・どの構造で取り込むかが検索精度を左右するため、文書解析の出力を一度自分の目で確認する。本演習は Docling を Python から直接呼び出して動作を確認するものであり、Open WebUI への接続(後述の発展節)とは独立して実施できる。
準備:Docling のインストール
新しいコマンドプロンプト(管理者権限不要)で、Docling を導入する:
python -m pip install --user --upgrade docling
python -c "import docling; print('docling version:', getattr(docling, '__version__', 'unknown'))"
準備するファイル
- 本文に加えて見出し・箇条書き・できれば表を含む PDF または DOCX ファイル 1 つ(例:学内の規程文書、講義シラバス、教科書の 1 ページ)。
- 機密情報を含まないものを選ぶ。
手順
- 新しいコマンドプロンプト(管理者権限不要)を起動し、作業フォルダを作成して移動する:
mkdir C:\work\docling-test cd /d C:\work\docling-test - 準備した PDF または DOCX を
C:\work\docling-test\sample.pdf(またはsample.docx)として配置する。 - 以下の Python コードを実行する(メモ帳で作成する場合は、保存時の文字コードを「UTF-8」に変更する):
from pathlib import Path from docling.document_converter import DocumentConverter # 対象フォルダ base_dir = Path(r"C:\work\docling-test") # まず PDF を探し、無ければ DOCX を使う pdf_path = base_dir / "sample.pdf" docx_path = base_dir / "sample.docx" if pdf_path.exists(): input_path = pdf_path else: input_path = docx_path print(f"読み込み対象: {input_path}") # Docling で変換 converter = DocumentConverter() result = converter.convert(str(input_path)) # Markdown にエクスポート markdown_text = result.document.export_to_markdown() # 入力ファイルと同じフォルダに sample.md として保存 output_path = base_dir / "sample.md" with open(output_path, "w", encoding="utf-8") as f: f.write(markdown_text) print(f"変換完了:{output_path} に出力") print("先頭 500 文字:") print(markdown_text[:500]) - 生成された
sample.mdを開き、元の PDF(または DOCX)と内容を比較する。
ヒント
- 初回実行時は、Docling 内部のレイアウト解析モデル(DocLayNet 等、数百 MB)が自動ダウンロードされるため、数分かかる場合がある。
- 処理時間はページ数に概ね比例する(1 ページあたり数秒程度)。
- PDF・DOCX のほか、PPTX、XLSX、HTML、画像(OCR)にも対応する。
考察ポイント
- 元文書中の表が、Markdown の表記法(パイプ
|区切り)として抽出されているか。単純なテキスト抽出では、表のセルが行優先または列優先に並べ替えられ、列の対応が失われやすい。 - 見出しの階層関係が
#の数で表現されているか。RAG では、見出し情報がチャンク境界の決定(同一節を 1 チャンクにまとめる等)に有用となる。 - 図・ヘッダ・フッタ・ページ番号がどう扱われたか(取り込まれたか、無視されたか、本文と混在したか)。
- 同じ文書を Open WebUI のデフォルト抽出エンジンと Docling とで処理した場合、検索の精度にどのような差が出ると予想されるか。
- RAG 全体の精度において、文書解析(演習 5)・埋め込み生成(演習 6)・検索および生成(演習 7)のどの段階の影響が最も大きいと考えられるか。
演習 6.埋め込みベクトルと意味的類似度(埋め込みの基礎)
RAG の中核概念である「埋め込み(embedding)」を体験する。埋め込みとは、テキスト(語・文・段落)を固定長の数値ベクトルに変換する処理である。意味の近いテキストどうしのベクトルは、ベクトル空間上で近い位置に配置される。RAG では、この性質を用いて、質問のベクトルと文書チャンクのベクトルの類似度から関連箇所を検索する。本演習では、本手順の埋め込みモデル bge-m3 を sentence-transformers 経由で読み込み、複数の文の埋め込みを生成し、コサイン類似度(2 つのベクトルがなす角度に基づく類似度。1.0 で完全一致、0.0 で無相関、-1.0 で正反対)を計算して、意味的類似度を実測する。
手順
- 以下の Python コードを実行する(メモ帳で作成する場合は、文字コードを「UTF-8」に変更する):
from sentence_transformers import SentenceTransformer import numpy as np # 本手順の RAG と同じ埋め込みモデル(bge-m3)を使用する model = SentenceTransformer("BAAI/bge-m3") sentences = [ "猫がソファの上で眠っている。", # S0:基準文 "ネコがソファーで寝ています。", # S1:S0 と同義(表記が異なる言い換え) "犬が庭で走り回っている。", # S2:主語と動作が異なる "今日の株価は大きく下落した。", # S3:S0 と無関係 "The cat is sleeping on the sofa.", # S4:S0 の英訳(同義の別言語) ] embeddings = model.encode(sentences) print("埋め込みベクトルの形状:", embeddings.shape) print() # 正規化してコサイン類似度行列を計算 norms = np.linalg.norm(embeddings, axis=1, keepdims=True) normalized = embeddings / norms similarity_matrix = normalized @ normalized.T print("コサイン類似度行列:") print(" ", " ".join([f"S{i}" for i in range(len(sentences))])) for i, row in enumerate(similarity_matrix): print(f"S{i}:", " ".join([f"{v:+.3f}" for v in row])) print() for i, s in enumerate(sentences): print(f"S{i}: {s}") - 出力されたコサイン類似度行列と、各文の対応関係を確認する。
ヒント
- 初回実行時は、埋め込みモデル bge-m3 が Hugging Face から自動ダウンロードされる(数百 MB〜)。
- 埋め込みベクトルの次元数は、出力の「形状」(例:
(5, 1024))の 2 番目の数値で確認できる。bge-m3 の Dense ベクトルは 1024 次元である。 - S0 と S1 は同じ意味を別の表記で書いた文、S0 と S2 は主語と動作が異なる文、S0 と S3 は無関係な文、S0 と S4 は別言語の同義文である。
- bge-m3 は日本語・英語を含む多言語に対応する。演習 7(Open WebUI 経由の RAG)と同じモデルを用いるため、本演習で観察した類似度の性質が、そのまま実運用の検索に対応する。
考察ポイント
- S0 と S1(同義の言い換え)の類似度は、S0 と S3(無関係)の類似度より高いか。
- S0 と S2(主語が異なるが構文は類似)の類似度は、S0 と S1 より低く、S0 と S3 より高い、中程度の値となるか。
- S0 と S4(別言語の同義文)の類似度はどの程度か。多言語モデルでは、言語が違っても意味が同じであれば高い類似度が出ることが期待される。
- 類似度が「単語の表層的な一致」ではなく「意味の近さ」を反映しているか。S0 の「猫」「眠る」と S1 の「ネコ」「寝る」は文字表記としては異なる(ひらがな・カタカナ・漢字の違い)が、意味は同じである。
- RAG での検索が「キーワード一致」ではなく「意味の近さ」で動作することの根拠が、本実測から読み取れるか。
演習 7.Open WebUI の Knowledge による RAG(検索拡張生成の体験)
Open WebUI の Knowledge 機能を用いて、RAG の一連の流れを体験する。RAG は、ユーザの質問に応じて、事前に登録した文書から関連箇所を検索し、その結果を文脈として LLM に渡したうえで応答を生成する仕組みである。これにより、LLM が学習していない情報(学内固有の規程、最新の指導要領、自校の過去問題集 等)に基づく応答が可能になる。本演習では、演習 5 で扱った文書解析と演習 6 で扱った埋め込みベクトルが、RAG のどの段階で使われるかを確認する。
準備:テスト用文書の作成
- メモ帳を開き、以下を入力する。本構成の用途(教科書冊子の品質チェック)に即した架空の規程である:
架空教科書作成委員会の規程(教科書冊子の校閲に関する内規) 第1条 教科書冊子の校閲は、最低 2 名の異なる教員が独立に行う。 第2条 校閲後、不備が見つかった場合は、修正案を「修正提案票(様式 7)」に記入する。 第3条 校閲完了の期限は試験日の 14 日前とする。 第4条 校閲対象は、設問本文、選択肢、配点、参照図表の整合性、および冊子全体の用語統一とする。 第5条 校閲記録は試験日から 3 年間保管する。 第6条 学外公開を伴う試験(模擬試験、外部公開答案を含む)の校閲については、校閲者 2 名のうち少なくとも 1 名は当該教科の専任教員でなければならない。 - 「ファイル → 名前を付けて保存」で、文字コードを
UTF-8に変更し、%USERPROFILE%\test_regulation.txtとして保存する。
手順
- Open WebUI を起動し、ブラウザで
http://localhost:8080を開く。 - 画面左側のメニューから「ワークスペース(Workspace)」→「ナレッジ(Knowledge)」を開く。
- 「+」ボタンで新規 Knowledge を作成する。名前を「校閲規程」、説明欄に「教科書冊子校閲の内規」と入力する。
- 作成された Knowledge を開き、「ファイルを追加(Add Content)」から
test_regulation.txtをアップロードする。アップロード時に内部で、(a)テキスト抽出、(b)チャンク分割、(c)bge-m3による埋め込み生成、(d)ChromaDB(Open WebUI 内蔵のベクトルデータベース)へのベクトル登録、が順に実行される。 - アップロード後、ファイル名に完了マーク(チェックマーク等)が表示されるまで待つ(数秒〜十数秒)。
- 左メニューの「新しいチャット(New Chat)」をクリックし、モデル LFM2.5-1.2B-Instruct を選択する。
- チャット入力欄で半角の
#を入力し、現れた候補から「校閲規程」を選択する。入力欄上部に Knowledge 名のチップ(選択中であることを示すラベル)が表示されることを確認する。 - 以下の質問を順に送信し、応答を確認する:
- 質問 A(直接記載の確認):
教科書冊子の校閲は何名で行うか。校閲記録の保管期間とあわせて答えよ。 - 質問 B(複数条文をまたぐ推論):
外部公開する模擬試験の答案を、非常勤講師 2 名で校閲することは本規程上認められるか。根拠条文とあわせて答えよ。
- 質問 A(直接記載の確認):
- 応答に出典表示(参照元のファイル名やチャンクへの参照)が付与される場合は、その表示も確認する。
- 比較のため、左メニューから「新しいチャット」を開始する。今度は Knowledge を選択せず、同じモデル LFM2.5-1.2B-Instruct で同じ 2 つの質問を送信する。
- 両者(Knowledge あり/なし)の応答を比較する。
ヒント
- 初回アップロード時、埋め込み生成のため Ollama の
bge-m3が呼び出される。Ollama サービスが起動していることが必須である。 - Knowledge を選択すると、質問送信時に Knowledge 内の文書チャンクが意味的類似度で検索され(演習 6 で見た仕組み)、上位 K 件(演習 4 で設定した Top K)がプロンプトに付加される。
- Knowledge を選択しない場合、モデルは事前学習データのみに基づいて応答するため、架空の規程内容は知り得ない。「情報がない」と返すか、根拠のない内容を生成する(ハルシネーション)かは、モデルとプロンプトに依存する。RAG は、このハルシネーションを抑制する目的でも用いられる。
- ファイルの内容を 1 回の質問に直接貼り付ける方法と異なり、Knowledge に登録した内容は複数のチャットから繰り返し参照できる。
考察ポイント
- 質問 A(直接記載)について、Knowledge を使用した応答に、
test_regulation.txtの具体的な数値(2 名、3 年間)が含まれているか。 - 質問 B(複数条文の組合せ)について、第 1 条(最低 2 名)と第 6 条(学外公開時は専任教員 1 名以上)を組み合わせた推論ができているか。「非常勤講師 2 名のみでは第 6 条に違反する」という結論と根拠条文が応答に含まれるか。
- Knowledge を使用しない応答では、規程の内容を答えられず、「情報がない」と返すか、根拠のない数値を生成するか。
- 応答に出典表示が付与された場合、どのチャンク(規程の何条)が引かれているか。引かれたチャンクが質問に対して妥当か。
- RAG の流れ(文書登録 → 解析 → チャンク分割 → 埋め込み生成 → ベクトル検索 → LLM への文脈注入 → 応答生成)の各段階で、本構成のどのコンポーネント(Open WebUI 内蔵の抽出または Docling、
bge-m3、ChromaDB、LLM)が動作しているかを対応付けられるか。 - Knowledge を用いることで初めて可能になる教科書冊子の品質チェックは何か(例:自校の出題基準書との照合、過年度問題集との重複検出、学習指導要領との対応関係の確認)。
- RAG の検索精度を上げるための調整余地(Chunk Size、Top K、Reranker、Embedding Model の選択)は、本演習の結果からどう判断できるか。
演習 8.単一設問の不備検出(条件不足・複数解の検出)
軽量モデル LFM2.5-1.2B-Instruct で、本構成の主要機能の基本動作を順に試行する。本段階の演習は精度評価ではなく、プロンプト設計の妥当性および基本動作の確認である。本演習では、条件不足により回答不能な設問に対し、モデルが解答を試みず指摘のみを返すかを確認する。
手順
- Open WebUI のチャット画面でモデル LFM2.5-1.2B-Instruct を選択する。
- モデル名横の設定アイコン(歯車)またはチャット入力欄付近のコントロールから、思考モード(応答前に内部で推論過程を生成する機能)を「オン」に設定する(思考モードに対応するモデルの場合)。
- 新しいチャットを開始し、以下のプロンプトを入力して送信する:
あなたは教科書のレビュアーである。次の設問に不備(条件不足・矛盾・複数解・図表参照不能)がないか検出せよ。不備があれば指摘のみを返し、解答は試みるな。 設問:ある長方形の面積は 24 平方センチメートルである。この長方形の周の長さを求めよ。 - 応答内容を確認する。
ヒント
- サンプル設問は、面積から周の長さを一意に決定できない(縦・横の組合せが無数に存在する)ため、不備(条件不足/複数解)に該当する。
- LFM2.5-1.2B-Instruct は軽量モデルであり、思考モードを備えない場合がある。その場合は通常のプロンプトのみで本演習を行い、思考モードの効果は後段の gemma4:e2b-it-qat で確認する。
考察ポイント
- 応答に「縦と横が特定できない」「複数解が存在する」「条件不足」等の指摘が含まれるか。
- 解答そのものが出力されていないか。
演習 9.誤字・送り仮名・係り受けの検出
表記レベルの不整合(誤字、送り仮名の誤り、係り受けの不整合)を、モデルが検出できるかを確認する。
手順
- 引き続きモデル LFM2.5-1.2B-Instruct を使用し、思考モードはオンのままとする(対応する場合)。
- 新しいチャットを開始し、以下のプロンプトを入力して送信する:
あなたは教科書のレビュアーである。次の設問本文に、誤字、送り仮名の誤り、係り受けの不整合がないか検出せよ。検出した場合は該当箇所と問題点を指摘せよ。 設問:次の文章を読み、問いに答えなさい。山田氏は研究室で長年に渡り実験を続けて、その成果を学界に発表する事を決断した。しかし、彼の研究は同僚から疑問視するられている部分もあり、論文の投稿前に再度の検証が必要であると考えていた。問い:山田氏が直面している課題を述べよ。 - 応答内容を確認する。
ヒント
- サンプル文には、係り受けの誤り(「疑問視するられている」)、漢字使用の問題(「事」)、送り仮名の問題(「に渡り」)が混入している。
考察ポイント
- 「疑問視するられている」(誤った受け身表現。正しくは「疑問視されている」)の指摘が含まれるか。
- 「事」(「こと」が望ましい)または「に渡り」(「にわたり」が望ましい)への言及があるか。
演習 10.思考モード オン/オフ の比較
論理関係の追跡が必要な場合に思考モードを「オン」で運用する根拠を確認する。同一プロンプトを思考モードのオンとオフで実行し、応答内容の差を比較する。本演習は、思考モード(reasoning)を備える gemma4:e2b-it-qat を用いると差が明確に現れやすい。LFM2.5-1.2B-Instruct が思考モードに対応する場合は同モデルでも試行する。
手順
- 思考モードに対応するモデル(gemma4:e2b-it-qat を推奨。後段のインストール完了後に実施してもよい)を選択し、設定で思考モードを「オフ」に切り替える。
- 新しいチャットを開始する(前のチャットの会話履歴が次の応答に影響しないようにするため)。
- 演習 8 と同じプロンプト(長方形の周の長さを求める設問)を送信する。
- 応答内容を記録する。
- モデル設定で、思考モードを再度「オン」に戻す。
- 新しいチャットを開始し、同じプロンプトを再度送信して、応答内容を記録する。
- 両モードの応答を比較する。
ヒント
- 思考モードがオフの場合、設問の不備を見落として解答を試みる傾向が現れることがある。
- 軽量モデルでは差異が顕著に現れない場合もある。思考モードを備える gemma4:e2b-it-qat でより明確な差が現れることがある。
考察ポイント
- 思考モードのオン/オフを切り替える操作ができるか。
- 両モードの応答にどのような差があるか(不備の指摘の有無、応答の構造、所要時間)。
- 「論理関係の追跡が必要な場合に『オン』で運用する」根拠が、応答の差から読み取れるか。
予備段階の総括
演習 1〜演習 10 の動作に問題がなければ、次の段階に進む。プロンプト設計に問題が見つかった場合は、本番段階に進む前にプロンプトを見直す。
gemma4:e2b-it-qat・gemma4:12b-it-qat モデルのインストール(任意で 26b-a4b-it-qat)
最軽量の動作確認用モデル LFM2.5-1.2B-Instruct の動作確認に続いて、一段上のモデル gemma4:e2b-it-qat と、上位の gemma4:12b-it-qat を導入する。メモリに余裕がある場合は、最上位の選択肢として gemma4:26b-a4b-it-qat も導入できる。ここまでの Ollama および Open WebUI の動作に問題がないことを確認したうえで進める。コンテキスト長・KV キャッシュ・Flash Attention は最初のインストールで設定済みのため、本段階では再設定しない。
いずれも Google DeepMind が公開しているオープンモデル Gemma 4 シリーズに属し、QAT(Quantization-Aware Training、量子化を考慮した学習)によって軽量化された版である。QAT は学習の段階から量子化を織り込むことで、4 ビットへ量子化してもメモリ使用量を削減しつつ精度低下を抑える。ライセンスはいずれも Apache 2.0 で、テキストに加えて画像入力にも対応し、思考モード(reasoning)を備える。
- gemma4:e2b-it-qat:エッジデバイス向けに設計された E2B モデルの QAT 版。「E」は有効パラメータ(effective parameters)を表し、E2B は有効 2.3B(埋め込みを含めると 5.1B)、35 層、語彙数 262K、コンテキスト長 128K(131072 トークン)である。Google 公表のベンチマークでは、E2B の MMLU Pro が 60.0%、多言語ベンチマーク MMMLU が 67.4% である。
- gemma4:12b-it-qat:エッジ向けの E4B と 26B クラスの中間にあたる 12B(総パラメータ約 11.95B)モデルの QAT 版。コンテキスト長は 256K(262144 トークン)である。Google 公表のベンチマークでは MMLU Pro 77.2%、MMMLU 83.4% で、E2B より高い数値を示す。E2B より規模が大きく、論理整合性の追跡や冊子横断照合といった、より高い推論能力を要する判定の担当に適する。
- gemma4:26b-a4b-it-qat(任意):MoE(Mixture of Experts、専門家混合)構造の 26B クラスモデルの QAT 版。総パラメータ 25.2B のうち推論ごとに活性化するのは 3.8B で、コンテキスト長は 256K(262144 トークン)である。Google 公表のベンチマークでは MMLU Pro 82.6%、MMMLU 86.3% と、本手順で扱うモデルのなかで最も高い数値を示す。MoE は推論ごとに一部のパラメータのみを活性化する構造のため、総パラメータが大きい割に推論は速い。
ハードウェアの前提
- gemma4:e2b-it-qat:ダウンロード容量が約 4.3GB あり、必要な VRAM/メインメモリもその分大きくなる。LFM2.5-1.2B-Instruct の GGUF(Q4_K_M 量子化)が約 731MB、VRAM 目安 1〜2GB であるのに対し、本モデルはリソース要求が大きい。
- gemma4:12b-it-qat:ダウンロード容量が約 7.2GB あり、e2b より大きい。QAT により、12B 規模でもメモリ 16GB クラスのノート PC で動作する設計だが、ディスク空き容量・メモリに余裕のある環境を前提とする。
- gemma4:26b-a4b-it-qat(任意):ダウンロード容量が約 16GB あり、本手順で扱うモデルのなかで最もリソース要求が大きい。4 ビット量子化時の所要メモリは 18GB 程度が目安であり、メモリ 32GB 以上の環境を前提とする。導入は任意で、リソースが不足する場合は省略してよい。
- 推論時のメモリ占有は 1 モデル分(モデル切替時に Ollama が自動でアンロードおよびロードを行う)。
ハードウェア要件(メモリ量、GPU の必要性)の事前確定は難しい。新規に PC を準備する前に、現有の機器で本手順を試行し、性能面の問題の有無を確認したうえで、本格運用のハードウェアを決定する。
量子化について
本段階では量子化されたモデルを用いる。量子化とは、モデル内部の重みパラメータを低ビット精度(例:32 ビット浮動小数点を 4 ビット整数)に変換し、メモリ使用量と推論速度を改善する手法である。gemma4:e2b-it-qat・gemma4:12b-it-qat・gemma4:26b-a4b-it-qat は、いずれも量子化を考慮した学習(QAT)によって軽量化されており、量子化に伴う精度低下を抑える設計となっている。
- LFM2.5-1.2B-Instruct:パラメータ数約 1.2B、Q4_K_M 量子化、約 731MB、VRAM 目安 1〜2GB。最軽量の動作確認用、および一次スクリーニング・独立した第二意見の担当。
- gemma4:e2b-it-qat:E2B(有効 2.3B、埋め込み込み 5.1B)、QAT 量子化、約 4.3GB、コンテキスト長 128K(131072 トークン)。思考モードを備え、不備検出・冊子横断照合の担当。画像入力にも対応する。
- gemma4:12b-it-qat:12B(総パラメータ約 11.95B)、QAT 量子化、約 7.2GB、コンテキスト長 256K(262144 トークン)。思考モードを備え、論理整合性の追跡・冊子横断照合など高い推論能力を要する判定の主担当。画像入力にも対応する。
- gemma4:26b-a4b-it-qat(任意):26B クラスの MoE(総パラメータ 25.2B、活性 3.8B)、QAT 量子化、約 16GB、コンテキスト長 256K(262144 トークン)。思考モードを備え、最も高い推論能力を要する判定の担当。画像入力にも対応する。メモリに余裕がある場合の最上位の選択肢。
これらのモデルは事前学習データ・ファインチューニング・モデル規模(パラメータ数や構造)が異なるため、誤り傾向の相関が低い。これにより「複数モデルが一致=信頼度が高い/相違=人手確認」という判定基準が成り立つ。クロスチェックは 2 モデルでも、3 モデル以上でも実施できる。
【インストールコマンドの実行方法】
管理者権限でコマンドプロンプトを起動する(手順:Windows キーまたはスタートメニュー → cmd と入力 → 右クリック → 「管理者として実行」)。実行時はコマンド全体をコマンドプロンプトにコピー&ペーストする。
インストールコマンド
REM ============================================================
REM 管理者権限チェック
net session >nul 2>&1
if errorlevel 1 ( echo [エラー] 管理者権限で実行してください & pause & exit /b 1 )
REM === 1. Ollama サービスの起動確認 ===
REM ダウンロードには Ollama サービスが必要
tasklist /fi "imagename eq ollama.exe" | find /I "ollama.exe" >nul 2>&1
if errorlevel 1 ( start "" "C:\Ollama\ollama.exe" serve & timeout /t 10 /nobreak >nul )
REM === 2. 本番段階モデルのダウンロード ===
REM 不備検出・冊子横断照合の担当:gemma4:e2b-it-qat(E2B、QAT 量子化、約 4.3GB)
REM 論理整合性・冊子横断照合の主担当:gemma4:12b-it-qat(12B、QAT 量子化、約 7.2GB)
echo gemma4:e2b-it-qat モデルをダウンロード中...
ollama pull gemma4:e2b-it-qat
echo gemma4:12b-it-qat モデルをダウンロード中...
ollama pull gemma4:12b-it-qat
echo モデルダウンロード完了
REM === 2b. (任意)最上位モデルのダウンロード ===
REM メモリ 32GB 以上の環境で利用できる最上位の選択肢
REM gemma4:26b-a4b-it-qat(26B クラスの MoE、活性 3.8B、QAT 量子化、約 16GB)
REM 不要な場合は次の 2 行を実行しなくてよい
echo gemma4:26b-a4b-it-qat モデルをダウンロード中...(任意)
ollama pull gemma4:26b-a4b-it-qat
REM === 3. 本番段階用 スタートメニュー ショートカット作成 ===
REM gemma4:e2b-it-qat 起動ショートカット
powershell -NoProfile -Command "$s=New-Object -ComObject WScript.Shell; $l=$s.CreateShortcut([Environment]::GetFolderPath('CommonPrograms')+'\Ollama gemma4 e2b-it-qat.lnk'); $l.TargetPath='cmd.exe'; $l.Arguments='/k \"start cmd /k ollama serve ^& timeout /t 5 /nobreak ^>nul ^& ollama run gemma4:e2b-it-qat\"'; $l.Save()"
REM gemma4:12b-it-qat 起動ショートカット
powershell -NoProfile -Command "$s=New-Object -ComObject WScript.Shell; $l=$s.CreateShortcut([Environment]::GetFolderPath('CommonPrograms')+'\Ollama gemma4 12b-it-qat.lnk'); $l.TargetPath='cmd.exe'; $l.Arguments='/k \"start cmd /k ollama serve ^& timeout /t 5 /nobreak ^>nul ^& ollama run gemma4:12b-it-qat\"'; $l.Save()"
REM (任意)gemma4:26b-a4b-it-qat 起動ショートカット
powershell -NoProfile -Command "$s=New-Object -ComObject WScript.Shell; $l=$s.CreateShortcut([Environment]::GetFolderPath('CommonPrograms')+'\Ollama gemma4 26b-a4b-it-qat.lnk'); $l.TargetPath='cmd.exe'; $l.Arguments='/k \"start cmd /k ollama serve ^& timeout /t 5 /nobreak ^>nul ^& ollama run gemma4:26b-a4b-it-qat\"'; $l.Save()"
echo インストール完了
演習 11.本番モデルの登録確認と動作検証
本番モデル gemma4:e2b-it-qat および gemma4:12b-it-qat(任意で gemma4:26b-a4b-it-qat)が登録され、それぞれ応答を返すことを確認する。あわせて、予備段階の LFM2.5-1.2B-Instruct と合わせた各モデルが利用可能であることを確認する。登録確認(ollama list)と CUI での動作確認を、1 つの演習にまとめる。
手順
- 新しいコマンドプロンプトで以下を実行し、登録済みモデルを確認する:
REM 期待される出力:LiquidAI/lfm2.5-1.2b-instruct、gemma4:e2b-it-qat、gemma4:12b-it-qat、 REM (任意で gemma4:26b-a4b-it-qat)、および埋め込みモデル bge-m3 ollama list - スタートメニューから「Ollama gemma4 e2b-it-qat」を実行し、テスト質問(例:「日本の首都はどこですか?」)を入力する。応答が返ることを確認し、
/byeで終了する。 - スタートメニューから「Ollama gemma4 12b-it-qat」を実行し、同様にテスト質問を入力する。応答が返ることを確認し、
/byeで終了する。 - 26b-a4b-it-qat を導入した場合は、スタートメニューから「Ollama gemma4 26b-a4b-it-qat」も同様に実行して確認する。
- 初回実行時にモデルが自動でダウンロードされる場合がある。その後に対話が始まる。サーバに接続できない場合は、別のコマンドプロンプトで
ollama serveを実行してサーバを起動してから、再度実行する。
ヒント
- 初回モデルロードに時間を要する(予備段階の LFM2.5-1.2B-Instruct よりサイズが大きいため。とくに gemma4:12b-it-qat や gemma4:26b-a4b-it-qat は時間がかかる)。
- 別のモデルを起動する際、先に読み込まれていたモデルは自動でアンロードされる。
- メモリ不足で応答が極端に遅い場合、他のメモリ消費の大きいアプリケーション(ブラウザの多タブ等)を終了する。それでも動作が重い場合は、より小さいモデル(gemma4:e2b-it-qat や LFM2.5-1.2B-Instruct)を主担当として運用する。
考察ポイント
ollama listの出力にgemma4:e2b-it-qatとgemma4:12b-it-qat(導入した場合はgemma4:26b-a4b-it-qat)が追加されているか。- 導入した各モデル(LFM2.5-1.2B-Instruct、gemma4:e2b-it-qat、gemma4:12b-it-qat、任意で gemma4:26b-a4b-it-qat)とも質問に対して応答を返すか。
- 応答が返るまでの時間が、モデルサイズとどう関係するか。
演習 12.複数モデルクロスチェック(単一設問の不備検出)
演習 8 と同一の単一設問プロンプトを複数モデル(gemma4:12b-it-qat、gemma4:e2b-it-qat、必要に応じて LFM2.5-1.2B-Instruct)で実行し、指摘内容の一致/不一致を判定する。本演習は、教科書冊子の品質チェック(不備検出・誤字検出・冊子横断検出)に向けた予備的な動作確認である。
手順
- Open WebUI のチャット画面を開く。
- モデル
gemma4:12b-it-qatを選択し、思考モードを「オン」にする。 - 新しいチャットを開始し、演習 8 と同じプロンプト(長方形の周の長さを求める設問)を入力して送信する。
- 応答内容を記録する。
- 新しいチャットを開始し、モデル
gemma4:e2b-it-qatに切り替えて同じプロンプトを送信し、応答内容を記録する。さらに必要に応じて、モデル LFM2.5-1.2B-Instruct でも同様に記録する。 - 各モデルの指摘内容を、以下の判定ルールに従って分類する:
- 用いたモデルがすべて同一の指摘 → 要修正
- 一部のモデルのみの指摘 → 要人手確認
- すべてのモデルが「問題なし」 → 通過
ヒント
- モデル切替時はロード待ちが発生する。
- モデル切替の都度「新しいチャット」を開始するのは、前のチャットの会話履歴が次の応答に影響しないようにするためである。
考察ポイント
- 各モデルとも「条件不足」または「複数解」の旨を指摘するか。
- モデル間の指摘内容の一致/不一致を識別でき、判定ルールに従って分類できるか。
- 指摘内容の表現や粒度に、モデルごとの傾向の差があるか。とくに gemma4:12b-it-qat と gemma4:e2b-it-qat で精度・粒度に差が出るか。
- 演習 8(軽量モデル単独)の結果と比較して、本番モデルでは指摘の精度・粒度がどう変わったか。
演習 13.冊子横断検出(設問間のヒント・誘導・解答漏洩)
複数設問を一度にプロンプトへ投入し、設問間にヒント・誘導・解答漏洩がないかを相互参照で検出する。本演習では、大きなコンテキスト長に対応したモデル(gemma4:12b-it-qat はコンテキスト長 256K、gemma4:e2b-it-qat は 128K)の特性を用いる。
手順
- Open WebUI のチャット画面でモデル
gemma4:12b-it-qatを選択し、思考モードを「オン」にする。 - 新しいチャットを開始し、以下のプロンプト(複数設問を一括投入)を入力して送信する:
あなたは教科書のレビュアーである。次の設問 1 から設問 3 までを通読し、設問間にヒント、誘導、解答漏洩がないか相互参照で検出せよ。検出した場合は該当箇所と問題点を指摘せよ。 設問 1:以下の三角形 ABC の面積を求めよ。底辺は 5cm、高さは 4cm である。 設問 2:三角形の面積は「底辺 × 高さ ÷ 2」で求められる。この公式を用いて、底辺 3cm、高さ 2cm の三角形の面積を求めよ。 設問 3:底辺 6cm、高さ 8cm の三角形の面積を求めよ。 - 応答内容を記録する。
- 新しいチャットを開始し、モデル
gemma4:e2b-it-qatに切り替えて同じプロンプトを送信し、応答内容を比較する。
ヒント
- 設問 2 は、設問 1 と設問 3 の解答に直結する公式を冊子内で明示しているため、ヒント・誘導の典型例として作成している。
- 本演習は最小サンプルでの動作確認である。実運用では、実際の教科書冊子(50〜100 ページ、100〜200 問)を一括投入する。コンテキスト長が大きい gemma4:12b-it-qat は、より長い冊子を一括投入できる。
- 冊子全文を一度に投入する場合、80 ページ・150 問を超えるときは、大問単位での前半/後半分割を検討する。
考察ポイント
- 応答に「設問 2 が設問 1 と設問 3 の解答公式をそのまま提示している」「設問 2 の解答公式が他設問のヒントになっている」等の指摘が含まれるか。
- 両モデルが同様の指摘を返すか。gemma4:12b-it-qat と gemma4:e2b-it-qat で検出範囲に差があるか。
- 単一設問では検出できず、横断検出で初めて検出できる事象として何が挙げられるか。
演習 14.二段プロンプト戦略(不備検出 → 通常解答)
第一段で不備の有無のみを判定し、不備なしと判定された設問のみ第二段で通常解答に進める運用を試行する。「解答せよ」という指示が不備の見逃しを誘発する事態を抑制する効果を確認する。
手順(第一段:不備検出)
- Open WebUI のチャット画面でモデル
gemma4:12b-it-qatを選択し、思考モードを「オン」にする。 - 新しいチャットを開始し、以下のプロンプトを入力して送信する:
あなたは教科書のレビュアーである。次の設問 1 および設問 2 について、不備(条件不足・矛盾・複数解・図表参照不能)の有無を最優先で検出せよ。不備がある場合は解答を試みず、不備の内容のみを指摘せよ。不備がない場合は「不備なし」とのみ返答せよ。 設問 1:ある長方形の面積は 24 平方センチメートルである。この長方形の周の長さを求めよ。 設問 2:底辺 6cm、高さ 8cm の三角形の面積を求めよ。 - 応答内容を確認する。設問 1 には「不備あり」(条件不足等)、設問 2 には「不備なし」と返ることを確認する。
手順(第二段:通常解答)
- 第一段で「不備なし」と判定された設問のみを取り出す。
- 新しいチャットを開始し(第一段と同じチャット内に続けて入力しない)、同じモデル
gemma4:12b-it-qatで以下のプロンプトを入力して送信する:次の設問に解答せよ。 設問:底辺 6cm、高さ 8cm の三角形の面積を求めよ。 - 応答に正しい解答(24 平方センチメートル)が含まれることを確認する。
ヒント
- 第一段と第二段はプロンプトを分離する。同一プロンプトで「不備検出と解答を同時に行え」と指示すると、解答指示の側面が優先され、不備の見逃しが起きやすい。
- 「新しいチャットを開始する」ことが、プロンプト分離の実装にあたる。同一チャット内では会話履歴がモデルに渡るため、第一段の文脈が第二段に影響する。
- 第一段で「不備あり」と判定された設問は第二段に進めず、指摘内容のみを人手レビューに回す。
- 本演習では設問 1 と設問 2 を 1 つのプロンプトに含めているが、実運用では、冊子全体を第一段で評価し、その出力を見て第二段に進める設問を選別する。
考察ポイント
- 第一段の応答で、設問 1 が「不備あり(条件不足)」、設問 2 が「不備なし」と区別されているか。
- 第二段の応答で、設問 2 に対して正しい解答が返るか。
- 第一段と第二段でプロンプトが分離されているか(別の新規チャットで送信したか)。
- 第一段と第二段を分離した場合と、両者を同一プロンプトに統合した場合とで、不備の検出結果に差が生じるか。
演習 15.国語教科冊子の品質チェック(総合演習)
これまでの演習で確認した機能(思考モード、複数モデルクロスチェック、冊子横断検出、二段プロンプト戦略)を組み合わせて、国語教科の教科書冊子(複数設問が掲載された冊子)を想定した品質チェックを実施する。
本演習で扱う品質チェックの観点:教科書冊子の品質チェックで確認すべき項目を、次の 7 観点に整理する。
- 誤字・脱字・送り仮名・表記ゆれ(演習 9 で扱った観点)
- 係り受けの不整合・主述の不一致(演習 9 で扱った観点)
- 設問条件の不足・矛盾・複数解(演習 8、12 で扱った観点)
- 図表・本文・選択肢の参照整合性(本文中の引用箇所と参照指示の対応)
- 設問間のヒント・誘導・解答漏洩(演習 13 で扱った観点)
- 選択肢の唯一性・排他性(複数の正答が成立しないか、明らかな誤答が含まれるか)
- 用語・配点・指示語の冊子内一貫性(同一概念に対する用語のゆれ、配点表示の統一、「次の」「上記の」等の指示語の参照先の明確さ)
サンプル冊子:国語教科の小冊子を想定した以下のサンプルを用いる。サンプルには、上記 7 観点に対応する不備が意図的に複数混入している。
【国語 小テスト(サンプル)】
配点:各問 10 点
問 1 次の文章を読み、後の問いに答えなさい。
「言葉は人と人とを繋ぐ橋である。私たちは日常において、絶えず言葉を交わし、互いの考えを伝え合っている。しかし、その言葉が時に誤解を生む事もある。なぜなら、同じ言葉でも受け取り方は人によって異なるからだ。」
問い:筆者が「言葉」をどのようなものとして捉えているか、本文中から十字以内で抜き出しなさい。
問 2 次の文の傍線部の主語を答えよ。
「彼は昨日、図書館で借りた本を友人に貸してあげた、その本は今日返ってきた。」
問 3 次の語の対義語を答えなさい。配点:各 5 点
(1)需要 (2)抽象
問 4 次の文章の内容として最も適切なものを、下のアからエの中から一つ選べ。
「読書は知識を広げる行為であり、また想像力を養う営みでもある。本を読むことは、他者の経験を追体験する事につながる。」
ア 読書とは知識を広げる行為のみを指す。
イ 読書は想像力を養うためだけの活動である。
ウ 読書は気晴らしのための娯楽の一種である。
エ 読書は知識を広げ、想像力を養い、他者の経験を追体験することにつながる。
問 5 上記の問 4 で扱った「読書」について、あなた自身の経験に基づいて百二十字以内で論じなさい。
問 6 次の文章中の傍線部「これ」が指す内容を答えなさい。
(※本文省略)
サンプル冊子に意図的に混入した不備(解説)
- 問 1:「事もある」(漢字「事」の使用)— 観点 1 に該当。
- 問 2:1 文中に句点(。)が一度しかなく、読点(、)で 2 つの文がつながれている — 観点 2 に該当。
- 問 3:他の問が各 10 点であるのに対し、問 3 のみ各 5 点となっており、配点表示に一貫性がない — 観点 7 に該当。
- 問 4:選択肢ア・イは本文の一部のみを「のみ」「だけ」で限定して述べている。選択肢ウは本文に記述のない「娯楽」を主張しており本文外。エは本文の主要な 3 要素を網羅しており、エが妥当な選択肢となる構造だが、ア・イを誤答と判定するか「部分的には正しい」と判定するかで解答が割れうる — 観点 6 に該当。
- 問 5:「上記の問 4 で扱った『読書』」という指示で問 4 の本文と選択肢の双方を参照しており、参照先が曖昧 — 観点 7 に該当。
- 問 6:本文が省略されており、設問成立の前提となる本文が欠落している — 観点 4 に該当。
- 冊子横断:問 4 の本文と問 5 の論題が「読書」で重複し、問 4 の選択肢が問 5 の論述方向のヒントになっている — 観点 5 に該当。
手順
第一段(不備検出のみ)を 2 モデル(gemma4:12b-it-qat と gemma4:e2b-it-qat)で実行し、第二段(解答可能な問の解答)は省略する。本演習では、検出結果のクロスチェックに焦点を当てる。
- Open WebUI のチャット画面でモデル
gemma4:12b-it-qatを選択し、思考モードを「オン」にする。 - 新しいチャットを開始し、以下のプロンプトを入力して送信する。
(ここに上記サンプル冊子の本文を貼り付ける)の箇所には、上記「サンプル冊子」の【国語 小テスト(サンプル)】から問 6 の末尾までの本文をそのままコピーして貼り付ける:あなたは国語の教科書冊子のレビュアーである。次の冊子全体について、以下の 7 観点で不備を検出せよ。検出した場合は、該当箇所(問番号と本文・選択肢の引用)と、どの観点に該当するか、何が問題かを示せ。検出しなかった場合は「該当なし」と返答せよ。解答そのものは出力するな。 観点: 1. 誤字・脱字・送り仮名・表記ゆれ 2. 係り受けの不整合・主述の不一致 3. 設問条件の不足・矛盾・複数解 4. 図表・本文・選択肢の参照整合性(参照先の本文や図表が冊子内に存在するか) 5. 設問間のヒント・誘導・解答漏洩 6. 選択肢の唯一性・排他性 7. 用語・配点・指示語の冊子内一貫性 冊子: (ここに上記サンプル冊子の本文を貼り付ける) - 応答内容を記録する。
- 新しいチャットを開始し、モデル
gemma4:e2b-it-qatに切り替えて同じプロンプトを送信し、応答内容を記録する。 - 両モデルの検出結果を、観点ごとに突き合わせ、以下の項目で集計する:
- 観点番号
- 解説(上記「サンプル冊子に意図的に混入した不備」)に記載された、期待される検出箇所
- gemma4:12b-it-qat の検出有無および指摘内容
- gemma4:e2b-it-qat の検出有無および指摘内容
- 判定(両モデル一致/片方のみ/両モデルとも未検出)
ヒント
- サンプルの問 6 は本文が省略されているため、観点 4(参照整合性)として検出されることを期待する。
- サンプルの問 4 と問 5 の関連は、単一設問の観点では検出が難しく、冊子横断の観点(観点 5)で検出される。
- サンプルの配点不整合(観点 7)は、冊子内の他設問との比較が必要なため、冊子全体を一括投入する本演習の構成で検出できる。
- モデルが観点 1〜7 のいずれにも該当しない指摘を返した場合は、「観点外の指摘」として別に記録する(評価対象には含めるが、判定上は参考扱い)。
考察ポイント
- 意図的に混入した不備のうち、両モデル一致で検出されたものはどれか。
- 片方のモデルのみが検出した不備はどれか(人手確認の対象)。
- 両モデルとも未検出の不備はどれか(プロンプトの観点定義の見直し、または観点別の個別プロンプトへの分解の検討対象)。
- 観点 1〜7 のうち、本構成で検出が安定した観点と、検出が不安定だった観点はどれか。
- 観点別に個別プロンプトへ分解する場合と、本演習のように 7 観点を一括して問う場合とで、検出結果に差が生じるか。
演習 16.長文・機密文書の相互矛盾検出(ローカル環境の特徴を生かす総合演習)
これまでの演習は一つの文書・一冊の冊子の内部を見てきた。本演習では、本環境の三つの特徴 ― 完全ローカル(機密保持)・超長コンテキスト(262144 トークン)・複数モデルのクロスチェック ― を同時に用い、複数の文書をまたいで生じる「条文間の矛盾」を検出する。これは、文書を外部に送れない(クラウド AI に貼れない)・全文を一度に読ませる必要がある・見落としを一台で相互検証したい、という三条件が重なるため、本環境でこそ実用的に成立する課題である。
想定する場面
社内には、年代や部署ごとに別々に制定された規程・ガイドラインが複数存在し、互いに矛盾していることがある(例:就業規則は「申請は 3 営業日前」、テレワーク規程は「前日まで」)。これらは機密情報を含むためクラウド AI に貼れず、かつ全文を突き合わせないと矛盾は見つからない。本演習は、その相互矛盾を一括検出する。
準備:テスト用文書の作成
- メモ帳を開き、以下を入力する。3 つの架空規程を 1 ファイルにまとめてあり、規程間に意図的な矛盾を複数混入してある:
==== 文書A:就業規則(抜粋) ==== 第12条 在宅勤務を希望する従業員は、勤務予定日の3営業日前までに所属長へ申請する。 第13条 在宅勤務時の標準勤務時間は9時から18時とし、休憩は1時間とする。 第27条 機密情報を含むファイルは、会社支給端末にのみ保存し、私物端末への保存を禁止する。 第31条 時間外勤務の上限は1か月あたり45時間とする。 ==== 文書B:テレワーク実施ガイドライン ==== 2.1 テレワークの申請は、実施日の前日17時までに上長へ届け出るものとする。 2.4 テレワーク時の勤務時間は10時から19時を標準とする。 3.2 業務データは、セキュリティ対策を施した私物端末への保存を認める。 5.1 育児・介護を理由とするテレワークは、当日朝までの申請を認める。 ==== 文書C:情報セキュリティ基本方針 ==== 4.1 いかなる業務データも、会社が認証した端末以外への保存を一律に禁止する。 4.3 時間外勤務は原則として月40時間を超えてはならない。 6.2 在宅勤務の標準勤務時間は、就業規則に定める時間に準ずる。 - 「ファイル → 名前を付けて保存」で、文字コードを
UTF-8に変更し、%USERPROFILE%\policy_set.txtとして保存する。
手順
- Open WebUI を起動し、モデル
gemma4:12b-it-qatを選択、思考モードを「オン」にする。 - 新しいチャットを開始し、以下のプロンプトを送信する。
(ここに文書を貼り付ける)には上記policy_set.txtの全文をそのまま貼り付ける:あなたは社内規程の整合性をチェックする監査担当である。次に示す複数の社内文書(文書A・文書B・文書C)を通読し、文書をまたいで矛盾している箇所を検出せよ。同一文書内ではなく、異なる文書の条項どうしが食い違っているものを対象とする。検出した各矛盾について、(1)関係する条項を文書名と番号つきで引用し、(2)どう食い違っているかを述べ、(3)どちらを優先すべきか判断材料(上位規程か、より厳しい基準か、例外規定か)を示せ。解決策の押し付けはせず、矛盾の指摘と論点整理にとどめよ。 文書群: (ここに文書を貼り付ける) - 応答内容を記録する。
- 新しいチャットを開始し、モデル
gemma4:e2b-it-qatに切り替えて同じプロンプトを送信し、応答内容を記録する。さらに余裕があればgemma4:26b-a4b-it-qatでも記録する。 - 各モデルが検出した矛盾を突き合わせ、演習 12 の判定ルール(全モデル一致=要対応/一部のみ=要人手確認/全モデル「矛盾なし」=通過)で分類する。
想定される矛盾(解説 ― 採点の参照用)
この文書群には、文書をまたぐ矛盾を意図的に 4 組混入している。
- 在宅勤務の申請期限:文書A 第12条「3 営業日前」と文書B 2.1「前日 17 時まで」が食い違う。さらに文書B 5.1 に当日朝までの例外があり、どれが優先かが論点となる。
- 標準勤務時間:文書A 第13条「9〜18 時」と文書B 2.4「10〜19 時」が異なり、加えて文書C 6.2 が「就業規則に準ずる」としているため、三者が三つ巴になる。
- 私物端末への保存可否:文書A 第27条・文書C 4.1「禁止」と文書B 3.2「認める」が正面衝突する。情報セキュリティ基本方針(文書C)という上位文書が優先されるべき、という論点を含む。
- 時間外勤務の上限:文書A 第31条「45 時間」と文書C 4.3「40 時間」が異なる。より厳しい基準を採るべきか、が論点となる。
ヒント
- 本演習の文書は最小サンプルである。実運用では、数十本の規程・契約書(合計で数十万字)を一度に貼り付ける。本環境はコンテキスト長 262144 トークンを設定済みのため、この規模の一括投入に耐える。クラウド AI ではこうした機密文書を外部送信できないが、本環境はローカル完結のため安全に扱える。
- 矛盾の種類は「数値の食い違い」「許可と禁止の衝突」「優先関係の不明確さ」に大別できる。応答を読む際はこの三類型で整理すると突き合わせやすい。
- 文書量が長大で 1 チャットに貼りきれない場合は、演習 7 の RAG(Knowledge)機能に文書群を登録し、矛盾しそうな論点(申請期限、勤務時間など)ごとに質問する方法に切り替える。
考察ポイント
- 4 組の矛盾のうち、各モデルが検出できたものはどれか。とくに、二者ではなく三文書が絡む「標準勤務時間」の三つ巴を、文書C の「準ずる」という間接表現まで踏まえて指摘できたか。
- 単一文書を個別に読ませた場合には決して検出できず、全文を一括投入して初めて検出できる矛盾はどれか。これが本環境の超長コンテキストの価値である。
gemma4:12b-it-qatとgemma4:e2b-it-qatで、検出できた矛盾の数や、優先関係(上位規程・厳しい基準)の論点整理の深さにどのような差が出たか。- この課題を、文書を外部に送信できるクラウド AI で行う場合と比べ、本環境(ローカル完結)であることの利点は何か。逆に、ローカル環境ゆえの制約(処理速度、モデル規模の上限)は何か。
- 矛盾が見つかったとき、本演習のプロンプトは「解決策の押し付けをせず論点整理にとどめる」よう指示している。なぜ最終判断を人手に残す設計が、規程監査では望ましいか。
本番段階の総括
演習 11〜演習 16 の動作に問題がなければ、実運用へ移行できる状態である。実運用では実際の教科書冊子(50〜100 ページ、100〜200 問)を用いて、一次スクリーニングを LFM2.5-1.2B-Instruct または gemma4:e2b-it-qat、論理整合性・不備検出および冊子横断照合を gemma4:12b-it-qat が担当し、図・表・年表・古代語・数式・化学式については複数モデルを併用する。メモリ 32GB 以上の環境では、最も高精度を要する判定に gemma4:26b-a4b-it-qat を加えることもできる。リソースに制約がある環境では、より小さいモデルを主担当に切り替えてもよい。図表・数式を含む文書を扱う場合は、次の発展節に従って Docling(docling-serve)を Open WebUI に接続したうえで、RAG 拡張(教科書・学習指導要領との照合)を Knowledge を教科別に作成して導入できる。
発展(任意):Docling による図表・数式を含む文書の高精度抽出(Docker + docling-serve)
本節は任意の発展ステップである。これまでの演習は、Open WebUI の標準(Default)抽出エンジンで完結する。しかし、本手順の主題である教科書冊子の品質チェックでは、表・図・グラフ・数式・化学式・図中テキストを含む文書を扱う。標準抽出エンジンはこれらの構造を十分に保持できず、表のセルの対応が崩れたり、図中のテキストや数式が取り込まれなかったりする。Docling を Open WebUI の抽出エンジンとして接続すると、表を構造ごと、図中テキストを OCR で、レイアウトを保持したまま取り込めるようになり、RAG の検索・回答精度が向上する。
テキスト中心の文書のみを扱う場合は、本節は省略してよい。図・表・数式を含む文書を RAG で扱う段階で導入する。
Open WebUI で Docling を使うには、Docling を pip install するだけでは不十分で、Docling のサーバ版である docling-serve を別プロセス(Docker コンテナ)として起動し、その URL を Open WebUI に登録する必要がある。本節では Docker を初めて使用する。
前提条件
- Docker Desktop for Windows がインストールされ、起動していること(次の手順 1 で導入する)。
- Open WebUI が動作していること(演習 3 まで完了していること)。
【手順 1:Docker Desktop のインストール】
管理者権限でコマンドプロンプトを起動し、以下を実行する:
REM ============================================================
REM 管理者権限チェック
net session >nul 2>&1
if errorlevel 1 ( echo [エラー] 管理者権限で実行してください & pause & exit /b 1 )
REM Docker Desktop のインストール
winget install --id Docker.DockerDesktop -e --silent --disable-interactivity --accept-source-agreements --accept-package-agreements
インストール後、Windows の再起動が必要な場合がある。再起動後、スタートメニューから Docker Desktop を起動し、初回セットアップ(WSL 2 バックエンドの有効化等)を完了させる。タスクトレイの Docker アイコンが「実行中(緑)」になるまで待つ。
【手順 2:docling-serve コンテナの起動】
Docker Desktop が起動した状態で、新しいコマンドプロンプト(管理者権限不要)を開き、用途に応じて次のいずれかを実行する。コンテナはポート 5001 で待ち受ける。
CPU のみの環境(または GPU を使わない場合):
docker run -d --name docling-serve -p 5001:5001 -e DOCLING_SERVE_ENABLE_UI=true quay.io/docling-project/docling-serve
NVIDIA GPU を使う場合(CUDA 対応イメージ。GPU により OCR・レイアウト解析が高速化する):
docker run -d --name docling-serve --gpus all -p 5001:5001 -e DOCLING_SERVE_ENABLE_UI=true quay.io/docling-project/docling-serve-cu128
起動後、ブラウザで http://localhost:5001/ui を開き、docling-serve の動作確認用 UI が表示されることを確認する(任意で、ここにテスト文書をアップロードして Markdown 出力を確認できる)。
【手順 3:Open WebUI への接続】
- Open WebUI の管理者パネル → Settings → Documents を開く。
- 「Content Extraction Engine」を
DefaultからDoclingに変更する。 - 表示される Docling のサーバ URL 欄に
http://localhost:5001を入力する(Open WebUI を Windows 上でネイティブに動かしている場合。Open WebUI 自身も Docker コンテナで動かしている場合はhttp://host.docker.internal:5001とする)。 - 必要に応じて、PDF の解析品質・OCR を設定する。Open WebUI の Docling パラメータ(
DOCLING_PARAMS)に以下のような JSON を設定すると、表を高精度モードで抽出し、日本語の図中テキストを OCR で読み取れる:{ "do_ocr": true, "pdf_backend": "dlparse_v4", "table_mode": "accurate", "ocr_engine": "tesseract", "ocr_lang": ["jpn", "eng"] }ocr_langは Tesseract では 3 文字コード(日本語jpn、英語eng)で指定する。数式・化学式を多く含む文書ではtable_modeをaccurateにすると構造保持が向上する。 - 「保存(Save)」を押す。
【手順 4:動作確認】
演習 7 と同じ手順で、今度は表・図・数式を含む PDF を Knowledge にアップロードする。アップロード後、その文書に対して表の数値や図中の項目を問う質問を送り、標準抽出エンジンのときと比べて応答精度が向上するかを確認する。
ヒント
- docling-serve コンテナを停止するには
docker stop docling-serve、再開するにはdocker start docling-serveを実行する。PC 再起動後は Docker Desktop の起動後にdocker start docling-serveで再開できる。 - 大きな文書で処理がタイムアウトする場合は、コンテナ起動時に環境変数
DOCLING_SERVE_MAX_SYNC_WAIT(既定 120 秒)を600等へ増やす(-e DOCLING_SERVE_MAX_SYNC_WAIT=600をdocker runに追加)。 - 図そのものの内容を文章で説明させたい(Picture Description)場合は、docling-serve に
-e DOCLING_SERVE_ENABLE_REMOTE_SERVICES=trueを付けて起動し、Open WebUI 側で画像説明モデル(ローカルのビジョンモデル、または Ollama 等の API)を設定する。 - OCR・レイアウト解析は CPU では時間がかかる。図表・数式の多い大量の文書を扱うなら、GPU 対応イメージ(
-cu128)の利用を検討する。
考察ポイント
- 同一の表・図・数式を含む文書を、標準抽出エンジンと Docling とで取り込んだ場合、RAG の応答精度(表の数値の正確さ、図中項目の参照可否)にどのような差が出るか。
- 本手順の主題(図表・数式を含む教科書冊子の品質チェック)において、Docling 接続が必須となる場面はどれか。
付録:他のモデルを試す・推論ツールの選択
本手順では、ダウンロード容量が小さく動作確認が容易な LFM2.5-1.2B-Instruct を共通の動作確認用モデルとして用い、一段上の選択肢として gemma4:e2b-it-qat、上位の選択肢として gemma4:12b-it-qat、最上位の選択肢として gemma4:26b-a4b-it-qat を扱った。Ollama を使うと、モデル名を差し替えるだけで他のモデルも同じ手順で試せる(モデルは初回実行時に自動的にダウンロードされる)。Gemma 4 シリーズには、ほかに 31B(Dense)の QAT モデルも公開されており、ハードウェアに余裕があれば同じ要領で導入できる。
高速化用の補助モデル(gemma-4-12B-it-assistant)について
Hugging Face で公開されている google/gemma-4-12B-it-assistant は、名称に「assistant」と付くが、単独の会話モデルではない。これは 12B 本体(google/gemma-4-12B-it)の推論を高速化するための補助モデル(ドラフター)であり、パラメータ数は約 0.4B と小さい。投機的デコーディング(Speculative Decoding、補助モデルが数トークン先を先読みし、本体がそれをまとめて検証する方式)のパイプラインで本体と組み合わせて使うことで、出力品質を変えずにデコード速度を高める用途のものである。Transformers で本体モデルと併用する構成が前提であり、本手順の Ollama(GGUF 形式・単一モデル運用)の構成にはそのままは組み込めない。校閲などの判定そのものを担うモデルではない点に注意する。
推論ツールの選択(本手順では Ollama を使用)
本手順は Ollama を推論ツールとして用いた。Ollama 以外にも、用途に応じて次のような選択肢がある。本手順ではこれらは扱わないが、目的によっては検討の余地がある。
- Ollama(本手順で使用):llama.cpp 系。ローカル API サーバ+モデル管理。数行の Python コードでモデルを呼び出せ、モデルは自動的にダウンロードされる。ローカル API サーバとしても動作し(既定でポート 11434 で待ち受ける)、OpenAI 互換 API も提供する。軽量な単一モデル運用に向く。
- LM Studio:コマンドライン操作を避けたい場合に向く GUI アプリ。アプリを起動し、モデルを選択してクリックして実行する。導入・運用手順は本手順では扱わない。
- vLLM:複数同時リクエストや高スループット(単位時間あたりの処理量)が必要な場合に向く推論基盤。サーバ運用が前提で、導入・運用手順は本手順では扱わない。
OpenAI 互換 API を採用するサーバには、既存の OpenAI クライアント(Python の openai ライブラリ等)をそのまま利用できる。
[動画]