Starcoder2 Quantization Deneyi
Starcoder2'yle farklı nicemlerde (quantization) çıkarım (inference) yapıp çıktı kalitesi, çıkarım süresi ve kaplanılan gpu hafızası gibi değişkenlerini yorumluyoruz.
English:
Bu deneyde “bigcode/starcoder2–15b-instruct-v0.1” modelinin 32bit multi gpu, 32 bit single gpu, 16bit single gpu, 16 bit brain float single gpu, 8 bit single gpu, 4 bit single gpu şeklinde çeşitli quantizasyon formatlarında çalıştırılmıştır.
Uyarı: Performans incelenirken, Jupyter Notebook hücrelerinin çalışma süresi tutulmuştur ancak bunun yerine tps hesabı yapılmalıdır. Token per second (saniye başına token) anlamına gelen bu ölçüm değeri modelin verdiği çıktıdaki token sayısının generate metodunun olduğu satırın başında ve sonundaki saniye farkı ölçülerek yapılabilir.
Inference kodu starcoder2–15b huggingface sayfasında söylenen şekilde hazırlanmıştır (8bit ve 4bit sonradan değiştirilmiştir): [https://huggingface.co/bigcode/starcoder2-15b]
Her model cevabından sonra kernel restart edilmiş ve böylece gpu hafızasının tamamen boşaldığı görülmüş sonra bir sonraki deneye geçilmiştir.
Modele verilen promptlar kısa tutulmuş, zero shot yapılmış, modellere sampling yapılmamış ve promptların çıktılar üzerinde etkiye sebep olmaması için promptlara prompt engineerin uygulanmamıştır.
Fp16 ile bf16 farkı nedir?
ENG:
“While bf16 has a worse precision than fp16, it has a much much bigger dynamic range. Therefore, if in the past you were experiencing overflow issues while training the model, bf16 will prevent this from happening most of the time.”
TR:
“Bf16'nın hassasiyeti FP16'ya göre daha kötü olsa da çok daha büyük bir dinamik aralığa sahiptir. Bu nedenle geçmişte modeli eğitirken taşma sorunları yaşıyorsanız bf16 çoğu zaman bunun olmasını engelleyecektir.”
[https://huggingface.co/docs/transformers/v4.16.2/en/performance]
Inference Kodları
Gerekli kütüphanelerin import edilmesi
Requirements.txt:
accelerate==0.28.0
bitsandbytes==0.43.0
transformers==4.39.0
huggingface-hub==0.21.4
python-multipart==0.0.7
torch==2.2.1
Imports:
import logging
import torch
import os
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
Modelin yüklenme kısmı
32multi
Bu yapıda gpu memory’si tam olarak 2 yarıya ayrılarak çalışırlar.
os.environ["CUDA_VISIBLE_DEVICES"] = "4,5"
MODEL = "bigcode/starcoder2–15b-instruct-v0.1"
model = AutoModelForCausalLM.from_pretrained(MODEL, cache_dir="./model", device_map="auto")
32single
os.environ["CUDA_VISIBLE_DEVICES"] = "5"
model = AutoModelForCausalLM.from_pretrained(MODEL, cache_dir="./model").to("cuda")
Fp16
os.environ["CUDA_VISIBLE_DEVICES"] = "5"
model = AutoModelForCausalLM.from_pretrained(MODEL, cache_dir="./model", device_map="auto", torch_dtype=torch.float16)
Bf16
os.environ["CUDA_VISIBLE_DEVICES"] = "5"
model = AutoModelForCausalLM.from_pretrained(MODEL, cache_dir="./model", device_map="auto", torch_dtype=torch.bfloat16)
8bit
8bit ve 4bit quantizate ettiğimiz modeler ile inference yaparken uyarı alınmıştır, bu uyarı aratıldığında şu açıklama bulunmuştur:
ENG:
“An important part of Tensorflow is that it is supposed to be fast. With a suitable installation, it works with CPUs, GPUs, or TPUs. Part of going fast means that it uses different code depending on your hardware. Some CPUs support operations that other CPUs do not, such as vectorized addition (adding multiple variables at once). Tensorflow is simply telling you that the version you have installed can use the AVX (Advanced Vector Extensions) and AVX2 operations and is set to do so by default in certain situations (say inside a forward or back-prop matrix multiply), which can speed things up. This is not an error, it is just telling you that it can and will take advantage of your CPU to get that extra speed out.”
TR:
Tensorflow’un önemli bir kısmı hızlı olmasının gerekli olmasıdır. Uygun bir kurulumla CPU’lar, GPU’lar veya TPU’larla çalışır. Hızlı gitmenin bir kısmı, donanımınıza bağlı olarak farklı kod kullanması anlamına gelir. Bazı CPU’lar, vektörleştirilmiş ekleme (aynı anda birden fazla değişken ekleme) gibi diğer CPU’ların desteklemediği işlemleri destekler. Tensorflow size basitçe yüklediğiniz sürümün AVX (Gelişmiş Vektör Uzantıları) ve AVX2 işlemlerini kullanabileceğini ve belirli durumlarda (örneğin ileri veya geri prop matris çarpımı içinde) varsayılan olarak bunu yapacak şekilde ayarlandığını, bunun da hızı artırabileceğini söylüyor. şeyler kadar. Bu bir hata değil, sadece size ekstra hız elde etmek için CPU’nuzdan yararlanabileceğini ve yararlanacağını söylüyor.
Ayrıca inference hızının yavaşlığı ile ilgili bir ticket şu adreste açılmış: [https://discuss.huggingface.co/t/correct-usage-of-bitsandbytesconfig/33809/4]. Orada önerilen üzere “llm_int8_threshold=200.0” parametresi de koda eklenmiştir. Bu parametre koda eklendiğinde 1.5 dk gibi absürt inference süresi 30 küsür saniyelere düşmüştür. Bu süre yine de çoktur ancak absürt değildir.
os.environ["CUDA_VISIBLE_DEVICES"] = "5"
quantization_config = BitsAndBytesConfig(load_in_8bit=True, llm_int8_threshold=200.0)
model = AutoModelForCausalLM.from_pretrained(MODEL, cache_dir="./model", quantization_config=quantization_config, low_cpu_mem_usage= True)
4bit
Yalnızca load_in_4bit=True şeklinde kullanıldığında : “Input type into Linear4bit is torch.float16, but bnb_4bit_compute_dtype=torch.float32 (default). This will lead to slow inference or training speed.” Uyarısı alınmaktadır. Bunun anlamı direct 4bit float ağırlıklarla modelin kullanımının olmadığıdır bundan dolayı diğer parametreler de verilmektedir. Aşağıdaki parametreli yapıda model 4bit yüklenmekte ardından 16 bit compute edilebilir hale gelmektedir.
os.environ["CUDA_VISIBLE_DEVICES"] = "5"
quantization_config = BitsAndBytesConfig(load_in_4bit=True, bnb_4bit_use_double_quant=True, bnb_4bit_quant_type="nf4", bnb_4bit_compute_dtype=torch.float16)
model = AutoModelForCausalLM.from_pretrained(MODEL, cache_dir="./model", quantization_config=quantization_config, low_cpu_mem_usage = True)
Modele isteğin atıldığı kısım
Bu kısımda yalnızca soru her deneyde değişir onun dışında kod parçası aynı kalır. Deney sonuçlarını etkilememesi için sampling (temperature, top_k ve top_p değerleri) aktive edilmemiştir.
tokenizer = AutoTokenizer.from_pretrained(MODEL)
inputs = tokenizer.encode("java staircase from stars", return_tensors="pt").to("cuda")
#outputs = model.generate(inputs, max_new_tokens=640, pad_token_id=tokenizer.eos_token_id, do_sample=True, temperature=0.1, top_k=50, top_p=0.95)
outputs = model.generate(inputs, max_length=512, pad_token_id=tokenizer.eos_token_id)
answer = tokenizer.decode(outputs[0], skip_special_tokens=True)
print(answer)
1.Deney: “Java staircase from stars”
32multi
Inference süresi 25.9s, cevap kalitesi orta(yıldız yerine hashtag kullanılmış), gpu hafızası 31.374Gb + 31.372Gb = 62.748Gb
32single
Inference süresi 23.4s, cevap kalitesi orta(yıldız yerine hashtag kullanılmış), gpu hafızası 62.392Gb
Fp16
Inference süresi 17.0s, cevap kalitesi orta(yıldız yerine hashtag kullanılmış), gpu hafızası 31.430Gb
Bf16
Inference süresi 17.7s, cevap kalitesi orta(yıldız yerine hashtag kullanılmış), gpu hafızası 31.414Gb
8bit
Inference süresi 36.8s, cevap kalitesi iyi, gpu hafızası 10.020Gb
4bit
Inference süresi 35.1, cevap kalitesi iyi (yıldız yerine hashtag kullanılmış), gpu hafızası 10.020Gb
2.Deney: “A Python FastAPI service app that does create read update delete operations on strings that are called prompt”
Bu örnekte Python ile çalışılmış ve biraz daha yaratıcılığa imkan verilmiştir.
32multi
Inference süresi 22.7s, cevap kalitesi iyi(kurulum adımları ve URI’lar verildikten sonra kod veriliyor), gpu hafızası 31.472Gb + 31.472Gb = 62.944 Gb
32single
Inference süresi 22.8s, cevap kalitesi iyi, gpu hafızası 62.392 Gb
Fp16
Inference süresi 16.6s, Cevap kalitesi iyi, gpu hafızası 31.430Gb
Bf16
Inference süresi 16.3s, Cevap kalitesi iyi, gpu hafızası 31.430Gb
8bit
Inference süresi 34.7, Cevap kalitesi orta, gpu hafızası 10.020Gb
4bit
Inference süresi 34.7s, Cevap kalitesi orta, gpu hafızası 10.020Gb.
Sonuç
Cevap kalitesi nicemler arasında değişiklik gösterir ve her model için ayrı ayrı belirtilmiştir. Fp16 ve Bf16 nicemleri, tüm deneylerde en hızlı çıkarım süresine sahiptir. 8bit ve 4bit modeller, en az GPU hafızasını kullanırken, çıkarım süresi de en uzundur. Pytorch’un bu sayfasında [https://pytorch.org/docs/stable/quantization.html] nicemli modellerin daha hızlı olduğu belirtilmiştir bundan dolayı burada yazılımsal (BitsAndBytesConfig veya diğer sınıflarda veya bu sınıfların kullanımında) veya donanımsal bir anomali olduğu sonucuna varılmıştır.
Eğer bunun neden olabileceğine dair bir tahmininiz varsa yorumlarda belirtirseniz sevinirim.