2 poin oleh GN⁺ 2025-04-26 | 1 komentar | Bagikan ke WhatsApp
  • LLM besar sulit di-deploy karena batas memori GPU, sementara DFloat11 mengecilkan bobot BFloat16 menjadi sekitar 70% ukurannya sambil mempertahankan output yang identik bit demi bit dengan aslinya
  • Kuncinya adalah bahwa exponent 8-bit pada BFloat16 sebenarnya hanya memuat sekitar 2,6 bit informasi; sign dan mantissa dipertahankan, sedangkan hanya exponent yang dikompresi dengan Huffman coding
  • Encoding panjang dinamis mudah menjadi bottleneck di GPU, sehingga DFloat11 disesuaikan untuk inferensi paralel dengan LUT hierarkis, kernel 2 tahap, dan dekompresi per transformer block
  • Pada Llama 3.3, Qwen 3, Mistral 3, DeepSeek R1 Distilled, FLUX.1, Stable Diffusion 3.5, dan lainnya, terbukti ada pengurangan ukuran model sekitar 30% sekaligus pelestarian output asli
  • Dibandingkan alternatif CPU offload, throughput token generation 2,3–46,2 kali lebih tinggi, dan memungkinkan inferensi lossless Llama 3.1 405B berukuran 810GB pada satu node GPU 8×80GB

Bottleneck memori yang dibidik DFloat11

  • Foundation model seperti LLM dan Diffusion Model tumbuh ukurannya dengan cepat, sehingga sulit di-deploy secara efisien pada hardware dengan keterbatasan memori
  • Llama 3.1 405B menyimpan 405 miliar parameter dalam format BFloat16 dan membutuhkan sekitar 810GB memori untuk inferensi penuh
    • Ini melampaui kapasitas server GPU kelas atas umum dengan GPU 8×80GB
    • Jika membutuhkan beberapa node, biaya deployment dan beban aksesibilitas meningkat
  • DFloat11 bertujuan mengompresi model BFloat16 menjadi sekitar 70% dari ukuran aslinya sambil menjaga akurasi 100% pada tugas apa pun

Pendekatan yang berbeda dari kuantisasi lossy

  • Kuantisasi adalah metode kompresi lossy yang mengurangi memori dengan menurunkan presisi bobot
    • Ini dapat sangat mengurangi penggunaan memori dan meningkatkan kecepatan inferensi, tetapi menimbulkan error aproksimasi
    • Penurunan akurasi sulit diprediksi karena bergantung pada model dasar, metode kuantisasi, benchmark evaluasi, dan target bit-width
  • Misalnya, menerapkan 8-bit SmoothQuant pada DeepSeek-R1-Distill-Qwen-1.5B menurunkan akurasi rata-rata reasoning task sebesar 9,09%
  • Meski metrik akurasi keseluruhan tampak serupa, model terkuantisasi dapat menunjukkan perilaku jawaban yang berbeda dari model asli
    • Dutta et al. mengamati fenomena flips, yaitu jawaban benar berubah menjadi salah, atau jawaban salah berubah menjadi benar
    • Qwen2-1.5B yang dikuantisasi dengan W8A16 GPTQ hanya mengalami penurunan akurasi GSM8K 8-shot sebesar 0,3%, tetapi status benar/salah berubah pada 6,37% jawaban
  • Di bidang seperti keuangan dan medis, perubahan output dari model terkuantisasi dapat membuatnya sulit memenuhi persyaratan regulasi dan keandalan
  • Kompresi model lossless yang ada selama ini terutama berfokus pada efisiensi penyimpanan checkpoint, pemangkasan waktu unduh dari model hub, dan hardware khusus seperti FPGA, sehingga manfaatnya kecil untuk inferensi GPU umum

Ruang kompresi yang tersisa pada exponent BFloat16

  • BFloat16 membagi 16 bit menjadi sign 1 bit, exponent 8 bit, dan mantissa 7 bit
  • Titik awal DFloat11 adalah analisis Shannon entropy per komponen BFloat16 pada bobot LLM
    • Entropy sign dan mantissa mendekati bit-width masing-masing, sehingga ruang kompresinya terbatas
    • Exponent dialokasikan 8 bit, tetapi entropy-nya hanya sekitar 2,6 bit
  • Distribusi nilai exponent sangat tidak seimbang
    • Dari 256 kemungkinan nilai 8-bit, hanya sekitar 40 yang digunakan
    • Nilai lainnya tidak muncul
    • Peringkat frekuensinya juga turun dengan cepat
  • Berkat entropy yang rendah, exponent menjadi target kompresi lossless, dan sekitar 5,4 bit informasi exponent dapat dikompresi

