11
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Apple SiliconでAIやっている人に朗報です。vllm-mlxが凄い。

Posted at

 最近インパクトの大きいApple Silicon向けフレームワークが出現しました。「vllm-mlx」です。

 一言で言うとvllmライクなインターフェースをApple Silicon向けに提供するもので、MacのGPU(Metal/MPS)アクセラレーションによるテキスト、画像、ビデオ、オーディオに対応してます。既存のmlx,mlx-lm,mlx-vlm,mlx-audioを全てvllmライクなインターフェース対応にします。今回はこのvllm-mlxの使い方を紹介します。

1. vllm-mlxの概要

 特長:
・マルチモーダル - テキスト、画像、動画、音声を1つのプラットフォームで実現
・Apple Silicon (M1、M2、M3、M4) によるネイティブGPUアクセラレーション
・ネイティブTTS音声 - スペイン語、フランス語、中国語、日本語 + 5言語
・OpenAI API互換 - OpenAIクライアントの代替として利用可能
・MCPツール呼び出し - モデルコンテキストプロトコルを介して外部ツールと連携
ページングKVキャッシュ - プレフィックス共有によるメモリ効率の高いキャッシュ
・連続バッチ処理 - 複数の同時ユーザーに対応できる高スループット
・原則、HuggingFace_hubのmlx-communityのrepo等にアップされているmlxに変換済み量子化モデルは使える

主な利用形態:
① 各mlxモデルをvllmライクにローカルサーバーとして起動し、OpenAI API互換で利用。更にvllm並の同時接続が可能なので、プロダクトレベルのクラウドLLMとしての利用も視野に入る(今後検証予定)。
② pythonコード内でmlx-lmやmlx-vlm等のラッパーとして汎用的にモデルをハンドリング。単純にmlx-xxの使い分けが不要になり、更なる高速処理・省メモリが可能になる。これは単なるラッパーでは無く、vllmと同じPaged KV Cache Architectureを採用しており、これにより処理スピードは1.14倍速く、メモリは80%に節約できる。

 現時点「vllm」はMetal GPU(MPS)未対応で、Macの対応はCPUのみ(experimental support)となっており、vllmのcommunityベースのvllm-metalというvllm用のpulginは存在しますが、vllm + vllm-metal pluginで安定した運用が可能かは不明です(知見をお持ちの方は是非教えて下さい)。

2. vllm-mlxの使い方

 基本的な使い方はvllmやOllamaに似ているのですが、サーバを起動してからクライアントでAPIにアクセスして使用します。vllm-mlxのインストール及びサーバーの起動は下記の通りです。モデルのrepo名(下記ではmlx-community/Llama-3.2-3B-Instruct-4bit)は、/path/to/your_local_modelでローカルに存在するモデルも指定可能です。またモデル名(下記例ではLlama-3.2-3B-Instruct-4bit)に"VL", "Vision", "mllm"等が含まれる場合は自動的にマルチモーダルのモデルとして起動されます。
 また、サーバーを起動せずに直接モデルを読み込む事も可能なので、本章後半に使い方を紹介します。

### インストール
git clone https://github.com/waybarrios/vllm-mlx.git
cd vllm-mlx
<<仮想環境をpython -m venv myenv 等で作り下記は仮想環境下で実行されることをお勧めします>>
pip install -e .

### サーバー起動
# シンプルモード(単一ユーザ, 最大スループット)
vllm-mlx serve mlx-community/Llama-3.2-3B-Instruct-4bit --port 8000

# 継続的バッチ処理 (複数同時接続ユーザ)
vllm-mlx serve mlx-community/Llama-3.2-3B-Instruct-4bit --port 8000 --continuous-batching

# APIキー認証を行う場合
vllm-mlx serve mlx-community/Llama-3.2-3B-Instruct-4bit --port 8000 --api-key your-secret-key

# ページキャッシュでメモリを節約する場合
vllm-mlx serve mlx-community/Llama-3.2-3B-Instruct-4bit --port 8000 --continuous-batching --use-paged-cache

 クライアント側のテストは、下記コマンドで予め用意されているgradioのチャットWebアプリを立ち上げるのが早くて簡単です。但し、vllm-mlx-chatはapi-key認証には対応していないようです。

vllm-mlx-chat --server-url http://localhost:8000

 次のように、vllm-mlx-chatから直接モデルを読み込んでgradioのチャットWebアプリを立ち上げることも可能です。

