Yapay Zekâ

Büyük Dil Modellerinin Tahmin ve İyileştirme için Bellek Optimizasyonu

mm
Memory for Large Language Model Inference

Büyük dil modelleri (LLM’ler) gibi GPT-4, Bloom ve LLaMA, milyarlarca parametre ile ölçeklenerek dikkat çekici yetenekler elde etti. Ancak, bu devasa modelleri tahmine veya iyileştirmeye dağıtmak, muazzam bellek gereksinimleri nedeniyle zorlu bir görevdir. Bu teknik blogda, LLM’lerin tahmine ve iyileştirmesi sırasında bellek tüketimini tahmin etme ve optimize etme tekniklerini keşfedeceğiz.

Bellek Gereksinimlerini Anlama

Bir LLM’i yüklemek için gereken bellek, öncelikle parametre sayısı ve parametreleri depolamak için kullanılan sayısal kesinlik tarafından belirlenir. Bir kural olarak:

  • X milyar parametreli bir modeli yüklemek için yaklaşık 4X GB VRAM gerekir 32-bit float精度de
  • X milyar parametreli bir modeli yüklemek için yaklaşık 2X GB VRAM gerekir 16-bit bfloat16/float16精度de

Örneğin, 175B parametreli GPT-3 modelini yüklemek için yaklaşık 350GB VRAM gerekir bfloat16精度de. Bugün, en büyük ticari olarak disponible GPU’lar gibi NVIDIA A100 ve H100 sadece 80GB VRAM sunar, bu da tensor paralellik ve model paralellik tekniklerini gerektirir.

Tahmin sırasında, bellek ayak izi, model parametreleri ve geçici aktivasyon tensörleri tarafından domine edilir. Tahmin sırasında zirve bellek kullanımının yüksek bir tahmini, model parametrelerini yüklemek için gereken bellek ve aktivasyonlar için belleğin toplamıdır.

Tahmin Belleğini nicelendirme

OctoCode modelini kullanarak, yaklaşık 15 milyar parametre ve bfloat16 formatında (~ 31GB) tahmine bellek gereksinimlerini nicelendirelim. Transformers kütüphanesini kullanarak modeli yükleyerek ve metin oluşturacağız:

from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
import torch

<p>model = AutoModelForCausalLM.from_pretrained(&quot;bigcode/octocoder&quot;,
torch_dtype=torch.bfloat16,
device_map=&quot;auto&quot;,
pad_token_id=0)
tokenizer = AutoTokenizer.from_pretrained(&quot;bigcode/octocoder&quot;)
pipe = pipeline(&quot;text-generation&quot;, model=model, tokenizer=tokenizer)</p>

<p>prompt = &quot;Soru: Python'da baytları gigabayta dönüştürmek için bir fonksiyon yazın.\n\nCevap:&quot;
result = pipe(prompt, max_new_tokens=60)[0][&quot;generated_text&quot;][len(prompt):]</p>

<p>def bytes_to_gigabytes(bytes):
return bytes / 1024 / 1024 / 1024</p>

<p>bytes_to_gigabytes(torch.cuda.max_memory_allocated())

Çıktı:

29.0260648727417

Zirve GPU bellek kullanımı yaklaşık 29GB’dir, bu da bfloat16 formatında model parametrelerini yüklemek için我们的 tahmini 31GB ile uyumlu.

Tahmin Belleğini nicelendirme ile Quantization

Bfloat16, LLM’lerin eğitimi için yaygın olarak kullanılan bir精度dir, ancak araştırmacılar, model ağırlıklarını daha düşük精度 veri türlerine (8-bit tam sayılar veya 4-bit tam sayılar) nicelendirdiklerinde, tahmine görevleri için önemli bellek kullanımını azaltabileceğini keşfettiler.

OctoCode modelinin 8-bit ve 4-bit nicelendirmesinden bellek tasarrufunu görelim:

&amp;lt;/div&amp;gt;
# 8-bit nicelendirme
model = AutoModelForCausalLM.from_pretrained(&quot;bigcode/octocoder&quot;, load_in_8bit=True,
pad_token_id=0)
pipe = pipeline(&quot;text-generation&quot;, model=model, tokenizer=tokenizer)
result = pipe(prompt, max_new_tokens=60)[0][&quot;generated_text&quot;][len(prompt):]
bytes_to_gigabytes(torch.cuda.max_memory_allocated())&lt;/pre&gt;
Çıktı:
15.219234466552734
# 4-bit nicelendirme
model = AutoModelForCausalLM.from_pretrained(&quot;bigcode/octocoder&quot;, load_in_4bit=True,
low_cpu_mem_usage=True, pad_token_id=0)
pipe = pipeline(&quot;text-generation&quot;, model=model, tokenizer=tokenizer)
result = pipe(prompt, max_new_tokens=60)[0][&quot;generated_text&quot;][len(prompt):]
bytes_to_gigabytes(torch.cuda.max_memory_allocated())

