2024年12月14日
こんにちは、AI/BI部のK.です。
*今回記事では、概念については詳しく説明せず、簡単に説明します。
この記事は非力なパソコンでもLLMを使用できるようにllama.cppというLLMを紹介したいことに焦点を当てます。
Llama.cppプロジェクトは、元々は大規模言語モデル「Llama」をC++で効率的に実行するために開始されたオープンソースプロジェクトです。
最初のLlamaから始まっているので、大分年季が入っているプロジェクトですが、最新の更新日付が常に更新され続ける程、未だに活発に開発が続けられている人気プロジェクトです。
プロジェクトURL:ggerganov/llama.cpp – Github
また、llama.cppは、Llamaモデルを最大限に活用するために設計されたライブラリであり、特にリソース制約のある環境(低スペックのマシンやGPU非搭載のマシン)でも動作するよう最適化されています。
その最適化の手段の一つとして、モデルの量子化にも対応しており、推論時の計算コストを大幅に削減することが可能です。
このような特性により、llama.cppは幅広い用途で利用されています。
llama.cppは、リソース効率、柔軟性、互換性を兼ね備えた、次世代の軽量言語モデル推論ライブラリです。
量子化は、大規模言語モデル(LLM)の重みとアクティベーション値を高精度データ(FP32やFP16)から低精度データ(INT8やINT4)に変換する手法です。
これにより、計算負荷が軽減され、推論速度が向上しますが、精度が若干低下することがあります。
この図は、32ビットの浮動小数点数(fp32)を4ビットの整数(int4)に量子化する方法を示しています。
まず、図1-1では単純にfp32の範囲を-8から7の範囲にスケーリングしていますが、情報量が十分に活用されていません。
そこで図1-2では、unsigned 4bit(uint4)を使うことで、0から15の範囲に最適にスケーリングしています。これにより4bitの表現力を最大限に活用できます。
さらに図1-3では、データを複数のブロックに分割し、各ブロックごとにスケーリングを行うことで、より細かな量子化が可能になります。
super-blockの最小値を基準に、各blockをスケーリングするというアプローチです。
これにより、データの分布に応じて柔軟に4bitの範囲を設定でき、精度を最大限に引き上げることができます。
GGML ではこの手法を採用しており、情報量の少ない型ほど細かなブロック分割を行うことで、効率的な量子化を実現しています。
GGUFとGGMLは、特にGPT(Generative Pre-trained Transformer)などの言語モデルの推論に使用されるファイルフォーマットです。
GGML や GGUF のプレフィクス「GG」は作者(ジョージ・ゲルガノフ)のイニシャルです。
the "GG" refers to the initials of its originator (Georgi Gerganov).
https://github.com/rustformers/llm/blob/main/crates/ggml/README.md</a >
Terminalを開きます。
mkdir -p llama.cpp/models
cd llama.cpp
今回使うモデルはollamaライブラリーであるMistral-7B
です。 Mistral-7B
はMistral AI社が開発したLLMです。
Terminalに次のコマンドを実行する:
digest=$(curl -fsSL \
-H 'Accept: application/vnd.docker.distribution.manifest.v2+json' \
"https://registry.ollama.ai/v2/library/mistral/manifests/7b" \
| jq -r '.layers[] | select(.mediaType == "application/vnd.ollama.image.model") | .digest')
以下のようにSHA256 Digestの結果が出てくる:
次に、SHA256 Digestでモデルをダウンロードする:
curl -L -H 'Accept: application/vnd.ollama.image.model' \
"https://registry.ollama.ai/v2/library/mistral/blobs/$digest" \
-o "./models/mistral-7b.gguf"
そして、モデルをダウンロード始まります。ダウンロード終わったら、次のようです:
同じllama.cpp
フォルダーにdocker-compose.yml
ファイルを作成します:
services:
llama-cpp:
container_name: llama-cpp
image: ghcr.io/ggerganov/llama.cpp:full
ports:
- "8020:8080"
volumes:
- ./models:/models
stdin_open: true
tty: true
restart: unless-stopped
command: >
--server
--port 8080
--host 0.0.0.0
--model /models/mistral-7b.gguf
--threads 12
--ctx-size 4096
そして:
docker compose up
次のような画面が表示されます
htop
で見ると、メモリーにモデル読み込んだことを確認できます
そして、別のTerminalを開いて:
curl --request POST \
--url http://127.0.0.1:8020/completion \
--header "Content-Type: application/json" \
--data '{"prompt": "User:日本語で回答してください。今日天気が良いから、散歩しま しょう! Assistant: ","n_predict": 128}' | \
jq .
そして、結果が出てくる
Terminal以外、llama.cpp既存Web UIも使えます。 ブラウザーから、PCのロカールIPまたはlocalhostを開くと:
これを試すと:
htop
を見ると、CPUが全力を出している
Chat
のAPIを選択しているので、返事内容が先と違います:
赤枠にサンプリング速度が表示されます。
本記事では、次世代の大規模言語モデル(LLM)ライブラリであるLlama.cppについて紹介しました。
Llama.cppの主な特徴は以下の通りです:
さらに、Llama.cppの中核をなすGGUF量子化モデルについても解説しました。GGUF形式は、モデルの効率的な保存と配布を実現する次世代のフォーマットです。
本記事を通して、Llama.cppの機能と特徴、そして量子化モデルの仕組みを理解していただけたと思います。この知識をもとに、さまざまな環境でLLMを活用していくことができるでしょう。
Llama.cppは、AIとLLMの可能性を最大限に引き出す、優れたツールといえます。ぜひ活用してみてください。