Local LLM に入門してみた
TL;DR
- ローカル LLM はクラウド上の LLM に比べてプライバシー保護や応答速度の面で優れている。
- モデルの量子化を行うことで、推論時間を短縮したり、スペックの高くないハードウェア上で動作させたりすることができる。
- LLM をローカルで簡単に動かすために様々なツールがあり、商業利用できるものとして Ollama がある。
クラウド LLM とローカル LLM の比較
ローカル LLM はクラウド上にホストされ、サービス提供されている LLM と比較して大きくプライバシーや即時応答性などの観点で利点がある。
プライバシー
サービス提供されている LLM では当然のことながら、サービス提供しているサーバーに情報を送る必要があるため、第三者への提供ができない機密性の高い個人情報や金融情報を渡すことはできない。ローカル LLM では自社のサーバー上でホストできるため、機密性の高い情報も扱うことができる。
こうした特性を利用して、医療情報をもとに医療診断をアシストしたり、金融情報から与信判断を提案するような利用が考えられる。
即時応答性
クラウド上にホストされたサービスを利用する際には基本的には同じリソースを他の利用者と共有して利用するため、利用状況によってはレスポンスが遅くなることがある。また、ネットワーク障害時には利用できなかったり、ネットワークによる遅延が生じたりする。一方、ローカル LLM ではそうした利用状況による遅延やネットワーク状況の影響を受けることはない。
このような特性を活かして、工場でのエッジコンピューティングや PC やスマートフォンのアシスタントのような利用が考えられる。iOS の Apple Intelligence や Windows の Copilot+PC がその例となる。
一覧
項目 | クラウド上の LLM | ローカル LLM | ローカル LLM の応用例 |
---|---|---|---|
コスト | サブスクリプションや使用量に応じた料金 | 初期投資(ハードウェア)と運用コストがかかる | 個人開発での PoC |
応答速度 | 高いが、ネットワーク遅延の影響を受ける | 非常に早い | エッジコンピューティング、PC やスマートフォン搭載 LLM |
推論速度 | 早い | モデル、ハードウェア依存 | |
回答精度 | モデル依存 | ||
スケーラビリティ | 高い | ハードウェアの性能やインフラ構成に依存 | - |
プライバシー | データが外部に送信されるためプライバシーリスクがある | データが外部に送信されないためプライバシー保護が強い | 機密データを扱う医療機関や金融機関の内部システム |
カスタマイズ性 | クラウド提供者の API に依存 | 自由度が高い | カスタマイズされた企業内部のチャットボットや専門性の高いナレッジシステム |
アップデート | 自動的に最新バージョンにアップデートされる | 手動でのアップデートが必要 | - |
手順
- 利用するモデルを探す。モデル名から用途やハードウェアに合ったモデルを選択する。
- 8B, 8x7B, … → パラメータ数
- GGUF, exl2, … → 量子化手法
- Q4_K_M, 5.0bpw, … → 量子化レベル
- MoE → Mixture of Experts Model: 一つの汎用 LLM ではなく Router と複数のエキスパートモデルから成る
- (ダウンロード)
- (必要に応じて) モデルを量子化
- 膨大なパラメータ数を持つ LLM を走らせるためにはそれなりのハードウェア性能を必要とする。手元の PC でもお手軽に走らせるために重みを量子化し、推論時間を短縮したり、必要なメモリを削減する。
- ダウンロード
- LLM を動かす
- (必要に応じて) ファインチューニング
ツール比較
ナイーブな方法として Transformers を利用する方法があるが、量子化や Web Server の構築などを簡単に行うツールがある。低レベルなものとして GGML モデルを動かす llama.cpp があり、それを利用する形で Ollama や LM Studio などがある。
アプリケーション開発という文脈では WebAPI や Python Library がサポートされており OSS である Ollama がおすすめである。
ツール | インターフェイス | 対応フォーマット | OpenAI API 互換性 Web API | 利用シーン |
---|---|---|---|---|
LM Studio | GUI | .gguf | ✅ | お手軽に Local で LLM を動かしてみたい時 |
Ollama | CLI, Library (ollama-python) | .gguf | ✅ | お手軽に Local で LLM を動かしてみたい、商用利用時(OSS) |
llama.cpp | CLI, Library | .gguf | ✅ | 量子化も自分で行いたい時(最新のモデルを試したい時) |
(Transformers) | Library | .safetensor , .gguf | ❌ |
llama.cpp
- C/C++ で LlaMA モデル (GGML) を量子化・推論するためのインターフェイス・実装。
- OpenAI API 互換性の web server を提供
-
.safetensor
フォーマットを良するためには自分で.gguf
に変換する必要があるが、huggingface のggml-org
スペース上で変換を行える。 - 後述する LM Studio や Ollama も内部では llama.cpp を利用している。
LM Studio
- モデルのダウンロード、管理、実行までを GUI で行う
- Huggingface のモデルを選択することができ、実行しているマシンのスペックで実行できるかどうかの目安を教えてくれる。
- OpenAI API 互換性の web server を提供
Ollama
- ollama のモデルレポジトリからモデルを選択する
- ollama-python という Python ライブラリや OpenAI API 互換性の web server を提供
- OSS (MIT License) のため、ライセンス上はプロダクション利用できる
ツールを使った実行手順
Ollama を使った手順を紹介する。
-
Ollama をインストール: https://ollama.com/
-
使いたいモデルを探す: https://ollama.com/library
-
.gguf
ファイルフォーマット
-
-
モデルをダウンロードする
ollama run <MODEL_NAME>
- ダウンロードが終わり次第インタラクティブモードに入るので、試してみる。
/bye
コマンドでインタラクティブモード終了。
❯ ollama run llama3.1
>>> Why is the sky blue?
The sky appears blue to our eyes because of a combination of factors, including:
1. **Scattering of light**: When sunlight enters Earth's atmosphere, it encounters tiny molecules of gases such as nitrogen and oxygen. These molecules scatter the light in
all directions, but they scatter shorter (blue) wavelengths more than longer (red) wavelengths. This is known as Rayleigh scattering.
2. **Absorption by water vapor and other gases**: Water vapor and other gases in the atmosphere absorb light at various wavelengths. The amount of absorption varies with
altitude and atmospheric conditions, which can affect the apparent color of the sky. However, for most conditions, this effect tends to make the sky appear slightly more blue.
3. **Reflection by aerosols**: Aerosols like dust particles, pollen, and pollution also scatter light. While they tend to scatter all wavelengths equally (Mie scattering),
their presence can make the sky appear a bit hazy or change its color depending on their size distribution and concentration. However, this effect usually is less pronounced
compared to Rayleigh scattering.
4. **Time of Day**: The apparent color of the sky changes throughout the day due to the position of the Sun relative to the observer's location. During sunrise and sunset, the
light travels through more of the atmosphere than at other times of day, which means more of the shorter wavelengths (like blue) are scattered out before reaching our eyes.
This makes sunsets often appear red or orange.
5. **Weather Conditions**: The presence of clouds can affect the apparent color of the sky. Clouds can block sunlight and scatter it in different ways, sometimes making the
sky appear white or light gray if they are thick and dense enough. However, when sunlight passes through gaps in clouds, it can create a range of colors, from pastel shades to
more vivid hues depending on the cloud's characteristics.
6. **Atmospheric Dust**: Tiny particles in the air due to dust storms, volcanic eruptions, or pollution can also change how light interacts with our atmosphere. They scatter
light differently than water vapor and gases, which can lead to a reddish tint if there are more large particles (like those from big dust storms) or a blue-ish hue if there
are smaller particles.
In summary, the sky's appearance is influenced by the scattering of sunlight, absorption by atmospheric gases and aerosols, the effect of time of day on this interaction,
weather conditions like clouds, and the presence of atmospheric dust.
- バックグラウンドでは ollama が動いているので
http://localhost:11434
に対して curl でリクエストを投げたり、openai の python SDK でリクエストを投げたりできる。
❯ curl http://localhost:11434/v1/chat/completions \
-H "content-type: application/json" \
-d '{
"model": "llama3.1",
"messages": [
{"role": "system", "content": "You are a helpful assistant"},
{"role": "user", "content": "Why is the sky blue?"}
],
"stream": false
}'
| jq
{
"id": "chatcmpl-169",
"object": "chat.completion",
"created": 1722865383,
"model": "llama3.1",
"system_fingerprint": "fp_ollama",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "The sky appears blue to us because of a thing called Rayleigh scattering, which I'd be happy to explain in simple terms.\n\nWhen sunlight enters Earth's atmosphere, it hits tiny molecules of gases like nitrogen and oxygen. These molecules scatter the light in all directions, but they don't scatter it evenly. The shorter (blue) wavelengths are scattered more than the longer (red) wavelengths, a process called Rayleigh scattering.\n\nAs a result, our eyes perceive the blue light as being more intense than the other colors, making the sky appear blue! This effect is most pronounced during the daytime when the sun is overhead, and it's why we see such a beautiful blue sky.\n\nWould you like to know more about this or is there something else I can help with?"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 35,
"completion_tokens": 155,
"total_tokens": 190
}
}
from openai import OpenAI
client = OpenAI(
base_url='http://localhost:11434/v1/',
## required but ignored
api_key='ollama',
)
chat_completion = client.chat.completions.create(
messages=[
{
'role': 'user',
'content': 'Say this is a test',
}
],
model='llama3',
)
response = client.chat.completions.create(
model="llava",
messages=[
{
"role": "user",
"content": [
{"type": "text", "text": "What's in this image?"},
{
"type": "image_url",
"image_url": "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",
},
],
}
],
max_tokens=300,
)
completion = client.completions.create(
model="llama3",
prompt="Say this is a test",
)
list_completion = client.models.list()
model = client.models.retrieve("llama3")
embeddings = client.embeddings.create(
model="all-minilm",
input=["why is the sky blue?", "why is the grass green?"],
)
参考: 量子化
膨大なパラメータ数を持つ LLM を走らせるためにはそれなりのハードウェア性能を必要とする。手元の PC でもお手軽に走らせたり、推論時間を短縮したりするためにトレーニング後のモデルの重みを量子化し、軽量化する。
一般的には元のモデルは 16bit の浮動小数であることが多いが、量子化により、4bit や 8bit などにされることが多い。
手法
ノート PC やスマートフォンのように軽量で CPU のみでも動作するような量子化を行う場合は GGML の後継である GGUF がよく用いられる。
GPTQ は 2024 年 8 月現在、他手法 (GGUF, AWQ, EXL2) よりも精度があまりよくないとされている。
手法 | 特徴 | ハードウェア用件 |
---|---|---|
GGUF | GGML の後継 | CPU のみでも動作する |
AWQ | 顕著な重みをキープし、マルチモーダルで良い性能 | GPU 必須 |
EXL2 | 重みごとに量子化レベルを変化させ、量子化を早くする | GPU 必須 |
GPTQ | transformer に統合されている、他手法の後塵を拝している | GPU 必須 |
GGUF (GPT-Generated Unified Format)
- GGML (Group-wise Gradient-based Mix-Bit Low-rank)の後継
- CPU のみ、または Apple Silicon に特化
- 高速化のために一部レイヤーを GPU に移せる
-
.gguf
という独自のファイルフォーマットがあり、llama.cpp でサポートされている
AWQ (Activation-Aware Weight Quantization)
- 顕著な重みをキープ
- インストラクションとマルチモーダルで良い性能
- 様々なプラットフォームに統合されている
EXL2 (ExLlamaV2)
- GPU 特化
- モデルの中で様々な bit による量子化を行い、平均が 2-8bit となるようにしている
GPTQ (Generalized Post-Training Quantization)
- 様々な GPU に特化
- 柔軟に量子化レベルを設定できる
- transformers に統合されている
参考資料
ファイルフォーマット
Safetensors
- 安全なファイルフォーマット(モデルが任意のコードを実行できない、など)
- huggingface ではデファクトスタンダード
- 複数ファイルになりがち
GGUF
- 1 つのバイナリファイル
- 様々な量子化をサポート
- CPU のみでも動作する
Discussion