ローカルLLMという世界 #4 - ランタイムとハーネス

#AI, ローカルLLM · 9min

← #3:Macの選び方

はじめに

モデルを選びそれが入るだけのRAMを用意してもモデルはそれだけでは動かない。

重みをメモリへ読み込み、プロンプトをトークンに変換しGPUで計算し次のトークンを生成するソフトウェアが必要になる。

さらにモデルへファイルを読ませたり、ツールを使わせたり、作業が終わるまで何度も行動させたりするなら、その外側にも別のソフトウェアが必要になる。

このあたりを調べ始めると、MLX、llama.cpp、LM Studio、oMLX、ハーネスといった名前が一度に出てくる。

全部ローカルLLMを動かすためのものではあるが担当している仕事は同じではないので書いていく。


概要

ローカルLLMを使う環境はざっくり次のようなものから構成される。

層何をするものか例
モデル・チェックポイント学習済みの重みそのものgpt-oss、Gemma、Qwenなどの各配布重み
モデル形式・量子化重みをどの形式と精度で保存するかGGUF、MLX向けに変換された重み
機械学習フレームワーク配列計算やGPU利用の土台を提供するMLX
ランタイム・推論エンジン重みを読み込み、実際に推論するMLX LM、llama.cpp
サーバー・管理・UIモデルの取得、起動、切り替え、API公開や対話画面を提供するLM Studio、oMLX、llama-server
エージェントハーネスファイルやツールを渡し、仕事が進むループを管理するコーディングエージェントなど

現実のソフトウェアは複数の層を兼ねる。

LM StudioはチャットUIであり、モデル管理アプリであり、llama.cppまたはMLXのランタイムを使ってモデルを動かすこともできる。(ちなみにoMLXにも管理画面と簡単なチャットがある)

そのため製品名だけを横に並べるとわかりにくいのでどれを選ぶかより先に今どの層の話をしているかを理解している必要が出てくる


ランタイムとは何か

ここでいうランタイムはモデルの重みを使って実際に推論を行うソフトウェアである。

どのモデル形式を読めるかやMacならApple SiliconのGPUをどう使うか、どの量子化に対応するか、KVキャッシュをどう持つかといった部分を担当する。

同じ名前のモデルでも、ランタイム、量子化、コンテキスト長、キャッシュの設定によって必要なメモリと生成速度は変わる。

モデルの賢さは重みで決まる部分が大きいが、それをどのくらい快適に引き出せるかはランタイムにも左右される。

MacでローカルLLMを動かす時にまず覚えておけばいい大きな選択肢がMLX LMとllama.cppである。


MLXとMLX LM

MLXはAppleの機械学習研究チームが開発しているApple Siliconを中心とした機械学習フレームワークである。CPUとGPUが同じメモリを共有するApple Siliconの構造を前提に作られている。

ただしMLX自体はLLM専用のアプリではない。

なんでもNumPyやPyTorchに近いAPIを持ちモデルの学習や推論を組み立てるための低レイヤーらしい。

そのMLXを使ってLLMの生成、量子化、ファインチューニングなどを行えるようにしたPythonパッケージがMLX LMである。

コマンドからチャットしたりPythonのコードへ組み込んだりできる。

Hugging Faceではmlx-communityを中心に、MLX LMですぐ読めるよう変換・量子化されたモデルも配布されている。ありがとうmlx-community。ありがとうHugging Face(そしてNVIDIAとの買収合意おめでとう🎉)

Macに寄せて作られていることはMLX系の大きな魅力である。一方で基本的にはApple Silicon中心の世界になる。

とはいえローカル推論向けに量子化されたモデルではGGUFというMLXと異なる形式をよく見かける。同じモデルでもGGUFには種類が多い。MLXには2,3しかないなんてこともよくある。

MacユーザーにはいつものことかもしれないがローカルLLMの世界でもそのまま持ち込まれてしまっている。


llama.cpp

llama.cppはC/C++で書かれたLLMの推論基盤でCPU、NVIDIA GPU、AMD GPU、Vulkanなど幅広い環境に対応している(Apple SiliconではMetalも使えるようにしてくれてる)

llama.cppの世界でよく見るモデル形式がGGUFである(さっき見た)。

モデル本体、量子化された重み、トークナイザーなど、推論に必要な情報を一つの形式にまとめて扱える。Hugging Faceでモデル名の後ろにGGUFやQ4_K_Mと付いたものを見かけるのはこのためである。

コマンドラインのllama-cliで対話でき、llama-serverを起動すればOpenAI互換のAPIとして他のアプリから利用できる。

ここでいうOpenAI互換とはAPIの呼び出し方が似ているという意味で、プロンプトがOpenAIへ送られるという意味ではない。

量子化の選択肢が多く、対応ハードウェアも広い。Mac以外でも同じ形式を使いたい時や、細かな設定を自分で選びたい時に強い。


LM Studio

LM StudioはローカルLLM入門時に最もユーザーフレンドリーなツールである。

