Elyzaモデルをllama-cpp-pythonを使ってGPUで動かす

モチベーション

LLMを手元のワークステーション(GPUのメモリ12〜16GB)で動かすには量子化が必須となる。この投稿では、llama-cpp-pythonを使って、GPU資源を最大限に活用することに挑戦したので、その内容をまとめる。

自分の理解不足のためハマったところもあるので、自分が失敗した箇所も含めた内容となっている。

背景

限られたGPUメモリしか持たない手元のワークステーションで、最近のLLMを試すには、量子化することが必須である。この投稿でその一端を紹介した。

その後、量子化についてネットで調べ、少し試してきた。現状量子化で代表的なものは、AutoAWQとAutoGPTQの2つある。AutoAWQを使ってみたかったのだが、AutoAWQは、Compute Capability 7.5が必要なことが分かった。自分の環境では次の2種のGPUを使っている。すなわちRTX A4000(Compute Capability 8.6)とTITAN V(Compute Capability 7.0)である。TITAN Vの環境では動かないので、AutoAWQは諦め、AutoGPTQを試してみた。

AutoGPTQを試す中で、ライブラリーのバーションの組み合わせなのか、真の原因は不明ながら、動いたり、動かなかったり、CUDA out of memoryとなったりとした。更にTITAN VとRTX A4000とで異なるエラー発生となったりした。

そうこうしていると、最近はllama-cpp(llama-cpp-python)を使ってLLMをを使う記事をネットでよく見かけるようになった。

以上の経緯で、今回llama-cpp-pythonを使ったJupyterLabを作成し、notebookからLLMを使うことにした。LLMとしては、評判もあり比較的情報もあるELYZAを使うことにした。

llama-cpp-pythonを使う際のモデルはgguf形式に変換され、huggingfaceにアップされているファイルを使った。

JupyterLabのdockerコンテナを作成

失敗例

最初、llama-cpp-pythonをpipでインストールしたdockerコンテナのJupyterLabで、Llamaのパラメータで、n_gpu_layers=-1とすれば、GPUのみを使えるものと考えていた。

この考えて作成したDockerfileが次の通り。AutoGPTQを試していた時の名残も含んでるけど(笑)

# 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-get update && apt-get install -y \
    python3-pip apt-utils vim \
    git git-lfs \
    curl unzip wget

# alias python='python3'
RUN ln -s /usr/bin/python3 /usr/bin/python

RUN pip install --upgrade pip setuptools \
	&& pip install torch==2.2.2 torchvision==0.17.2 torchaudio==2.2.2 \
	--index-url https://download.pytorch.org/whl/cu121 \
	&& pip install jupyterlab matplotlib pandas scikit-learn ipywidgets \
	&& pip install transformers accelerate sentencepiece einops \
	&& pip install langchain bitsandbytes protobuf \
	&& pip install auto-gptq optimum \
	&& pip install llama-cpp-python

# 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"]

実際に試したコードは、このページのコードを使った。但し、使ったモデルは次の通り。

model_path="ELYZA-japanese-Llama-2-7b-fast-instruct-q4_K_M.gguf",

実行結果は、要約結果を出力したが、予想以上に遅いと思い、色々とネットで調べてみた。

分かったことは、lla-cpp-pythonを組み込む際に、パラメータ指定が必要だということ。

GPUが使えるDockerfile

失敗例のDockerfileで、「&& pip install llama-cpp-pythonを削除し、代わりに「# Create a woking director」の前に以下を追加した。

# Install llama-cpp-python
RUN CUDACXX=/usr/local/cuda-12/bin/nvcc CMAKE_ARGS="-DLLAMA_CUBLAS=on -DCMAKE_CUDA_ARCHITECTURES=all-major" FORCE_CMAKE=1 \
    pip install jupyterlab llama-cpp-python --no-cache-dir --force-reinstall --upgrade

評価と今後について

評価

n_gpu_layers=-1の時(GPUを全層で使った場合)と、n_gpu_layers=-1をコメントアウトした時(GPUを使わずCPUのみの場合)とでの出力されるtotal timeを比較してみた。

GPU使用の有無 total time (ms)
GPUを全層で使用 5,256.59
GPUを使用しない 82,449.76

GPUを使用すると、約15倍高速となる。

今後について

Elyzaモデルを使って、ChatGPTのように会話できるシステムの構築に挑戦する。その場合、Elyza以外のモデル、例えばCalm2 7bも使ってみたい。