Format DFloat11

  • DFloat11 atau DF11 adalah format floating-point panjang dinamis yang mengompresi hanya exponent dari bobot BFloat16 menggunakan entropy coding
  • Huffman tree dibangun berdasarkan distribusi exponent pada bobot model
    • Nilai exponent yang sering muncul diberi kode pendek
    • Nilai yang jarang muncul diberi kode panjang
  • Sign dan mantissa dipertahankan seperti aslinya
    • Exponent disimpan dalam bentuk bit-packed pada byte array EncodedExponent
    • Sign dan mantissa disimpan terpisah dalam byte array PackedSignMantissa
  • Hasilnya, bobot BFloat16 berkurang rata-rata menjadi sekitar 11 bit, dan dapat dipulihkan ke nilai BFloat16 asli tanpa kehilangan presisi

Dekompresi yang disesuaikan untuk inferensi GPU

  • Bobot yang di-entropy-code menggunakan encoding panjang dinamis, sehingga tidak dapat langsung dimasukkan ke matrix multiplication
    • Weight matrix yang diperlukan harus segera didekompresi kembali ke BFloat16 asli
    • Setelah matrix multiplication selesai, matrix BFloat16 langsung dibuang untuk menghemat memori GPU
  • Huffman decoding umum menelusuri tree secara sekuensial per bit, sehingga tidak cocok dengan struktur paralel GPU
    • Jika satu thread menangani dekompresi, utilisasi GPU rendah dan latency meningkat

Decoding berbasis LUT hierarkis

  • DFloat11 menggunakan decoding berbasis lookup table alih-alih penelusuran Huffman tree
  • Jika panjang maksimum Huffman code adalah L, satu LUT membutuhkan ukuran 2^L
    • Pada LLM, L biasanya berada di rentang 24–32
    • LUT berskala 2^32 entri sulit dimuat ke SRAM GPU
  • Untuk menghindarinya, Huffman tree dibagi menjadi subtree setinggi 8 yang tidak saling tumpang tindih, dan tiap subtree dijadikan compact LUT berisi 256 entri
  • Dalam LUT hierarkis, sebagian entri harus berperan sebagai referensi yang menunjuk ke LUT di bawahnya
    • Ini memanfaatkan fakta bahwa banyak nilai exponent tidak digunakan pada LLM
    • Nilai exponent yang tidak digunakan pada rentang 240–255 dipakai ulang sebagai pointer internal
    • Nilai-nilai ini merepresentasikan besaran yang sangat besar, sekitar ±2^113 hingga ±2^128, dan tidak muncul pada bobot LLM
  • Dalam eksperimen, jumlah compact LUT k pada Huffman tree exponent BFloat16 berada di rentang 4–8
    • Bersama CodeLengths, memori yang digunakan maksimal (8 + 1) × 256 bytes
    • Ukuran ini muat di SRAM dan memungkinkan lookup berulang dilakukan dengan cepat

Kernel GPU 2 tahap dan metadata bantu

  • Setiap thread GPU menangani segmen n byte berurutan dari encoded exponent
    • Dalam eksperimen digunakan n = 8
    • Thread mendecode Huffman code yang dimulai di dalam segmennya sendiri
  • Kode panjang dinamis menimbulkan dua masalah
    • Posisi bit awal yang tepat untuk tiap thread tidak jelas
    • Selain thread pertama, sulit mengetahui output index dari decoded element
  • Masalah pertama diselesaikan dengan array Gaps
    • Gaps memiliki satu entri per thread
    • Setiap entri menunjukkan bit offset dari Huffman code valid pertama relatif terhadap byte awal thread
    • Karena panjang kode maksimum 32 bit, offset berada dalam rentang [0, 31] dan disimpan dalam 5 bit
  • Masalah posisi output diatasi dengan hanya menyimpan posisi per thread block untuk mengurangi overhead memori
    • Jika menyimpan posisi output 32-bit untuk tiap thread, overhead menjadi besar pada puluhan ribu thread per weight matrix
    • DFloat11 hanya menyimpan posisi output element pertama dari tiap thread block
  • Kernel bekerja dalam dua tahap
    • Pada tahap 1, tiap thread mendecode segmennya sendiri dan hanya menghitung jumlah element tanpa menulis ke HBM
    • Thread dalam block melakukan prefix sum dengan Blelloch algorithm untuk menghitung posisi output tiap thread
    • Pada tahap 2, segmen yang sama didecode lagi, lalu nilai decoded ditulis ke SRAM write buffer sesuai posisi yang dihitung
    • Encoded exponent dimuat ke SRAM sebelum pass pertama untuk menghindari akses global memory ganda
    • Setelah semua decoded exponent ditulis ke SRAM, satu coalesced write dilakukan ke HBM

