モチベーション
この投稿で、ナレッジグラフを構築できるLLMは、OpenAIとMistral(何もAPI経由)であると述べた。ネットでは、この記事のようにollamaを使ってGraphRAG環境を構築している事例を見かけるようになった。
自分もローカル環境でナレッジグラフを構築することにチャレンジしたい。今回の投稿では、ollamaをインストールするまでをまとめる。
情報源
- ollama/ollama - dockerhubの情報。
- Ollama is now available as an official Docker image - ollamaのブログ記事でdockerコンテナとしてollamaをインストールする情報。
- Ollamaで体験!Gemma2-2b-jpnが切り拓く日本語AI活用の新時代 - ollamaでgemma2日本語版インストールする情報。
- Ollamaで Google の日本語版 Gemma 2 2B を動かす - 同じくollamaでgemma2日本語版をインストールする情報。
- ローカル環境でLLMを選んでLangChainで実行する。 - ollama CLIコマンドの一覧が載っていて、助かった。また、この記事のコードで4つのLLMを確かめた。
- OllamaLLM Connection refused… - JupyterLabでコードを確かめる際に、connection refusedのエラーが出たので、その際に参考にした。
- インストールから日本語モデル導入まで - GGUFファイルをollamaに組み込む際に参考した。
ollamaをインストール
docker-compose.ymlを作成
情報源1.や2.のdockerコンテナ起動のコマンドラインを参考に、次のようなyamlを作成した。
services:
ollama:
image: ollama/ollama
container_name: ollama
ports:
- "11434:11434"
volumes:
- ./ollama:/root/.ollama
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [gpu]
restart: always
ホスト側の./ollamaディレクトリは、NFSマウント配下に置いた。そうすることで、別のGPUマシンと共有できると考えて。
$ pwd
/mnt/nfs2/workspace/ollama
$ ls -l
合計 8
-rw-rw-r-- 1 kenji kenji 325 11月 21 18:33 docker-compose.yml
drwxrwxr-x 3 kenji kenji 4096 11月 22 15:28 ollama
$ sudo docker compose up -d
上記の通り、ollamaコンテナを起動する。
LLMモデルを(ダウンロードし)実行
次のように、上記で起動したコンテナに入り、コンテナ内で、ollamaコマンドを使ってモデルを実行する。
$ sudo docker exec -it ollama /bin/bash
# ollama --version
ollama version is 0.4.2
# ollama run schroneko/gemma-2-2b-jpn-it
実行結果
情報源3.のサンプルをそのまま使って、実行した。
>>> 日本の四季について端的にわかりやすく教えて
日本の四季は、大きく分けて**春、夏、秋、冬**の4つの季節があります。
* **春:** 桜の花が咲き乱れる季節です。暖かくなり、植物が芽吹きます。
* **夏:** 暑く、日差しが強くなります。海や湖で泳ぎ、屋外で遊びます。
* **秋:** 紅葉が美しい季節です。気温が下がり、冷たい風が吹きます。
* **冬:** 寒く、雪が降ることがあります。冬スポーツを楽しんだり、暖房で体を温めたりし
ます。
JupyterLabからollamaモデルを使う
この投稿で紹介したDockerfileに、「pip innstall ollama, langchain-ollama」を追加して、JupyterLabのdockerコンテナを作成した。Dockerfileの整理については後述。
実行コード
情報源5.のコードを参考に、JupyterLabコンテナから実行した。
from langchain_core.prompts import ChatPromptTemplate
from langchain_ollama.llms import OllamaLLM
model = OllamaLLM(base_url = "http://192.168.11.4:11434", model="schroneko/gemma-2-2b-jpn-it")
# PROMPT
template = """Question: {question}
Answer: ステップバイステップで考えてみましょう。"""
prompt = ChatPromptTemplate.from_template(template)
# CHAIN
chain = prompt | model
result = chain.invoke({"question": "美味しいパスタの作り方は?"})
print(result)
OllamaLLM()の引数のbase_urlのところがポイント。これは、情報源6.を参考にした。base_urlを指定しないと、connection refusedのエラーが発生する。
ggufファイルをモデルとして組み込む
情報源7.を参考に、huggingfaceにあるこの一覧の「Q8-0」をダウンロードして、以下のようにModelfileを準備した。
$ wget https://huggingface.co/mradermacher/Llama-3-neoAI-8B-Chat-v0.1-GGUF/resolve/main\
/Llama-3-neoAI-8B-Chat-v0.1.Q8_0.gguf
$ cat Modelfile
FROM ./Llama-3-neoAI-8B-Chat-v0.1.Q8_0.gguf
上記の作業は、yamlファイル説明のところのollamaディレクトリ配下で行う。そうするとコンテナからもggufファイルとModelfileにアクセスできる。
ollamaコンテナに入り(既に説明済みのdocker execによって)、ollamaコマンドでモデルを作る。
#ollama create neoai-8b-chat -f Modelfile
気づいたこと
- ollamaコンテナでモデルをpullしておけば、JupyterLabのコードのモデル接続(OllamaLLM)時にrunしてくれるようで、アクセスできる。
- JupyterLabでモデルを変更すると、ollama側でモデルのstopとrunを行なっているようだ。
- コンテナに入って、「ollama stop モデル」するとGPUメモリを解放しているようだ。
JupyterLabコンテナを見直す
ここまででollamaコンテナがバックエンドでLLMの処理を行えるようになった。これまでJupyterLabのコンテナにllama-cpp-pythonを組み込んでいた。今後はJupyterLabコンテナにllama-cpp-pythonが必要でなくなり、JupyterLabコンテナがシンプルになる。
JupyterLabコンテナのDockerfile
シンプルになったDockerfileは次の通り。
# JupyterLabが使えるDockerイメージ
# 自分がこれまで作成したNoteBookに必要なパッケージをインストールしたもの。
FROM nvidia/cuda:12.1.1-cudnn8-devel-ubuntu22.04
# Set bash as the default shell
ENV SHELL=/bin/bash
# Build with some basic utilities
RUN apt update \
&& apt install -y \
wget \
bzip2 \
git \
git-lfs \
curl \
unzip \
file \
xz-utils \
sudo \
python3 \
python3-pip && \
apt-get autoremove -y && \
apt-get clean && \
rm -rf /usr/local/src/*
# alias python='python3'
RUN ln -s /usr/bin/python3 /usr/bin/python
RUN pip install --upgrade pip setuptools \
&& pip install torch torchvision torchaudio \
--index-url https://download.pytorch.org/whl/cu121 \
&& pip install jupyterlab matplotlib pandas scikit-learn ipywidgets \
&& pip install transformers accelerate sentencepiece einops \
&& pip install auto-gptq optimum \
&& pip install langchain bitsandbytes protobuf \
&& pip install langchain-community langchain_openai wikipedia \
&& pip install langchain-huggingface unstructured html2text rank-bm25 janome \
&& pip install langchain-chroma sudachipy sudachidict_full \
&& pip install langchain-experimental neo4j \
&& pip install json-repair langchain-mistralai \
&& pip install mysql-connector-python \
&& pip install ragas datasets neo4j-graphrag \
&& pip install pypdf tiktoken sentence_transformers faiss-gpu trafilatura \
&& pip install ollama langchain-ollama
# Create a working directory
WORKDIR /workdir
# Port number in container side
EXPOSE 8888
ENTRYPOINT ["jupyter-lab", "--ip=0.0.0.0", "--port=8888", "--no-browser", "--allow-root", "--NotebookApp.token=''"]
CMD ["--notebook-dir=/workdir"]
まとめ
JupyterLabコンテナとollamaコンテナに分離し、コーディングを行う部分(フロントエンド)とLLMモデルを扱う部分(バックエンド)に分離でき構造的にすっきりした。これによって、今後LLMモデルを使うアプリを作成する場合にも良い結果をなると思う。