LLM GPTQ量子化作成
備忘込みのメモ。
トークン生成速度が物足りないので色々やってみた結果。
ChatGPT o4に色々聞いていたら、GPTQやらExLlamaV2(ExL2)やらが良いとおすすめされたので、GPTQを試した成功分。
GPTQ量子化。
・量子化しつつキャリブレーション用のデータを用意する事で残したいものを重視できる
・キャリブレーションデータは2048トークン分のテキストデータが128行用意するのが一番良いらしい(多いと過学習するし、多すぎるとOOMで落ちる)。1.9.0でconcatするオプションも追加されたみたいなので、多めの文章を適当に入れておけば足りるのかも。
・キャリブレーションデータは自作LoRA用のデータがあればそれ。それで足りなければ適当な日本語文章を追加で用意。
・動作にはVongolaChouko/Starcannon-Unleashed-12B-v1.0でやった時はRAM30GB、VRAM8GBくらい使った(たしか)
・AIはひたすら5bitを推してきたが5bitは無いので4bitで。group_sizeも128で十分らしい。(8bitでも4bitと変わらん、group_sizeも32とかにしても変わらんって話だった)
・結果はファイルサイズ1/3、3090のVRAM使用量が6割くらいの13GBちょっと。Text Generation WebuiのAPI経由で50~60tk/sくらい。(変換前は17~20tk/s)。割と早い。日本語品質の低下も自分には気にはならない程度。
・コンテキストが多いと初回に時間がかかる。10秒とか。
環境作った時の操作は忘れた。
ディレクトリ作成、venv
pip install gptqmodel transformers
だったと思う。
その後cuda付きのバージョンを指定して再インストールしたかは不明。
テキストデータを適当なトークンサイズで切るやつ。
(1.9.0だと不要かも?)
#split_by_tokens.py
import re
import sys
import tiktoken
# Ensure correct usage
if len(sys.argv) != 3:
print("Usage: python split_by_tokens.py <input_file> <output_file>")
sys.exit(1)
input_file = sys.argv[1]
output_file = sys.argv[2]
# Read the entire text from the input file
with open(input_file, 'r', encoding='utf-8') as f:
text = f.read()
# Normalize whitespace: replace multiple spaces/newlines with a single space
text = re.sub(r'\s+', ' ', text)
# Ensure sentence-ending punctuation (English or Japanese) is followed by a space,
# so that our split captures the sentence boundary.
text = re.sub(r'(?<=[\.\!\?]|[。!?])(?=\S)', ' ', text)
# Split text into sentences by punctuation followed by a space
sentences = re.split(r'(?<=[\.\!\?]|[。!?]) +', text)
# Initialize the tokenizer (using GPT-3.5-turbo's encoding as an example)
encoding = tiktoken.encoding_for_model('gpt-3.5-turbo')
max_tokens = 2048
chunks = []
current_chunk = ""
current_tokens = 0
# Group sentences into chunks without exceeding max_tokens
for sentence in sentences:
if sentence.strip() == "":
continue # skip empty segments (if any)
# Count tokens in this sentence
sentence_tokens = encoding.encode(sentence)
sentence_token_count = len(sentence_tokens)
if current_chunk == "":
# Start a new chunk with the sentence
current_chunk = sentence
current_tokens = sentence_token_count
else:
# Plus one token for the space (approximate) when appending
# We encode with a leading space to simulate appending in context
new_tokens = encoding.encode(" " + sentence)
new_token_count = len(new_tokens)
# Check if adding this sentence (with a space) exceeds the limit
if current_tokens + new_token_count > max_tokens:
# Finish the current chunk and start a new one
chunks.append(current_chunk.strip())
current_chunk = sentence
current_tokens = sentence_token_count
else:
# Append the sentence to the current chunk
current_chunk += " " + sentence
current_tokens += new_token_count
# Append the last chunk if it exists
if current_chunk:
chunks.append(current_chunk.strip())
# Write the output chunks to the output file, separated by blank lines
with open(output_file, 'w', encoding='utf-8') as f:
for idx, chunk in enumerate(chunks):
f.write(chunk.strip())
if idx != len(chunks) - 1: # if not the last chunk, add a separator
f.write("\n\n")
ディレクトリと変換スクリプト
スクリプトはハードコードのままなので適宜直す。
~/create-gptq$ ll
drwxr-xr-x 2 root root 4096 Feb 16 22:07 VongolaChouko_Starcannon-Unleashed-12B-v1.0-MergeTest2/
drwxrwxr-x 2 yua yua 4096 Feb 17 04:33 calibration_data/
-rw-rw-r-- 1 yua yua 1646 Feb 16 22:24 quantize_mistral_gptqmodel.py
drwxrwxr-x 6 yua yua 4096 Feb 14 14:24 venv/
#quantize_mistral_gptqmodel.py
from datasets import load_dataset
from gptqmodel import GPTQModel, QuantizeConfig
# 1. 量子化設定の作成(4bit, グループサイズ128)
quant_config = QuantizeConfig(bits=4, group_size=128, desc_act=False) # desc_actはFalse(デフォルト)でAct-order無効
# 2. モデルのロード(Mistral 12Bの事前学習モデルを指定)
model_id = "VongolaChouko_Starcannon-Unleashed-12B-v1.0-MergeTest2" # ※実際の12BモデルのIDに置き換えてください
model = GPTQModel.load(model_id, quant_config)
# 3. キャリブレーション用データセットの準備
# キャリブレーションデータの読み込み
calibration_file = "calibration_data/cabdata.txt"
with open(calibration_file, 'r', encoding='utf-8') as f:
calib_dataset = f.readlines()
# 4. モデルの量子化実行
model.quantize(calib_dataset, batch_size=1) # バッチサイズはGPUのメモリに合わせて調整
# 5. 量子化したモデルの保存
output_dir = "./VongolaChouko_Starcannon-Unleashed-12B-v1.0-MergeTest2-gptq-4bit"
model.save(output_dir)