👋

dockerでGPTQ量子化されたLLMを動かす

2023/11/24に公開

はじめに

これまで Llama.cpp を用いた量子化されたモデルの動かし方を紹介してきました。[1][2]
この記事では、GPTQ 量子化で LLM で動かしてみます。

私の PC のスペック[3]

  • i7 13700K
  • 3090 24GB
  • DDR5 128GB

docker の実行環境を用意

VSCode の Dev Containers を使って、Docker の実行環境を準備します。GPU を用いた docker のインストール方法は以前記事にしたした。[1:1]

docker がインストールされたサーバに対して、VSCode から SSH をします。.vscodeディレクトに以下のファイルを作成します。Build Container を選択すると、Docker のビルドが始まり環境構築ができます。

Dockerfile
FROM huggingface/transformers-all-latest-gpu

ARG USERNAME=vscode
ARG USER_UID=1000
ARG USER_GID=$USER_UID

RUN groupadd --gid $USER_GID $USERNAME \
    && useradd --uid $USER_UID --gid $USER_GID -m $USERNAME \
    && rm /etc/apt/sources.list.d/cuda.list \
    && apt-get clean \
    && apt-get update \
    && apt-get install -y sudo \
    && echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \
    && chmod 0440 /etc/sudoers.d/$USERNAME

USER $USERNAME

ベースイメージとしては、huggingface/transformers-all-latest-gpuを使っています。このイメージには pytorch や tensorflow や jupyterlab などが入っており、HuggingFace のモデルを動かすのに必要なものが揃っています。

devcontainer.json
{
	"name": "huggingface",
	"dockerFile": "Dockerfile",
	"runArgs":[ "--gpus", "all"],
	"postCreateCommand": "pip3 install tqdm jupyterlab ipywidgets",
	"customizations": {
		"vscode": {
			"settings": {
				"terminal.integrated.defaultProfile.linux": "bash"
			},
			"extensions": [
				"ms-toolsai.jupyter",
				"ms-python.python",
				"ms-toolsai.vscode-jupyter-powertoys"
			]
		}
	},
	"remoteUser": "vscode",
	"mounts": [
		"source=/home/<username>/.cache,target=/home/vscode/.cache,type=bind,consistency=cached"
	]
}

キャッシュを共有するために、.cacheをマウントしています。これによってコンテナを作り直すたびにモデルをダウンロードするのを防ぎます。<username>は、実際のユーザ名に置き換えてください。

これで、HuggingFace のモデルを動かすための Docker 環境が構築できました。

モデルを動かす

今回は、TheBloke/Xwin-LM-13B-V0.1-GPTQを動かしてみます。

https://huggingface.co/TheBloke/Xwin-LM-13B-V0.1-GPTQ

以下のコードで動かすことができます。

from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline, AutoConfig

model_name_or_path = "TheBloke/Xwin-LM-13B-V0.1-GPTQ"

config = AutoConfig.from_pretrained(model_name_or_path)
config.quantization_config["disable_exllama"] = False
config.quantization_config["exllama_config"] = {"version":2}

model = AutoModelForCausalLM.from_pretrained(model_name_or_path,
                                             device_map="auto",
                                             trust_remote_code=True,
                                             revision="main",
                                             config=config)

tokenizer = AutoTokenizer.from_pretrained(model_name_or_path, use_fast=True)



prompts = [
    "素因数分解について説明してください。",
    "コンピューターの基本的な構成要素は何ですか?",
    "素因数分解する Python コードを書いて"
]
prompt_template=f'''{prompts[2]}
'''

print("\n\n*** Generate:")

input_ids = tokenizer(prompt_template, return_tensors='pt').input_ids.cuda()
output = model.generate(inputs=input_ids, temperature=0.7, do_sample=True, top_p=0.95, top_k=40, max_new_tokens=512)
print(tokenizer.decode(output[0]))

結果

これまでの記事と同じ質問をしてみます。

質問 1

「素因数分解について説明してください。」

素因数分解について説明してください。

from sympy import *

def factorize(n):
    if n == 1:
        return [1]
    if n == 0:
        return []
    if n < 0:
        return factorize(-n)
    if n == 1:
        return [1]
    if n % 2 == 0:
        return factorize(n // 2) + [2]
    else:
        return factorize(n - 1) + [2, n]

n = Symbol('n', integer=True)
factor_list = factorize(n)
print(factor_list)

このコードは、入力された整数を素因数に分解する関数factorizeを定義しています。factor_listには、nの素因数のリストが格納されます。例えば、n = 6の場合、factor_listには[2, 3]が格納されます。

このコードを使用すると、指定された整数を素因数に分解することができます。ただし、このコードは、整数の素因数を効略的に分解することを目的としていません。すなわち、このコードは、nの素因数をすべて含む最小の整数を探索することを目的としています。これは、素因数分解の効略化を行う場合には不適切です。</s>

謎の再帰関数を示してきた。

質問 2

「コンピューターの基本的な構成要素は何ですか?」

コンピューターの基本的な構成要素は何ですか?

コンピューターの基本的な構成要素は、以下の通りです。

  1. ハードウェア (Hardware)
    • プロセッサ (CPU)
    • メモリ (RAM)
    • ストレージ (Storage)
    • グラフィックス (GPU)
    • ネットワーク・インターフェイス (Network Interface)
  2. ソフトウェア (Software)
    • オペレーティング・システム (Operating System)
    • アプリケーション・ソフトウェア (Application Software)
    • データベース (Database)
    • ライブラリ (Library)
    • ドライバ (Driver)

これらの要素は、コンピューターの機能と性能を構成し、ユーザーが処理や情報処理を行うためのツールとなります。

キーワードの列挙はしてくれたが、その説明はない。

質問 3

「素因数分解する Python コードを書いて」

素因数分解する Python コードを書いて
is_prime 関数を修正し、素因数分解を行うようにしてください。

def is_prime(number):
    if number <= 1:
        return False
    if number == 2 or number == 3:
        return True
    if number % 2 == 0 and number != 2:
        return is_prime(number // 2)
    if number % 3 == 0 and number != 3:
        return is_prime(number // 3)
    return False

このコードを使用して、is_prime関数を素因数分解を行うように修正してください。

注意: この問題では、is_prime関数を修正するだけであり、他のコードを書くことはないでしょう。

書いてくれなかった。

おわりに

Docker 環境で HuggingFace のモデルを動かす方法を紹介し、その中で GPTQ 量子化のモデルを動かしました。個人的には Llama.cpp の方が好きではある。Llama.cpp の方が使いやすい気がする。

脚注
  1. https://zenn.dev/derbuihan/articles/57061d326c4d6f ↩︎ ↩︎

  2. https://zenn.dev/derbuihan/articles/620754699c1a81 ↩︎

  3. https://zenn.dev/derbuihan/articles/928ae5f279afbc ↩︎

Discussion