Dekompresi per transformer block

  • Dekompresi satu weight matrix bisa terlalu kecil untuk memanfaatkan resource GPU secara penuh
  • Semakin besar ukuran matrix, throughput dekompresi DFloat11 semakin membaik
  • Beberapa matrix didekompresi bersama untuk meningkatkan throughput dan menyembunyikan latency
    • Semua weight matrix DFloat11 dalam satu transformer block didekompresi sebagai satu batch
    • Batched decompression ini dilakukan tepat sebelum forward pass transformer block tersebut
  • Token embedding dan language modeling head pada LLM juga menjadi target kompresi
    • Matrix-matrix ini cukup besar untuk memenuhi resource GPU, sehingga tidak memerlukan batching terpisah

Hasil evaluasi dan efek nyata

  • DFloat11 dievaluasi pada LLM dan diffusion transformer, termasuk Llama 3, Qwen 3, Mistral 3, DeepSeek R1 Distilled, FLUX.1, Stable Diffusion 3.5, dan lainnya
  • Hasilnya menunjukkan pengurangan ukuran model sekitar 30% dan pelestarian penuh output asli
    • Output identik bit-for-bit dengan model asli
    • Karena bukan kompresi lossy, presisi bobot BFloat16 asli tetap dipertahankan
  • Dibandingkan dengan alternatif yang melakukan offload sebagian model tak terkompresi ke CPU untuk memenuhi batas memori, DFloat11 mencapai throughput 2,3–46,2 kali lebih tinggi dalam token generation
  • Pada anggaran memori GPU tetap, DFloat11 memungkinkan generation length 5,7–14,9 kali lebih panjang dibanding model tak terkompresi
  • Llama 3.1 405B adalah model berukuran 810GB, tetapi DFloat11 memungkinkan inferensi lossless pada satu node GPU 8×80GB A100
  • Hasil ini menunjukkan bahwa kebutuhan hardware untuk menjalankan Llama-3.1-405B dapat dipangkas setengahnya sambil melakukan inferensi tanpa accuracy loss