Çıktı:

9.543574333190918

8-bit nicelendirmesiyle, bellek gereksinimi 31GB’den 15GB’ye düşer, 4-bit nicelendirmesiyle ise 9.5GB’ye düşer! Bu, 15B parametreli OctoCode modelini tüketici GPU’ları gibi RTX 3090 (24GB VRAM) üzerinde çalıştırma olanağı sağlar.

Ancak, daha agresif nicelendirme gibi 4-bit’in bazen 8-bit veya bfloat16精度ye göre doğruluk kaybına neden olabileceğini unutmayın. Kullanıcılar, kullanım durumları için bellek tasarrufu ve doğruluk arasında bir denge kurmalıdır.

Nicelendirme, LLM’lerin dağıtımını kaynak kısıtlı ortamlarda, bulut örneklerinde, kenar cihazlarında veya hatta cep telefonlarında ermögelenerek bellek kullanımını önemli ölçüde azaltabilen güçlü bir tekniktir.

İyileştirme için Bellek Tahmini

Nicelendirme, verimli tahmine için kullanılırken, tensor paralellik ve model paralellik gibi teknikler, büyük dil modellerinin eğitimi veya iyileştirmesi sırasında bellek gereksinimlerini yönetmek için kritiktir.

İyileştirme sırasında zirve bellek tüketimi, genellikle tahmine göre 3-4 kat daha yüksektir ve şunlar için ek bellek gereksinimlerini içerir:

  • Gradyanlar
  • Optimizer durumları
  • İleri geçişten geri yayılım için depolanan aktivasyonlar

Muhafazakar bir tahmin, X milyar parametreli bir LLM’yi iyileştirmek için yaklaşık 4 * (2X) = 8X GB VRAM gerekir bfloat16精度de.

Örneğin, 7B parametreli LLaMA modelini iyileştirmek için yaklaşık 7 * 8 = 56GB VRAM gerekir her GPU için bfloat16精度de. Bu, mevcut GPU’ların bellek kapasitesini aşar ve dağıtılmış iyileştirme tekniklerini gerektirir.

Dağıtılmış İyileştirme Teknikleri

Birkaç dağıtılmış iyileştirme yöntemi, büyük modeller için GPU bellek kısıtlamalarını aşmak için önerilmiştir:

  1. Veri Paralellik: Klasik veri paralellik yaklaşımı, tüm modeli birden fazla GPU’ya kopyalar ve eğitim veri partilerini dağıtır. Bu, eğitim süresini GPU sayısıyla lineer olarak azaltır, ancak her GPU’daki zirve bellek gereksinimini azaltmaz.
  2. ZeRO Stage 3: Gelişmiş bir veri paralellik biçimi, model parametrelerini, gradyanları ve optimizer durumlarını GPU’lar arasında böler. Bu, her GPU’da yalnızca gerekli paylaşılan verileri tutarak klasik veri paralellikten daha az bellek kullanır.
  3. Tensor Paralellik: Modeli kopyalamak yerine, tensor paralellik, model parametrelerini satırlara veya sütunlara böler ve bunları GPU’lar arasında dağıtır. Her GPU, parametrelerin, gradyanların ve optimizer durumlarının bir paylaşılan kümesini işler, bu da önemli bellek tasarrufu sağlar.
  4. Boru Hattı Paralellik: Bu teknik, model katmanlarını farklı GPU’lar veya işçiler arasında böler, her cihazın bir alt küme katmanları çalıştırır. Aktivasyonlar işçiler arasında geçirilir, bu da zirve belleği azaltır, ancak iletişim yükünü artırır.

Bu dağıtılmış yöntemler için bellek kullanımını tahmin etmek zorlu bir görevdir, çünkü parametreler, gradyanlar, aktivasyonlar ve optimizer durumlarının dağılımı tekniklere göre değişir. Ayrıca, transformer gövdesi ve dil modeli başlığı gibi farklı bileşenler, farklı bellek ayırma davranışları gösterebilir.

LLMem Çözümü

Araştırmacılar, LLMem’i önerdiler, bu da LLM’lerin dağıtılmış iyileştirme yöntemleri uygulanırken GPU bellek tüketimini doğru bir şekilde tahmin eden bir çözümdür.

Ön eğitimli LLM'ler için GPU Bellek Kullanımının Tahmini

Ön eğitimli LLM’ler için GPU Bellek Kullanımının Tahmini