# マルチモーダル チャット (text + images + video)
vllm-mlx-chat --model mlx-community/Qwen3-VL-4B-Instruct-3bit

# テキスト チャット
vllm-mlx-chat --model mlx-community/Llama-3.2-3B-Instruct-4bit --text-only

 vllm-mlxのrepo内のexamplesのフォルダ内に他のサンプルコードも色々あるので、興味ある方は試してみて下さい。

 ちなみに一番利用する機会が多いと想定されるOpenAI API互換でのアクセスは、下記のようになります。

openai_api.py

### /v1/chat/completionsのケース

from openai import OpenAI

client = OpenAI(base_url="http://localhost:8000/v1", api_key="<your-secret-key>")

# Non-streaming
response = client.chat.completions.create(
    model="default",
    messages=[{"role": "user", "content": "Hello!"}],
    max_tokens=100
)

# Streaming
stream = client.chat.completions.create(
    model="default",
    messages=[{"role": "user", "content": "Tell me a story"}],
    stream=True
)
for chunk in stream:
    if chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="")

### /v1/completionsのケースは上記responseを下記に置き換える
#response = client.completions.create(
#    model="default",
#    prompt="The capital of France is",
#    max_tokens=50
#)

 この場合はvllm-mlxのserverを起動する際に設定した"--api-key"で認証可能になるため、クラウドLLMをリモートで使う場合は必須と思われます。この"--api-key"の認証機能が使えるかどうかはクライアント側の設定次第ですが、AIエージェントアプリ等の殆どがOpenAI API互換を利用できるため、vllm-mlxサーバーの連続バッチ処理と合わせて使う用途は広いので有効な方法ではないかと思われます。

 次はサーバーを起動せずに直接モデルを読み込んでvllm-mlxを利用するユースケースを紹介します。vllm-mlxではPython APIをが用意されており、mlx-lmやmlx-vlmを使うのと同じ要領で使うことも出来ます。 これにより言語モデルとマルチモーダルモデルをある程度統一的に扱うことも可能になります。

python_api.py

### 言語モデルの場合
from vllm_mlx.models import MLXLanguageModel

# モデルのロード
model = MLXLanguageModel("mlx-community/Llama-3.2-3B-Instruct-4bit")
model.load()

# テキスト生成
output = model.generate("What is the capital of France?", max_tokens=100)
print(output.text)

# ストリーミング推論
for chunk in model.stream_generate("Tell me a story about a robot"):
    print(chunk.text, end="", flush=True)

# チャット推論
messages = [
    {"role": "system", "content": "You are a helpful assistant."},
    {"role": "user", "content": "Hello, who are you?"}
]
response = model.chat(messages)
print(response.text)


### マルチモーダルモデル
from vllm_mlx.models import MLXMultimodalLM

# モデルのロード
mllm = MLXMultimodalLM("mlx-community/Qwen3-VL-4B-Instruct-3bit")
mllm.load()

# 画像の説明
description = mllm.describe_image("photo.jpg")
print(description)

# Q&A形式
answer = mllm.answer_about_image("photo.jpg", "What color is the car?")
print(answer)

# 複数画像の推論
output = mllm.generate(
    prompt="Compare these two images",
    images=["image1.jpg", "image2.jpg"]
)
print(output.text)

 上記以外にもビデオやオーディオの扱い等も可能です。

3. まとめと今後の展開について

 今回は「vllm-mlx」の紹介をさせてもらいました。これまでもOllamaやvllmやLMStudio等をApple Silicon Macで使用してAIの開発をされてきた方は多いと思いますが、Metal GPUの性能を最大限引き出すvllm-mlxの出現で従来のフレームワークを発展的に統合出来る可能性も出てきたのではないかと考えます。またMLXの従来のフレームワークであるmlx-lm/mlx-vlmを継承しつつ、更に高パフォーマス(高速且つ省メモリ)化出来るのも嬉しいですよね。Ollama等に比べて他のAI基盤との連携のカバー範囲はまだ限られていますが、現状の対応可能範囲(OpenAI API互換クラウドLLM・Python APIでのローカル処理)でも十分利用する価値があるのではないかと考えます。
 今後はAIエージェントのAgonoや、コード生成・支援のOpenCodeや、各種AI-OSINTツールにvllm-mlxを連携させ、使い勝手とパフォーマンスを検証するとともに、プロダクトレベルのクラウドLLMとして利用できるかどうかを、連続バッチ処理を含めて検証して行きたいと思います。

11
13
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?