アプリの中からモデルを検索してダウンロードし、読み込み、チャットができる(素晴らしい!)

もちろん設定を変え、必要ならAPIサーバーとしてポートを開放することでローカルの他のAppからAIを利用することもできる(実はTailscaleベースのLM Linkでネットワーク越しに接続する機能もサポートされてる)

内部ではMac、Windows、Linuxでllama.cppのGGUFモデルを扱い、Apple SiliconのMacではMLXモデルも扱える。

つまりLM StudioはMLXやllama.cppと競合する一つのランタイムというより、それらを実行バックエンドとして選択、管理するフロントエンドみたいなものかもしれない。

最初にローカルLLMを試す、量子化違いのモデルを切り替える、チャットで答えの傾向を見るといった用途では扱いやすい。

OpenAI互換APIも出せるので、LM Studioの画面以外からモデルを呼ぶこともできる。

Appleの公式サイトでもLM Studioの画面が紹介されている。


oMLX

oMLXはApple Silicon上でMLXモデルを動かすための推論サーバーである。

LM Studioがllama.cppとMLXを適宜切り替えてくれるのに対してこいつはMLX専門。

複数リクエストをまとめて処理するContinuous Batching、複数モデルのロードと追い出し、OpenAI・Anthropic互換API、管理画面など、モデルを継続的にサービスとして使うための機能を持つ。

特徴的なのがKVキャッシュをRAMとSSDに保持する仕組みである。

これとは別にリクエスト間で共通するPrefixのキャッシュを共有・再利用する仕組みも持つ。

長い会話やコーディングエージェントで同じ長い文脈を何度もPrefillし直す待ち時間を減らす方向に作られている。

LM Studioがモデル探しから対話までをまとめたデスクトップアプリだとすれば、oMLXはMacをローカルLLMサーバーとして運用することに寄ったソフトウェアである。

メニューバーアプリと管理画面もあるが真価が出るのはコーディングエージェントや別のチャットUIからAPI経由で何度も呼ぶ時だと思う。

互換APIがあることと、すべてのクライアントで完全に同じように動くことは別である。

Thinkingやツール呼び出しは、モデル、チャットテンプレート、サーバー、接続先のハーネスが同じ形式を理解できて初めて成立する。

自分のM5 Max・128GBの環境で使った範囲では、oMLXの方がLM Studioより少し速く感じることがあった。モデルや設定をそろえて計測したベンチマークではなく、使ってみた時の体感差である。


ハーネスとは何か

ハーネスという言葉はランタイムほど厳密な(言葉の)用法が固まっていない。

そのためここでは特にエージェントハーネスの意味で使う。

ハーネスはモデルに会話の履歴、指示、ファイル、ツール、実行結果を渡して次に何をさせるかを管理する外枠のことである。

チャットUIがプロンプトと回答を往復させるだけなのに対し、コーディングエージェントはファイルを読み、コードを書き、コマンドを実行し、その結果を見て修正するというループを管理する。

モデルは次に何をするかを出力するがその出力を本当にツールとして実行し結果をモデルへ戻すのはハーネス側の仕事である。

同じモデルとランタイムを使っても、ハーネスが違えば体験はかなり変わる。

チャットでは賢く見えたモデルがコーディングエージェントではうまく動かないこともある。

逆に、モデル単体では少し弱くても、ハーネスが仕事を小さく分け、必要な情報だけを渡せば実用に足ることもある。

ローカルLLMではモデルの性能だけでなくモデルとハーネスの相性も見る必要がある。

有名な例だとClaude CodeとCodexはどちらも同じ種類のコーディングのためのハーネスである。

自分が両方を使った範囲ではClaude Codeの方が圧倒的に完成度が高いと感じた。


結局どれを選ぶか

したいこと組み合わせの考え方
まずローカルLLMと会話してみたいLM Studioでモデルの検索、ダウンロード、実行までまとめて行う
GGUFを細かく設定して動かしたいllama.cppを直接使うか、LM Studioからllama.cppランタイムを使う
MacでMLXモデルを直接試したいMLX LMのCLIやPython APIを使う
Macを常時使えるローカルLLMサーバーにしたいoMLXからMLXモデルをAPIとして公開する
コーディングエージェントから使いたいLM Studio、oMLX、llama-serverなどでAPIを出し、その上にハーネスを接続する

結論!!!

最初はLM Studioだけで十分。

そこでモデル、量子化、コンテキスト長の感覚をつかみ、もっと細かく触りたくなったらMLX LMやllama.cppを直接動かすのが良さそう。

更なるスピードが欲しいとかローカルLLMを別のアプリから日常的に使いたくなったらoMLXやllama-serverでAPIを出す。順番としてはそんな感じで十分楽しめる(はず)

次回

次は実際にモデルを動かしてみた話を書くつもり。

ローカルLLMという世界

  1. #1:手元で動くAI
  2. #2:基本編
  3. #3:Macの選び方
  4. #4:ランタイムとハーネス(この記事)
  5. #5:モデルを使ってみた(公開準備中)

参考資料