LLMem, hesaplamadan önce parametreleri birleştirmek (ZeRO Stage 3), geri yayılım sırasında çıktı toplamak (tensor paralellik) ve transformer gövdesi ve dil modeli başlığı için farklı bellek ayırma stratejileri gibi faktörleri dikkate alır.

Deneysel sonuçlar, LLMem’in tek bir GPU’da LLM’lerin iyileştirilmesi için zirve GPU bellek kullanımını %1,6’nın altında bir hata oranıyla tahmin edebileceğini, bu da DNNMem’in ortalama %42,6’lık hata oranını aşar. LLM’lerin birden fazla GPU’da dağıtılmış iyileştirme yöntemleri uygulandığında, LLMem %3,0’lık ortalama bir hata oranıyla başarılı olur.

LLMem, bellek gereksinimlerini önceden doğru bir şekilde tahmin ederek, kullanıcıların en verimli dağıtılmış iyileştirme yapılandırmasını seçmesine yardımcı olur.

Yeni Teknikler

Nicelendirme, tensor paralellik ve model paralellik gibi teknikler kurulmuşken, araştırmacılar, verimli LLM eğitimi ve dağıtımı için yeni yöntemler keşfetmeye devam ediyor.

  1. LoRA ve QLoRA: Bu teknikler, büyük bir LLM’yi doğrudan iyileştirmek yerine, yeni bilgi ile güncellemek için daha küçük bir artımlı bir adaptör modülünü eğitmeyi içerir. Bu, model performansını korurken önemli bellek tasarrufu sağlar.
  2. FlashAttention: Self-attention mekanizması, transformer modellerinde bir bellek ve hesaplama darboğazdır. FlashAttention, standard attentionı lineer karmaşıklıkta yaklaşık olarak hesaplar, bu da bellek gereksinimlerini girdinin uzunluğunun karesinden lineer olarak azaltır.
  3. Uzmanlar Karışımı: Bu yaklaşım, her girdi veri örneğini, tüm modeli işlemek yerine, uzman bir modele yönlendirir. Bu, her örnek için yalnızca bir alt küme uzmanların etkinleştirilmesini sağlayarak bellek tasarrufu sağlar.
  4. Ters Model Cerrahisi: Araştırmacılar, daha az önemli bileşenleri (dikkat başlıkları) kaldırarak modeli cerrahi olarak sıkıştırmayı keşfettiler. Bu, bellek/hız için doğruluk arasında bir ticaret sağlar.
  5. Offloading: Son olarak, parametreleri, optimizer durumlarını veya aktivasyonları CPU RAM’ine veya diske offload eden teknikler, büyük modeller için sınırlı GPU belleğini tamamlayabilir.

Bu yeni yöntemler, verimli LLM eğitimi ve dağıtımı için araştırma ekosistemini göstermektedir.

Sonuç

Büyük dil modellerinin bellek gereksinimleri, gerçek dünya uygulamalarında yaygın olarak benimsenmeleri için önemli bir engel oluşturur. LLM’lerin dağıtımını optimize etmek için bellek tahmin tekniklerini anlama, nicelendirme, dağıtılmış eğitim stratejileri ve yeni gelişen yenilikleri kullanarak, kaynak kısıtlı cihazlarda LLM’lerin verimli bir şekilde çalıştırılmasını sağlayabiliriz.

Araçlar gibi LLMem, bellek gereksinimlerini doğru bir şekilde tahmin ederek, kullanıcıların en verimli dağıtılmış iyileştirme yapılandırmasını seçmesine yardımcı olur. Donanım geliştikçe ve araştırma ilerledikçe, daha verimli LLM eğitimi ve tahmine doğru ilerleyebiliriz, bu da doğal dil işleme ve yapay zeka alanlarında ilerlemeye yol açar.

Model kapasitesi, doğruluk ve kaynak kullanımı arasında doğru dengeyi bulmak, büyük dil modellerinin çeşitli alanlarda ve kullanım durumlarında tam potansiyellerini açığa çıkarmak için kritik olacaktır. Bellek optimizasyon tekniklerini benimseyerek, state-of-the-art dil AI’nin erişilebilir, ölçeklenebilir ve sürdürülebilir olacağı bir geleceğe doğru ilerlemekteyiz.

Son beş yıldır Makine Öğrenimi ve Derin Öğrenme dünyasına kendimi adamış bulunuyorum. Tutkum ve uzmanlığım, özellikle AI/ML'ye odaklanarak 50'den fazla çeşitli yazılım mühendisliği projesine katkıda bulunmama yol açtı. Süregelen meraklılığım da beni Doğal Dil İşleme alanına yöneltti, bu alana daha da derinlemesine girmeye hevesliyim.