BFloat16 (BF16)
BFloat16 (BF16), FP32'nin 8 bitlik üssüne ve 7 bitlik kesirine sahip 16 bitlik bir kayan nokta biçimidir; belleğin yarısını kullanırken FP32'nin değer aralığını korur. FP16'dan farkları.
BFloat16 (beyin kayan noktası, BF16), 1 işaret biti, 8 üs biti ve 7 kesir bitinden oluşan 16 bitlik bir kayan nokta biçimidir. Standart 32 bit kayan noktalı sayı biçimiyle (FP32) aynı üs genişliğini koruduğu için yaklaşık 1.2 × 10⁻³⁸ ile 3.4 × 10³⁸ arasındaki değerleri kapsar; üstelik her sayıyı belleğin yarısını kullanarak saklar. Bunun bedeli duyarlılıktır: 7 kesir biti, yalnızca iki ila üç anlamlı ondalık basamak sağlar. Derin öğrenme bu yuvarlamayı iyi tolere eder. Google Brain'de Google'ın TPU'ları için tasarlanan bu biçim, büyük modelleri modern GPU'larda ve hızlandırıcılarda eğitmek için varsayılan 16 bitlik biçim hâline geldi.
BF16 Sayıları Nasıl Temsil Eder#
Bir BF16 değeri, FP32 değerinin üst yarısıyla bire bir aynıdır: işaret ve üs aynıdır, kesir ise 23 bitten 7 bite düşürülmüştür. Bu nedenle FP32'yi BF16'ya dönüştürmek yalnızca alt 16 biti yuvarlayarak atar; geriye dönüştürme ise sıfırlar ekler. Bu da biçimin donanımda uygulanmasını ucuz hâle getirir. Diğer yaygın 16 bitlik biçim olan IEEE FP16 veya yarı duyarlık, bitleri farklı böler: 5 üs biti ve 10 kesir biti kullanarak aralık pahasına duyarlılık sağlar. Üç biçimi aynı değerler üzerinde karşılaştırınca fark ortaya çıkar:
import torch
# Largest value, smallest normal value, and spacing just above 1.0 for each format
for dtype in [torch.float32, torch.float16, torch.bfloat16]:
info = torch.finfo(dtype)
print(f"{dtype!s:15} max={info.max:.3g} tiny={info.tiny:.3g} eps={info.eps:.3g}")
# A large activation, a tiny gradient, and a value that needs fine precision
x = torch.tensor([70000.0, 1e-8, 1.001953125])
print("FP16:", x.half().tolist())
print("BF16:", x.bfloat16().tolist())BF16'nın en büyük değeri 3.39e38'dir; FP16'nınki ise 65,504'tür. BF16'nın en küçük normal değeri olan 1.18e-38, FP32'ninkiyle aynıdır. FP16, 70,000 değerini sonsuza, 1e-8 değerini sıfıra dönüştürürken BF16 her ikisini de sırasıyla 70,144 ve yaklaşık 1.0e-8 olarak korur. FP16'nın daha ince aralıklı adımı (BF16'nın 0.00781 değerine karşı eps 0.000977), 1.001953125 değerini tam olarak korur; BF16 ise bu değeri 1.0'a yuvarlar.
Eğitimde BF16 ve FP16#
Eğitim sırasında aralık, duyarlılıktan daha önemlidir. Gradyanlar genellikle FP16'nın temsil edebildiği en küçük değerlerin altına düşüp kaybolur. Bu nedenle FP16 karma duyarlıklı eğitim, geri yayılımdan önce kaybı bir ölçekleme katsayısıyla çarpar ve gradyanlar taştığında bu katsayıyı düşürür; bu tekniğe kayıp ölçekleme denir. Aralığı FP32 ile aynı olduğu için BF16'da kayıp ölçekleme gerekmez. BF16 eğitimi, görüntü, konuşma, dil ve öneri modellerinde FP32 ile aynı sayıda yinelemede aynı sonuçları verir ve hiperparametreleri değiştirmeyi gerektirmez. Karma duyarlıklı eğitim, ağırlıkların ana kopyasını FP32'de tutar; matris çarpımlarını ise FP32 biriktirmeyle BF16'da yürütür. Çünkü BF16'da 7 kesir bitli çok sayıda çarpımı toplamak fazla bilgi kaybına yol açar. Bu iki 16 bitlik biçim arasındaki seçim çoğunlukla donanıma bağlıdır:
PyTorch, BF16'yı torch.autocast(device_type="cuda", dtype=torch.bfloat16) aracılığıyla otomatik karma duyarlık kullanarak uygular. Ultralytics YOLO, eğitim için aynı seçeneği amp="bf16" ile sunar. Bu seçenek, ileri geçişi BF16 autocast altında yürütür ve CUDA GPU'larda yerel BF16 desteği olduğunda varsayılan FP16 kipinin kullandığı gradyan ölçekleyicisini devre dışı bırakır.
Donanım Desteği#
Google'ın ikinci ve üçüncü nesil Cloud TPU'ları matris birimlerinde BF16 çarpımı yapıp FP32'de biriktirir; sonraki TPU nesilleri de bu biçimi korudu. NVIDIA GPU'lar Ampere neslinden itibaren A100, H100 ve Blackwell GPU'lar dâhil Tensor Cores üzerinde BF16 çalıştırır. Advanced Matrix Extensions (AMX) özellikli Intel Xeon işlemciler de CPU'da BF16'yı hızlandırır. Bir NVIDIA A100 üzerinde BF16 ve FP16 Tensor Core işlemlerinin ikisi de 312 teraFLOPS tepe performansına ulaşır; bu, GPU'nun standart FP32 işlemlerindeki 19.5 teraFLOPS değerinin 16 katıdır.
BF16 ve İlgili Biçimler#
- Yarı duyarlık (FP16): Daha yüksek duyarlılığa ve çok daha dar aralığa sahip IEEE 16 bitlik biçim. Aktivasyonların aralık içinde kaldığı ve ek duyarlılığın yarar sağladığı çıkarım işlemlerinde hâlâ yaygındır.
- TF32: BF16'nın 8 bitlik üs genişliğiyle FP16'nın 10 bitlik kesir genişliğini birleştiren NVIDIA Tensor Core matematik kipi. Kütüphaneler bunu Ampere ve daha yeni GPU'larda FP32 matris çarpımları için kullanabilirken tensörler 32 bitlik biçimde saklanmaya devam eder.
- FP8: Hopper ve Blackwell GPU'ların desteklediği E4M3 ve E5M2 gibi 8 bitlik kayan nokta biçimleri. En büyük modellerin eğitimi ve çıkarımı sırasında bellek kullanımını bir kez daha yarıya indirir.
- Model nicemleme: Eğitilmiş ağırlıkları dağıtım için INT8 veya INT4 gibi tamsayı biçimlerine dönüştürür.
Büyük Dil Modellerinde BF16#
Açık ağırlıklı büyük dil modellerinin (LLM'ler) çoğu BF16 karma duyarlıkla eğitilir ve nicemlenmiş FP8 ve INT4 sürümlerinin karşılaştırıldığı referans olan BF16 ağırlıklarıyla yayımlanır. Parametre başına 2 bayt kullanıldığında, 70 milyar parametreli bir modelin ağırlıkları BF16'da 140 GB yer kaplar; bu, tek bir NVIDIA H100'ün 80 GB belleğinden fazladır. Dolayısıyla böyle bir modeli BF16'da sunmak, modeli en az iki GPU'ya bölmeyi gerektirir.










