<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>VRAM on kenji.blog</title><link>http://kenji.blog/id/tags/vram/</link><description>Recent content in VRAM on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>id</language><copyright>kenjinote</copyright><lastBuildDate>Fri, 11 Sep 2026 01:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/id/tags/vram/index.xml" rel="self" type="application/rss+xml"/><item><title>Teknik Mengatasi Kekurangan Memori GPU dalam Pengembangan AI (CPU Offloading, dll.)</title><link>http://kenji.blog/id/p/ai-gpu-vram-optimization-cpu-offloading/</link><pubDate>Fri, 11 Sep 2026 01:00:00 +0900</pubDate><guid>http://kenji.blog/id/p/ai-gpu-vram-optimization-cpu-offloading/</guid><description>&lt;img src="http://kenji.blog/p/ai-gpu-vram-optimization-cpu-offloading/img/eyecatch.jpg" alt="Featured image of post Teknik Mengatasi Kekurangan Memori GPU dalam Pengembangan AI (CPU Offloading, dll.)" />&lt;h1 id="pengantar-pengembangan-ai-dan-tembok-vram">Pengantar: Pengembangan AI dan &amp;lsquo;Tembok VRAM&amp;rsquo;
&lt;/h1>&lt;p>Dalam beberapa tahun terakhir, teknologi AI generatif seperti Large Language Models (LLM) dan Diffusion Models telah mengalami perkembangan yang sangat pesat. Namun, ketika melatih (fine-tuning) atau menjalankan inferensi model-model AI mutakhir ini di lingkungan lokal, banyak pengembang dan peneliti menghadapi hambatan fisik yang sangat besar, yaitu &lt;strong>&amp;ldquo;kekurangan memori GPU (VRAM)&amp;rdquo;&lt;/strong>.&lt;/p>
&lt;p>Meskipun menggunakan GPU high-end untuk konsumen seperti NVIDIA GeForce RTX 4090, VRAM maksimal yang tersedia hanyalah 24GB, sehingga mustahil untuk memuat model raksasa seperti Llama 3 70B secara langsung. GPU untuk data center seperti H100 (80GB) dan B200 (192GB) sangatlah mahal, dan tidak mudah dijangkau oleh individu atau tim skala kecil. Jika kita tidak dapat menembus &amp;lsquo;Tembok VRAM (The Wall of VRAM)&amp;rsquo; ini, kita bahkan tidak akan bisa menyentuh model-model mutakhir tersebut.&lt;/p>
&lt;p>Dalam artikel ini, kami akan menjelaskan secara mendalam dari sisi inferensi maupun pembelajaran mengenai teknik-teknik canggih untuk mematahkan kendala fisik batasan VRAM ini melalui rekayasa perangkat lunak dan arsitektur perangkat keras. Mari kita bahas lebih dalam menggunakan rumus matematika dan diagram untuk teknik seperti CPU offloading, optimasi cache KV, gradient checkpointing, hingga arsitektur Unified Memory terbaru. Dengan membaca artikel ini, Anda akan memahami perilaku VRAM secara mendalam dan memperoleh pengetahuan praktis untuk menangani model raksasa dengan sumber daya yang terbatas.&lt;/p>
&lt;hr>
&lt;h1 id="1-anatomi-konsumsi-vram-model-ai-inferensi-dan-pembelajaran">1. Anatomi Konsumsi VRAM Model AI (Inferensi dan Pembelajaran)
&lt;/h1>&lt;p>Langkah pertama untuk mengatasi kekurangan VRAM adalah memahami secara akurat &amp;ldquo;apa&amp;rdquo; dan &amp;ldquo;berapa banyak&amp;rdquo; memori yang dikonsumsi dari sudut pandang mikro. Jika kita dapat memperkirakannya secara akurat menggunakan rumus matematika daripada menganggapnya sebagai kotak hitam, kita dapat memilih metode optimasi yang tepat.&lt;/p>
&lt;h2 id="11-perhitungan-memori-parameter-model-bobot">1.1 Perhitungan Memori Parameter Model (Bobot)
&lt;/h2>&lt;p>Jumlah memori dasar yang dikonsumsi oleh parameter (Weights) yang membentuk model AI ditentukan oleh total jumlah parameter model dan tipe data (Precision: Presisi) yang digunakan untuk merepresentasikannya.&lt;/p>
&lt;p>Tipe data yang umum digunakan dalam deep learning dan jumlah byte per parameter ($B$) adalah sebagai berikut:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>FP32 (Single-precision floating-point format):&lt;/strong> 4 byte (presisi standar saat pembelajaran)&lt;/li>
&lt;li>&lt;strong>FP16 / BF16 (Half-precision floating-point format):&lt;/strong> 2 byte (inferensi umum dan mixed-precision training)&lt;/li>
&lt;li>&lt;strong>INT8 (Integer 8-bit):&lt;/strong> 1 byte (model yang dikuantisasi)&lt;/li>
&lt;li>&lt;strong>INT4 (Kuantisasi integer 4-bit):&lt;/strong> 0.5 byte (kuantisasi ekstrem seperti GPTQ, AWQ, GGUF)&lt;/li>
&lt;/ul>
&lt;p>Jika total jumlah parameter dari keseluruhan model adalah $P$, maka jumlah memori dasar yang ditempati oleh bobot itu sendiri, $M_{weights}$, dapat dinyatakan dengan rumus berikut:&lt;/p>
$$ M_{weights} = P \times B $$&lt;p>Sebagai contoh, jika Anda memuat model &amp;ldquo;Llama 3 8B&amp;rdquo; (sekitar 8 miliar parameter) yang dirilis oleh Meta dalam format FP16 (setengah presisi), perhitungannya adalah sebagai berikut:&lt;/p>
$$ M_{weights} = 8,000,000,000 \times 2 \text{ bytes} \approx 16,000,000,000 \text{ bytes} \approx 16 \text{ GB} $$&lt;p>Dengan kata lain, sekadar memuat bobot model ke GPU akan mengonsumsi 16GB VRAM. Pada RTX 3060 (12GB), error Out of Memory (OOM) akan terjadi pada titik ini. Namun, jika model dikuantisasi menjadi INT4, memori yang dibutuhkan menjadi $8 \times 0.5 = 4 \text{ GB}$, yang memungkinkannya dimuat dengan mudah.&lt;/p>
&lt;h2 id="12-konsumsi-memori-saat-inferensi-peningkatan-cache-kv">1.2 Konsumsi Memori Saat Inferensi: Peningkatan Cache KV
&lt;/h2>&lt;p>Dalam inferensi LLM (terutama pembuatan teks autoregresif), hal yang menekan VRAM sama atau bahkan lebih besar daripada bobotnya adalah &lt;strong>Cache KV (Key-Value Cache)&lt;/strong>.
Pada arsitektur Transformer, tensor Key dan Value pada setiap lapisan attention terus di-cache dalam VRAM untuk mencegah perhitungan ulang informasi token yang telah diproses di masa lalu. Hal ini meningkatkan kecepatan komputasi (Compute), tetapi seiring dengan bertambahnya panjang konteks (panjang prompt masukan + panjang teks yang dihasilkan), konsumsi memori meningkat secara linear dan eksponensial.&lt;/p>
&lt;p>Jumlah memori cache KV yang dikonsumsi saat memproses 1 token, $M_{kv\_token}$, dihitung secara akurat berdasarkan arsitektur model dengan rumus berikut:&lt;/p>
$$ M_{kv\_token} = 2 \times N_{layers} \times N_{heads\_kv} \times D_{head} \times B $$&lt;p>Di sini, setiap variabel memiliki arti sebagai berikut:&lt;/p>
&lt;ul>
&lt;li>$2$ : Karena ada dua tensor, Key dan Value&lt;/li>
&lt;li>$N_{layers}$ : Jumlah lapisan (layer) Transformer&lt;/li>
&lt;li>$N_{heads\_kv}$ : Jumlah head attention KV (GQA: Grouped Query Attention akan memiliki lebih sedikit dari jumlah head biasa)&lt;/li>
&lt;li>$D_{head}$ : Jumlah dimensi tiap head (biasanya jumlah dimensi hidden layer $D_{model} / N_{heads}$)&lt;/li>
&lt;li>$B$ : Jumlah byte tipe data (2 untuk FP16)&lt;/li>
&lt;/ul>
&lt;p>Total kapasitas cache KV, $M_{kv\_total}$, adalah hasil perkalian nilai di atas dengan panjang urutan ($L_{seq}$) dan ukuran batch ($BatchSize$).&lt;/p>
$$ M_{kv\_total} = M_{kv\_token} \times L_{seq} \times BatchSize $$&lt;p>&lt;strong>Contoh Spesifik: Pada Llama 2 7B&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>$N_{layers} = 32$&lt;/li>
&lt;li>$N_{heads\_kv} = 32$ (Dalam kasus MHA)&lt;/li>
&lt;li>$D_{head} = 128$&lt;/li>
&lt;li>FP16 ($B=2$)&lt;/li>
&lt;li>Ukuran Batch 1, Panjang Konteks 8192 (Konteks 8K)&lt;/li>
&lt;/ul>
$$ M_{kv\_total} = 2 \times 32 \times 32 \times 128 \times 2 \times 8192 \times 1 = 4,294,967,296 \text{ bytes} \approx 4 \text{ GB} $$&lt;p>Jika konteks diperpanjang hingga 32K (32768 token), cache KV saja akan menghabiskan sekitar 16GB. Jika ukuran batch ditambah menjadi 4, akan menjadi 64GB. Hal ini menjadikan VRAM yang dibutuhkan jauh lebih besar daripada ukuran model itu sendiri, yang merupakan tantangan besar saat inferensi.&lt;/p>
&lt;h2 id="13-konsumsi-memori-saat-pembelajaran-optimizer-gradien-dan-aktivasi">1.3 Konsumsi Memori Saat Pembelajaran: Optimizer, Gradien, dan Aktivasi
&lt;/h2>&lt;p>Dibandingkan dengan inferensi, pembelajaran model (pre-training atau fine-tuning) mengonsumsi VRAM yang jauh lebih banyak. Hal ini karena memori perlu mempertahankan informasi untuk backpropagation (propagasi balik), bukan hanya untuk forward pass (propagasi maju) yang sederhana. Memori saat pembelajaran terutama terdiri dari 4 elemen berikut:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Bobot Model (Model Weights):&lt;/strong> Sama seperti saat inferensi, tetapi dalam mixed-precision training, model sering kali menahan baik FP16 maupun FP32 (master weights).&lt;/li>
&lt;li>&lt;strong>Gradien (Gradients):&lt;/strong> Gradien per parameter dihitung dalam backpropagation. Untuk FP16, besarnya 2 byte per parameter.&lt;/li>
&lt;li>&lt;strong>Status Optimizer (Optimizer States):&lt;/strong> Optimizer canggih seperti AdamW menyimpan momen pertama (Momentum) dan momen kedua (Variance) untuk setiap parameter. Demi stabilitas pembelajaran, ini umumnya disimpan di FP32 (4 byte). Dengan kata lain, kedua momen tersebut menghabiskan $4 + 4 = 8$ byte per parameter.&lt;/li>
&lt;li>&lt;strong>Aktivasi (Activations):&lt;/strong> Output (status menengah) dari setiap lapisan saat forward pass harus disimpan di memori untuk menghitung gradien pada backpropagation. Hal ini sangat bergantung pada ukuran batch dan panjang urutan, sehingga ukurannya bisa sangat besar.&lt;/li>
&lt;/ol>
&lt;p>Ringkasnya, dalam Mixed Precision Training yang menggunakan optimizer Adam standar, dibutuhkan sekitar &lt;strong>16-20 byte&lt;/strong> memori per parameter (master weight 4 + FP16 weight 2 + gradien 2 + optimizer 8 + α).&lt;/p>
$$ M_{train\_param} \approx P \times 16 \text{ bytes} $$&lt;p>Untuk melatih model 7B (7 miliar parameter), dibutuhkan memori sekitar $7B \times 16 = 112 \text{ GB}$ hanya untuk parameter. Jika ditambah dengan aktivasi, total VRAM yang dibutuhkan bisa mencapai lebih dari 140GB. Untuk menjalankannya pada VRAM 24GB, diperlukan teknik optimasi ekstrem yang akan dijelaskan di bab berikutnya.&lt;/p>
&lt;hr>
&lt;h1 id="2-teknik-menghemat-vram-saat-inferensi">2. Teknik Menghemat VRAM Saat Inferensi
&lt;/h1>&lt;p>Berbagai teknologi perangkat lunak telah dikembangkan untuk melampaui batasan perangkat keras saat menjalankan model raksasa untuk inferensi.&lt;/p>
&lt;h2 id="21-cpu-offloading-dan-pembagian-lapisan">2.1 CPU Offloading dan Pembagian Lapisan
&lt;/h2>&lt;p>Jika model raksasa tidak muat di satu atau beberapa GPU, sebagian model ditempatkan di memori sistem (RAM CPU) dan komputasi dilanjutkan sambil mentransfer data ke GPU hanya saat diperlukan. Pendekatan ini disebut &lt;strong>CPU Offloading&lt;/strong>. Alat seperti &lt;code>llama.cpp&lt;/code> atau &lt;code>Accelerate&lt;/code> dari Hugging Face mendukung fitur ini.&lt;/p>
&lt;pre class="mermaid">
graph TD
A[&amp;#34;RAM Sistem (DDR4 / DDR5)&amp;#34;] --&amp;gt; B[&amp;#34;VRAM GPU (GDDR6X)&amp;#34;]
B[&amp;#34;VRAM GPU (GDDR6X)&amp;#34;] --&amp;gt; C[&amp;#34;Tensor Cores (Komputasi)&amp;#34;]
subgraph &amp;#34;Pemisahan Lapisan dan Offloading&amp;#34;
D[&amp;#34;Lapisan Bawah 1-15 (Ditetapkan di GPU)&amp;#34;]
E[&amp;#34;Lapisan Atas 16-32 (Di-offload ke CPU)&amp;#34;]
end
E[&amp;#34;Lapisan Atas 16-32 (Di-offload ke CPU)&amp;#34;] -.-&amp;gt; B[&amp;#34;VRAM GPU (GDDR6X)&amp;#34;]
&lt;/pre>
&lt;p>&lt;strong>Mekanisme dan Tantangan:&lt;/strong>
Model Transformer memiliki struktur di mana setiap lapisan ditumpuk secara seri, sehingga perhitungan untuk suatu lapisan tidak akan dimulai sampai perhitungan lapisan sebelumnya selesai. Menggunakan prinsip ini, hanya lapisan yang muat di GPU (misal: lapisan 1 hingga 15) yang dibiarkan menetap (pinned) di VRAM, sedangkan lapisan sisanya (lapisan 16 hingga 32) ditempatkan di RAM CPU yang berkapasitas besar namun lambat. Selama inferensi, setelah perhitungan lapisan 15 selesai, bobot lapisan ke-16 ditransfer (disalin) dari CPU ke GPU melalui bus PCIe untuk dihitung di GPU.&lt;/p>
&lt;p>Namun, &lt;strong>bandwidth PCIe menjadi bottleneck (leher botol) yang parah&lt;/strong>. Bandwidth maksimal secara teori untuk PCIe 4.0 x16 adalah 32GB/s (satu arah), namun dibandingkan dengan bandwidth internal VRAM GPU terbaru (misalnya GDDR6X pada RTX 4090 yang mencapai 1008GB/s, atau HBM3 pada H100 yang melebihi 3TB/s), kecepatannya dua tingkat besaran lebih lambat. Jadi, jika CPU offloading digunakan terlalu sering, kecepatan inferensi (Tokens per Second) akan menurun drastis.
Untuk meminimalkan penurunan kecepatan, hal praktis yang perlu dilakukan adalah memuat sebanyak mungkin lapisan ke GPU (memaksimalkan Lapisan GPU) dan mengurangi jumlah lapisan yang di-offload sesedikit mungkin.&lt;/p>
&lt;h2 id="22-kuantisasi-cache-kv-dan-pagedattention">2.2 Kuantisasi Cache KV dan PagedAttention
&lt;/h2>&lt;p>Untuk Cache KV, yang menjadi penyebab utama tingginya konsumsi VRAM selama inferensi, terdapat dua optimasi kuat:&lt;/p>
&lt;p>&lt;strong>1. Kuantisasi Cache KV (KV Cache Quantization):&lt;/strong>
Selain bobot model, Cache KV itu sendiri yang dihasilkan secara dinamis saat eksekusi juga dikuantisasi menjadi INT8, INT4, atau FP8 untuk disimpan di VRAM. Hal ini mengurangi ukuran Cache KV hingga setengah atau seperempatnya. Engine inferensi terbaru (seperti vLLM dan llama.cpp) telah menyertakan fitur ini untuk menghasilkan penghematan VRAM yang signifikan sembari meminimalkan penurunan akurasi.&lt;/p>
&lt;p>&lt;strong>2. PagedAttention:&lt;/strong>
Konsep &amp;ldquo;paging&amp;rdquo; dari memori virtual sistem operasi diaplikasikan pada Cache KV, yang diperkenalkan dalam engine inferensi vLLM, dinamakan &lt;strong>PagedAttention&lt;/strong>. Dalam engine inferensi tradisional, ruang VRAM yang berdekatan dialokasikan di awal (Pre-allocation) sesuai dengan panjang urutan maksimum yang ditetapkan. Oleh karena itu, jika input yang sebenarnya ternyata lebih pendek, akan terjadi fragmentasi dan pemborosan memori, yang kadang menyebabkan lebih dari 60% VRAM terbuang sia-sia.&lt;/p>
&lt;p>PagedAttention membagi Cache KV ke dalam blok-blok ukuran tetap (halaman) dan menyimpannya secara terdistribusi di ruang memori fisik yang tidak bersebelahan. Dengan demikian, pemborosan memori dapat dikurangi menjadi hampir nol (hanya terbatas pada fragmentasi internal), sehingga memungkinkan peningkatan ukuran batch secara signifikan dalam kapasitas VRAM yang sama.&lt;/p>
&lt;pre class="mermaid">
graph LR
A[&amp;#34;Cache KV Logis&amp;#34;] --&amp;gt; B[&amp;#34;Blok VRAM Fisik&amp;#34;]
A1[&amp;#34;Token 1, 2, 3, 4&amp;#34;] --&amp;gt; B3[&amp;#34;Blok 3 (Dialokasikan)&amp;#34;]
A2[&amp;#34;Token 5, 6, 7, 8&amp;#34;] --&amp;gt; B1[&amp;#34;Blok 1 (Dialokasikan)&amp;#34;]
A3[&amp;#34;Token Selanjutnya...&amp;#34;] -.-&amp;gt; B2[&amp;#34;Blok 2 (Kosong)&amp;#34;]
&lt;/pre>
&lt;h2 id="23-flashattention-memecahkan-kompleksitas-memori-perhitungan-attention">2.3 FlashAttention: Memecahkan Kompleksitas Memori Perhitungan Attention
&lt;/h2>&lt;p>Kekurangan VRAM tidak hanya disebabkan oleh ruang untuk menyimpan data, tetapi juga kekurangan &amp;ldquo;workspace sementara&amp;rdquo; saat komputasi dilakukan. Mekanisme Self-Attention Transformer standar mengharuskan kita untuk mematerialisasi matriks attention raksasa $N \times N$ pada VRAM untuk panjang urutan $N$. Kompleksitas memori ini mencapai $O(N^2)$, yang menjadi penyebab utama terjadinya OOM saat menangani konteks panjang.&lt;/p>
&lt;p>Hal ini diselesaikan dengan &lt;strong>FlashAttention&lt;/strong> (dan FlashAttention-2, 3).
FlashAttention adalah algoritma yang dirancang dengan memperhatikan arsitektur perangkat keras GPU (hierarki antara HBM yang sangat besar namun lambat dan SRAM yang sangat kecil namun super cepat). Algoritma ini menggunakan teknik yang disebut Tiling untuk memuat data per blok ke SRAM dan menyelesaikan perhitungan attention, dengan demikian sepenuhnya menghindari proses penulisan matriks $N \times N$ ke HBM (VRAM).&lt;/p>
&lt;p>Akibatnya, kompleksitas memori lapisan attention berkurang drastis dari $O(N^2)$ menjadi $O(N)$ (berbanding lurus dengan panjang urutan), dan batas maksimum panjang konteks pun sangat dilonggarkan.&lt;/p>
&lt;h2 id="24-kebangkitan-unified-memory-dan-apple-silicon">2.4 Kebangkitan Unified Memory dan Apple Silicon
&lt;/h2>&lt;p>Pendekatan untuk mengatasi masalah ini dari dasar arsitektur PC adalah &lt;strong>Unified Memory Architecture (UMA)&lt;/strong> yang diadopsi oleh Apple Silicon (seri Max atau Ultra dari M1/M2/M3/M4) dan beberapa APU modern (seperti AMD Strix Point).&lt;/p>
&lt;p>Dalam arsitektur ini, CPU dan GPU di motherboard berbagi ruang memori fisik yang persis sama (misalnya, LPDDR5 hingga 192GB). Oleh karena itu, konsep &amp;ldquo;transfer data yang lambat via PCIe dari CPU ke GPU&amp;rdquo; sama sekali tidak ada secara fisik.&lt;/p>
&lt;pre class="mermaid">
graph TD
subgraph &amp;#34;Arsitektur Memori Terpadu (misal Apple Silicon)&amp;#34;
A[&amp;#34;Core CPU&amp;#34;] &amp;lt;--&amp;gt; C[&amp;#34;Kontroler Memori Bersama&amp;#34;]
B[&amp;#34;Core GPU / Neural Engine&amp;#34;] &amp;lt;--&amp;gt; C[&amp;#34;Kontroler Memori Bersama&amp;#34;]
C[&amp;#34;Kontroler Memori Bersama&amp;#34;] &amp;lt;--&amp;gt; D[&amp;#34;Kumpulan Memori Terpadu (misal 192GB)&amp;#34;]
end
&lt;/pre>
&lt;p>Keuntungan terbesar arsitektur ini adalah tidak adanya tembok pasti pemisah VRAM, sehingga hampir seluruh area memori sistem bisa langsung digunakan untuk memuat LLM raksasa. Jika Anda menggunakan Mac Studio dengan memori terpadu sebesar 192GB, Anda bisa memuat model super besar sekelas 70B atau bahkan lebih besar (seperti Grok-1) dalam satu perangkat tanpa kuantisasi, dan menjalankan inferensinya dengan sangat cepat. Kecepatan akses (bandwidth) memorinya mencapai 800GB/s pada M2 Ultra, setara dengan diskrit GPU untuk kalangan konsumen. Ini adalah pendekatan perangkat keras yang sangat kuat dalam memecahkan dilema &amp;ldquo;kapasitas memori&amp;rdquo; berbanding &amp;ldquo;bandwidth&amp;rdquo;.&lt;/p>
&lt;hr>
&lt;h1 id="3-teknik-menghemat-vram-saat-pembelajaran-fine-tuning">3. Teknik Menghemat VRAM Saat Pembelajaran (Fine-Tuning)
&lt;/h1>&lt;p>Terdapat banyak terobosan yang diciptakan untuk mengatasi masalah penggunaan VRAM saat pembelajaran (Training), yang menuntut VRAM lebih banyak dibandingkan saat inferensi. Untuk menjalankan fine-tuning menggunakan resource yang terbatas, diperlukan kombinasi teknologi berikut:&lt;/p>
&lt;h2 id="31-gradient-checkpointing">3.1 Gradient Checkpointing
&lt;/h2>&lt;p>Dalam backpropagation deep learning, output perantara (Activations) pada semua lapisan dalam forward pass harus dipertahankan dalam memori untuk menghitung gradien. Jika panjang urutan dan ukuran batch meningkat, memori aktivasi ini mulai mendominasi konsumsi VRAM.&lt;/p>
&lt;p>&lt;strong>Gradient Checkpointing (Activation Recomputation)&lt;/strong> adalah teknik jenius yang memanfaatkan pertukaran (trade-off) antara kapasitas memori dan waktu komputasi (Compute).
Alih-alih menyimpan semua output perantara di memori, teknik ini hanya menyimpan output pada lapisan (checkpoint) tertentu. Saat backpropagation membutuhkan nilai perantara yang tidak di-checkpoint, nilai tersebut direstorasi dengan &lt;strong>menghitung ulang forward pass dari checkpoint terdekat yang disimpan&lt;/strong>.&lt;/p>
&lt;p>Beban komputasi meningkat sekitar 20-30% dan total waktu pembelajaran menjadi lebih lama, tetapi konsumsi VRAM oleh aktivasi bisa ditekan drastis dari $O(N)$ ($N$ = jumlah lapisan) menjadi $O(\sqrt{N})$. Teknik ini sangat krusial; bahkan bisa dikatakan mustahil untuk melatih model skala besar saat ini tanpanya.&lt;/p>
&lt;h2 id="32-lora-dan-qlora-low-rank-adaptation">3.2 LoRA dan QLoRA (Low-Rank Adaptation)
&lt;/h2>&lt;p>Teknik yang benar-benar memecahkan masalah VRAM dari akarnya adalah &lt;strong>LoRA&lt;/strong>, pionir dari metode PEFT (Parameter-Efficient Fine-Tuning).&lt;/p>
&lt;p>Metode ini membekukan (freeze) matriks bobot besar awal model $W_0 \in \mathbb{R}^{d \times k}$ sehingga tidak dilatih. Sebagai gantinya, dua matriks berpangkat rendah (low-rank) berukuran sangat kecil $A \in \mathbb{R}^{r \times k}$ dan $B \in \mathbb{R}^{d \times r}$ ditambahkan secara paralel, dan hanya parameter $A$ dan $B$ ini saja yang dilatih. (Di mana rank $r$ adalah nilai kecil $r \ll d, k$).&lt;/p>
$$ W_{adapted} = W_0 + \Delta W = W_0 + B A $$&lt;p>Dengan demikian, jumlah parameter yang dilatih menjadi kurang dari 1% dari aslinya (kadang kurang dari 0.1%), dan memori &amp;ldquo;gradien&amp;rdquo; beserta &amp;ldquo;status optimizer&amp;rdquo; yang tadinya rakus memori juga berkurang drastis di bawah 1%.&lt;/p>
&lt;p>Evolusi ekstrem dari metode ini adalah &lt;strong>QLoRA (Quantized LoRA)&lt;/strong>.
Di QLoRA, bobot model dasar $W_0$ dikuantisasi hingga sekecil mungkin ke dalam 4-bit (format NF4: NormalFloat4) lalu dimuat ke VRAM. Kemudian matriks kecil LoRA $A, B$ dilatih dalam BF16 (16-bit) untuk mempertahankan akurasi perhitungan.
Dengan mengurangi ukuran VRAM model dasar menjadi seperempat menggunakan kuantisasi 4-bit, ditambah teknik &lt;strong>Paged Optimizers&lt;/strong>, metode ini secara otomatis memindahkan (offload) status optimizer sementara ke RAM CPU jika VRAM berpotensi habis. Ini memungkinkan fine-tuning model raksasa seperti Llama 3 70B hanya dengan satu GPU dengan VRAM 24GB (seperti RTX 4090).&lt;/p>
&lt;h2 id="33-deepspeed-zero-dan-offloading">3.3 DeepSpeed ZeRO dan Offloading
&lt;/h2>&lt;p>Dalam lingkungan dengan banyak GPU (Multi-GPU), Data Parallelism belaka tidak cukup untuk menyelesaikan masalah VRAM. Karena setiap GPU menyimpan salinan seluruh model, batas kapasitas VRAM dari masing-masing GPU tidak akan pernah dapat dilampaui.&lt;/p>
&lt;p>&lt;strong>ZeRO (Zero Redundancy Optimizer)&lt;/strong>, sebuah pustaka buatan Microsoft bernama &lt;strong>DeepSpeed&lt;/strong>, adalah teknologi yang secara masif membagi (shard) parameter model, gradien, dan status optimizer ke berbagai GPU. Hal ini membuat &amp;ldquo;jumlah total&amp;rdquo; VRAM dari beberapa GPU bisa ditangani seolah-olah layaknya satu kolam memori yang sangat besar.&lt;/p>
&lt;pre class="mermaid">
graph TD
subgraph &amp;#34;ZeRO Stage 3 (Partisi Parameter)&amp;#34;
A[&amp;#34;GPU 0&amp;#34;] --&amp;gt; D[&amp;#34;Partisi 0 (Menyimpan 1/3 Bobot/Gradien/Optimizer)&amp;#34;]
B[&amp;#34;GPU 1&amp;#34;] --&amp;gt; E[&amp;#34;Partisi 1 (Menyimpan 1/3 Bobot/Gradien/Optimizer)&amp;#34;]
C[&amp;#34;GPU 2&amp;#34;] --&amp;gt; F[&amp;#34;Partisi 2 (Menyimpan 1/3 Bobot/Gradien/Optimizer)&amp;#34;]
end
D[&amp;#34;Partisi 0 (Menyimpan 1/3 Bobot/Gradien/Optimizer)&amp;#34;] &amp;lt;--&amp;gt; E[&amp;#34;Partisi 1 (Menyimpan 1/3 Bobot/Gradien/Optimizer)&amp;#34;]
E[&amp;#34;Partisi 1 (Menyimpan 1/3 Bobot/Gradien/Optimizer)&amp;#34;] &amp;lt;--&amp;gt; F[&amp;#34;Partisi 2 (Menyimpan 1/3 Bobot/Gradien/Optimizer)&amp;#34;]
&lt;/pre>
&lt;ul>
&lt;li>&lt;strong>ZeRO Stage 1:&lt;/strong> Membagi status optimizer ke masing-masing GPU&lt;/li>
&lt;li>&lt;strong>ZeRO Stage 2:&lt;/strong> Gradien juga dibagi ke masing-masing GPU&lt;/li>
&lt;li>&lt;strong>ZeRO Stage 3:&lt;/strong> Parameter (bobot) dari model itu sendiri juga dibagi ke masing-masing GPU&lt;/li>
&lt;/ul>
&lt;p>Selain itu, jika menggunakan fitur &lt;strong>ZeRO-Offload&lt;/strong>, perhitungan untuk memperbarui gradien dan status optimizer yang telah dibagi dengan ZeRO dapat dijalankan di memori CPU host (&lt;strong>offloaded to CPU memory&lt;/strong>) dan bukan pada GPU. Ini akan mengurangi beban pada GPU VRAM secara signifikan, sehingga pembelajaran model besar dimungkinkan walau dengan sumber daya GPU terbatas. Karena komputasinya dilakukan di CPU dan hasilnya dikirim balik ke GPU melalui PCIe, kecepatan pembelajaran akan menurun, namun hal ini dapat menghindari kondisi terburuk yaitu &amp;ldquo;error crash akibat memori penuh&amp;rdquo; (OOM).&lt;/p>
&lt;hr>
&lt;h1 id="4-contoh-implementasi-hugging-face-accelerate-dan-deepspeed">4. Contoh Implementasi: Hugging Face Accelerate dan DeepSpeed
&lt;/h1>&lt;p>Sebagai penutup, berikut ditunjukkan contoh sederhana mengenai cara mengimplementasikan CPU offloading dan optimasi VRAM ke dalam kode Python yang sebenarnya.&lt;/p>
&lt;h2 id="41-offloading-otomatis-dengan-hugging-face-device_mapauto">4.1 Offloading Otomatis dengan Hugging Face &lt;code>device_map=&amp;quot;auto&amp;quot;&lt;/code>
&lt;/h2>&lt;p>Jika Anda menggunakan pustaka &lt;code>transformers&lt;/code> dan &lt;code>accelerate&lt;/code> dari Hugging Face, alat tersebut dapat mendistribusikan layer secara otomatis antara GPU dan RAM CPU saat Anda memuat model.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">transformers&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">AutoModelForCausalLM&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">AutoTokenizer&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">model_id&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;meta-llama/Llama-2-13b-hf&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Menggunakan device_map=&amp;#34;auto&amp;#34;, bagian yang tidak muat dalam VRAM akan di-offload ke RAM CPU&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># load_in_8bit=True mengkuantisasi bobot dalam 8-bit untuk penghematan memori ekstra&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">model&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">AutoModelForCausalLM&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">from_pretrained&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">model_id&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">device_map&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;auto&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">load_in_8bit&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">offload_folder&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;offload_dir&amp;#34;&lt;/span> &lt;span class="c1"># Jika masih kurang, Anda bisa melakukan offload hingga ke disk (SSD)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Saat kode ini dieksekusi, pustaka &lt;code>accelerate&lt;/code> di baliknya akan menganalisis kapasitas VRAM dan RAM CPU yang tersedia, kemudian menempatkan (Dispatch) lapisan model dengan cara yang paling optimal.&lt;/p>
&lt;h2 id="42-pengaturan-cpu-offload-pada-deepspeed-zero-2">4.2 Pengaturan CPU Offload pada DeepSpeed (ZeRO-2)
&lt;/h2>&lt;p>Berikut adalah contoh file konfigurasi (JSON) untuk mengaktifkan CPU offloading di DeepSpeed saat proses pembelajaran.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-json" data-lang="json">&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;fp16&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;enabled&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">true&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;zero_optimization&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;stage&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;offload_optimizer&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;device&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;cpu&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;pin_memory&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">true&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;allgather_partitions&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;allgather_bucket_size&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mf">2e8&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;overlap_comm&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;reduce_scatter&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;reduce_bucket_size&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mf">2e8&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;contiguous_gradients&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">true&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;train_batch_size&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">16&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;gradient_accumulation_steps&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">4&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Dalam konfigurasi ini, dengan mengatur &lt;code>offload_optimizer&lt;/code> ke &lt;code>&amp;quot;cpu&amp;quot;&lt;/code>, perhitungan pembaruan dan penyimpanan status dari optimizer (seperti Adam) yang boros VRAM akan dieksekusi di sisi CPU sistem. VRAM GPU pun dapat dikhususkan untuk tugas terpenting, yaitu komputasi perhitungan forward/backward dari model. Dengan mengatur &lt;code>pin_memory: true&lt;/code>, masalah page fault dapat dicegah, dan transfer PCIe antara CPU-GPU dimaksimalkan secepat mungkin.&lt;/p>
&lt;hr>
&lt;h1 id="kesimpulan">Kesimpulan
&lt;/h1>&lt;p>Kekurangan memori GPU (Out of Memory) dalam pengembangan AI merupakan masalah abadi yang akan terus menghantui pengembang seiring dengan ukuran model yang semakin membesar. Meskipun demikian, dengan menggabungkan pemahaman yang mendalam tentang arsitektur perangkat keras seperti yang dijelaskan pada artikel ini dengan teknik-teknik optimasi algoritma perangkat lunak, inferensi dan pembelajaran model raksasa yang sekilas terlihat mustahil pada lingkungan lokal menjadi memungkinkan.&lt;/p>
&lt;p>&lt;strong>Ringkasan Solusi Saat Inferensi:&lt;/strong>&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Kuantisasi (INT4 / INT8 / FP8):&lt;/strong> Secara drastis mengompresi ukuran model itu sendiri, sehingga mengurangi ruang yang terpakai di VRAM.&lt;/li>
&lt;li>&lt;strong>CPU Offloading:&lt;/strong> Memindahkan lapisan model yang tak muat dalam VRAM ke dalam memori sistem (trade-off berupa penurunan kecepatan karena keterbatasan bandwidth PCIe).&lt;/li>
&lt;li>&lt;strong>Optimasi Cache KV:&lt;/strong> Mengamankan panjang konteks (Context Length) dengan menggunakan metode Paging (PagedAttention), kuantisasi cache, atau FlashAttention.&lt;/li>
&lt;li>&lt;strong>Pemanfaatan Unified Memory:&lt;/strong> Memanfaatkan UMA (seperti Apple Silicon) untuk langsung menggunakan memori berkapasitas besar saat inferensi.&lt;/li>
&lt;/ol>
&lt;p>&lt;strong>Ringkasan Solusi Saat Pembelajaran:&lt;/strong>&lt;/p>
&lt;ol>
&lt;li>&lt;strong>PEFT (LoRA / QLoRA):&lt;/strong> Membatasi ukuran parameter yang ingin dilatih, dan mengkuantisasi model dasar secara ekstrem.&lt;/li>
&lt;li>&lt;strong>Gradient Checkpointing:&lt;/strong> Menghapus hasil aktivasi perantara dari forward pass dan menghitungnya kembali saat backpropagation demi menghemat konsumsi VRAM (ditukar dengan waktu komputasi tambahan).&lt;/li>
&lt;li>&lt;strong>ZeRO &amp;amp; CPU Offloading (DeepSpeed):&lt;/strong> Menembus batas VRAM dengan membagi status optimizer dan gradien ke berbagai GPU, atau dengan melakukan offload ke dalam memori CPU.&lt;/li>
&lt;/ol>
&lt;p>Mari manfaatkan sepenuhnya teknologi mutakhir ini untuk mendapatkan kinerja pengembangan AI semaksimal mungkin dalam keterbatasan sumber daya perangkat keras. Pada bidang yang perubahannya terjadi sangat pesat ini, algoritma penghematan memori baru sangat diharapkan untuk terus bermunculan di masa depan. Secara rutin memantau tren pustaka (library) terbaru serta mengimplementasikannya dalam sistem Anda akan menjadi kunci kesuksesan.&lt;/p></description></item></channel></rss>