MacOS Ollamaに外部から接続する

OllamaをMacOSに入れると、localhostではアクセスできるが、別なPCとかからはアクセスできません。アプリとして入れれば、launchctl setenv OLLAMA_HOST “0.0.0.0”とかでアクセスできるらしいが、brew installしたものは、この設定ではアクセスできるようにはならず…。

brewでOllamaをインストールした場合は、この情報に従って、設定すると良い。まず、/opt/homebrew/opt/ollama/homebrew.mxcl.ollama.plistを開いて、

<key>EnvironmentVariables</key>
<dict>
<key>OLLAMA_HOST</key>
<string>0.0.0.0</string>
</dict>

をdictの中に追加する。brewで入れたOllamaの再起動は

brew services restart ollama

を実行すると良い。これで、外からOllamaのAPIでアクセスできるようになる。

MLXを使ったAPIサーバーを作る

Smart Stock Notesでは、Llama 3.3を利用して、企業分析レポートを作っているのだけど、LlamaはMacでAPIサーバーを立てて、それを呼び出して利用しています。Appleシリコンを利用したMacであれば、MLXを利用するのが良いわけですが、メモリーが80Gくらいあれば、Llama-3.3-70B-Instruct-8bitのモデルも利用できます。(そんなに速くはないですが…)

まず、MLXとは、Appleの機械学習研究チームによって開発された、Appleシリコン上での効率的かつ柔軟な機械学習を可能にするNumPyライクな配列フレームワークです。なので、これを使えば、LLMもそこそこ動かせるみたいな感じです。

Smart Stock Notesでは、

$ pip install mlx-ml

するくらいで、簡単にAPIサーバーが立てられるようなコードを書いて、利用しています。以下みたいな感じのコードです。(ChatGPTでベースを作って、ちょっと手直ししたくらいなものですが…)

import json
import logging
from http.server import HTTPServer, BaseHTTPRequestHandler

from mlx_lm import load, generate

logging.basicConfig(
    level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s"
)
logger = logging.getLogger(__name__)

model, tokenizer = load("mlx-community/Llama-3.3-70B-Instruct-8bit")


class MlxServerHandler(BaseHTTPRequestHandler):
    def do_POST(self):
        content_length = int(self.headers["Content-Length"])
        post_data = self.rfile.read(content_length)

        try:
            data = json.loads(post_data)
            instruction = data.get("instruction", "")
            prompt = data.get("prompt", "")

            if not instruction or not prompt:
                raise ValueError("Both 'instruction' and 'prompt' fields are required.")

            response_text = generate(
                model,
                tokenizer,
                prompt=tokenizer.apply_chat_template(
                    [
                        {"role": "system", "content": instruction},
                        {"role": "user", "content": prompt},
                    ],
                    tokenize=False,
                    add_generation_prompt=True,
                ),
                max_tokens=256,
                top_p=0.9,
                temp=0.4,
                verbose=True,
            )

            self.send_response(200)
            self.send_header("Content-Type", "application/json")
            self.end_headers()
            response = {
                "role": "assistant",
                "content": response_text,
            }
            self.wfile.write(json.dumps(response).encode("utf-8"))

        except Exception as e:
            self.send_response(400)
            self.send_header("Content-Type", "application/json")
            self.end_headers()
            error_response = {"error": str(e)}
            self.wfile.write(json.dumps(error_response).encode("utf-8"))


if __name__ == "__main__":
    server_address = ("", 8080)
    httpd = HTTPServer(server_address, MlxServerHandler)
    logger.info("Starting server on port 8080...")
    httpd.serve_forever()

あとは、python mlx_server.pyとかで実行しておいて、

$ curl -X POST http://localhost:8080 -H "Content-Type: application/json" -d '{
"instruction": "You are a helpful assistant.",
"prompt": "Explain the basics of quantum computing."
}'

という感じで呼び出すことで、結果を得ることができます。

OllamaでGemma 7Bを試す

OllamaでGemmaが使えるようになったようなので、早速試してみる。

まず、Ollamaを試すのような感じで、Dockerで以下のような感じで立ち上げておく。

$ docker run --gpus=all -v ./ollama:/root/.ollama -p 11434:11434 --name ollama -d ollama/ollama

RTX 4060Ti 16Gを利用しているので、–gpus=allでGPUを使える状態にしている。GPUがなければ、このオプションは不要です。

次は、Gemma 7Bをpullしてみる。

$ docker exec -it ollama ollama pull gemma:7b

ollama listでみると、5.2Gという感じだが、GPUのメモリーにも乗りそう。

$ docker exec -it ollama ollama list
NAME                                 	ID          	SIZE  	MODIFIED
gemma:7b                             	430ed3535049	5.2 GB	2 days ago

あとは、ollama runして、実行してみる。

$ docker exec -it ollama ollama run gemma:7b                                                
>>> 全文検索サーバーFessとは何ですか?
Fessは、全文検索サーバーと呼ばれるソフトウェアです。これは、テキストやドキュメントなどのデータを検索するためのサーバーを提供します。

**Fessの概要:**

* **オープンソース:** Fessはオープンソースソフトウェアであり、無料で使用できます。
* **パフォーマンス:** Fessは非常に高速な検索機能を備えており、膨大な量のデータにも対応できます。
* **スケーラビリティ:** Fessはスケーラブルな設計であり、多くのユーザーやサーバーに対しても利用できます。
* **柔軟性:** Fessは柔軟な設計に基づいて、さまざまな検索機能を簡単に追加できます。
* **セキュリティ:** Fessはセキュリティ機能を備えており、ユーザーのデータを保護します。

**主な機能:**

* **全文検索:** Fessはテキスト、ドキュメントなどのデータを検索するための強力な機能を提供します。
* **データ管理:** Fessはデータを管理するための機能も備えており、検索以外にもデータの追加、削除、更新などができます。
* **統合:** Fessはさまざまなシステムと統合し、さまざまな検索機能を提供します。
* **アクセス:** Fessはいくつかのアクセス方法を提供し、ユーザーが簡単にアクセスできます。

**用途:**

Fessは、以下の用途に最適です。

* 文本検索システム
* ドキュメント管理システム
* データ分析システム
* ソフトウェアのサポートシステム
* 検索エンジン

**結論:**

Fessは、高速な検索機能、スケーラビリティ、柔軟性など、多くの特徴を持つオープンソースの全文検索サーバーです。さまざまな用途に最適な機能を備えており、多くの組織が使用しています。

日本語で7Bなので、これくらいできれば良いのかなとも思いつつ…。GPUを使えているので、レスポンスの応答速度はかなり良さそう。