推論モデルプロバイダーを用意する

推論モデルにはhttps://huggingface.co/elyza/Llama-3-ELYZA-JP-8B-GGUFを、 推論モデルプロバイダーにはollamaを用いる。 ollamaはLinuxをはじめとした各プラットフォーム用バイナリが配布されているので、 まずはそれをてきとうなディレクトリに展開しておく。

ollamaサーバーの起動

サーバーの起動はシンプルに、ollama serveとするだけである。 必要に応じて、環境変数でパラメータを指定する。

OLLAMA_FLASH_ATTENTION=1 \
OLLAMA_DEBUG=1 \
OLLAMA_KEEP_ALIVE=-1 \
./bin/ollama serve

モデルのダウンロードと実行

モデルダウンロードの実行もシンプルで、ollama run モデル名とするだけである。 今回は、hf.co/elyza/Llama-3-ELYZA-JP-8B-GGUFを用いてみる。

% ./bin/ollama run hf.co/elyza/Llama-3-ELYZA-JP-8B-GGUF:latest

実行するとプロンプトが表示されるので、そこにてきとうな質問を入力し、動作するか確認する。

>>> 銀山温泉ってどんなところ?
銀山温泉は、山形県尾花沢市にある温泉街です。江戸時代に始まった銀の採掘で栄えたこの地には、昔ながらの建物や情緒ある通りが残り、風情あふれる温泉街を形成しています。

特徴:

1. 歴史と文化: 銀山温泉は1800年代初めに銀鉱山として開業し、明治時代には最盛期を迎えました。鉱山跡や当時の建物が残り、歴史と文化を感じることができます。
2. 温泉: 湯量豊富な源泉は17本あり、泉質も異なるため、複数の温泉を楽しむことが可能です。湯元楼、新鉱泉、銀山荘など、多くの温泉宿が点在しています。
3. 美しい自然: 温泉街は標高800mに位置し、四季折々の美しい景色を堪能できます。周囲は山や森に囲まれ、トレッキングや登山などのアクティビティも人気です。

おすすめの過ごし方:

1. 温泉巡り: 多くの温泉宿で源泉かけ流しの湯を楽しむことができます。
2. 歴史散策: 鉱山跡、古い建物、資料館などを訪れ、この地の歴史と文化に触れることができます。
3. トレッキングや登山: 自然豊かな周囲でトレッキングや登山を楽しむことができます。

銀山温泉は、自然、歴史、文化が三位一体となった魅力的な温泉街です。のんびりと過ごす休日には最適な場所です。

>>>

モデルの情報を確認

ollama runには、次のようなコマンドが用意されている。

>>> /?
Available Commands:
  /set            Set session variables
  /show           Show model information
  /load <model>   Load a session or model
  /save <model>   Save your current session
  /clear          Clear session context
  /bye            Exit
  /?, /help       Help for a command
  /? shortcuts    Help for keyboard shortcuts