1 komentar

 
GN⁺ 2025-04-26
Opini Hacker News
  • Ini hanyalah konsekuensi dari fakta bahwa rentang dinamis bfloat16 sangat lebar, tetapi dalam praktiknya rentang itu tidak dipakai sepenuhnya.
    Orang suka jika hiperparameter terlihat seperti 0,01, bukan 10^10, tetapi presisi relatif yang sama bisa dipakai pada setiap eksponen. Meski hiperparameter jaringan, bobot yang diinisialisasi, data pelatihan, dan sebagainya semuanya dikalikan 10^6, perilakunya secara umum tetap mirip karena area batas atas nyaris tidak digunakan. Namun, beberapa fungsi khusus bisa menjadi pengecualian.
    Entropi tipikal nilai bfloat16 yang terlihat pada bobot dan aktivasi sekitar 10–12 bit, dan dalam praktiknya hanya sekitar 65–75% dari rentang nilai yang dipakai. Bit tanda dan mantissa hampir seperti noise yang sulit dikompresi.
    Sifat seperti ini sudah beberapa kali dimanfaatkan baik dalam komputasi berkinerja tinggi klasik maupun AI. Contohnya adalah pekerjaan kompresi lossless dari lab Martin Burtscher (https://userweb.cs.txstate.edu/~burtscher/), fpzip dari LLNL (https://computing.llnl.gov/projects/fpzip), dan pustaka saya yang dibuat pada 2021, dietgpu (https://github.com/facebookresearch/dietgpu). Di klaster GPU besar, kami mengompresi secara lossless semua data sebelum transfer, misalnya gradien atau bobot dari backup, lalu mendekompresinya saat diterima, sehingga mengurangi total waktu pelatihan wall-clock sekitar 10%. Karena lossless, hasil komputasinya sama seperti sebelumnya.
    Selain itu, rANS lebih efisien daripada pengodean Huffman pada set instruksi bergaya SIMD dan juga lebih mudah diimplementasikan. Di DFloat11 pun data harus didekompresi sebelum operasi aritmetika, sehingga latensi dan kehilangan throughput bisa dikurangi.

    • Sebagai tambahan bagi yang tidak sengaja membuka profilnya, Jeff benar-benar orang yang sangat memahami bidang ini. Meta/FAIR dan sebagian besar komunitas mendapat banyak manfaat dari kodenya.
    • Saya penasaran apakah ada tulisan yang merangkum rANS. Kalau dicari online, yang muncul hanya solusi pemodelan turbulensi, dan sepertinya bukan itu yang dimaksud.
      Kuantisasi adalah alat utama bagi pelaku LLM lokal, dan biasanya RAM menjadi bottleneck. Saya juga penasaran apakah ada kompresi lossless yang lebih baik untuk bobot BF16.
      DFloat11 tampaknya bisa disisipkan ke workflow kuantisasi yang ada dengan relatif mudah, tetapi Anda tampaknya cukup skeptis terhadap paper ini, jadi saya ingin memahami apa yang saya lewatkan.
    • Pernyataan bahwa mengalikan segala sesuatu di jaringan dengan 10^6 akan membuatnya berperilaku hampir sama terdengar sangat meragukan.
      Dalam lapisan neural network, input dikalikan dengan bobot dan dijumlahkan, lalu output itu menjadi input lapisan berikutnya, dan proses ini bisa diulang lebih dari seratus kali. Saat mencapai lapisan output akhir, faktor 10^6 itu akan diterapkan berkali-kali dan membesar seperti bola salju hingga sekitar 10^600.
    • Jika melihat halaman lampiran terakhir, paper aslinya melaporkan bahwa DFloat11 menurunkan jumlah token per detik sekitar 2–3× pada model Llama-3.1-8b, Qwen-2.5-14b/32b, dan Mistral-small-24b. Kehilangan throughput pada model lain tidak dilaporkan.
      Kasus ketika token per detik lebih tinggi dengan DFloat11 hanya terjadi saat dibandingkan dengan inferensi yang meng-offload sebagian lapisan ke CPU.
      Ini trade-off ruang-kecepatan khas ilmu komputer, dan tidak ada makan siang gratis.
    • Jadi apakah bfloat itu sebuah kesalahan? Bukankah tujuan awalnya adalah meningkatkan rentang dinamis?
      Meski begitu, biaya untuk memotong dan mengisi dengan nol kecil.
  • Yang paling menonjol adalah implikasi praktisnya. Membuat model 405B parameter bisa menjalankan inferensi lossless pada satu node 8×80GB GPU itu cukup menakjubkan.
    Ini bisa menjadi pembuka besar bagi lab riset maupun startup yang ingin menjalankan model frontier tanpa biaya infrastruktur raksasa.

    • Atau serahkan biaya infrastruktur kepada penyedia neocloud dan sewa dari mereka. Sebagai keterbukaan, saya menjalankan salah satu penyedia seperti itu.
    • Saya bukan ahli di bidang ini, jadi ingin bertanya: apakah angka 405B punya makna khusus?
    • Model kuantisasi 4-bit DeepSeek atau Llama 3 405B sudah bisa masuk ke GPU-GPU tersebut, dan kabarnya hampir tidak ada loss dibandingkan model penuh. Dengan mempertimbangkan itu, ini tidak terasa sebesar itu.
    • Untuk saat ini memang berguna, tetapi di dunia tempat ukuran model, ukuran memori GPU, dan dukungan berbagai presisi berubah cepat, ini belum sampai menjadi pembuka yang sangat besar.
  • Saya bersyukur bisa hidup di zaman semenarik ini. Setiap kali membuka HN, selalu ada kabar baru terkait machine learning dan model transformer.
    Saya harus membacanya lebih dalam, tetapi saya penasaran apakah llama.cpp memakai semacam kernel kustom bersama cuBLAS, atau hanya memanfaatkan kernel cuBLAS dengan baik.

    • Menarik bahwa satuan waktu hilang dari kalimat itu.
      2 minggu? Dua bulan? Dua hari? 2 menit?
      Kadang semuanya benar. Ini benar-benar zaman yang menarik.
  • Setelah perang format bobot ini terselesaikan, hardware bisa dibuat untuk mendukungnya. Apa pun format bobot yang akhirnya diputuskan sebagai yang cukup optimal, kita akan membutuhkan hardware perkalian matriks yang dioptimalkan untuk itu.

    • Optimisasi di sini bersifat setelah fakta. Untuk melakukan pengodean Huffman, pelatihan harus dilakukan lebih dulu, jadi ini bukan masalah format murni.
  • Dalam kasus penggunaan agen nyata, sering kali sulit menyeimbangkan kualitas, biaya, dan performa. Teknik ini bisa membantu menghindari trade-off yang dibuat teknik kuantisasi, termasuk hasil yang sulit diprediksi saat mencoba mengoptimalkan biaya agen.
    Jika DFloat11 memungkinkan model dimasukkan ke GPU yang lebih murah, penghematan biaya bisa cukup besar dalam beberapa kasus. Saya bekerja di xmad.ai

  • Dibandingkan dengan alternatif meng-offload sebagian model yang tidak dikompresi ke CPU karena keterbatasan memori, DFloat11 disebut memiliki throughput pembuatan token 1,9–38,8 kali lebih tinggi. Dengan anggaran memori GPU yang tetap, ini memungkinkan panjang konteks 5,3–13,17 kali lebih panjang dibandingkan model yang tidak dikompresi
    Dari panjang konteks saja, ini tampaknya sudah berguna meski modelnya muat di memori. Namun, berdasarkan pemahaman dasar bahwa LLM sering kali dibatasi bandwidth memori, saya penasaran apakah jumlah token per detik juga membaik saat semuanya berada di GPU

    • Tidak. Dekompresi dilakukan dengan memindahkan tensor satu per satu dari memori ke memori, jadi justru lebih buruk
      Makalahnya mengklaim kurang dari 200GB/s di A100, dan dari benchmark tampaknya 1,5–4 kali lebih lambat pada batch size 1, tergantung GPU dan model. Tentu saja, jika batch size cukup besar, overhead ini sebagian besar hilang
      Codec lossless lain bisa mencapai 600GB/s pada hardware yang sama, jadi tampaknya masih ada ruang perbaikan. Namun bandwidth memori mentah A100 adalah 1,6TB/s
    • Dalam model mental saya, ini mungkin saja bisa. Mirip seperti DoubleSpace di DOS yang sedikit mempercepat loading disk dari hard disk yang lambat
    • Jika ukuran model menjadi 70%, kecepatannya akan menjadi 1/0,7, yaitu 1,43 kali
  • Apakah ini berarti kebutuhan memori LLM yang tidak dikuantisasi secara umum bisa dikurangi 30%? Kalau benar, itu cukup besar

    • Jika kuantisasi Q8 saja sudah dianggap berlebihan tetapi mengurangi ukuran menjadi 50% dan memberikan peningkatan kecepatan 2 kali secara bersih tanpa overhead komputasi tambahan, maka ini tidak terlalu besar. Q4KM yang lebih umum kira-kira berada di level 30%
      Jika bisa ditambahkan di atas kuantisasi yang ada, jelas ini menarik, tetapi kuantisasi K juga sudah menggunakan presisi berbeda per layer berdasarkan dampak perplexity secara keseluruhan. Misalnya Q6 mencampur 4-bit dan 8-bit, yang mirip dengan metrik entropi yang digunakan di sini. Jika ikut mempertimbangkan imatrix yang dikalibrasi, secara konseptual ia mengompresi lebih kuat dengan cara yang mirip FFT
  • Apakah ini berbeda dari ZipNN? https://arxiv.org/pdf/2411.05239
    Saya melihat ada penyebutan, tetapi tidak paham apakah ini berbasis pada itu, atau berbeda, atau lebih baik

    • Ketemu. Kabar ini mengingatkan saya pada makalah ini https://proceedings.neurips.cc/paper/2020/file/747e32ab0fea7...
    • Tidak terlalu. Mereka hanya menambahkan sedikit pekerjaan transposisi data, yaitu mengumpulkan byte-byte individual dari word data lalu menyusunnya, serta opsi memakai kompresor LZ/berbasis kamus untuk mengompresi duplikasi
      Namun kompresor jenis LZ tampaknya tidak terlalu berarti untuk bobot neural network. Redundansinya tidak setinggi kebanyakan data teks yang banyak pengulangan, dan jika datanya tidak sangat sparse, mungkin tidak ada cukup pengulangan yang bisa dimanfaatkan untuk mengimbangi overhead kamus
      Jika menambahkan kompresor jenis LZ dan memasukkannya ke jalur inti inferensi, dekompresinya akan jauh lebih lambat. Yang terbaik adalah menggabungkan dekompresi dengan kernel komputasi. Misalnya bisa dibuat seperti GEMM yang mendekompresi tiap tile sebelum operasi aritmetika, dan semakin sederhana rutinitas dekompresinya, semakin mudah hal ini dilakukan
  • Cukup keren melihat betapa cepat semua ini bergerak. Rasanya setiap minggu ada teknik efisiensi baru atau upgrade hardware baru
    Mudah sekali perhatian kita tersedot oleh peningkatan seperti ini

  • Apakah ini bisa dijalankan juga pada model baru? Kalau saya tidak salah paham, kodenya tampaknya hanya untuk inferensi