ひさしぶり(?)のニッチ記事。
はじめに
LLMの推論エンジンであるExLlamaV3がついにv1.0.0以上となり正式リリースされました。
v1.0.0では新しいattentionカーネルの導入やAmpere世代GPU(A10など)での大幅な性能向上が実現されており、個人的にはこれは試さずにはいられません。
なお、ローカルLLM推論エンジンとしてはllama.cppやvLLM、SGLangなどもありますが、ExLlamaV3は低bitでも精度が落ちづらい独自のEXL3量子化形式に特化しており、MTPやDFlashといったSpeculative Decodingが標準で組み込まれている点が特徴的です。v1.0ではほとんどのモデルで複数GPUを使ったTensor Parallelism (TP)にも対応しています。
そこで今回は、Databricks Free EditionのServerless GPU環境(A10)を使ってExLlamaV3 v1.1.0を動かしてみました。
ExLlamaV3とは
ExLlamaV3は、EXL3形式で量子化されたLLMを高速に推論するためのPythonライブラリです。
v1.0での主な特徴は以下の通りです:
- 高速推論: 独自の最適化カーネルとオンラインキャッシュ量子化により、同クラスの推論エンジンと比較して高速
- EXL3対応: 独自の量子化形式EXL3に対応し、精度を保ちながらメモリ効率を向上
- Speculative Decoding対応: MTP(Multi-Token Prediction)やDFlash(Draft Model Flash)による推論高速化
- ストリーミング生成: トークン単位でのリアルタイム出力
- Ampere世代での性能向上: v1.0.0で新しいGEMM/GEMVカーネルが導入され、A10などのAmpere GPUでの性能が大幅に改善
なお、v1.0.0ではflash-attention-2やxformersへの依存が削除され、独自実装に移行しています。
v1.0.0は2026年7月14日、v1.1.0は2026年7月18日にリリースされました。v1.0.0で大規模なアーキテクチャ変更とパフォーマンス改善が行われ、v1.1.0ではTPモードの最適化やバグ修正が追加されています。
ExLlamaV3はまだ比較的新しいバージョンです。今後もAPIが変更される可能性があります。
検証環境
今回は以下の環境で検証しました:
- プラットフォーム: Databricks Free Edition
- コンピュート: Serverless GPU (A10 1基)
- Python: 3.12
- CUDA: 12.8
- PyTorch: 2.9.0
- ExLlamaV3: 1.1.0
- モデル: Qwen3.6-27B-exl3 (3.50bpw) および Qwen3.6-27B-DFlash-exl3(3.50bpw)
Databricks Free Editionでは、Serverless GPUが無料で利用できるため、手軽にGPU推論を試すことができます。A10はAmpere世代のGPUで、v1.0.0でのパフォーマンス改善の恩恵を受けやすい環境です。
今回作るもの
ExLlamaV3を使って、以下の3つのモードで推論を実行できるノートブックを作成します:
- baseline: 通常の自己回帰デコードのみ、投機的デコードなし。
- mtp: Multi-Token Predictionを投機的デコードに利用
- dflash: DFlash(ブロック拡散型ドラフトモデル)を投機的デコードに利用
Step0. ライブラリのインストール
まず、ExLlamaV3と関連ライブラリをインストールします。
%uv pip install https://github.com/turboderp-org/exllamav3/releases/download/v1.1.0/exllamav3-1.1.0+cu128.torch2.9.0-cp312-cp312-linux_x86_64.whl transformers>=5.12.1
%restart_python
ExLlamaV3はPyPIからもインストールできますが、今回はCUDA 12.8とPyTorch 2.9.0に対応した事前構築バイナリ(wheelファイル)を使用します。これによりコンパイル時間を省略し、すぐに使い始めることができます。
インストール後、Pythonカーネルを再起動して変更を反映させます。
Step1. モデルパスの設定とウィジェット
モデルのパスや推論モードを切り替えられるように、Databricksのウィジェットを使って設定します。
# モデルのパス(EXL3形式の量子化モデル)
dbutils.widgets.text("model_directory", "")
model_directory = dbutils.widgets.get("model_directory")
dbutils.widgets.dropdown("mode", "baseline", ["baseline", "mtp", "dflash"])
mode = dbutils.widgets.get("mode")
dbutils.widgets.text("dflash_directory", "")
dflash_directory = dbutils.widgets.get("dflash_directory")
print(f"モデルパス: {model_directory}")
print(f"モード: {mode}")
ウィジェットで以下を設定できるようにしました:
- model_directory: メインモデルのパス(HuggingFace IDまたはローカルパス)
- mode: 推論モード(baseline/mtp/dflash)
- dflash_directory: DFlashモード用のドラフトモデルのパス
今回はベースモデルとしてにあらかじめダウンロードしておいた以下のQwen3.6-27Bモデルを使用します。
DFlashモデルはこちら。
Step2. モデルの読み込み
次に、選択したモードに応じてモデルを読み込みます。
モデル読み込みコード(長いので折り畳み)
from exllamav3 import (
Model,
Config,
Cache,
Tokenizer,
Generator,
Job,
Sampler,
CacheLayer_fp16,
CacheLayer_quant,
)
from exllamav3.util import Timer
CACHE_SIZE = 4096 * 4
def load_model(mode: str):
# モデル設定の読み込み
config = Config.from_directory(model_directory)
print(f"Loading model: {model_directory}...")
# モデル、キャッシュ、トークナイザーの初期化
model = Model.from_config(config)
draft_model = draft_cache = None
try:
if mode == "mtp":
# MTP: 本体と同じ config を component="mtp" で読む
draft_model = Model.from_config(config, component="mtp")
draft_cache = Cache(
draft_model,
max_num_tokens=CACHE_SIZE,
layer_type=CacheLayer_quant,
k_bits=4,
v_bits=4,
)
draft_model.load(progressbar=True)
print("✓ ドラフトモデルのロードが完了しました")
elif mode == "dflash":
# DFlash: 別チェックポイントを通常ドラフトとして読む
draft_config = Config.from_directory(dflash_directory)
draft_model = Model.from_config(draft_config)
draft_cache = Cache(
draft_model,
max_num_tokens=CACHE_SIZE,
max_batch_size=1,
layer_type=CacheLayer_quant,
k_bits=4,
v_bits=4,
)
draft_model.load(progressbar=True)
print("✓ DFlashドラフトモデルのロードが完了しました")
max_history = draft_model.caps.get("default_draft_size") if draft_model else 0
cache = Cache(
model,
max_num_tokens=CACHE_SIZE,
max_history=max_history,
max_batch_size=1,
layer_type=CacheLayer_quant,
k_bits=4,
v_bits=4,
)
model.load(progressbar=True)
print("✓ モデルのロードが完了しました")
print("Loading tokenizer...")
tokenizer = Tokenizer.from_config(config)
print("✓ tokenizerのロードが完了しました")
return model, cache, tokenizer, draft_model, draft_cache
except Exception as e:
print(f"Error: {e}")
if draft_model:
draft_model.unload()
if model:
model.unload()
model, cache, tokenizer, draft_model, draft_cache = load_model(mode)
このコードのポイント:
- baselineモード: ドラフトモデルなしで通常の推論
-
mtpモード: 同じモデルの
component="mtp"を指定してMTPコンポーネントを読み込む - dflashモード: 別のドラフトモデルを読み込んでSpeculative Decodingを実行
-
KVキャッシュの量子化:
CacheLayer_quantで4bitに量子化してメモリを節約(v1.0.0の新しいattentionカーネルによりオンライン量子化が可能)
Step3. 推論実行
チャットテンプレートを利用するために、transformersトークナイザーを準備します。
from transformers import AutoTokenizer
# HF Tokenizerの読み込み
hf_tokenizer = AutoTokenizer.from_pretrained(model_directory)
次に、Generator を初期化して以下のコードで推論を実行します:
推論実行コード(長いので折り畳み)
from exllamav3 import ComboSampler, GreedySampler, Job
from pprint import pprint
# 設定
max_batch_size = 1
max_chunk_size = 2048
max_new_tokens = 1000
sampler = ComboSampler(temperature=0.7, top_p=0.9)
system_prompt = "You are a kind AI assistant."
prompts = [
"Databricksとは何ですか?",
]
# Initialize the generator
generator = Generator(
model=model,
cache=cache,
tokenizer=tokenizer,
max_batch_size=max_batch_size,
max_chunk_size=max_chunk_size,
draft_model=draft_model,
draft_cache=draft_cache,
num_draft_tokens = None,
show_visualizer=False,
)
# Create jobs
jobs = []
for prompt in prompts:
fprompt = hf_tokenizer.apply_chat_template(
[
{"role": "system", "content": system_prompt},
{"role": "user", "content": prompt},
],
tokenize=False,
add_generation_prompt=True,
add_bos=True,
)
input_ids = tokenizer.encode(fprompt, encode_special_tokens=True)
job = Job(
input_ids=input_ids,
max_new_tokens=max_new_tokens,
stop_conditions=[tokenizer.eos_token_id, "<turn|>"],
sampler=sampler,
)
jobs.append(job)
# Enqueue all the jobs at once
generator.enqueue(jobs)
new_tokens = 0
prompt_tokens = 0
time_generate = 0.0
time_prefill = 0.0
response_store = []
while generator.num_remaining_jobs():
results = generator.iterate()
for r in results:
response_store.append(r)
text = r.get("text")
if text:
print(text, end="", flush=True)
if r.get("eos"):
prompt_tokens = r.get("prompt_tokens", 0)
new_tokens = r.get("new_tokens", 0)
time_generate = r.get("time_generate", 0.0)
time_prefill = r.get("time_prefill", 0.0)
break
speed_total = new_tokens / (time_generate + time_prefill)
print("\n\n")
print("Overall output: {:.2f} tokens/sec".format(speed_total))
print("Prompt tokens: {:d}".format(prompt_tokens))
print("New tokens: {:d}".format(new_tokens))
print("Token Generation time: {:.2f} sec".format(time_generate))
print("Prefill time: {:.2f} sec".format(time_prefill))
動作確認
「Databricksとは何ですか?」という質問で、mtpモードとdflashモードの両方で推論を実行し、内容と実行時間を確認してみました。
mtpモードでの実行結果:
Here's a thinking process:
1. **Understand User Query**: The user is asking "Databricksとは何ですか?" (What is Databricks?) in Japanese.
2. **Identify Key Concepts**:
- Databricks is a company/platform.
- It's known for its unified analytics platform.
- Built on Apache Spark.
- Focuses on data engineering, data science, machine learning, and AI.
- Cloud-native (AWS, Azure, GCP).
- Key features: Delta Lake, Unity Catalog, MLflow, collaborative notebooks, etc.
- Founded by creators of Apache Spark.
- Acquired by Microsoft in 2022 (though it operates independently).
3. **Structure the Response (in Japanese)**:
- Introduction/Definition
- Core Features/Technology
- Main Use Cases
- Cloud Support & Ecosystem
- Key Products/Components
- Summary/Conclusion
- Keep it clear, concise, and accurate.
4. **Draft the Response (Mental Refinement in Japanese)**:
Databricksは、データ分析・機械学習・AI開発を統合的に行うためのクラウドベースのプラットフォームです。Apache Sparkの創設者たちによって設立され、大規模なデータ処理とAI/MLワークロードを効率的に実行できるよう設計されています。
主な特徴:
- **統一されたプラットフォーム**: データエンジニアリング、データサイエンス、AI/MLを1つの環境で管理可能
- **Delta Lake**: ACIDトランザクションをサポートするオープンソースのデータレイクフォーマット
- **Unity Catalog**: データとAIリソースの統一されたガバナンス・セキュリティ管理
- **MLflow**: 機械学習ライフサイクル管理(実験追跡、モデル管理、デプロイ)
- **コラボレーション機能**: ノートブックベースでチーム開発が容易
- **マルチクラウド対応**: AWS、Azure、Google Cloudで利用可能
用途例:
- 大規模データのETL/データパイプライン構築
- 機械学習モデルのトレーニングとデプロイ
- ビジネスインテリジェンスやAIアプリケーションの開発
- データガバナンスとセキュリティの一元管理
Databricksは2022年にMicrosoftによって買収されましたが、独立した運営を続けており、エンタープライズ向けのデータ&AI基盤として世界中で広く採用されています。
必要に応じて、特定の機能や導入事例についてさらに詳しく説明できます。
5. **Self-Correction/Verification**:
- Accuracy: Databricks is indeed founded by Spark creators, cloud-native, supports Delta Lake, Unity Catalog, MLflow, multi-cloud, acquired by Microsoft in 2022. All correct.
- Language: Japanese is natural and professional.
- Structure: Clear, logical, covers definition, features, use cases, ecosystem, and current status.
- Tone: Helpful and informative.
- No overclaiming or outdated info. (Microsoft acquisition was Nov 2022, still independent operation - correct)
- Could add a note about open-source roots vs commercial platform, but not strictly necessary.
Everything looks solid. Ready to output.✅
</think>
**Databricks**は、大規模なデータ処理・分析・機械学習(ML)・AI開発を統合的に実行できる**クラウドベースのデータ&AIプラットフォーム**です。Apache Sparkの創設者たちによって設立され、エンタープライズ環境で「データとAIを1つの環境で管理する」ことを目指して設計されています。
### 🔑 主な特徴
| 機能 | 概要 |
|------|------|
| **統一されたワークスペース** | データエンジニアリング、データサイエンス、AI/MLを同じプラットフォームで実行・コラボレーション可能 |
| **Delta Lake** | ACIDトランザクション・スキーマ管理・タイムトラベルをサポートするオープンソースのデータレイクフォーマット |
| **Unity Catalog** | データ・モデル・ノートブックなどのリソースを一元管理し、アクセス制御・監査・データカタログを統合 |
| **MLflow** | 実験追跡・モデル管理・デプロイを標準化し、MLライフサイクルを効率化 |
| **コラボレーション環境** | Jupyterノートブック形式で複数人が同時に編集・レビュー・コードレビューが可能 |
| **マルチクラウド対応** | AWS、Microsoft Azure、Google Cloudのいずれでも同じ体験で利用可能 |
### 🎯
Overall output: 55.44 tokens/sec
Prompt tokens: 29
New tokens: 995
Token Generation time: 17.87 sec
Prefill time: 0.08 sec
dflashモードでの実行結果:
Here's a thinking process:
1. **Understand User Query**: The user is asking "Databricksとは何ですか?" (What is Databricks?) in Japanese.
...(省略)
Overall output: 48.87 tokens/sec
Prompt tokens: 29
New tokens: 984
Token Generation time: 20.05 sec
Prefill time: 0.08 sec
A10 GPU 1基で、mtpモードで約55 tokens/sec、dflashモードでも約49 tokens/secの速度が出ました。
今回試した内容だとMTPのほうが高速でToken Generationできました。
(VRAM消費量はどちらも14GB未満でした)
ちなみにbaseline(投機的デコードを使わない)であれば30 tokens/secぐらいでした。
個人的には、27Bクラスのモデルでこの速度が出るのは十分実用的だと思います。
どちらのSpeculative Decodingモードも通常の自己回帰デコードよりも高速に推論できるため、インタラクティブな用途にも使えそうです。
とはいえ、モデルサイズやプロンプト長によってはメモリが足りなくなる可能性もあるため、適切なモデルサイズの選択が重要になります。
まとめ
ExLlamaV3 v1.1.0をDatabricks Free Editionで動かしてLLMの推論を行ってみました。
個人的には、v1.0.0で実施された大規模なアーキテクチャ変更とパフォーマンス改善(新しいattentionカーネル、Ampere世代での性能向上など)により、依存関係も減って安定版として使いやすくなったと感じました。
MTPやDFlashといった高速化手法も簡単に試せる点も魅力的です。Databricks Free EditionのServerless GPUを使えば、無料でこうした最新のLLM推論技術を試せるのは良いですね。
とはいえ、ExLlamaV3の正式リリースがなされたばかりで、ドキュメントも発展途上なので、トラブルシューティングには少し苦労する場面もありそうです。
引き続き、ローカルLLM推論の選択肢の引出しを増やしていこうと思います。
参考文献