Use """ to begin a multi-line message.

モデルの概要を確認したい時は、/show infoを実行する。

>>> /show info
  Model
    architecture        llama
    parameters          8.0B
    context length      8192
    embedding length    4096
    quantization        unknown

  Parameters
    stop    "<|im_start|>"
    stop    "<|im_end|>"

  License
    META LLAMA 3 COMMUNITY LICENSE AGREEMENT
    Meta Llama 3 Version Release Date: April 18, 2024

ollamaのModelfileを得たい時は、/show modelfileとする。

>>> /show modelfile
# Modelfile generated by "ollama show"
# To build a new Modelfile based on this, replace FROM with:
# FROM hf.co/elyza/Llama-3-ELYZA-JP-8B-GGUF:latest

FROM /home/gloria/.ollama/models/blobs/sha256-91553c45080b11d95be21bb67961c9a5d2ed7556275423efaaad6df54ba9beae
TEMPLATE "<|im_start|>system
<|im_end|>
<|im_start|>user
<|im_end|>
<|im_start|>assistant
<|im_end|>
"
PARAMETER stop <|im_start|>
PARAMETER stop <|im_end|>
LICENSE "META LLAMA 3 COMMUNITY LICENSE AGREEMENT
..."

なんらかのカスタマイズを加えたい時は、これをベースにモデルを登録するとよさそうである。 その際のFROMは、モデルの元のパス(今回はhf.co/elyza/Llama-3-ELYZA-JP-8B-GGUF:latest)に置き換える。

その他の便利コマンド

ダウンロード済みモデルの一覧を参照

% ./bin/ollama ls
NAME                                           ID              SIZE      MODIFIED
hf.co/elyza/Llama-3-ELYZA-JP-8B-GGUF:latest    12b66520839d    4.9 GB    55 minutes ago

メモリ上にロード済みのモデル一覧を参照

GPUが足りない時は、CPUに自動的に振り分けられるが、ollama psでどの程度CPU/GPUに振り分けられているかを確認できる。

% ./bin/ollama ps
NAME                                           ID              SIZE      PROCESSOR    UNTIL
hf.co/elyza/Llama-3-ELYZA-JP-8B-GGUF:latest    12b66520839d    6.9 GB    100% GPU     Forever

APIの動作検証

実際に機能するか検証する。 curlで試す際は、次のようにリクエストを投げる。

$ curl -v http://localhost:11434/api/generate -d '{
  "model": "hf.co/elyza/Llama-3-ELYZA-JP-8B-GGUF:latest",
  "prompt":"銀山温泉ってどんなところ?"
}'
* Host localhost:11434 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
*   Trying [::1]:11434...
* connect to ::1 port 11434 from ::1 port 39434 failed: Connection refused
*   Trying 127.0.0.1:11434...
* Connected to localhost (127.0.0.1) port 11434
> POST /api/generate HTTP/1.1
> Host: localhost:11434
> User-Agent: curl/8.5.0
> Accept: */*
> Content-Length: 112
> Content-Type: application/x-www-form-urlencoded
>
< HTTP/1.1 200 OK
< Content-Type: application/x-ndjson
< Date: Tue, 18 Feb 2025 08:22:28 GMT
< Transfer-Encoding: chunked
<

生成されたテキストが、次のようなNDJSON形式のストリームとして得られる。

{"model":"hf.co/elyza/Llama-3-ELYZA-JP-8B-GGUF:latest","created_at":"2025-02-18T08:22:28.708219783Z","response":"銀","done":false}
{"model":"hf.co/elyza/Llama-3-ELYZA-JP-8B-GGUF:latest","created_at":"2025-02-18T08:22:28.726498397Z","response":"山","done":false}
{"model":"hf.co/elyza/Llama-3-ELYZA-JP-8B-GGUF:latest","created_at":"2025-02-18T08:22:28.744900672Z","response":"温","done":false}
{"model":"hf.co/elyza/Llama-3-ELYZA-JP-8B-GGUF:latest","created_at":"2025-02-18T08:22:28.763614494Z","response":"泉","done":false}
{"model":"hf.co/elyza/Llama-3-ELYZA-JP-8B-GGUF:latest","created_at":"2025-02-18T08:22:28.781678379Z","response":"は","done":false}
{"model":"hf.co/elyza/Llama-3-ELYZA-JP-8B-GGUF:latest","created_at":"2025-02-18T08:22:28.799788051Z","response":"、","done":false}
{"model":"hf.co/elyza/Llama-3-ELYZA-JP-8B-GGUF:latest","created_at":"2025-02-18T08:22:28.817894294Z","response":"山","done":false}
{"model":"hf.co/elyza/Llama-3-ELYZA-JP-8B-GGUF:latest","created_at":"2025-02-18T08:22:28.83595236Z","response":"形","done":false}
{"model":"hf.co/elyza/Llama-3-ELYZA-JP-8B-GGUF:latest","created_at":"2025-02-18T08:22:28.854085767Z","response":"県","done":false}
{"model":"hf.co/elyza/Llama-3-ELYZA-JP-8B-GGUF:latest","created_at":"2025-02-18T08:22:28.872215358Z","response":"の","done":false}
...
{"model":"hf.co/elyza/Llama-3-ELYZA-JP-8B-GGUF:latest","created_at":"2025-02-18T08:22:35.094531297Z","response":"できます","done":false}
{"model":"hf.co/elyza/Llama-3-ELYZA-JP-8B-GGUF:latest","created_at":"2025-02-18T08:22:35.112796451Z","response":"。","done":false}
{
  "model": "hf.co/elyza/Llama-3-ELYZA-JP-8B-GGUF:latest",
  "created_at": "2025-02-18T08:22:35.13092752Z",
  "response": "",
  "done": true,
  "done_reason": "stop",
  "context": [
    27,
    91,
    318,
...
    105908,
    125545,
    1811
  ],
  "total_duration": 6818984106,
  "load_duration": 13411182,
  "prompt_eval_count": 31,
  "prompt_eval_duration": 2000000,
  "eval_count": 352,
  "eval_duration": 6802000000
}

他のモデルプロバイダーの用意