<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Local AI on kenji.blog</title><link>http://kenji.blog/id/tags/local-ai/</link><description>Recent content in Local AI on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>id</language><copyright>kenjinote</copyright><lastBuildDate>Fri, 11 Sep 2026 16:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/id/tags/local-ai/index.xml" rel="self" type="application/rss+xml"/><item><title>Cara Tercepat Melakukan Tuning TinyLLaMA di Lingkungan On-Premises</title><link>http://kenji.blog/id/p/tinyllama-on-premises-fast-tuning-guide/</link><pubDate>Fri, 11 Sep 2026 16:00:00 +0900</pubDate><guid>http://kenji.blog/id/p/tinyllama-on-premises-fast-tuning-guide/</guid><description>&lt;img src="http://kenji.blog/p/tinyllama-on-premises-fast-tuning-guide/img/eyecatch.jpg" alt="Featured image of post Cara Tercepat Melakukan Tuning TinyLLaMA di Lingkungan On-Premises" />&lt;h2 id="1-pendahuluan-mengapa-harus-tinyllama-dan-on-premises-saat-ini">1. Pendahuluan: Mengapa Harus TinyLLaMA dan On-Premises Saat Ini?
&lt;/h2>&lt;p>Evolusi Large Language Models (LLM) berlangsung dengan kecepatan yang luar biasa, dan seiring dengan itu, jumlah parameter model terus membengkak hingga skala ratusan miliar. Di satu sisi, model super raksasa seperti GPT-4 dan Claude 3 membanggakan kinerja yang tak tertandingi, namun biaya komputasi yang dibutuhkan untuk inferensi dan pelatihan, serta kekhawatiran tentang keamanan dan privasi data saat menggunakan API eksternal menjadi hambatan besar bagi perusahaan. Terutama dalam tugas-tugas yang menangani data internal yang sangat rahasia dan informasi pribadi, mengirimkan data ke API LLM publik di cloud sering kali tidak dapat diterima dari sudut pandang kepatuhan (seperti GDPR dan APPI).&lt;/p>
&lt;p>Oleh karena itu, yang kini menjadi sorotan adalah &lt;strong>Small Language Models (SLM)&lt;/strong> dan &lt;strong>pengoperasian lokal di lingkungan on-premises&lt;/strong>. Di antaranya, &amp;ldquo;&lt;strong>TinyLLaMA&lt;/strong>&amp;rdquo; hadir dengan ukuran yang ringkas yaitu hanya 1.1B (1,1 miliar) parameter, namun telah melalui pre-training dengan dataset yang sangat besar yaitu sekitar 3 triliun token, sehingga menunjukkan kinerja yang luar biasa dibandingkan dengan model di kelasnya.&lt;/p>
&lt;p>Artikel ini menyediakan panduan lengkap untuk melakukan fine-tuning (penyesuaian) TinyLLaMA agar menjadi &amp;ldquo;tercepat dan berefisiensi tinggi&amp;rdquo; untuk tugas-tugas khusus perusahaan Anda di lingkungan on-premises (server lokal atau workstation). Kami akan menjelaskan secara komprehensif mulai dari latar belakang matematis, teknologi optimasi terbaru, hingga kode implementasi PyTorch secara spesifik.&lt;/p>
&lt;hr>
&lt;h2 id="2-arsitektur-dan-karakteristik-tinyllama">2. Arsitektur dan Karakteristik TinyLLaMA
&lt;/h2>&lt;p>TinyLLaMA mengikuti arsitektur LLaMA (Large Language Model Meta AI) yang dikembangkan oleh Meta. Meskipun jumlah parameternya ditekan menjadi 1.1B, ia menggunakan tumpukan teknologi yang sama dengan LLaMA 2, sehingga memiliki kompatibilitas ekosistem yang sangat tinggi.&lt;/p>
&lt;h3 id="komponen-arsitektur-utama">Komponen Arsitektur Utama
&lt;/h3>&lt;ol>
&lt;li>&lt;strong>RMSNorm (Root Mean Square Normalization):&lt;/strong>
Ini adalah metode normalisasi yang menghilangkan pengurangan rata-rata dari perhitungan LayerNorm konvensional, sehingga meningkatkan efisiensi komputasi. Metode ini menjaga stabilitas pelatihan sekaligus meningkatkan throughput.&lt;/li>
&lt;li>&lt;strong>Fungsi Aktivasi SwiGLU:&lt;/strong>
Dalam Feed Forward Network (FFN), SwiGLU diadopsi menggantikan ReLU dan GELU konvensional. Secara matematis dapat dinyatakan sebagai berikut:
$$ \text{SwiGLU}(x, W, V) = \text{Swish}(xW) \otimes (xV) $$
Di sini, $\otimes$ melambangkan perkalian elemen-demi-elemen (Hadamard product), dan fungsi Swish adalah $\text{Swish}(z) = z \cdot \sigma(\beta z)$. Hal ini secara signifikan meningkatkan daya ekspresi model.&lt;/li>
&lt;li>&lt;strong>RoPE (Rotary Position Embedding):&lt;/strong>
Ini adalah metode yang menggabungkan keuntungan dari positional encoding absolut dan relatif. Metode ini memiliki kemampuan generalisasi yang tinggi bahkan ketika panjang urutan diperluas.&lt;/li>
&lt;li>&lt;strong>Grouped Query Attention (GQA):&lt;/strong>
Ini adalah pendekatan perantara antara Multi-Head Attention (MHA) dan Multi-Query Attention (MQA). Dengan mengelompokkan head key dan value, metode ini menghemat bandwidth memori dan secara dramatis meningkatkan kecepatan inferensi.&lt;/li>
&lt;/ol>
&lt;p>Diagram Mermaid berikut menunjukkan aliran data keseluruhan dan struktur blok Transformer dari TinyLLaMA.&lt;/p>
&lt;div class="mermaid">graph TD
A["Teks Input"] --> B["Tokenizer (BPE)"]
B --> C["Lapisan Embedding"]
C --> D["Blok Transformer (x22 Lapisan untuk TinyLLaMA)"]
D --> E["RMSNorm (Akhir)"]
E --> F["Proyeksi Linear (Ukuran Kosakata)"]
F --> G["Probabilitas Output (Softmax)"]
subgraph "Anatomi Blok Transformer"
D1["Hidden State Input"] --> D2["RMSNorm"]
D2 --> D3["Grouped Query Attention (GQA)"]
D3 --> D4["Residual Add"]
D4 --> D5["RMSNorm"]
D5 --> D6["SwiGLU FFN"]
D6 --> D7["Residual Add"]
D7 --> D8["Output ke Lapisan Berikutnya"]
D1 -.-> D4
D4 -.-> D7
end&lt;/div>
&lt;hr>
&lt;h2 id="3-terobosan-fine-tuning-lora-dan-qlora">3. Terobosan Fine-Tuning: LoRA dan QLoRA
&lt;/h2>&lt;p>Untuk melakukan fine-tuning pada seluruh parameter di lingkungan on-premises, bahkan untuk model 1.1B, model tersebut akan mengonsumsi puluhan GB VRAM (memori video) untuk menyimpan status optimizer dan gradien. Agar dapat melakukan pelatihan secara efisien dengan sumber daya yang terbatas, teknik &lt;strong>PEFT (Parameter-Efficient Fine-Tuning)&lt;/strong>, yaitu &amp;ldquo;&lt;strong>LoRA&lt;/strong>&amp;rdquo; dan ekstensi kuantisasinya &amp;ldquo;&lt;strong>QLoRA&lt;/strong>&amp;rdquo;, menjadi sangat penting.&lt;/p>
&lt;h3 id="31-latar-belakang-matematis-lora-low-rank-adaptation">3.1 Latar Belakang Matematis LoRA (Low-Rank Adaptation)
&lt;/h3>&lt;p>LoRA adalah metode yang mengunci (freeze) matriks bobot yang telah dilatih sebelumnya (pre-trained), dan memperkirakan jumlah pembaruan bobot tersebut ($\Delta W$) sebagai hasil perkalian dari dua matriks kecil berpangkat rendah (low-rank).&lt;/p>
&lt;p>Misalkan bobot pre-trained adalah $W_0 \in \mathbb{R}^{d \times k}$. Pada full fine-tuning, $W_0$ itu sendiri diperbarui menjadi $W_0 + \Delta W$, namun pada LoRA, matriks pembaruan $\Delta W$ didekomposisi sebagai berikut:&lt;/p>
$$ \Delta W = B \times A $$
&lt;p>Di sini, $B \in \mathbb{R}^{d \times r}$ dan $A \in \mathbb{R}^{r \times k}$, di mana $r$ adalah hyperparameter yang disebut rank, dengan nilai yang sangat kecil (biasanya 8, 16, 32, dll.) yang memenuhi $r \ll \min(d, k)$.&lt;/p>
&lt;p>Perhitungan forward pass adalah sebagai berikut:&lt;/p>
$$ h = W_0 x + \Delta W x = W_0 x + B A x $$
&lt;p>Pada keadaan awal, matriks $A$ diinisialisasi secara acak menggunakan distribusi normal (distribusi Gaussian), dan matriks $B$ diinisialisasi sebagai matriks nol. Akibatnya, nilai $\Delta W$ pada awal pelatihan adalah nol, memungkinkan dimulainya pelatihan dengan output dari model dasar yang dipertahankan sepenuhnya.&lt;/p>
&lt;div class="mermaid">graph LR
X["Vektor Input x"] --> W0["Bobot Pre-trained Beku (W_0)"]
X --> A["Matriks LoRA A yang Dapat Dilatih (r x k)"]
A --> B["Matriks LoRA B yang Dapat Dilatih (d x r)"]
W0 --> Add["Penambahan Vektor"]
B --> Add
Add --> Y["Vektor Output h"]&lt;/div>
&lt;h3 id="32-inovasi-qlora-quantized-lora">3.2 Inovasi QLoRA (Quantized LoRA)
&lt;/h3>&lt;p>QLoRA mendorong pendekatan LoRA lebih jauh, dengan melakukan kuantisasi pada model dasar $W_0$ ke dalam presisi 4-bit (NormalFloat 4, NF4) sebelum dimuat ke dalam memori. Hal ini secara dramatis mengurangi konsumsi VRAM.&lt;/p>
&lt;p>Ada tiga teknologi penting yang terintegrasi di dalam QLoRA:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Kuantisasi 4-bit NormalFloat (NF4):&lt;/strong> Tipe data yang secara teoritis optimal untuk bobot yang mengikuti distribusi normal.&lt;/li>
&lt;li>&lt;strong>Double Quantization (Kuantisasi Ganda):&lt;/strong> Mengkuantisasi konstanta kuantisasi itu sendiri (scale factor) untuk menghemat memori lebih lanjut.&lt;/li>
&lt;li>&lt;strong>Paged Optimizers:&lt;/strong> Menggunakan fitur memori terpadu NVIDIA untuk sementara waktu memindahkan status optimizer ke RAM CPU saat VRAM hampir habis.&lt;/li>
&lt;/ol>
&lt;p>Dengan ini, tuning yang biasanya membutuhkan 16GB hingga 24GB VRAM dapat dijalankan dengan nyaman bahkan pada GPU kelas konsumen (seperti RTX 3060 12GB atau RTX 4070).&lt;/p>
&lt;hr>
&lt;h2 id="4-persyaratan-perangkat-keras-dan-pengaturan-di-lingkungan-on-premises">4. Persyaratan Perangkat Keras dan Pengaturan di Lingkungan On-Premises
&lt;/h2>&lt;p>Persyaratan perangkat keras untuk melakukan tuning TinyLLaMA (1.1B) dengan QLoRA dapat ditekan sangat rendah.&lt;/p>
&lt;h3 id="spesifikasi-perangkat-keras-yang-disarankan">Spesifikasi Perangkat Keras yang Disarankan
&lt;/h3>&lt;ul>
&lt;li>&lt;strong>GPU:&lt;/strong> NVIDIA RTX 3060 (12GB), RTX 3090/4090 (24GB), atau NVIDIA A10G/A100, dll. Meskipun VRAM 8GB adalah batas minimal untuk berjalan, disarankan memiliki 12GB atau lebih untuk mengakomodasi ukuran batch (batch size) yang memadai.&lt;/li>
&lt;li>&lt;strong>CPU:&lt;/strong> CPU modern 8 core atau lebih (Intel Core i7/i9, AMD Ryzen 7/9)&lt;/li>
&lt;li>&lt;strong>RAM:&lt;/strong> 32GB atau lebih (penting sebagai tujuan pemindahan data dari VRAM saat menggunakan Paged Optimizers)&lt;/li>
&lt;li>&lt;strong>Penyimpanan:&lt;/strong> NVMe SSD (untuk mempercepat pemuatan dataset dan penyimpanan model)&lt;/li>
&lt;/ul>
&lt;h3 id="membangun-lingkungan-perangkat-lunak">Membangun Lingkungan Perangkat Lunak
&lt;/h3>&lt;p>Langkah-langkah berikut mengasumsikan lingkungan Ubuntu 22.04 LTS. Python 3.10 atau versi yang lebih baru akan digunakan.&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;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Membuat dan mengaktifkan lingkungan virtual (virtual environment)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">python3 -m venv tinyllama_env
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">source&lt;/span> tinyllama_env/bin/activate
&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"># Menginstal PyTorch (untuk CUDA 12.1)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121
&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"># Menginstal pustaka terkait Transformer&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">pip install transformers datasets peft trl accelerate bitsandbytes
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;hr>
&lt;h2 id="5-teknik-optimasi-untuk-tuning-tercepat">5. Teknik Optimasi untuk Tuning Tercepat
&lt;/h2>&lt;p>Untuk menyelesaikan tuning dengan &amp;ldquo;kecepatan maksimum&amp;rdquo;, tidak cukup hanya dengan menjalankan skrip; teknik optimasi berikut harus dikombinasikan.&lt;/p>
&lt;h3 id="51-flash-attention-2">5.1 Flash Attention 2
&lt;/h3>&lt;p>Mekanisme Attention standar memiliki kompleksitas waktu dan ruang $O(N^2)$ terhadap panjang urutan $N$. Flash Attention 2 mengoptimalkan akses memori antara SRAM dan HBM (High Bandwidth Memory) pada GPU, mengurangi hambatan I/O tanpa mengurangi jumlah komputasi. Ini meningkatkan kecepatan pelatihan beberapa kali lipat dan secara drastis mengurangi konsumsi memori.&lt;/p>
&lt;h3 id="52-gradient-checkpointing">5.2 Gradient Checkpointing
&lt;/h3>&lt;p>Alih-alih menyimpan semua aktivasi perantara yang dihitung selama forward pass ke dalam VRAM, metode ini hanya menyimpan sebagian dan menghitung ulang sisanya jika diperlukan saat backward pass. Meskipun waktu komputasi meningkat sekitar 20%, konsumsi memori berkurang secara drastis. Hasilnya, Anda dapat mengatur ukuran batch yang lebih besar, dan meningkatkan throughput secara keseluruhan.&lt;/p>
&lt;h3 id="53-pelatihan-presisi-campuran-mixed-precision-training-dan-bfloat16">5.3 Pelatihan Presisi Campuran (Mixed Precision Training) dan Bfloat16
&lt;/h3>&lt;p>Untuk memaksimalkan penggunaan Tensor Core pada GPU, komputasi selama pelatihan dilakukan dengan tipe data &lt;code>bfloat16&lt;/code> (Brain Floating Point). Dibandingkan dengan &lt;code>float16&lt;/code>, &lt;code>bfloat16&lt;/code> memiliki panjang bit eksponen yang sama dengan &lt;code>float32&lt;/code>, sehingga risiko overflow dan underflow sangat rendah, menjadikan pelatihan lebih stabil.&lt;/p>
&lt;hr>
&lt;h2 id="6-praktik-kode-fine-tuning-qlora-untuk-tinyllama">6. Praktik: Kode Fine-Tuning QLoRA untuk TinyLLaMA
&lt;/h2>&lt;p>Selanjutnya, kami akan menjelaskan skrip PyTorch untuk tuning tercepat yang mencakup semua optimasi di atas. Di sini, kami menggunakan &lt;code>SFTTrainer&lt;/code> dari pustaka &lt;code>trl&lt;/code> (Transformer Reinforcement Learning) oleh Hugging Face.&lt;/p>
&lt;h3 id="61-persiapan-dataset-dan-pemuatan-model">6.1 Persiapan Dataset dan Pemuatan Model
&lt;/h3>&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;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&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">import&lt;/span> &lt;span class="nn">torch&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">datasets&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">load_dataset&lt;/span>
&lt;/span>&lt;/span>&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="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">AutoModelForCausalLM&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">AutoTokenizer&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">BitsAndBytesConfig&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">TrainingArguments&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="kn">from&lt;/span> &lt;span class="nn">peft&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">LoraConfig&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">get_peft_model&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">prepare_model_for_kbit_training&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">trl&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">SFTTrainer&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"># 1. Menentukan model dan tokenizer&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="o">=&lt;/span> &lt;span class="s2">&amp;#34;TinyLlama/TinyLlama-1.1B-Chat-v1.0&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"># 2. Pengaturan kuantisasi 4-bit untuk QLoRA&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">bnb_config&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">BitsAndBytesConfig&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_4bit&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">bnb_4bit_use_double_quant&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">bnb_4bit_quant_type&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;nf4&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">bnb_4bit_compute_dtype&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">torch&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">bfloat16&lt;/span> &lt;span class="c1"># Komputasi dilakukan dalam bfloat16&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>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 3. Memuat model (Mengaktifkan Flash Attention 2)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Loading model...&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">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">quantization_config&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">bnb_config&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">use_flash_attention_2&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span> &lt;span class="c1"># Kunci percepatan maksimal&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>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 4. Memuat tokenizer&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">tokenizer&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">AutoTokenizer&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">from_pretrained&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">model_id&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">trust_remote_code&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">tokenizer&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">pad_token&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">tokenizer&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">eos_token&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">tokenizer&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">padding_side&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;right&amp;#34;&lt;/span> &lt;span class="c1"># Diatur ke right untuk menghindari bug selama pelatihan fp16/bf16&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="62-penerapan-adaptor-lora-dan-pemformatan-dataset">6.2 Penerapan Adaptor LoRA dan Pemformatan Dataset
&lt;/h3>&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;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&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="c1"># 5. Persiapan untuk pelatihan k-bit dan aktivasi gradient checkpointing&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">gradient_checkpointing_enable&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&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">prepare_model_for_kbit_training&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">model&lt;/span>&lt;span class="p">)&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"># 6. Pengaturan LoRA&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">peft_config&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">LoraConfig&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">r&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">16&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># Rank&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">lora_alpha&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">32&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># Scaling factor&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">lora_dropout&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mf">0.05&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">bias&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;none&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">task_type&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;CAUSAL_LM&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">target_modules&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;q_proj&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;k_proj&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;v_proj&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;o_proj&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;gate_proj&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;up_proj&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;down_proj&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="c1"># Menerapkannya ke semua layer Linear meningkatkan kinerja&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>&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">get_peft_model&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">model&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">peft_config&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&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">print_trainable_parameters&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Contoh output: trainable params: 14,286,848 || all params: 1,114,335,232 || trainable%: 1.282%&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"># 7. Memuat dataset (Di sini menggunakan dataset instruksi bahasa Jepang sebagai contoh)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Dalam praktiknya, Anda memuat file JSONL privat dari on-premises, dll.&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">dataset&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">load_dataset&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;kunishou/databricks-dolly-15k-ja&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">split&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;train&amp;#34;&lt;/span>&lt;span class="p">)&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="k">def&lt;/span> &lt;span class="nf">format_instruction&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">sample&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> Memformat string agar sesuai dengan format ChatML atau template prompt
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> &amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">prompt&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;&amp;lt;|im_start|&amp;gt;user&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">sample&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;instruction&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">sample&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;input&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="s2">&amp;#34;&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">prompt&lt;/span> &lt;span class="o">+=&lt;/span> &lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">sample&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;input&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">prompt&lt;/span> &lt;span class="o">+=&lt;/span> &lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;&amp;lt;|im_end|&amp;gt;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s2">&amp;lt;|im_start|&amp;gt;assistant&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">sample&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;output&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;lt;|im_end|&amp;gt;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;text&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">prompt&lt;/span>&lt;span class="p">}&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">dataset&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">dataset&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">map&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">format_instruction&lt;/span>&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;h3 id="63-pelaksanaan-pelatihan">6.3 Pelaksanaan Pelatihan
&lt;/h3>&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;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&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="c1"># 8. Pengaturan parameter pelatihan&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">training_args&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">TrainingArguments&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">output_dir&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;./tinyllama-lora-output&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">per_device_train_batch_size&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">8&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># Naikkan jika VRAM Anda memungkinkan&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">gradient_accumulation_steps&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># Ukuran batch efektif = 8 * 2 = 16&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">optim&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;paged_adamw_32bit&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># Menghemat VRAM dengan Paged Optimizer&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">save_steps&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">100&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">logging_steps&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">10&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">learning_rate&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mf">2e-4&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">fp16&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">False&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">bf16&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># Pelatihan presisi campuran (bfloat16)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">max_grad_norm&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mf">0.3&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">max_steps&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">500&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># 500 langkah untuk tujuan pengujian. Pada produksi, tentukan dengan epoch&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">warmup_ratio&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mf">0.03&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">group_by_length&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">lr_scheduler_type&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;cosine&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="p">)&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"># 9. Memulai pelatihan menggunakan SFTTrainer&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">trainer&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">SFTTrainer&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&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">model&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">train_dataset&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">dataset&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">peft_config&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">peft_config&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">dataset_text_field&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;text&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">max_seq_length&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">1024&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># Sesuaikan dengan panjang input yang diharapkan&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">tokenizer&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">tokenizer&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">args&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">training_args&lt;/span>&lt;span class="p">,&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>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Starting training...&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">trainer&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">train&lt;/span>&lt;span class="p">()&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"># 10. Menyimpan adaptor LoRA&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">trainer&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">model&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">save_pretrained&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;./tinyllama-lora-final&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">tokenizer&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">save_pretrained&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;./tinyllama-lora-final&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="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Training complete and model saved.&amp;#34;&lt;/span>&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;hr>
&lt;h2 id="7-evaluasi-kinerja-dan-pemecahan-masalah-troubleshooting">7. Evaluasi Kinerja dan Pemecahan Masalah (Troubleshooting)
&lt;/h2>&lt;p>Berikut adalah masalah umum yang sering dihadapi saat menjalankan pelatihan di lingkungan on-premises beserta solusinya.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Terjadinya OOM (Out Of Memory):&lt;/strong>
&lt;ul>
&lt;li>Turunkan nilai &lt;code>per_device_train_batch_size&lt;/code> menjadi &lt;code>1&lt;/code>.&lt;/li>
&lt;li>Tingkatkan &lt;code>gradient_accumulation_steps&lt;/code> untuk mempertahankan ukuran batch efektif.&lt;/li>
&lt;li>Persingkat &lt;code>max_seq_length&lt;/code> dari &lt;code>2048&lt;/code> menjadi &lt;code>1024&lt;/code> atau &lt;code>512&lt;/code>.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;strong>Loss Tidak Menurun atau Mengalami Divergensi:&lt;/strong>
&lt;ul>
&lt;li>Kecepatan pembelajaran (&lt;code>learning_rate&lt;/code>) mungkin terlalu besar. Coba turunkan dari &lt;code>2e-4&lt;/code> menjadi sekitar &lt;code>5e-5&lt;/code>.&lt;/li>
&lt;li>Jika Anda menggunakan Float16 dan bukan Bfloat16, gradien underflow mungkin sedang terjadi. Pastikan nilai &lt;code>bf16=True&lt;/code>.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;strong>String Aneh Muncul Saat Inferensi:&lt;/strong>
&lt;ul>
&lt;li>Pastikan bahwa &lt;code>padding_side=&amp;quot;right&amp;quot;&lt;/code> telah diatur dengan benar. Selain itu, Anda perlu memverifikasi apakah format dataset (seperti token khusus &lt;code>&amp;lt;|im_start|&amp;gt;&lt;/code>) sejalan dengan yang digunakan selama pre-training model dasar.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="8-penerapan-deployment-model-setelah-tuning">8. Penerapan (Deployment) Model Setelah Tuning
&lt;/h2>&lt;p>Setelah tuning selesai, yang disimpan bukanlah &amp;ldquo;keseluruhan model dasar&amp;rdquo;, melainkan hanya &amp;ldquo;&lt;strong>Adaptor LoRA (bobot diferensial)&lt;/strong>&amp;rdquo; yang berukuran beberapa MB hingga puluhan MB. Untuk melakukan inferensi berkecepatan tinggi, bobot LoRA ini perlu digabungkan (di-merge) ke dalam model dasar asli dan diekspor sebagai model tunggal.&lt;/p>
&lt;h3 id="skrip-penggabungan-model">Skrip Penggabungan Model
&lt;/h3>&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;/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">import&lt;/span> &lt;span class="nn">torch&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">peft&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">AutoPeftModelForCausalLM&lt;/span>
&lt;/span>&lt;/span>&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">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">output_dir&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;./tinyllama-lora-final&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"># Memuat model dan adaptor dalam FP16/BF16&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">AutoPeftModelForCausalLM&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">output_dir&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">torch_dtype&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">torch&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">bfloat16&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="n">tokenizer&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">AutoTokenizer&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">from_pretrained&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">output_dir&lt;/span>&lt;span class="p">)&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"># Menggabungkan bobot dan menyimpannya&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">merged_model&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">model&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">merge_and_unload&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">merged_model&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">save_pretrained&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;./tinyllama-merged&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">safe_serialization&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">tokenizer&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">save_pretrained&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;./tinyllama-merged&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="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Model merged and saved successfully!&amp;#34;&lt;/span>&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;h3 id="meluncurkan-server-inferensi-kecepatan-tinggi-menggunakan-vllm">Meluncurkan Server Inferensi Kecepatan Tinggi Menggunakan vLLM
&lt;/h3>&lt;p>Untuk penerapan di lingkungan on-premises, guna memaksimalkan kecepatan inferensi (Tokens per second), kami sangat menyarankan untuk tidak menggunakan &lt;code>pipeline&lt;/code> bawaan Hugging Face, melainkan menggunakan &lt;strong>vLLM&lt;/strong> atau &lt;strong>TGI (Text Generation Inference)&lt;/strong>. vLLM memanfaatkan teknologi PagedAttention untuk mencegah fragmentasi memori GPU, secara drastis meningkatkan kapasitas pemrosesan permintaan bersamaan (concurrent requests).&lt;/p>
&lt;p>Diagram Mermaid berikut mengilustrasikan pipeline dari pelatihan hingga penerapan server inferensi.&lt;/p>
&lt;div class="mermaid">graph TD
A["Data Privat Mentah"] --> B["Pra-pemrosesan &amp; Pemformatan (JSONL)"]
B --> C["QLoRA Fine-Tuning (SFTTrainer)"]
C --> D["Bobot Adaptor LoRA (.safetensors)"]
D --> E["Gabung dengan Base TinyLLaMA 1.1B"]
E --> F["Model Gabungan"]
F --> G["Terapkan via Server vLLM"]
G --> H["Endpoint API / UI (misalnya Chatbot)"]&lt;/div>
&lt;p>Menjalankan server API menggunakan vLLM dapat diselesaikan hanya dengan satu perintah berikut.&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;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">python -m vllm.entrypoints.openai.api_server &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> --model ./tinyllama-merged &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> --host 0.0.0.0 &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> --port &lt;span class="m">8000&lt;/span> &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> --max-model-len &lt;span class="m">2048&lt;/span> &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> --dtype bfloat16
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Dengan ini, sebuah endpoint yang kompatibel dengan API OpenAI dibangun di lingkungan on-premises, memungkinkan pemanfaatan AI lokal secara aman dan berkecepatan tinggi.&lt;/p>
&lt;hr>
&lt;h2 id="9-kesimpulan">9. Kesimpulan
&lt;/h2>&lt;p>Artikel ini menjelaskan metode fine-tuning tercepat dan paling hemat memori di lingkungan on-premises untuk &amp;ldquo;TinyLLaMA&amp;rdquo;, sebuah model yang ringan dengan 1.1B parameter namun berkinerja tinggi.&lt;/p>
&lt;ul>
&lt;li>Dengan &lt;strong>LoRA / QLoRA&lt;/strong>, tuning LLM berskala penuh dapat dilakukan bahkan dengan GPU kelas konsumen.&lt;/li>
&lt;li>Dengan memanfaatkan &lt;strong>Flash Attention 2&lt;/strong> dan &lt;strong>Gradient Checkpointing&lt;/strong> secara optimal, waktu pelatihan dan konsumsi VRAM diminimalkan secara ekstrem.&lt;/li>
&lt;li>Penerapan yang memanfaatkan &lt;strong>vLLM&lt;/strong> memungkinkan tercapainya throughput yang tinggi bahkan di lingkungan produksi.&lt;/li>
&lt;/ul>
&lt;p>Pengoperasian LLM lokal secara on-premises tidak hanya melindungi kerahasiaan data, tetapi juga menjadi senjata terkuat untuk membangun AI khusus pada domain tertentu (hukum, medis, peraturan internal, dll.) dengan biaya rendah. Kami berharap Anda dapat menggunakan panduan ini untuk melatih TinyLLaMA khusus perusahaan Anda.&lt;/p></description></item><item><title>Panduan Pengembangan Model AI Skala Kecil (seperti TinyLLaMA) Menggunakan C++</title><link>http://kenji.blog/id/p/cpp-small-ai-model-tinyllama-dev-guide/</link><pubDate>Fri, 11 Sep 2026 14:00:00 +0900</pubDate><guid>http://kenji.blog/id/p/cpp-small-ai-model-tinyllama-dev-guide/</guid><description>&lt;img src="http://kenji.blog/p/cpp-small-ai-model-tinyllama-dev-guide/img/eyecatch.jpg" alt="Featured image of post Panduan Pengembangan Model AI Skala Kecil (seperti TinyLLaMA) Menggunakan C++" />&lt;h1 id="panduan-pengembangan-model-ai-skala-kecil-seperti-tinyllama-menggunakan-c">Panduan Pengembangan Model AI Skala Kecil (seperti TinyLLaMA) Menggunakan C++
&lt;/h1>&lt;p>Baru-baru ini, minat terhadap eksekusi model bahasa besar (LLM) di lingkungan lokal telah meningkat secara pesat. Secara khusus, model berskala kecil seperti TinyLLaMA (1.1B parameter) dapat diinferensi dengan kecepatan praktis bahkan pada perangkat edge dengan sumber daya terbatas atau laptop umum (termasuk lingkungan Windows). Sementara pengembangan menggunakan Python dan PyTorch adalah arus utama, ketika mengejar kinerja dan efisiensi memori terbaik, kombinasi C++ dan pustaka tensor berbasis C, &amp;ldquo;ggml&amp;rdquo;, telah menjadi standar de facto.&lt;/p>
&lt;p>Artikel ini akan menjelaskan secara rinci prosedur pengembangan (atau pemahaman mendalam tentang struktur internal llama.cpp yang sudah ada) untuk membangun mesin inferensi dari awal guna memuat TinyLLaMA dan melakukan pembuatan teks menggunakan C++.&lt;/p>
&lt;hr>
&lt;h2 id="1-mengapa-c-dan-ggml">1. Mengapa C++ dan ggml?
&lt;/h2>&lt;p>Dalam tahap pelatihan AI, Python sangat diuntungkan dengan fleksibilitas dan ekosistemnya yang kaya. Namun, dalam fase penerapan dan &amp;ldquo;Inferensi&amp;rdquo;, C++ menjadi pilihan yang kuat karena alasan berikut:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Pengurangan Overhead&lt;/strong>: Global Interpreter Lock (GIL) Python dan overhead runtime dapat dihilangkan sepenuhnya.&lt;/li>
&lt;li>&lt;strong>Efisiensi Memori dan Alokasi Arena&lt;/strong>: Karena alokasi dan dealokasi memori dapat dikontrol secara manual, lonjakan yang tidak dapat diprediksi akibat &lt;em>garbage collection&lt;/em> dapat dicegah.&lt;/li>
&lt;li>&lt;strong>Akses Langsung ke Perangkat Keras&lt;/strong>: Dapat langsung memanggil fungsi bawaan SIMD (Intrinsics) seperti AVX-512, AVX2, dan ARM NEON untuk memaksimalkan kemampuan komputasi CPU.&lt;/li>
&lt;li>&lt;strong>Tanpa Dependensi&lt;/strong>: ggml adalah pustaka C/C++ dengan nol dependensi (Zero dependencies), yang dapat dengan mudah dibangun bahkan di lingkungan MSVC di Windows asalkan ada kompilator.&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="2-gambaran-keseluruhan-arsitektur">2. Gambaran Keseluruhan Arsitektur
&lt;/h2>&lt;p>Alur dari seluruh &lt;em>pipeline&lt;/em> inferensi ditunjukkan dalam diagram Mermaid di bawah ini. Ini adalah serangkaian proses mulai dari teks masukan pengguna hingga pembuatan token berikutnya.&lt;/p>
&lt;div class="mermaid">graph TD
A["Teks Masukan Pengguna"] --> B["BPE Tokenizer"]
B --> C["Array ID Token"]
C --> D["Pencarian Lapisan Embedding"]
D --> E["Blok Transformer"]
E --> F["RMSNorm"]
F --> G["Lapisan LM Head"]
G --> H["Array Logit"]
H --> I["Modul Sampler"]
I --> J["ID Token Berikutnya"]
J --> K["Detokenizer"]
K --> L["Potongan Teks Keluaran"]
J -.-> |"Tambahkan ke Konteks"| C&lt;/div>
&lt;p>Karena ini adalah model auto-regresif, token yang dihasilkan ditambahkan kembali ke konteks dan disirkulasikan sebagai masukan untuk memprediksi token berikutnya (bagian garis putus-putus pada diagram).&lt;/p>
&lt;hr>
&lt;h2 id="3-format-model-dan-pemetaan-memori-mmap">3. Format Model dan Pemetaan Memori (mmap)
&lt;/h2>&lt;p>Kendala terbesar dalam menangani bobot jaringan saraf yang sangat besar adalah operasi I/O disk dan konsumsi memori. Implementasi C++ menyelesaikan masalah ini dengan &lt;strong>pemetaan memori (mmap)&lt;/strong>.&lt;/p>
&lt;h3 id="31-cara-kerja-pemetaan-memori-dan-implementasi-di-windows">3.1 Cara Kerja Pemetaan Memori dan Implementasi di Windows
&lt;/h3>&lt;p>Menggunakan mmap memungkinkan konten file dipetakan langsung ke dalam ruang memori virtual proses.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Zero-copy (Tanpa Salinan)&lt;/strong>: Data dibaca langsung dari disk ke dalam tembolok halaman kernel, dan tidak ada salinan ekstra ke ruang pengguna yang terjadi.&lt;/li>
&lt;li>&lt;strong>On-demand Load (Page Fault)&lt;/strong>: Tepat saat CPU mengakses alamat memori tersebut, &lt;em>page fault&lt;/em> terjadi, dan hanya &lt;em>chunk&lt;/em> yang diperlukan (biasanya 4KB) yang dimuat ke dalam memori fisik.&lt;/li>
&lt;/ul>
&lt;p>Di lingkungan Windows, API Win32 &lt;code>CreateFileMapping&lt;/code> dan &lt;code>MapViewOfFile&lt;/code> digunakan sebagai pengganti POSIX &lt;code>mmap&lt;/code>.&lt;/p>
&lt;div class="mermaid">sequenceDiagram
participant OS["OS Windows"]
participant RAM["Memori Fisik"]
participant App["Aplikasi C++"]
App->>OS: "CreateFileMapping / MapViewOfFile"
OS-->>App: "Penunjuk Alamat Memori Virtual"
App->>App: "Baca Data Tensor pada Penunjuk"
OS->>RAM: "Page Fault / Muat halaman dari Disk"
RAM-->>App: "Data siap untuk Komputasi SIMD"&lt;/div>
&lt;h3 id="32-struktur-biner-format-gguf">3.2 Struktur Biner Format GGUF
&lt;/h3>&lt;p>&lt;strong>GGUF (GPT-Generated Unified Format)&lt;/strong>, yang dikonversi dari format seperti &lt;code>.safetensors&lt;/code> Hugging Face, adalah format pamungkas untuk inferensi. GGUF memiliki tata letak biner ketat berikut:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Magic Bytes&lt;/strong>: &lt;code>0x46554747&lt;/code> (GGUF).&lt;/li>
&lt;li>&lt;strong>Version&lt;/strong>: Nomor versi format.&lt;/li>
&lt;li>&lt;strong>Tensor Count &amp;amp; Metadata Count&lt;/strong>: Jumlah tensor dan jumlah pasangan kunci-nilai metadata.&lt;/li>
&lt;li>&lt;strong>Metadata (Key-Value Pairs)&lt;/strong>: Kunci dengan prefiks panjang string, dan nilai yang diketik.&lt;/li>
&lt;li>&lt;strong>Tensor Info&lt;/strong>: Nama setiap tensor, jumlah dimensi, tipe data (FP16, Q4_K, dll.), dan posisi &lt;em>offset&lt;/em> di dalam file.&lt;/li>
&lt;li>&lt;strong>Padding&lt;/strong>: Padding yang dimasukkan agar data tensor sejajar (aligned) pada batas tertentu (biasanya 32 byte atau 64 byte). Ini penting untuk akses memori cepat dalam instruksi SIMD (khususnya AVX).&lt;/li>
&lt;li>&lt;strong>Tensor Data&lt;/strong>: Array data bobot aktual yang telah disejajarkan.&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="4-basis-matematis-tinyllama-dan-algoritma-c">4. Basis Matematis TinyLLaMA dan Algoritma C++
&lt;/h2>&lt;p>TinyLLaMA menggabungkan beberapa penyempurnaan arsitektur tingkat lanjut untuk efisiensi. Ekspresi matematis untuk mengimplementasikan ini dengan benar dalam C++ dijelaskan di bawah ini.&lt;/p>
&lt;h3 id="41-rmsnorm-root-mean-square-normalization">4.1 RMSNorm (Root Mean Square Normalization)
&lt;/h3>&lt;p>Ini mengurangi biaya komputasi dengan menghilangkan pemusatan rata-rata dari LayerNorm dan hanya melakukan penskalaan varians.&lt;/p>
$$ \text{RMSNorm}(x) = \frac{x}{\sqrt{\frac{1}{d}\sum_{i=1}^{d} x_i^2 + \epsilon}} \odot \gamma $$
&lt;p>$d$ adalah jumlah dimensi, dan $\gamma$ adalah tensor penskalaan yang telah dipelajari.
Saat diimplementasikan di C++, ini dioptimalkan dengan terlebih dahulu menghitung jumlah kuadrat array pada kecepatan tinggi menggunakan &lt;code>_mm256_fmadd_ps&lt;/code> dari AVX2, dll., dan mengalikannya dengan akar kuadrat terbalik (seperti instruksi &lt;code>_mm256_rsqrt_ps&lt;/code>).&lt;/p>
&lt;h3 id="42-rope-rotary-position-embedding">4.2 RoPE (Rotary Position Embedding)
&lt;/h3>&lt;p>Ini adalah teknik yang menerapkan informasi posisi token sebagai rotasi (Rotate) di ruang tensor. Ini dapat dianggap sebagai rotasi pada bidang kompleks, dan rotasi berikut diterapkan ke pasangan dimensi yang berdekatan $(x_1, x_2)$ dari vektor $x$.&lt;/p>
$$ \text{RoPE}(x, m) = \begin{pmatrix} x_{1} \cos(m\theta) - x_{2} \sin(m\theta) \\ x_{1} \sin(m\theta) + x_{2} \cos(m\theta) \end{pmatrix} $$
&lt;p>Di sini, $m$ adalah indeks posisi absolut token, dan $\theta$ adalah frekuensi dasar yang dihitung sebelumnya. Dalam ggml, eksekusi paralel dapat dicapai hanya dengan menambahkan operator &lt;code>ggml_rope&lt;/code> selama pembangunan grafik inferensi.&lt;/p>
&lt;h3 id="43-grouped-query-attention-gqa">4.3 Grouped-Query Attention (GQA)
&lt;/h3>&lt;p>Dalam Multi-Head Attention (MHA) reguler, terdapat jumlah head yang sama untuk masing-masing Query, Key, dan Value. Namun, TinyLLaMA mengadopsi &lt;strong>Grouped-Query Attention (GQA)&lt;/strong> untuk secara drastis mengurangi &lt;em>bandwidth&lt;/em> memori dan konsumsi tembolok KV (KV Cache).&lt;/p>
$$ \text{Attention}(Q, K, V) = \text{softmax}\left(\frac{Q K^T}{\sqrt{d_k}}\right) V $$
&lt;p>Di GQA, beberapa head Query berbagi satu head Key/Value. Dalam implementasi C++, perlu melakukan operasi &lt;em>broadcast&lt;/em> pada tensor KV agar sesuai dengan jumlah Query sebelum menjalankan perkalian matriks &lt;code>ggml_mul_mat&lt;/code>.&lt;/p>
&lt;h3 id="44-fungsi-aktivasi-swiglu">4.4 Fungsi Aktivasi SwiGLU
&lt;/h3>&lt;p>Pada lapisan Feed-Forward Network (FFN), SwiGLU digunakan sebagai pengganti GELU.&lt;/p>
$$ \text{SwiGLU}(x) = \text{Swish}(x W_{\text{gate}}) \otimes (x W_{\text{up}}) $$
$$ \text{Swish}(z) = z \cdot \sigma(z) = z \cdot \frac{1}{1 + e^{-z}} $$
&lt;p>Dalam grafik komputasi, ini diekspresikan dengan menggabungkan operator &lt;code>ggml_silu&lt;/code> dan &lt;code>ggml_mul&lt;/code>.&lt;/p>
&lt;hr>
&lt;h2 id="5-pembangunan-grafik-komputasi-dan-manajemen-memori-dengan-ggml">5. Pembangunan Grafik Komputasi dan Manajemen Memori dengan ggml
&lt;/h2>&lt;p>ggml mengambil pendekatan &amp;ldquo;Define-and-Run&amp;rdquo;, di mana grafik komputasi statis untuk inferensi dibangun dan dievaluasi nanti.&lt;/p>
&lt;h3 id="51-ggml_context-dan-arena-allocator">5.1 ggml_context dan Arena Allocator
&lt;/h3>&lt;p>Fitur ggml yang paling unik adalah &amp;ldquo;alokasi arena&amp;rdquo;, yang sama sekali tidak menggunakan alokasi memori dinamis (&lt;code>malloc&lt;/code> atau &lt;code>new&lt;/code>) dalam putaran inferensi.
Area memori (&lt;em>arena&lt;/em>) bersebelahan yang besar dialokasikan saat inisialisasi, dan penunjuk area ini dinaikkan nilainya (incremented) setiap kali &lt;code>ggml_new_tensor&lt;/code> dll. dipanggil. Ketika satu langkah inferensi selesai, hanya dengan mengatur ulang penunjuk alokasi ke posisi awalnya, alokasi memori untuk langkah inferensi berikutnya selesai secara instan.&lt;/p>
&lt;h3 id="52-contoh-konkret-pembangunan-grafik">5.2 Contoh Konkret Pembangunan Grafik
&lt;/h3>&lt;p>Untuk setiap langkah inferensi, grafik komputasi berikut dirakit dalam memori.&lt;/p>
&lt;div class="mermaid">graph TD
A["ID Masukan Token"] --> B["Pencarian Embed"]
B --> C["ggml_rms_norm"]
C --> D["Proyeksi Q / K / V"]
D --> E["Posisi ggml_rope"]
E --> F["Simpan Tembolok KV"]
E --> G["Muat Tembolok KV"]
G --> H["Self Attention"]
H --> I["Skala &amp; Softmax"]
I --> J["Keluaran Attention"]
J --> K["Proyeksi Keluar"]
K --> L["Tambah Residual"]&lt;/div>
&lt;hr>
&lt;h2 id="6-kuantisasi-quantization-dan-optimisasi-windows--simd">6. Kuantisasi (Quantization) dan Optimisasi Windows / SIMD
&lt;/h2>&lt;p>Jika Anda menangani TinyLLaMA (1.1B) dalam FP16, Anda membutuhkan sekitar 2,2GB memori, tetapi melalui kuantisasi 4-bit (seperti Q4_K), ini dapat dikompresi secara dramatis menjadi sekitar 600MB.&lt;/p>
&lt;h3 id="61-arsitektur-kuantisasi-blok">6.1 Arsitektur Kuantisasi Blok
&lt;/h3>&lt;p>ggml tidak mengkuantisasi seluruh tensor secara seragam, melainkan dalam satuan &amp;ldquo;blok&amp;rdquo;.
Dalam format &lt;code>Q4_0&lt;/code>, 32 nilai FP16 dikelompokkan ke dalam satu blok.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Faktor Skala&lt;/strong>: Satu nilai FP16 (2 byte)&lt;/li>
&lt;li>&lt;strong>Data Terkuantisasi&lt;/strong>: 32 nilai 4-bit (16 byte)
Ini meminimalkan dampak dari &lt;em>outlier&lt;/em> lokal.&lt;/li>
&lt;/ul>
&lt;h3 id="62-akselerasi-produk-titik-dengan-avx2">6.2 Akselerasi Produk Titik dengan AVX2
&lt;/h3>&lt;p>Saat membangun untuk CPU x86 terbaru di lingkungan Windows, pemrosesan SIMD dilakukan dalam alur berikut, memanfaatkan tanda (flag) kompilator seperti &lt;code>/arch:AVX2&lt;/code>.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Muat&lt;/strong>: Muat data terkuantisasi 4-bit dari memori ke dalam register AVX 256-bit.&lt;/li>
&lt;li>&lt;strong>Ekspansi dan Buka Paket&lt;/strong>: Ekspansi nilai 4-bit menjadi Int8 atau Int16 dengan &lt;em>bit mask&lt;/em> dan operasi pergeseran (&lt;em>shift&lt;/em>).&lt;/li>
&lt;li>&lt;strong>Dikuantisasi Balik (Dequantization)&lt;/strong>: Kalikan faktor skala untuk mengonversi ke angka &lt;em>floating-point&lt;/em>.&lt;/li>
&lt;li>&lt;strong>Operasi FMA&lt;/strong>: Jalankan operasi perkalian-penjumlahan secara paralel dengan nilai aktivasi dan &lt;code>_mm256_fmadd_ps&lt;/code> (Fused Multiply-Add).&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="7-detail-implementasi-tembolok-kv-kv-cache">7. Detail Implementasi Tembolok KV (KV Cache)
&lt;/h2>&lt;p>Dalam generasi auto-regresif, &amp;ldquo;Tembolok KV&amp;rdquo; (KV Cache) adalah fitur penting untuk mengabaikan penghitungan Key dan Value dari token masa lalu.&lt;/p>
&lt;p>Poin-poin penting saat menerapkan dalam C++ adalah sebagai berikut:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Prapengalokasian Tensor&lt;/strong>: Inisialisasi tensor yang sangat besar untuk ukuran konteks maksimum (misalnya: 2048 token) untuk tembolok KV (FP16 disarankan).&lt;/li>
&lt;li>&lt;strong>Salinan Offset&lt;/strong>: Saat komputasi dilakukan untuk posisi token $N$, simpan vektor K dan V yang diperoleh pada langkah tersebut di baris ke-$N$ dari tensor tembolok KV menggunakan &lt;code>ggml_cpy&lt;/code> atau sejenisnya.&lt;/li>
&lt;li>&lt;strong>Pembuatan Tampilan Saat Attention&lt;/strong>: Saat menghitung Attention, buat &amp;ldquo;tampilan&amp;rdquo; (view) yang hanya menunjuk ke bagian dari token ke-0 hingga ke-$N$ dan teruskan ke perkalian matriks.&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="8-bpe-tokenizer-dan-decoding">8. BPE Tokenizer dan Decoding
&lt;/h2>&lt;p>String masukan diperlakukan sebagai urutan byte UTF-8 dan dicocokkan dengan kosakata yang telah ditentukan sebelumnya. Di C++, algoritma menggunakan &lt;strong>Pohon Trie (Pohon Prefiks)&lt;/strong> atau antrean prioritas (priority queue) diimplementasikan untuk mempercepat pencarian kosakata.&lt;/p>
&lt;p>Dari logit yang dikeluarkan dari LM Head, probabilitas diskalakan menggunakan parameter Temperature, kandidat dipersempit dengan metode ekstraksi Top-K atau Top-P (Nucleus Sampling), dan token berikutnya pada akhirnya ditentukan menggunakan angka acak.&lt;/p>
&lt;hr>
&lt;h2 id="9-mempersiapkan-proyek-c-lingkungan-windows--powershell">9. Mempersiapkan Proyek C++ (Lingkungan Windows / PowerShell)
&lt;/h2>&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;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cmake" data-lang="cmake">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">cmake_minimum_required&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">VERSION&lt;/span> &lt;span class="s">3.14&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">project&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">TinyLLaMACpp&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">set&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">CMAKE_CXX_STANDARD&lt;/span> &lt;span class="s">17&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="c"># Pengaturan Optimisasi dan bendera AVX2 untuk Windows (MSVC)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&lt;/span>&lt;span class="nb">if&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">MSVC&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span> &lt;span class="nb">add_compile_options&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">/O2&lt;/span> &lt;span class="s">/arch:AVX2&lt;/span> &lt;span class="s">/fp:fast&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span> &lt;span class="nb">add_link_options&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">/STACK:8388608&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">else&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span> &lt;span class="nb">add_compile_options&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">-O3&lt;/span> &lt;span class="s">-march=native&lt;/span> &lt;span class="s">-ffast-math&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">endif&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">add_library&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">ggml&lt;/span> &lt;span class="s">OBJECT&lt;/span> &lt;span class="s">ggml/ggml.c&lt;/span> &lt;span class="s">ggml/ggml-alloc.c&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">target_compile_definitions&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">ggml&lt;/span> &lt;span class="s">PRIVATE&lt;/span> &lt;span class="s">GGML_USE_AVX2&lt;/span> &lt;span class="s">GGML_USE_F16C&lt;/span> &lt;span class="s">GGML_USE_FMA&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">add_executable&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">main&lt;/span> &lt;span class="s">main.cpp&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">target_link_libraries&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">main&lt;/span> &lt;span class="s">ggml&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Contoh perintah pembuatan (build) di PowerShell:&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;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="n">mkdir&lt;/span> &lt;span class="n">build&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">cd &lt;/span>&lt;span class="n">build&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">cmake&lt;/span> &lt;span class="p">..&lt;/span> &lt;span class="n">-G&lt;/span> &lt;span class="s2">&amp;#34;Visual Studio 17 2022&amp;#34;&lt;/span> &lt;span class="n">-A&lt;/span> &lt;span class="n">x64&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">cmake&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-build&lt;/span> &lt;span class="p">.&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-config&lt;/span> &lt;span class="n">Release&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;hr>
&lt;h2 id="10-kesimpulan">10. Kesimpulan
&lt;/h2>&lt;p>Membangun mesin inferensi dari awal untuk model AI berskala kecil seperti TinyLLaMA menggunakan C++ dan ggml adalah kesempatan bagus untuk mengungkap kotak hitam (&lt;em>black box&lt;/em>) pembelajaran mendalam dan mempelajari keindahan kontrol perangkat keras tingkat rendah. Mari kita membuka masa depan Edge AI sambil menikmati sepenuhnya esensi pemrograman sistem, seperti pemuatan &lt;em>zero-copy&lt;/em> menggunakan pemetaan memori, optimisasi SIMD, dan pembangunan tembolok KV.&lt;/p></description></item><item><title>【Pengantar Implementasi RAG】 Cara Membuat AI Lokal Membaca Dokumen Anda Sendiri</title><link>http://kenji.blog/id/p/rag-local-ai-implementation-guide/</link><pubDate>Fri, 11 Sep 2026 13:00:00 +0900</pubDate><guid>http://kenji.blog/id/p/rag-local-ai-implementation-guide/</guid><description>&lt;img src="http://kenji.blog/p/rag-local-ai-implementation-guide/img/eyecatch.jpg" alt="Featured image of post 【Pengantar Implementasi RAG】 Cara Membuat AI Lokal Membaca Dokumen Anda Sendiri" />&lt;h1 id="pendahuluan">Pendahuluan
&lt;/h1>&lt;p>Dalam beberapa tahun terakhir, evolusi Large Language Models (LLM) sangat luar biasa, dengan banyak AI seperti ChatGPT dan Claude menyusup ke kehidupan dan pekerjaan kita. Namun, LLM umum memiliki kelemahan yang jelas. Yaitu mereka hanya mengetahui &amp;ldquo;informasi publik pada saat pelatihan&amp;rdquo;. Secara alami, mereka tidak dapat menjawab pertanyaan mengenai &amp;ldquo;dokumen pribadi&amp;rdquo; seperti peraturan internal perusahaan, catatan pribadi, dan materi proyek yang belum dipublikasikan. Jika Anda memaksanya untuk menjawab, ada risiko tinggi bahwa ia akan menghasilkan kebohongan yang masuk akal tetapi bertentangan dengan fakta (halusinasi).&lt;/p>
&lt;p>Oleh karena itu, arsitektur teknologi yang saat ini meledak dalam popularitas di seluruh dunia adalah &lt;strong>RAG (Retrieval-Augmented Generation)&lt;/strong>. Dengan menggunakan RAG, dimungkinkan untuk secara dinamis memberikan pengetahuan unik dari basis data eksternal ke LLM, memungkinkannya untuk menghasilkan jawaban yang akurat dan berdasar berdasarkan pengetahuan tersebut.&lt;/p>
&lt;p>Selain itu, ketika menangani area perusahaan atau informasi rahasia pribadi, mengirim data ke API berbasis cloud seperti OpenAI seringkali tidak diizinkan berdasarkan kebijakan keamanan. Di sinilah dibutuhkan pembangunan &amp;ldquo;RAG lokal&amp;rdquo; yang dikombinasikan dengan &lt;strong>AI lokal&lt;/strong> (LLM yang beroperasi secara mandiri di PC Anda sendiri atau server on-premise).&lt;/p>
&lt;p>Dalam artikel ini, kami akan menjelaskan secara mendalam mulai dari teori dasar RAG, metode implementasi spesifik dari RAG lokal menggunakan Python, latar belakang matematis (mekanisme pencarian vektor), hingga teknik lanjutan untuk menjalankan sistem di lingkungan produksi.&lt;/p>
&lt;hr>
&lt;h1 id="1-arsitektur-keseluruhan-rag">1. Arsitektur Keseluruhan RAG
&lt;/h1>&lt;p>RAG bukanlah model AI tunggal, melainkan arsitektur sistem tempat berbagai komponen bekerja sama. Secara garis besar, ia terdiri dari dua fase: &amp;ldquo;Fase Ingestion (Pemasukan Data)&amp;rdquo; dan &amp;ldquo;Fase Retrieval &amp;amp; Generation (Pencarian dan Pembuatan)&amp;rdquo;.&lt;/p>
&lt;p>Diagram Mermaid berikut menunjukkan gambaran keseluruhan sistem RAG.&lt;/p>
&lt;div class="mermaid">graph TD
subgraph "Fase Ingestion (Persiapan Awal)"
Doc["Dokumen Milik Sendiri (PDF, TXT, dll.)"] --> Loader["Pemuat Dokumen"]
Loader --> Splitter["Pemisahan Teks (Chunking)"]
Splitter --> EmbedModel1["Model Embedding"]
EmbedModel1 --> VectorDB["Database Vektor"]
end
subgraph "Fase Inferensi (Saat Pengguna Bertanya)"
User["Pertanyaan dari Pengguna (Kueri)"] --> EmbedModel2["Model Embedding"]
EmbedModel2 --> QueryVector["Vektor Kueri"]
QueryVector --> Search["Pencarian Kemiripan (Pencarian Vektor)"]
VectorDB --> Search
Search --> Context["Ekstraksi Chunk Terkait (Konteks)"]
User --> PromptBuilder["Pembangun Prompt"]
Context --> PromptBuilder
PromptBuilder --> LocalLLM["LLM Lokal"]
LocalLLM --> Answer["Pembuatan Jawaban Akhir"]
end&lt;/div>
&lt;h2 id="fase-ingestion-persiapan-awal">Fase Ingestion (Persiapan Awal)
&lt;/h2>&lt;ol>
&lt;li>&lt;strong>Pemuatan Dokumen&lt;/strong>: Memuat data tidak terstruktur seperti PDF, Word, dan file teks.&lt;/li>
&lt;li>&lt;strong>Chunking (Pemisahan Teks)&lt;/strong>: Untuk menyesuaikan batasan input LLM (jendela konteks) dan untuk meningkatkan akurasi pencarian, teks panjang dipisahkan menjadi bagian-bagian (chunk) yang bermakna.&lt;/li>
&lt;li>&lt;strong>Embedding (Vektorisasi)&lt;/strong>: Chunk yang telah dipisahkan dimasukkan ke dalam model embedding (Embedding Model) dan diubah menjadi array numerik (vektor) dengan dimensi ratusan hingga ribuan.&lt;/li>
&lt;li>&lt;strong>Penyimpanan ke Database&lt;/strong>: Menyimpan vektor yang telah diubah beserta data teks aslinya ke dalam database vektor (Vector DB) dengan saling menautkan satu sama lain.&lt;/li>
&lt;/ol>
&lt;h2 id="fase-inferensi-saat-dijalankan">Fase Inferensi (Saat Dijalankan)
&lt;/h2>&lt;ol>
&lt;li>&lt;strong>Vektorisasi Kueri&lt;/strong>: Kalimat pertanyaan dari pengguna divektorisasi menggunakan model embedding yang sama dengan yang digunakan saat persiapan awal.&lt;/li>
&lt;li>&lt;strong>Pencarian Kemiripan&lt;/strong>: Perhitungan kemiripan dilakukan antara vektor kueri dan vektor dokumen di dalam database, dan sejumlah kecil teks chunk teratas yang secara semantik dekat (relevansi tinggi) akan diambil.&lt;/li>
&lt;li>&lt;strong>Pembangunan Prompt&lt;/strong>: Teks terkait yang diambil akan digabungkan dengan kalimat pertanyaan pengguna sebagai &amp;ldquo;konteks (pengetahuan latar belakang)&amp;rdquo; untuk membuat prompt input bagi LLM.&lt;/li>
&lt;li>&lt;strong>Pembuatan Jawaban&lt;/strong>: LLM, yang menerima prompt yang telah diperluas, akan menghasilkan jawaban berdasarkan informasi konteks yang diberikan.&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h1 id="2-pemahaman-mendalam-tentang-pencarian-vektor-dan-embeddings">2. Pemahaman Mendalam tentang Pencarian Vektor dan Embeddings
&lt;/h1>&lt;p>Inti dari RAG adalah &amp;ldquo;pencarian vektor (pencarian semantik)&amp;rdquo;. Sementara pencarian kata kunci tradisional (seperti BM25) didasarkan pada kecocokan kata yang tepat atau frekuensi, pencarian vektor didasarkan pada &amp;ldquo;kemiripan makna&amp;rdquo;. Misalnya, kata yang berbeda seperti &amp;ldquo;anjing&amp;rdquo; dan &amp;ldquo;anak anjing&amp;rdquo;, atau &amp;ldquo;PC&amp;rdquo; dan &amp;ldquo;komputer pribadi&amp;rdquo; akan cocok dalam pencarian jika maknanya mirip.&lt;/p>
&lt;h2 id="apa-itu-model-embedding-embedding-model">Apa itu Model Embedding (Embedding Model)?
&lt;/h2>&lt;p>Model embedding adalah jaringan saraf yang menerima teks bahasa alami sebagai input dan mengeluarkan vektor padat (Dense Vector) dengan panjang tetap. Model umum (misalnya &lt;code>text-embedding-3-small&lt;/code> atau sumber terbuka &lt;code>multilingual-e5-large&lt;/code>) memetakan teks ke dalam vektor bilangan real berdimensi 384 atau 1024.&lt;/p>
&lt;p>Dalam ruang multidimensi (ruang laten) ini, telah dipelajari bahwa kalimat dengan makna yang mirip akan memiliki jarak spasial yang lebih dekat di ruang koordinat.&lt;/p>
&lt;h2 id="latar-belakang-matematis-perhitungan-kemiripan-kesamaan-kosinus">Latar Belakang Matematis Perhitungan Kemiripan: Kesamaan Kosinus
&lt;/h2>&lt;p>Ketika database vektor mencari dokumen yang relevan, metrik jarak yang paling umum digunakan adalah &lt;strong>Kesamaan Kosinus (Cosine Similarity)&lt;/strong>. Berbeda dengan jarak Euclidean (jarak spasial absolut), Kesamaan Kosinus berfokus pada &amp;ldquo;sudut antara dua vektor&amp;rdquo;. Karena tidak terlalu terpengaruh oleh panjang kalimat (norma vektor), metrik ini sangat cocok untuk menghitung kemiripan teks.&lt;/p>
&lt;p>Dinyatakan secara matematis, Kesamaan Kosinus dari vektor $\mathbf{A}$ dan $\mathbf{B}$ adalah sebagai berikut.&lt;/p>
$$ \text{Cosine Similarity}(\mathbf{A}, \mathbf{B}) = \cos(\theta) = \frac{\mathbf{A} \cdot \mathbf{B}}{\|\mathbf{A}\| \|\mathbf{B}\|} = \frac{\sum_{i=1}^{n} A_i B_i}{\sqrt{\sum_{i=1}^{n} A_i^2} \sqrt{\sum_{i=1}^{n} B_i^2}} $$
&lt;ul>
&lt;li>$\mathbf{A} \cdot \mathbf{B}$ merepresentasikan produk titik (Dot Product).&lt;/li>
&lt;li>$\|\mathbf{A}\|$ merepresentasikan norma L2 (panjang) dari vektor $\mathbf{A}$.&lt;/li>
&lt;li>$n$ adalah jumlah dimensi vektor.&lt;/li>
&lt;/ul>
&lt;p>Kesamaan kosinus mengambil nilai dari -1 hingga 1.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Mendekati 1&lt;/strong>: Arah kedua vektor hampir sama (maknanya sangat mirip)&lt;/li>
&lt;li>&lt;strong>Mendekati 0&lt;/strong>: Kedua vektor ortogonal (tidak berhubungan)&lt;/li>
&lt;li>&lt;strong>Mendekati -1&lt;/strong>: Kedua vektor menghadap ke arah yang berlawanan (maknanya berlawanan)&lt;/li>
&lt;/ul>
&lt;p>Database vektor terbaru (seperti Chroma, FAISS, Qdrant) mengadopsi algoritma Approximate Nearest Neighbor (ANN) yang disebut HNSW (Hierarchical Navigable Small World), yang dioptimalkan untuk dapat mencari dokumen dengan kesamaan kosinus tinggi dalam hitungan milidetik, bahkan dari jutaan data vektor.&lt;/p>
&lt;hr>
&lt;h1 id="3-tumpukan-teknologi-untuk-membangun-rag-lokal">3. Tumpukan Teknologi untuk Membangun RAG Lokal
&lt;/h1>&lt;p>Untuk membangun RAG lokal sepenuhnya yang tidak bergantung pada cloud, kita memanfaatkan ekosistem sumber terbuka (open source). Berikut ini adalah tumpukan teknologi yang direkomendasikan.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Model Bahasa (LLM)&lt;/strong>
&lt;ul>
&lt;li>Alat: &lt;code>Ollama&lt;/code> atau &lt;code>Llama.cpp&lt;/code>&lt;/li>
&lt;li>Model: Model terbuka yang ringan dan berkinerja tinggi seperti &lt;code>Llama-3-8B-Instruct&lt;/code>, &lt;code>Gemma-2-9B-It&lt;/code>, &lt;code>Qwen2-7B-Instruct&lt;/code>. Untuk tugas bahasa Jepang, model yang disetel untuk bahasa Jepang seperti &lt;code>Llama-3-ELYZA-JP-8B&lt;/code> cukup sesuai.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;strong>Model Embedding (Embedding)&lt;/strong>
&lt;ul>
&lt;li>Model: &lt;code>intfloat/multilingual-e5-large&lt;/code> atau &lt;code>BAAI/bge-m3&lt;/code>. Saat berjalan secara lokal, umumnya model ini diunduh dari Hugging Face dan dijalankan dengan Sentence-Transformers.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;strong>Database Vektor (Vector DB)&lt;/strong>
&lt;ul>
&lt;li>&lt;code>ChromaDB&lt;/code>: Berbasis Python dan sangat mudah diatur. Ideal untuk pengembangan lokal.&lt;/li>
&lt;li>&lt;code>FAISS&lt;/code>: Pustaka pencarian vektor berkecepatan tinggi yang dikembangkan oleh Meta.&lt;/li>
&lt;li>&lt;code>Qdrant&lt;/code> / &lt;code>Milvus&lt;/code>: Untuk lingkungan produksi skala besar.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;strong>Kerangka Kerja Orkestrasi&lt;/strong>
&lt;ul>
&lt;li>&lt;code>LangChain&lt;/code>: Standar de facto untuk menghubungkan komponen (Chain).&lt;/li>
&lt;li>&lt;code>LlamaIndex&lt;/code>: Kerangka koneksi data yang dikhususkan terutama untuk RAG.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;p>Kali ini, kita akan mengimplementasikannya dengan kombinasi yang paling mudah diperkenalkan: &lt;strong>LangChain + ChromaDB + Ollama + HuggingFaceEmbeddings&lt;/strong>.&lt;/p>
&lt;hr>
&lt;h1 id="4-tutorial-implementasi-membangun-rag-lokal-lengkap-dengan-python">4. Tutorial Implementasi: Membangun RAG Lokal Lengkap dengan Python
&lt;/h1>&lt;p>Mulai dari sini, kita akan membangun RAG lokal sambil menulis kode Python yang sebenarnya. Pastikan Anda telah menginstal Ollama di PC Anda dan menjalankannya di latar belakang. Juga, pastikan untuk menarik (pull) model di Ollama terlebih dahulu (misalnya: &lt;code>ollama run llama3&lt;/code>).&lt;/p>
&lt;h2 id="langkah-1-menginstal-pustaka-yang-diperlukan">Langkah 1: Menginstal Pustaka yang Diperlukan
&lt;/h2>&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;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">pip install langchain langchain-community langchain-huggingface
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">pip install chromadb sentence-transformers pypdf
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="langkah-2-gambaran-keseluruhan-kode-implementasi">Langkah 2: Gambaran Keseluruhan Kode Implementasi
&lt;/h2>&lt;p>Berikut adalah skrip Python lengkap untuk memuat file PDF, mengubahnya menjadi vektor, dan meminta LLM lokal untuk menjawab pertanyaan.&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;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;span class="lnt">39
&lt;/span>&lt;span class="lnt">40
&lt;/span>&lt;span class="lnt">41
&lt;/span>&lt;span class="lnt">42
&lt;/span>&lt;span class="lnt">43
&lt;/span>&lt;span class="lnt">44
&lt;/span>&lt;span class="lnt">45
&lt;/span>&lt;span class="lnt">46
&lt;/span>&lt;span class="lnt">47
&lt;/span>&lt;span class="lnt">48
&lt;/span>&lt;span class="lnt">49
&lt;/span>&lt;span class="lnt">50
&lt;/span>&lt;span class="lnt">51
&lt;/span>&lt;span class="lnt">52
&lt;/span>&lt;span class="lnt">53
&lt;/span>&lt;span class="lnt">54
&lt;/span>&lt;span class="lnt">55
&lt;/span>&lt;span class="lnt">56
&lt;/span>&lt;span class="lnt">57
&lt;/span>&lt;span class="lnt">58
&lt;/span>&lt;span class="lnt">59
&lt;/span>&lt;span class="lnt">60
&lt;/span>&lt;span class="lnt">61
&lt;/span>&lt;span class="lnt">62
&lt;/span>&lt;span class="lnt">63
&lt;/span>&lt;span class="lnt">64
&lt;/span>&lt;span class="lnt">65
&lt;/span>&lt;span class="lnt">66
&lt;/span>&lt;span class="lnt">67
&lt;/span>&lt;span class="lnt">68
&lt;/span>&lt;span class="lnt">69
&lt;/span>&lt;span class="lnt">70
&lt;/span>&lt;span class="lnt">71
&lt;/span>&lt;span class="lnt">72
&lt;/span>&lt;span class="lnt">73
&lt;/span>&lt;span class="lnt">74
&lt;/span>&lt;span class="lnt">75
&lt;/span>&lt;span class="lnt">76
&lt;/span>&lt;span class="lnt">77
&lt;/span>&lt;span class="lnt">78
&lt;/span>&lt;span class="lnt">79
&lt;/span>&lt;span class="lnt">80
&lt;/span>&lt;span class="lnt">81
&lt;/span>&lt;span class="lnt">82
&lt;/span>&lt;span class="lnt">83
&lt;/span>&lt;span class="lnt">84
&lt;/span>&lt;span class="lnt">85
&lt;/span>&lt;span class="lnt">86
&lt;/span>&lt;span class="lnt">87
&lt;/span>&lt;span class="lnt">88
&lt;/span>&lt;span class="lnt">89
&lt;/span>&lt;span class="lnt">90
&lt;/span>&lt;span class="lnt">91
&lt;/span>&lt;span class="lnt">92
&lt;/span>&lt;span class="lnt">93
&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">import&lt;/span> &lt;span class="nn">os&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">langchain_community.document_loaders&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">PyPDFLoader&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">langchain_text_splitters&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">RecursiveCharacterTextSplitter&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">langchain_huggingface&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">HuggingFaceEmbeddings&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">langchain_community.vectorstores&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">Chroma&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">langchain_community.llms&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">Ollama&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">langchain_core.prompts&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">PromptTemplate&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">langchain.chains&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">RetrievalQA&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="k">def&lt;/span> &lt;span class="nf">main&lt;/span>&lt;span class="p">():&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 1. Memuat dokumen&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Memuat dokumen...&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="c1"># Tentukan jalur PDF yang ingin dibaca&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">file_path&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;sample_company_policy.pdf&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">loader&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">PyPDFLoader&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">file_path&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">documents&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">loader&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">load&lt;/span>&lt;span class="p">()&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"># 2. Pemisahan Chunk (Text Splitting)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Pisahkan ke ukuran yang sesuai agar tidak merusak makna kalimat&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">text_splitter&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">RecursiveCharacterTextSplitter&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">chunk_size&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">500&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># Jumlah karakter maksimum per chunk&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">chunk_overlap&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">50&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># Jumlah karakter tumpang tindih antara chunk sebelumnya dan berikutnya (mencegah putusnya konteks)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">separators&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="se">\n\n&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;。&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;、&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34; &amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;&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="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">chunks&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">text_splitter&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">split_documents&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">documents&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;Dibagi menjadi &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="nb">len&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">chunks&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2"> chunk.&amp;#34;&lt;/span>&lt;span class="p">)&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"># 3. Inisialisasi Model Embedding (Local HuggingFace Model)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Menggunakan model multibahasa&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Memuat model embedding...&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">embeddings&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">HuggingFaceEmbeddings&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_name&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;intfloat/multilingual-e5-large&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">model_kwargs&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="s1">&amp;#39;device&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s1">&amp;#39;cpu&amp;#39;&lt;/span>&lt;span class="p">}&lt;/span> &lt;span class="c1"># Jika ada GPU, gunakan &amp;#39;cuda&amp;#39; atau &amp;#39;mps&amp;#39;&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>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 4. Membangun Database Vektor (Chroma)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Membangun database vektor...&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">persist_directory&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;./chroma_db&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">vectorstore&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">Chroma&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">from_documents&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">documents&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">chunks&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">embedding&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">embeddings&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">persist_directory&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">persist_directory&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="c1"># Membuat pencari (Retriever). Diatur untuk mengambil 3 dokumen terkait teratas&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">retriever&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">vectorstore&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">as_retriever&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">search_kwargs&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;k&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">3&lt;/span>&lt;span class="p">})&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"># 5. Inisialisasi LLM Lokal (Ollama)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Terhubung ke LLM lokal...&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="c1"># Pastikan Anda telah mengambil model terlebih dahulu dengan &amp;#39;ollama pull llama3&amp;#39; atau semacamnya&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">llm&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">Ollama&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">model&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;llama3&amp;#34;&lt;/span>&lt;span class="p">)&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"># 6. Definisi Template Prompt&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">prompt_template&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;Anda adalah asisten cerdas yang mengetahui peraturan perusahaan dan informasi internal.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">Gunakan hanya konteks (informasi latar belakang) berikut untuk menjawab pertanyaan pengguna secara rinci.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">Jika Anda tidak dapat menemukan jawaban dari konteks, jujurlah dan jawab &amp;#34;Saya tidak tahu dari informasi yang diberikan&amp;#34; tanpa menebak-nebak.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">【Konteks】
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">&lt;/span>&lt;span class="si">{context}&lt;/span>&lt;span class="s2">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">【Pertanyaan】
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">&lt;/span>&lt;span class="si">{question}&lt;/span>&lt;span class="s2">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">【Jawaban】:
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">PROMPT&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">PromptTemplate&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">template&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">prompt_template&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">input_variables&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;context&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;question&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="p">)&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"># 7. Membangun Rantai RAG&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">qa_chain&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">RetrievalQA&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">from_chain_type&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">llm&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">llm&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">chain_type&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;stuff&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">retriever&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">retriever&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">return_source_documents&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># Atur apakah akan mengembalikan sumber informasi&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">chain_type_kwargs&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;prompt&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">PROMPT&lt;/span>&lt;span class="p">}&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>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 8. Eksekusi Pertanyaan&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">query&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;Tolong beri tahu saya tentang persyaratan penggantian biaya transportasi untuk kerja jarak jauh.&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s2">Pertanyaan: &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">query&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&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">result&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">qa_chain&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">invoke&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="s2">&amp;#34;query&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">query&lt;/span>&lt;span class="p">})&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="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;【Jawaban】&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="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">result&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;result&amp;#39;&lt;/span>&lt;span class="p">])&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s2">---&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="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;【Sumber Informasi Referensi】&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="k">for&lt;/span> &lt;span class="n">doc&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">result&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;source_documents&amp;#39;&lt;/span>&lt;span class="p">]:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;- Halaman &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">doc&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">metadata&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;page&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;Tidak diketahui&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">: &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">doc&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">page_content&lt;/span>&lt;span class="p">[:&lt;/span>&lt;span class="mi">50&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">...&amp;#34;&lt;/span>&lt;span class="p">)&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="k">if&lt;/span> &lt;span class="vm">__name__&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="s2">&amp;#34;__main__&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">main&lt;/span>&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;h2 id="penjelasan-poin-poin-kode">Penjelasan Poin-Poin Kode
&lt;/h2>&lt;ol>
&lt;li>&lt;strong>RecursiveCharacterTextSplitter&lt;/strong>:
Ini adalah pemisah yang paling direkomendasikan dalam pemisahan bahasa alami. Ia mencoba untuk membagi dalam urutan paragraf (&lt;code>\n\n&lt;/code>), baris (&lt;code>\n&lt;/code>), dan tanda baca titik (&lt;code>。&lt;/code>), berusaha untuk mempertahankannya dalam &lt;code>chunk_size&lt;/code> yang ditentukan sambil sebisa mungkin menjaga kesatuan makna. Dengan mengatur &lt;code>chunk_overlap&lt;/code>, ini mencegah terputusnya batas konteks yang menyebabkan hilangnya informasi.&lt;/li>
&lt;li>&lt;strong>HuggingFaceEmbeddings&lt;/strong>:
&lt;code>intfloat/multilingual-e5-large&lt;/code> adalah model embedding sumber terbuka yang sangat kuat dan mendukung banyak bahasa. Teks dapat divektorisasi secara offline dalam memori lokal tanpa menggunakan API cloud (seperti &lt;code>text-embedding-ada-002&lt;/code> milik OpenAI).&lt;/li>
&lt;li>&lt;strong>ChromaDB&lt;/strong>:
Karena beroperasi dalam memori atau penyimpanan lokal (berbasis SQLite), tidak perlu menyiapkan server database yang rumit. Dengan menentukan &lt;code>persist_directory&lt;/code>, Anda dapat melompati proses vektorisasi pada saat dijalankan ulang dan memuat DB dari disk.&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h1 id="5-teknik-rag-lanjutan-advanced-rag-techniques">5. Teknik RAG Lanjutan (Advanced RAG Techniques)
&lt;/h1>&lt;p>Sistem RAG dasar (Naive RAG) yang dibangun dalam tutorial di atas sudah dapat beroperasi, tetapi ketika akurasi respons yang tinggi diwajibkan di lingkungan produksi, pengenalan teknik tingkat lanjut berikut ini diperlukan.&lt;/p>
&lt;h2 id="51-pencarian-hibrida-hybrid-search">5.1 Pencarian Hibrida (Hybrid Search)
&lt;/h2>&lt;p>Meskipun pencarian vektor mahir menangkap &amp;ldquo;makna&amp;rdquo;, terkadang pencarian ini buruk pada pencarian kata kunci yang ketat seperti &amp;ldquo;kata benda khusus&amp;rdquo;, &amp;ldquo;nomor model produk&amp;rdquo;, atau &amp;ldquo;ID karyawan&amp;rdquo;.
Oleh karena itu, dengan melakukan &lt;strong>pencarian semantik&lt;/strong> melalui pencarian vektor secara paralel dengan &lt;strong>pencarian kata kunci&lt;/strong> menggunakan algoritma seperti BM25, lalu memberikan skor dan mengintegrasikan hasil dari keduanya (menggunakan metode seperti Reciprocal Rank Fusion; RRF), kita dapat secara dramatis mengurangi kelalaian dalam pencarian.&lt;/p>
&lt;h2 id="52-pemeringkatan-ulang-re-ranking">5.2 Pemeringkatan Ulang (Re-ranking)
&lt;/h2>&lt;p>Meskipun pencarian vektor cepat, hal tersebut tidak selalu mengevaluasi relevansi kontekstual yang tepat dari konteks tersebut. Alur pipa umum untuk meningkatkan akurasi pencarian adalah sebagai berikut.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Pencarian Awal (First-stage Retrieval)&lt;/strong>: Mengambil sekitar 20 hingga 30 chunk terkait secara luas dan dangkal dari database vektor.&lt;/li>
&lt;li>&lt;strong>Evaluasi Ulang (Re-ranking)&lt;/strong>: Menggunakan model pembelajaran mesin lain yang lebih berat yang disebut Cross-Encoder (contoh: &lt;code>bge-reranker&lt;/code>), kita memasukkan pasangan kueri pengguna dan chunk yang diambil untuk menghitung ulang skor kesesuaian semantik.&lt;/li>
&lt;li>&lt;strong>Penyaringan&lt;/strong>: Hanya 3 hingga 5 teratas dengan skor tinggi yang akan diteruskan ke prompt LLM sebagai konteks akhir.&lt;/li>
&lt;/ol>
&lt;p>Metode ini mencegah informasi noise yang tidak relevan masuk ke LLM dan dapat sangat meningkatkan presisi (Precision) jawaban.&lt;/p>
&lt;div class="mermaid">graph LR
Query["Kueri"] --> VSearch["Pencarian Vektor (20 Teratas)"]
VSearch --> Reranker["Model Reranker (Cross-Encoder)"]
Query --> Reranker
Reranker --> TopK["3 Teratas Akurasi Tinggi"]
TopK --> LLM["Pembuatan LLM"]&lt;/div>
&lt;h2 id="53-chunking-semantik-dan-pencarian-dokumen-induk">5.3 Chunking Semantik dan Pencarian Dokumen Induk
&lt;/h2>&lt;p>Alih-alih memisahkan teks secara mekanis dengan jumlah karakter tetap, ada teknik yang disebut &amp;ldquo;Semantic Chunking&amp;rdquo; yang mendeteksi perubahan makna kalimat dengan AI dan memisahkannya.
Selain itu, dalam teknik yang disebut &amp;ldquo;Parent Document Retriever (Pencarian Dokumen Induk)&amp;rdquo;, vektorisasi dilakukan dalam unit yang sangat kecil (seperti kalimat) untuk pencarian guna mencapai pencarian presisi tinggi, dan saat diteruskan ke LLM, &amp;ldquo;paragraf besar asli (dokumen induk)&amp;rdquo; yang berisi kalimat tersebut diserahkan kepada LLM, sehingga menyediakan konteks yang memadai untuk LLM.&lt;/p>
&lt;hr>
&lt;h1 id="6-tantangan-dan-solusi-saat-mengoperasikan-rag-lokal">6. Tantangan dan Solusi saat Mengoperasikan RAG Lokal
&lt;/h1>&lt;p>Saat membangun dan mengoperasikan RAG di lingkungan lokal, terdapat beberapa hambatan tertentu.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Kehabisan VRAM (Memori Video)&lt;/strong>:
Untuk menjalankan LLM lokal pada kecepatan praktis (puluhan token per detik), model tersebut harus dimuat ke dalam VRAM GPU. Menjalankan model kelas 8B dalam fp16 (titik kambang 16-bit) memerlukan sekitar 16GB VRAM, tetapi dengan menggunakan teknologi &lt;strong>Kuantisasi (Quantization)&lt;/strong> (teknologi kompresi menjadi 4-bit atau 8-bit, seperti format GGUF atau AWQ), kecepatan operasi yang memadai dapat dicapai bahkan pada 8GB VRAM (seperti pada PC gaming biasa). Llama.cpp dan Ollama mendukung format kuantisasi ini secara standar.&lt;/li>
&lt;li>&lt;strong>Batasan Jendela Konteks&lt;/strong>:
Jika jumlah konteks yang diperoleh melalui pencarian terlalu banyak, dapat melampaui batas input LLM (batas token) atau menyebabkan model melupakan bagian tengah dari informasi tersebut (fenomena Lost in the middle). Menyesuaikan jumlah chunk yang diekstrak dan menyeleksinya secara ketat dengan teknik pemeringkatan ulang (re-ranking) yang disebutkan sebelumnya adalah suatu keharusan.&lt;/li>
&lt;li>&lt;strong>Manajemen Kesegaran Data&lt;/strong>:
Saat dokumen sumber diperbarui, vektor dokumen yang bersangkutan di dalam database vektor juga harus diperbarui atau dihapus (operasi CRUD). Karena ChromaDB mendukung pembaruan berbasis ID dokumen, mengelola nilai hash file dan mengatur pemrosesan batch yang hanya menyinkronkan perbedaannya adalah langkah yang praktis.&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h1 id="kesimpulan">Kesimpulan
&lt;/h1>&lt;p>RAG (Retrieval-Augmented Generation) adalah paradigma kuat yang mengubah AI dari sekadar asisten serbaguna biasa menjadi &amp;ldquo;pakar pribadi Anda&amp;rdquo; atau &amp;ldquo;pakar spesialis dalam operasi internal perusahaan&amp;rdquo;.&lt;/p>
&lt;p>Bahkan dengan persyaratan kerahasiaan tingkat tinggi yang tidak dapat menggunakan layanan cloud, terbukti bahwa dengan menggabungkan ekosistem sumber terbuka seperti Ollama, LangChain, dan ChromaDB, sebuah lingkungan &amp;ldquo;RAG Lokal&amp;rdquo; yang lengkap dapat dibangun dengan relatif mudah.&lt;/p>
&lt;p>Berdasarkan pemahaman matematis tentang ruang vektor dan pendekatan lanjutan seperti pemisahan teks dan pemeringkatan ulang yang dijelaskan dalam artikel ini, silakan coba kembangkan sistem AI orisinal Anda menggunakan data Anda sendiri. Kecepatan evolusi AI lokal sangat mencengangkan, dan sistem yang Anda bangun hari ini dapat secara instan ditingkatkan kinerjanya pada hari esok hanya dengan menukarnya ke model ringan yang lebih cerdas saat model tersebut dirilis.&lt;/p>
&lt;hr>
&lt;p>&lt;em>Di blog ini, kami akan terus menerbitkan artikel mendalam tentang teknologi AI dan RAG di masa mendatang. Jika Anda memiliki pertanyaan atau masukan, jangan ragu untuk meninggalkannya di kolom komentar.&lt;/em>&lt;/p></description></item><item><title>【Terbaru 2026】Panduan Lengkap Menjalankan LLM Lokal di Lingkungan Windows</title><link>http://kenji.blog/id/p/local-llm-windows-2026/</link><pubDate>Fri, 11 Sep 2026 10:00:00 +0900</pubDate><guid>http://kenji.blog/id/p/local-llm-windows-2026/</guid><description>&lt;img src="http://kenji.blog/p/local-llm-windows-2026/img/eyecatch.jpg" alt="Featured image of post 【Terbaru 2026】Panduan Lengkap Menjalankan LLM Lokal di Lingkungan Windows" />&lt;h1 id="1-pendahuluan-mengapa-llm-lokal-di-windows-sekarang">1. Pendahuluan: Mengapa LLM Lokal di Windows Sekarang?
&lt;/h1>&lt;p>Pada tahun 2026, evolusi AI Generatif dan Large Language Models (LLM) menunjukkan pergeseran paradigma besar dari layanan API raksasa di cloud ke &amp;ldquo;LLM lokal&amp;rdquo; yang berjalan di PC pribadi atau lingkungan on-premise. AI cloud seperti GPT-5 dari OpenAI dan Claude 3.5 dari Anthropic sangat kuat, namun tidak semua perusahaan atau individu dapat mengirimkan seluruh data mereka ke cloud. Dari perspektif privasi, keamanan, latensi, serta biaya jangka panjang dan berkelanjutan, permintaan untuk LLM lokal meningkat pesat seperti yang belum pernah terjadi sebelumnya.&lt;/p>
&lt;p>Khususnya di lingkungan Windows, evolusi ekosistem LLM lokal sangat luar biasa. Hingga beberapa tahun yang lalu, menjadi rahasia umum bahwa &amp;ldquo;pengembangan dan eksekusi AI sama dengan Linux&amp;rdquo;, tetapi pada tahun 2026, Windows telah bertransformasi menjadi platform AI yang sangat kuat dan mudah digunakan.&lt;/p>
&lt;p>Artikel ini memberikan panduan lengkap untuk membangun, mengoperasikan, dan mengoptimalkan LLM lokal di lingkungan Windows, berdasarkan tren teknologi terbaru tahun 2026. Mulai dari pengaturan sederhana menggunakan Ollama untuk pemula, optimasi ekstrem memanfaatkan llama.cpp untuk pengguna tingkat lanjut, hingga pemahaman mendalam tentang arsitektur dan pendekatan matematis perhitungan VRAM, serta fine-tuning lokal, kami akan menjelaskannya secara menyeluruh dengan volume yang melimpah.&lt;/p>
&lt;h2 id="11-tren-teknologi-seputar-llm-lokal-tahun-2026">1.1 Tren Teknologi Seputar LLM Lokal Tahun 2026
&lt;/h2>&lt;p>Tren utama yang membentuk ekosistem LLM lokal saat ini adalah sebagai berikut:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Adopsi Penuh Format GGUF&lt;/strong>: GGUF (GPT-Generated Unified Format), yang mengintegrasikan metadata dan tensor ke dalam satu file, telah sepenuhnya menjadi standar de facto. Ini memungkinkan eksekusi di lingkungan mana pun hanya dengan mengunduh satu file dari Hugging Face.&lt;/li>
&lt;li>&lt;strong>Demokratisasi Arsitektur MoE (Mixture of Experts)&lt;/strong>: Banyak model MoE berskala kecil namun berkinerja tinggi telah dirilis. Dengan hanya mengaktifkan beberapa &amp;ldquo;ahli&amp;rdquo; selama inferensi, ini mencapai kinerja yang sebanding dengan model raksasa sambil menekan beban komputasi PC konsumen.&lt;/li>
&lt;li>&lt;strong>Abstraksi dan Optimasi Lanjutan dari Mesin Inferensi&lt;/strong>: Alat seperti Ollama, LM Studio, dan AnythingLLM telah disempurnakan, sehingga pengguna tidak perlu lagi peduli dengan dependensi kompleks seperti instalasi driver CUDA. Selain itu, dengan dukungan asli Windows untuk FlashAttention 3, kecepatan inferensi meningkat secara dramatis.&lt;/li>
&lt;li>&lt;strong>Pemanfaatan NPU dan Kemunculan PC Windows Copilot+&lt;/strong>: Bahkan pada laptop tanpa GPU, teknologi yang menggunakan NPU (Neural Processing Unit) bawaan untuk menjalankan LLM skala kecil (SLM: Small Language Models) dengan konsumsi daya rendah telah mencapai tahap praktis.&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h1 id="2-persyaratan-perangkat-keras-dan-persiapan-os">2. Persyaratan Perangkat Keras dan Persiapan OS
&lt;/h1>&lt;p>Untuk menjalankan LLM lokal pada kecepatan yang praktis (15-30 token atau lebih per detik), pemilihan perangkat keras adalah yang paling penting.&lt;/p>
&lt;h2 id="21-konfigurasi-perangkat-keras-yang-disarankan">2.1 Konfigurasi Perangkat Keras yang Disarankan
&lt;/h2>&lt;p>Seiring dengan evolusi PC AI, spesifikasi yang dibutuhkan juga berubah.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>OS&lt;/strong>: Windows 11 Pro (24H2 atau lebih baru). Diperlukan untuk memanfaatkan fungsionalitas penuh WSL2, manajemen memori tingkat lanjut, dan API terbaru dari DirectML.&lt;/li>
&lt;li>&lt;strong>CPU&lt;/strong>: Intel Core Ultra seri 200 ke atas, atau AMD Ryzen seri 9000 ke atas. Saat menggunakan inferensi CPU bersama-sama, komunikasi memori bandwidth tinggi sangat penting.&lt;/li>
&lt;li>&lt;strong>RAM&lt;/strong>: Minimal 32GB, disarankan 64GB atau lebih. Bandwidth memori utama (MB/s) menjadi bottleneck penentu selama inferensi CPU atau offloading. Memori berkecepatan tinggi DDR5-6000 atau lebih adalah ideal.&lt;/li>
&lt;li>&lt;strong>GPU&lt;/strong>: NVIDIA seri RTX 4000/5000. Dalam LLM lokal, yang paling penting bukanlah kinerja komputasi melainkan &amp;ldquo;kapasitas VRAM&amp;rdquo;.
&lt;ul>
&lt;li>&lt;strong>Entry level&lt;/strong>: RTX 4060 Ti (versi 16GB) - Kinerja biaya (cost-performance) terbaik. Sangat cocok untuk model kelas 8B-14B.&lt;/li>
&lt;li>&lt;strong>Menengah (Mid-range)&lt;/strong>: RTX 4070 Ti SUPER (16GB) / RTX 4080 SUPER (16GB)&lt;/li>
&lt;li>&lt;strong>High-end&lt;/strong>: RTX 4090 (24GB) / RTX 5090 (32GB) - Diperlukan untuk menjalankan model terkuantisasi kelas 30B-70B.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;strong>Penyimpanan&lt;/strong>: SSD NVMe PCIe Gen4 atau Gen5. Mengurangi waktu pemuatan model puluhan GB secara dramatis.&lt;/li>
&lt;/ul>
&lt;h2 id="22-pengaturan-wsl2-windows-subsystem-for-linux-2">2.2 Pengaturan WSL2 (Windows Subsystem for Linux 2)
&lt;/h2>&lt;p>Meskipun banyak alat GUI berjalan secara native di Windows, WSL2 sangat praktis untuk pengembangan menggunakan Python, kompilasi alat terbaru, dan fine-tuning LoRA yang akan dijelaskan nanti. Di lingkungan Windows 11 terbaru, hanya dengan menginstal driver NVIDIA di sisi host, GPU (CUDA) dapat digunakan secara transparan dari WSL2.&lt;/p>
&lt;p>Buka PowerShell dengan hak administrator dan jalankan berikut ini:&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;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="c"># Instalasi WSL2 dan Ubuntu terbaru&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">wsl&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-install&lt;/span> &lt;span class="n">-d&lt;/span> &lt;span class="n">Ubuntu&lt;/span>&lt;span class="p">-&lt;/span>&lt;span class="mf">24.04&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="c"># Pembaruan kernel&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">wsl&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-update&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Setelah instalasi, jalankan &lt;code>nvidia-smi&lt;/code> di terminal WSL2. Jika GPU terdeteksi secara normal, instalasi berhasil.&lt;/p>
&lt;hr>
&lt;h1 id="3-arsitektur-llm-lokal-dan-mekanisme-inferensi">3. Arsitektur LLM Lokal dan Mekanisme Inferensi
&lt;/h1>&lt;p>Memahami struktur internal bagaimana model menghasilkan teks di lingkungan lokal sangat berguna untuk pemecahan masalah dan pengoptimalan.&lt;/p>
&lt;p>Diagram Mermaid di bawah ini menunjukkan alur (pipeline) inferensi LLM lokal yang umum.&lt;/p>
&lt;div class="mermaid">graph TD
User["Input Pengguna (Prompt)"] --> Tokenizer["Tokenizer (Tokenizer)"]
Tokenizer --> Embedding["Lapisan Penyematan (Embedding)"]
subgraph "Transformer Block (x Layers)"
Embedding --> Attn["Perhatian Diri (Self-Attention)"]
Attn --> KVCache["Cache KV (Penyimpanan Key/Value)"]
Attn --> FFN["Jaringan Feed-Forward (FFN)"]
end
FFN --> Logits["Perhitungan Logit (Logits)"]
Logits --> Sampler["Sampler (Temperature, Top-K, Top-P)"]
Sampler --> OutputToken["Token Output"]
OutputToken --> |"Pembuatan Autoregresif"| Tokenizer
OutputToken --> Decoder["Detokenizer (Detokenizer)"]
Decoder --> FinalOutput["Teks Output Akhir"]&lt;/div>
&lt;h2 id="31-dua-fase-prefill-dan-decode">3.1 Dua Fase: Prefill dan Decode
&lt;/h2>&lt;p>Pembuatan teks LLM dibagi menjadi dua fase dengan karakteristik komputasi yang berbeda.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Fase Prefill (Pemrosesan Prompt)&lt;/strong>: Ini adalah fase untuk memproses dan memahami seluruh prompt input sekaligus. Karena komputasi paralel memungkinkan, kapasitas komputasi GPU (FLOPS) berbanding lurus dengan kecepatan. Jika prompt panjang, fase ini bisa memakan waktu beberapa detik.&lt;/li>
&lt;li>&lt;strong>Fase Decode (Pembuatan Token)&lt;/strong>: Fase ini memprediksi token demi token dan memasukkannya kembali sebagai input berikutnya (autoregresif). Karena komputasi paralel terbatas dalam fase ini, bandwidth VRAM GPU (Memory Bandwidth) menjadi bottleneck penentu.&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h1 id="4-perhitungan-konsumsi-vram-dan-pemahaman-matematis-ukuran-model">4. Perhitungan Konsumsi VRAM dan Pemahaman Matematis Ukuran Model
&lt;/h1>&lt;p>Untuk menilai dengan tepat &amp;ldquo;model mana yang dapat berjalan di PC saya?&amp;rdquo;, Anda perlu memahami rumus perhitungan VRAM. Jika fallback ke memori sistem (RAM) terjadi karena kekurangan VRAM, kecepatan inferensi akan melambat 10 hingga 100 kali lipat.&lt;/p>
&lt;h2 id="41-vram-dasar-berdasarkan-ukuran-parameter">4.1 VRAM Dasar Berdasarkan Ukuran Parameter
&lt;/h2>&lt;p>Ini adalah jumlah memori untuk memuat bobot (weights) model ke dalam VRAM.
Dihitung menggunakan ukuran model $P$ (jumlah parameter, satuan: 1 Miliar = 1B) dan jumlah byte per parameter $B$.&lt;/p>
$$
V_{base} = P \times B \quad \text{(GB)}
$$
&lt;p>Misalnya, jika memuat model parameter 8B (8 miliar) dalam FP16 (titik mengambang presisi setengah, 16-bit = 2 byte):&lt;/p>
$$
V_{base} = 8 \times 2 = 16 \text{ GB}
$$
&lt;p>Dengan kata lain, meskipun GPU memiliki VRAM 16GB, batasnya sudah hampir tercapai hanya dengan memuat model.&lt;/p>
&lt;h2 id="42-keajaiban-kuantisasi-quantization">4.2 Keajaiban Kuantisasi (Quantization)
&lt;/h2>&lt;p>Di sinilah &amp;ldquo;kuantisasi&amp;rdquo; muncul. Ini secara dramatis mengurangi ukuran model dengan menurunkan presisi parameter. Pada kuantisasi 4-bit yang paling umum (contoh: Q4_K_M), rata-rata adalah sekitar 0,55 byte per parameter.&lt;/p>
$$
V_{base\_4bit} = 8 \times 0.55 = 4.4 \text{ GB}
$$
&lt;p>Dengan demikian, jika Anda memiliki 16GB VRAM, Anda dapat menjalankan model 8B dengan kelonggaran yang cukup.&lt;/p>
&lt;h2 id="43-perhitungan-cache-kv-versi-kompatibel-gqa">4.3 Perhitungan Cache KV (Versi Kompatibel GQA)
&lt;/h2>&lt;p>Selama inferensi, &amp;ldquo;Cache KV&amp;rdquo; untuk mempertahankan konteks masa lalu akan mengonsumsi VRAM. Pada model terbaru seperti Llama 3, GQA (Grouped Query Attention) diadopsi untuk menghemat memori.&lt;/p>
&lt;p>Konsumsi Cache KV $V_{kv}$ (Gigabyte) direpresentasikan oleh rumus berikut.&lt;/p>
$$
V_{kv} = 2 \times b \times s \times l \times \left( \frac{h_{kv}}{h_q} \right) \times h_q \times d \times B_{kv} \div 10^9
$$
&lt;p>Disederhanakan, ini dapat dihitung dengan mudah menggunakan jumlah head key dan value $h_{kv}$.&lt;/p>
$$
V_{kv} = 2 \times b \times s \times l \times h_{kv} \times d \times B_{kv} \div 10^9
$$
&lt;p>Di mana:&lt;/p>
&lt;ul>
&lt;li>$b$: Ukuran batch (biasanya 1 untuk penggunaan lokal pribadi)&lt;/li>
&lt;li>$s$: Panjang sekuens (panjang konteks, contoh: 8192)&lt;/li>
&lt;li>$l$: Jumlah lapisan (contoh: 32)&lt;/li>
&lt;li>$h_{kv}$: Jumlah head KV (contoh: 8)&lt;/li>
&lt;li>$d$: Jumlah dimensi per head (contoh: 128)&lt;/li>
&lt;li>$B_{kv}$: Jumlah byte dari Cache KV (2 untuk FP16)&lt;/li>
&lt;/ul>
&lt;p>Contoh perhitungan (Llama 3 8B, konteks 8192, Cache FP16):
$V_{kv} = 2 \times 1 \times 8192 \times 32 \times 8 \times 128 \times 2 \div 10^9 \approx 1.07 \text{ GB}$&lt;/p>
&lt;p>Perhatikan bahwa semakin panjang panjang konteks $s$, VRAM yang dibutuhkan akan meningkat secara linier.&lt;/p>
&lt;hr>
&lt;h1 id="5-praktik-1-pengaturan-tercepat--tersingkat-menggunakan-ollama">5. Praktik 1: Pengaturan Tercepat &amp;amp; Tersingkat Menggunakan Ollama
&lt;/h1>&lt;p>Setelah memahami teorinya, mari kita coba menjalankan LLM di lingkungan Windows secara nyata.
Hingga tahun 2026, alat yang paling ramah pengguna adalah &amp;ldquo;Ollama&amp;rdquo;. Ia menyediakan CLI intuitif yang mirip Docker.&lt;/p>
&lt;h2 id="51-instalasi-dan-eksekusi">5.1 Instalasi dan Eksekusi
&lt;/h2>&lt;ol>
&lt;li>Unduh penginstal versi Windows dari &lt;a class="link" href="https://ollama.com/" target="_blank" rel="noopener"
>Situs Resmi Ollama&lt;/a> dan jalankan.&lt;/li>
&lt;li>Buka PowerShell dan masukkan perintah berikut. Di sini, kita akan menggunakan &lt;code>llama3:8b&lt;/code> yang mendukung bahasa Jepang.&lt;/li>
&lt;/ol>
&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;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="n">ollama&lt;/span> &lt;span class="n">run&lt;/span> &lt;span class="n">llama3&lt;/span>&lt;span class="err">:&lt;/span>&lt;span class="n">8b&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Pada percobaan pertama, model akan diunduh. Setelah selesai, Anda dapat langsung berinteraksi di terminal.&lt;/p>
&lt;h2 id="52-pembuatan-ai-kustom-dengan-modelfile">5.2 Pembuatan AI Kustom dengan Modelfile
&lt;/h2>&lt;p>Anda dapat dengan mudah membuat AI yang memiliki persona tertentu. Buat &lt;code>Modelfile&lt;/code> di lokasi yang diinginkan.&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;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">FROM llama3:8b
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">SYSTEM &amp;#34;&amp;#34;&amp;#34;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Anda adalah insinyur perangkat lunak senior yang sangat hebat.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Untuk pertanyaan pengguna, selalu jawab secara logis dan ringkas, dengan menyertakan contoh kode.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&amp;#34;&amp;#34;&amp;#34;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">PARAMETER temperature 0.3
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">PARAMETER num_ctx 8192
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Bangun model kustom Anda sendiri dan jalankan dengan perintah berikut.&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;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="n">ollama&lt;/span> &lt;span class="n">create&lt;/span> &lt;span class="n">SeniorDev&lt;/span> &lt;span class="o">-f&lt;/span> &lt;span class="p">./&lt;/span>&lt;span class="n">Modelfile&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">ollama&lt;/span> &lt;span class="n">run&lt;/span> &lt;span class="n">SeniorDev&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="53-penggunaan-dari-aplikasi-eksternal-ai-editor">5.3 Penggunaan dari Aplikasi Eksternal (AI Editor)
&lt;/h2>&lt;p>Ollama mengekspos endpoint API yang kompatibel dengan OpenAI di &lt;code>http://localhost:11434&lt;/code>.
Hanya dengan mengatur URL ke atas di pengaturan backend ekstensi VS Code seperti Cursor atau Continue.dev, dan menetapkan nama model ke &lt;code>SeniorDev&lt;/code> dll, Anda mendapatkan asisten pengkodean lokal yang kuat secara gratis.&lt;/p>
&lt;hr>
&lt;h1 id="6-praktik-2-penyesuaian-kinerja-ekstrem-dengan-llamacpp">6. Praktik 2: Penyesuaian Kinerja Ekstrem dengan llama.cpp
&lt;/h1>&lt;p>Jika Anda ingin mencoba manajemen memori yang mendetail atau format terbaru (seperti kuantisasi EXL2 atau IQ) sesegera mungkin, operasikan langsung mesin intinya &lt;code>llama.cpp&lt;/code>.&lt;/p>
&lt;h2 id="61-langkah-build-llamacpp">6.1 Langkah Build llama.cpp
&lt;/h2>&lt;p>Di lingkungan Windows, yang terbaik adalah membangun dari sumber menggunakan CUDA Toolkit dan CMake.&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;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="n">git&lt;/span> &lt;span class="n">clone&lt;/span> &lt;span class="n">https&lt;/span>&lt;span class="err">:&lt;/span>&lt;span class="p">//&lt;/span>&lt;span class="n">github&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">com&lt;/span>&lt;span class="p">/&lt;/span>&lt;span class="n">ggerganov&lt;/span>&lt;span class="p">/&lt;/span>&lt;span class="n">llama&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nb">cpp
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">cd &lt;/span>&lt;span class="n">llama&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nb">cpp
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">&lt;/span>&lt;span class="n">mkdir&lt;/span> &lt;span class="n">build&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">cd &lt;/span>&lt;span class="n">build&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="c"># Konfigurasi dan kompilasi untuk dukungan CUDA&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">cmake&lt;/span> &lt;span class="p">..&lt;/span> &lt;span class="n">-DLLAMA_CUBLAS&lt;/span>&lt;span class="p">=&lt;/span>&lt;span class="n">ON&lt;/span> &lt;span class="n">-DBUILD_SHARED_LIBS&lt;/span>&lt;span class="p">=&lt;/span>&lt;span class="n">OFF&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">cmake&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-build&lt;/span> &lt;span class="p">.&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-config&lt;/span> &lt;span class="n">Release&lt;/span> &lt;span class="n">-j&lt;/span> &lt;span class="mf">16&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="62-peluncuran-lanjutan-dalam-mode-server">6.2 Peluncuran Lanjutan dalam Mode Server
&lt;/h2>&lt;p>Gunakan &lt;code>llama-server.exe&lt;/code> yang telah dibangun untuk meng-host 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;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="p">.\&lt;/span>&lt;span class="n">bin&lt;/span>&lt;span class="p">\&lt;/span>&lt;span class="n">Release&lt;/span>&lt;span class="p">\&lt;/span>&lt;span class="nb">llama-server&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="py">exe&lt;/span> &lt;span class="p">`&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">-&lt;/span>&lt;span class="n">-model&lt;/span> &lt;span class="s2">&amp;#34;C:\models\Llama-3-8B-Instruct.Q4_K_M.gguf&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="p">-&lt;/span>&lt;span class="n">-ctx-size&lt;/span> &lt;span class="mf">8192&lt;/span> &lt;span class="p">`&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">-&lt;/span>&lt;span class="n">-n-gpu-layers&lt;/span> &lt;span class="mf">99&lt;/span> &lt;span class="p">`&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">-&lt;/span>&lt;span class="n">-threads&lt;/span> &lt;span class="mf">8&lt;/span> &lt;span class="p">`&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">-&lt;/span>&lt;span class="n">-flash-attn&lt;/span> &lt;span class="p">`&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">-&lt;/span>&lt;span class="n">-port&lt;/span> &lt;span class="mf">8080&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;ul>
&lt;li>&lt;code>--n-gpu-layers 99&lt;/code>: Membongkar (offload) semua lapisan yang memungkinkan ke VRAM GPU.&lt;/li>
&lt;li>&lt;code>--flash-attn&lt;/code>: Mengaktifkan FlashAttention 3, mencapai peningkatan kecepatan inferensi dan pengurangan konsumsi VRAM dari Cache KV.&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h1 id="7-gui-frontend-lm-studio-dan-membangun-rag-lokal">7. GUI Frontend: LM Studio dan Membangun RAG Lokal
&lt;/h1>&lt;p>Jika Anda tidak nyaman dengan baris perintah, atau jika Anda ingin melakukan RAG (Retrieval-Augmented Generation) secara intuitif, gunakan GUI.&lt;/p>
&lt;h2 id="71-lm-studio">7.1 LM Studio
&lt;/h2>&lt;p>LM Studio adalah aplikasi brilian yang menggabungkan pencarian model, pengunduhan, pemeriksaan awal persyaratan sistem, dan bahkan UI obrolan menjadi satu. Cukup dengan menekan tombol &amp;ldquo;Local Server&amp;rdquo; di dalam aplikasi, API yang kompatibel dengan OpenAI akan dimulai.&lt;/p>
&lt;h2 id="72-arsitektur-rag-menggunakan-anythingllm">7.2 Arsitektur RAG menggunakan AnythingLLM
&lt;/h2>&lt;p>Berikut adalah diagram arsitektur lingkungan RAG untuk membaca dokumen internal perusahaan atau catatan pribadi.&lt;/p>
&lt;div class="mermaid">graph LR
Document["Dokumen (PDF, MD)"] --> Chunking["Pembagian Potongan (Chunking)"]
Chunking --> EmbedModel["Model Penyematan"]
EmbedModel --> VectorDB["Database Vektor"]
UserQuery["Pertanyaan Pengguna"] --> EmbedQuery["Penyematan Pertanyaan"]
EmbedQuery --> VectorDB
VectorDB --> |"Pencarian Kemiripan"| RetrievedDocs["Ekstraksi Dokumen Terkait"]
UserQuery --> PromptBuilder["Pembuatan Prompt"]
RetrievedDocs --> PromptBuilder
PromptBuilder --> LocalLLM["LLM Lokal"]
LocalLLM --> Answer["Jawaban Akhir"]&lt;/div>
&lt;p>Dengan AnythingLLM versi desktop (Windows), Anda hanya perlu menentukan Ollama (LLM dan Embedding) dari layar pengaturan, dan mengaturnya untuk menggunakan VectorDB lokal (LanceDB), dan arsitektur ini selesai dalam beberapa menit. Lahirlah AI privat yang tidak mengirimkan data apa pun ke luar.&lt;/p>
&lt;hr>
&lt;h1 id="8-fine-tuning-lora-di-windows-wsl2">8. Fine-tuning (LoRA) di Windows WSL2
&lt;/h1>&lt;p>Jika Anda tidak hanya ingin menjalankannya secara lokal, tetapi juga ingin membuat model Anda lebih pintar dengan data Anda sendiri, fine-tuning menggunakan LoRA (Low-Rank Adaptation) dimungkinkan. Hingga tahun 2026, menggunakan pustaka bernama &amp;ldquo;Unsloth&amp;rdquo;, pelatihan model 8B dapat diselesaikan dalam beberapa jam bahkan dengan VRAM 16GB di lingkungan Windows WSL2.&lt;/p>
&lt;p>Jalankan berikut ini di dalam Ubuntu WSL2 untuk mengatur lingkungan.&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;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">conda create --name unsloth_env &lt;span class="nv">python&lt;/span>&lt;span class="o">=&lt;/span>3.11
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">conda activate unsloth_env
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">pip install &lt;span class="s2">&amp;#34;unsloth[colab-new] @ git+https://github.com/unslothai/unsloth.git&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">pip install --no-deps trl peft accelerate bitsandbytes
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Unsloth mengoptimalkan kernel CUDA hingga batasnya, mencapai kecepatan pelatihan sekitar 2 kali lipat dan mengurangi konsumsi VRAM hingga separuhnya dibandingkan dengan pustaka Hugging Face standar. Hanya dengan meluncurkan Jupyter Notebook dan memuat kumpulan data (format JSONL), Anda dapat melakukan pelatihan beberapa epoch bahkan pada RTX 4060 Ti dll dengan VRAM 12GB hingga 16GB.&lt;/p>
&lt;hr>
&lt;h1 id="9-pemecahan-masalah-kinerja">9. Pemecahan Masalah Kinerja
&lt;/h1>&lt;p>Ini adalah masalah umum dan solusinya.&lt;/p>
&lt;h3 id="1-kecepatan-inferensi-sangat-lambat-1-2-tokens">1. Kecepatan inferensi sangat lambat (1-2 token/s)
&lt;/h3>&lt;p>&lt;strong>Penyebab&lt;/strong>: Model tidak muat sepenuhnya di VRAM dan sedang dibongkar (offload) ke memori sistem (RAM).
&lt;strong>Solusi&lt;/strong>: Periksa &amp;ldquo;Memori GPU Khusus&amp;rdquo; di Task Manager. Jika mencapai batas, kurangi ukuran konteks (&lt;code>-c&lt;/code>) atau gunakan model kuantisasi dengan bit yang lebih rendah (seperti Q4_K_M).&lt;/p>
&lt;h3 id="2-kesalahan-cuda-out-of-memory">2. Kesalahan &amp;ldquo;CUDA out of memory&amp;rdquo;
&lt;/h3>&lt;p>&lt;strong>Penyebab&lt;/strong>: VRAM telah habis sepenuhnya. Ini terutama terjadi ketika percakapan diperpanjang dan Cache KV membengkak.
&lt;strong>Solusi&lt;/strong>: Secara sengaja batasi nilai &lt;code>num_ctx&lt;/code> untuk Ollama atau &lt;code>-c&lt;/code> untuk llama.cpp menjadi lebih kecil.&lt;/p>
&lt;h3 id="3-pembuatan-teks-bahasa-jepangindonesia-aneh">3. Pembuatan teks bahasa Jepang/Indonesia aneh
&lt;/h3>&lt;p>&lt;strong>Penyebab&lt;/strong>: Ketidaksesuaian template prompt, atau model yang tidak didukung.
&lt;strong>Solusi&lt;/strong>: Gunakan model yang menyertakan &lt;code>Instruct&lt;/code> dalam namanya, dan pastikan template yang benar yang ditentukan oleh pembuat model, seperti format ChatML atau Llama3, dipilih di sisi alat.&lt;/p>
&lt;hr>
&lt;h1 id="10-kesimpulan-dan-prospek-masa-depan">10. Kesimpulan dan Prospek Masa Depan
&lt;/h1>&lt;p>Pada tahun 2026, membangun LLM lokal di lingkungan Windows tidak lagi menjadi hak istimewa eksklusif segelintir insinyur. Melalui standar de facto format GGUF, munculnya ekosistem yang disempurnakan seperti Ollama dan LM Studio, serta pengoptimalan perangkat keras termasuk FlashAttention, siapa pun kini dapat dengan mudah memperoleh lingkungan AI tingkat perusahaan (enterprise).&lt;/p>
&lt;p>Silakan manfaatkan poin-poin yang dijelaskan dalam artikel ini:&lt;/p>
&lt;ol>
&lt;li>Gunakan &lt;strong>perhitungan matematis VRAM&lt;/strong> untuk secara logis memilih ukuran model dan tingkat kuantisasi yang paling sesuai dengan spesifikasi PC Anda.&lt;/li>
&lt;li>Gunakan &lt;strong>Ollama&lt;/strong> untuk membangun lingkungan tercepat dan meningkatkan produktivitas secara dramatis dengan menghubungkannya ke editor AI.&lt;/li>
&lt;li>Gunakan kontrol parameter lanjutan dari &lt;strong>llama.cpp&lt;/strong> untuk memaksimalkan kinerja batas perangkat keras Anda.&lt;/li>
&lt;li>Gunakan &lt;strong>AnythingLLM&lt;/strong> untuk membangun sistem RAG lokal yang aman yang menangani data rahasia.&lt;/li>
&lt;li>Manfaatkan &lt;strong>Unsloth (WSL2)&lt;/strong> untuk melatih AI kustom yang memiliki pengetahuan khusus Anda sendiri.&lt;/li>
&lt;/ol>
&lt;p>&amp;ldquo;Demokratisasi&amp;rdquo; AI tidak lagi sekadar buzzword, tetapi sistem nyata yang berjalan di desktop Windows Anda. Bebaskan diri Anda dari biaya penggunaan API cloud dan risiko kebocoran informasi, serta melangkahlah sekarang ke dunia AI privat yang bebas dan kuat.&lt;/p></description></item></channel></rss>