UnityのNPCをローカルLLMで喋らせてみた〜ゲームの中で動くAI会話〜
ゲームのNPCに、決められた台詞ではなくその場で考えた返事を喋らせたい。UnityからローカルLLMを呼んでNPCに人格と記憶を持たせ、ゲームループを止めずに動かせるかを実測しました。同期呼び出しは描画フレーム0枚、平均fpsは2.4%しか落ちないのに1% Lowは20%落ちる、記憶を切り詰めると入力が半分なのに待ち時間は1.8倍——予想が2つ外れた記録です。
プログラミングや3DCGで何か作りたいと思っているエンジニアがいます
ゲームのNPCに、決められた台詞ではなくその場で考えた返事を喋らせたい。UnityからローカルLLMを呼んでNPCに人格と記憶を持たせ、ゲームループを止めずに動かせるかを実測しました。同期呼び出しは描画フレーム0枚、平均fpsは2.4%しか落ちないのに1% Lowは20%落ちる、記憶を切り詰めると入力が半分なのに待ち時間は1.8倍——予想が2つ外れた記録です。
モデルを軽くする量子化は「賢さはほとんど落ちない」と言われます。本当かどうか、F16を1つ落として手元でQ8からQ2まで作り、perplexity・KL divergence・実際の出力の3つで測りました。数字の崖はQ3から。ところがQ2でもFizzBuzzは動き、17×24も当てます。崩れたのは日本語の説明文だけでした。さらに「日本語のほうが先に壊れるのでは」という予想を検証したところ、perplexityでは外れて見えたのにKL divergenceでは1.5倍脆いと出る——測り方で結論が変わる場面に行き当たった記録です。
AIの速さには tok/s・TTFT・スループットと色々な単位が出てきますが、「指示してから出力が終わるまで」は1つの数字では見られません。読み込む時間と書き出す時間に分けて足す、という見方を実測で確かめました。入力8千トークンでは最初の1文字まで39秒かかり、待ち時間の割合は7.9%から95.4%まで入れ替わります。さらに同時に使う人が増えると1人あたりは7分の1に落ちるのに全体の処理量は増える——同じ機械から3つの「速度」が出た記録です。
ローカルLLMで「モデルのどの部分をGPUに置き、どの部分をCPUに逃がすか」は自分で指定できます。llama.cppの -ngl / -ot / --n-cpu-moe を Apple M4・Radeon 780M・RTX 3060 の3構成で実測しました。統合メモリなら逃がしても損は小さいはず——という予想は外れ、M4では専門家をCPUへ回した瞬間に生成速度が37.77から2.53 tok/sへ、全部CPUに置くより10倍遅くなりました。真犯人はmmapで、--no-mmap を付けると6.6倍まで回復します。
どちらもCPUにGPUを内蔵しメインメモリを共有する「統合メモリ」構成。Apple M4(Mac)とRyzen 7 7840HSのRadeon 780M(ミニPC)で、同じQwen2.5-Coderの7B・14Bを同じ条件で走らせて比べました。生成速度は7BでM4が19.55 tok/s(MLXなら22.60)に対し780Mは13.37、14BはM4 10.69に対し780M 6.72。M4が約1.5倍速い一方、メモリ帯域の差は120GB/s対89.6GB/sの1.34倍しかありません。帯域だけでは説明できないこの差の正体を、iPhone由来のApple GPUとグラフィックボード由来のRDNA 3という両者の設計の出自から掘り下げます。
外付けRTX 3060でゲームを動かし、同じPCの内蔵GPU Radeon 780MでローカルLLMを同時に走らせたらどうなるかを実測しました。結論は「成立する。ただし代償は平均fpsではなくフレームの安定性に出る」。平均fpsは-15.7%で済むのに、1% Lowは-43.3%、0.1% Lowは-47.9%まで落ち込みます。GPU同士は競合しておらず、犯人はDDR5メモリコントローラでした。AI側も生成-8.7%に対しプロンプト処理-20.8%と削られ方が違う。アプリごとにGPUを割り当てる設定方法と、対戦ゲームでは避けるべき理由まで実測値つきで整理します。
1台のミニPC(Ryzen 7 7840HS)で、内蔵GPU Radeon 780M(統合メモリ)と外付けRTX 3060(OCuLink接続のeGPU)を切り替えて実測しました。llama.cpp Vulkanで7B・14B・MoE 30B-A3Bの3種類を測ると、ゲームは全指標きっちり3.47倍差なのに、AIはモデル次第で1.67〜10.8倍と振れ幅が段違い。さらに「BIOSでVRAM割当を増やさないと大きいモデルは載らない」という予想が外れ、512MB設定のまま14.2GBを確保できた理由も判明。-ngl 99を付けると起動すらしない罠、Smart App Controlが公式バイナリを弾く問題まで実測値つきで記録します。
前回書いた「806MBの崖」は間違いでした。実物のQwen2.5をCore MLに変換したところ、943MBのモデルが演算の99.7%をANEで実行。原因を1つずつ切り分けると、正体は「約2GBのサイズの壁」と「特定の形だけ落ちる落とし穴」の2つでした。bisect_modelで分割すれば1.5B・3BもANEに載り、1.8倍速くなります。
最近のPCには当たり前のようにNPUが載っています。ローカルLLMをNPUで動かせるのか調べたら、Ollama・llama.cpp・LM Studioといった主流ランタイムは、そもそもNPUを使っていませんでした。なぜLLMが苦手なのか(想定モデルサイズとメモリ帯域)を図解し、さらにMacのNeural Engineで実測。float16にするだけで約10倍、450MBまでは3倍速、806MBでコンパイル失敗という「NPUを最大限に使う条件」を数字で確かめ、今NPUを存分に活かせる場面も整理しました。
ローカルLLMを動かす『推論エンジン』を、同じモデル・同じ量子化で比較。Mac(Apple M4)でllama.cpp(Metal)とMLXはほぼ互角(20.6 vs 21.1 tok/s、MLXはロードが速く省メモリ)。Windows(RTX 3060・CUDA)は同じllama.cppのコードで約3倍速の62.1 tok/s。量子化とは何か・VRAMに載るとは何かを図解し、自分のPCならどのサイズが最適かの判断表も作りました。
声で話せるローカルAIアシスタント(p936/p937)を実際に使うと『返事までの間』が長い。遅延を実測して内訳(文字起こし→LLM生成→音声合成)に分解し、LLMを逐次出力して文ができた端から音声合成・再生する『逐次パイプライン』で改善。最初の音までが実測13.5秒→2.7秒(約80%短縮)。Windows(CUDA)でも同じコードで動作し6.9→1.6秒。バッチと逐次の違いを図解+実装コード。
以前『MCPとは』を概念だけ解説しました(p909)。今回はその実践編。自作のローカルAIエージェント(p935)をMCPクライアントにして、自作の最小MCPサーバと公式のfilesystemサーバを道具として繋ぎます。ローカルLLM(Ministral 3・完全オフライン)が自律的にMCPの道具を呼ぶまでを実装コードつきで。道具名の衝突を名前空間で解決するなど、実際にやって初めてわかったハマりどころも正直に書きました。WindowsでもMac共通コードで動作確認済み。
自分のブログ全記事(66本)をローカルLLMに読ませて、"あの記事どこ?"を出典つきで答えるAI検索(RAG)を作りました。以前作ったローカルAIエージェント(p935)への機能追加として実装。記事本文を抽出→チャンク分割→multilingual-e5で埋め込み→ローカルDBに保存し、質問に近い記事を探して記事タイトルとURLつきで回答します。RAGの仕組みを図解し、本文抽出・チャンク分割・ベクトル検索・出典つき回答のキモになる実装コードも掲載。すべてローカル完結で記事データは外に出ません。Macで作ったインデックスDBはコピーするだけでWindowsでも動きました。
以前作ったローカルAIエージェント(p935)の画像機能を強化。写真を『ドラッグ&ドロップ』で複数まとめて渡すと、各画像を説明→タグ付け→画像内の文字起こし(OCR的)まで一括処理。『提案→確認→コピー』の安全なやり方でタグ別フォルダに整理しCSVにも出力。スクショ→画面説明も。すべてローカル完結でネット不要・写真が外に出ないのが強み。D&D/画像をローカルLLMに渡す/安全なコピー整理など再現用のコードも掲載。Mac/Windows同一コードで動作(Windowsの画面撮影はPySideに統一)。
ネット接続なしで動く“オフラインのコーディング相棒”を、以前作ったローカルAIエージェント(p935)への機能追加として作りました。コード特化モデル Qwen2.5-Coder を積み、GUIから使うモデルを切り替え(汎用⇔コード特化)、コーディングモードでコード生成・修正・説明。CLIからも呼べて将来VS Codeからも叩ける薄い入口も用意。クラウドAIとの違い、そして『14BはVRAM12GBのGPUには重く、7Bが最適(実測22 tok/s)』というつまずき、Mac/Windows同一コードで動いた話まで、実際の画面つきで解説します。
以前作ったローカルAIエージェント(p935・Ministral 3 14B)に、音声認識Whisperと音声合成VOICEVOXを統合。声で「◯◯を検索して」と話すと、エージェントが道具を実行して結果を声で返します。全部Macローカル。GPU/CPUの役割分担、音声用の工夫、Windows(RTX3060)でのSmart App Control対策(faster-whisper)まで解説します。
マイクで話す→AIが答える→声で返す、を全部Macローカルで。音声認識Whisper・ローカルLLM(Ollama+Qwen2.5)・音声合成VOICEVOXを1つのデスクトップアプリに統合しました。クラウドに送らないのでプライバシー安心・無料・オフラインOK。コード・モデル・設定値・つまずきまで再現できるよう解説します。
クラウド型AIエージェントの『有料・トークン消費が膨大』問題を、完全ローカルで解決できないか試作。Ministral 3 14B(Q4)をllama-cpp-pythonで動かし、Web検索・ファイル読み書き・PC操作(マウス/キーボード)・CLI/MCP・RAG記憶・画像理解を1つのデスクトップアプリに統合。緊急停止と重要操作の確認も実装。Mac(M4)で構築しWindows(RTX3060)でも検証。コード・設定値つきで解説します。
AI市場はこの数年でどう変わったのか。ChatGPTの利用者数、推論の精度・速度・コストの変化、クラウド型AIを支えるデータセンターと電力、ローカルで動くAI(ローカルLLM)の今と市販PCの限界、GPU/VRAMの仕組み、メモリ半導体の高騰、Claude Fable 5が公開3日で止まった実例、そして市場の課題と今後を、最新統計(IEA・Gartner・Statista等)を出典つきで整理します。
ネット接続なしで動くAIアプリをMacで自作。軽量LLM(Qwen2.5-3B・gguf)をllama-cpp-pythonでデスクトップアプリに直接組み込み、PySide6のGUIで文章生成・要約をオフライン実行。Apple SiliconのGPU(Metal)で約38トークン/秒。インストール・モデル・コード・設定値まで再現できるよう解説します。