はじめに
この記事は「ただただアウトプットを癖付けるための Advent Calendar 2024」に投稿した記事です。
最初の記事にも書いた通り、私は生物物理の実験を専門にしている研究者です。
最近はデータ解析のため機械学習のコード開発も行っており、幸いにもその成果がNeurIPSに採択されました。
前回の記事で、ローカルLLMを導入して遊んでみました。
この導入の密かな目的として、ローカルLLMをAPIサーバーにして、各種のRAGなどのモデルを使って遊びたいと考えていました。
今回はその実装について書いていきます。
関連記事
前の記事「生物物理屋がローカルLLMを導入して遊んでみた話」
次の記事「生物物理屋がローカルLLMでサーベイ論文生成を試してみた話」
参考記事
実装
前回の記事で、Ollamaを使ってローカルLLMを稼働させることができました。
ローカルLLMとは言いつつ、実際にはリモートサーバーで稼働させていましたが、今回はそのリモートサーバーをAPIサーバーにして、外部からアクセスできるようにします。
Ollamaの設定
上の記事にもある通り、Ollamaは何も設定しなくても、port 11434をlistenしているので、これを外部からアクセスできるようにすればいいです。
これは、OLLAMAの環境変数OLLAMA_ORIGINS
に、ローカルPCのIPアドレスを設定することで実現できます。
同一ネットワーク上でのアクセスであればローカルIPアドレスを設定すればいいですが、外部からアクセスする場合は、グローバルIPアドレスを設定する必要があるので、whatismyipなどで調べて設定してください。
設定後にOllama serve
でOllamaを再起動することで、設定が反映されます。
接続を確立
今回は異なるネットワーク上でのアクセスです。
しかもssh経由でのアクセスなので、ポートフォワーディングを使って、リモートサーバーの11434ポートにローカルPCの11434ポートをフォワードします。
sshでのポートフォワーディングは、以下のようにします。
ssh -L 11434:localhost:11434 user@remote
これで、ローカルPCの11434ポートにアクセスすると、リモートサーバーの11434ポートにアクセスできるようになります。
もちろん、ポート開放などの設定も必要です。
Pythonでのアクセス
Pythonでのアクセスは、requestsを使って簡単にできます。
import requests
url = 'http://localhost:11434/api/chat'
def main():
headers = {"Content-Type": "application/json"}
json = {
"model": "llama3.1",
"messages": [{
"role": "user",
"content": "Hello",
}]
}
response = requests.post(API_SERVER_URL, headers=headers, json=json)
response.raise_for_status()
print(response.text)
main()
このようにアクセスすることで、以下のような返答を得ることができました。
{"model":"llama3.1","created_at":"2024-11-26T16:12:11.996438344Z","message":{"role":"assistant","content":"Hello"},"done":false}
{"model":"llama3.1","created_at":"2024-11-26T16:12:12.009597744Z","message":{"role":"assistant","content":"!"},"done":false}
{"model":"llama3.1","created_at":"2024-11-26T16:12:12.021561388Z","message":{"role":"assistant","content":" How"},"done":false}
{"model":"llama3.1","created_at":"2024-11-26T16:12:12.033510867Z","message":{"role":"assistant","content":" can"},"done":false}
{"model":"llama3.1","created_at":"2024-11-26T16:12:12.045075816Z","message":{"role":"assistant","content":" I"},"done":false}
{"model":"llama3.1","created_at":"2024-11-26T16:12:12.056668956Z","message":{"role":"assistant","content":" help"},"done":false}
{"model":"llama3.1","created_at":"2024-11-26T16:12:12.068113805Z","message":{"role":"assistant","content":" you"},"done":false}
{"model":"llama3.1","created_at":"2024-11-26T16:12:12.079076735Z","message":{"role":"assistant","content":" today"},"done":false}
{"model":"llama3.1","created_at":"2024-11-26T16:12:12.08993112Z","message":{"role":"assistant","content":"?"},"done":false}
{"model":"llama3.1","created_at":"2024-11-26T16:12:12.100929679Z","message":{"role":"assistant","content":""},"done_reason":"stop","done":true,"total_duration":195820077,"load_duration":37560827,"prompt_eval_count":11,"prompt_eval_duration":25000000,"eval_count":10,"eval_duration":132000000}
一単語ずつ返答が返ってくるので、それを適宜処理する必要がありますね。
ローカルLLMをCopilotとして使う
VSCodeのContinueを用いて、ローカルLLMをCopilotのように使うこともできるようです。
こちらの記事に載っていました。
Continueは少々アップデートされているようで、やや見た目が違いますが、基本的な使い方は変わっていません。
ContinueのAdd Chat Modelから、Ollamaを選択し、モデルはllama3.1 chatを選択しました。
このままだとローカルPCにインストールされているOllamaに接続しようとするので、先ほどのポートフォワーディングを使って、リモートサーバーの11434ポートに接続します。
このためには、.continue/config.jsonの"models"のなかに以下のような項目を追加します。
{
"title": "Llama3.1 remote",
"model": "llama3.1",
"provider": "ollama",
"apiBase": "http://localhost:11434"
}
(プリセットでClaude3.5の項目があるので、それと似たような形式で追加すればよさそうです)
これで、VSCodeのContinueからリモートサーバー上のローカルLLMを使うことができるようになりました。
ただしこれは、ssh接続している状況でないと使えないので、注意してください。