<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>LLM on kenji.blog</title><link>http://kenji.blog/id/categories/llm/</link><description>Recent content in LLM 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/categories/llm/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>Perbandingan Lengkap API ChatGPT, Gemini, dan Claude! Mana yang Harus Dipilih?</title><link>http://kenji.blog/id/p/chatgpt-gemini-claude-api-comparison/</link><pubDate>Fri, 11 Sep 2026 12:00:00 +0900</pubDate><guid>http://kenji.blog/id/p/chatgpt-gemini-claude-api-comparison/</guid><description>&lt;img src="http://kenji.blog/p/chatgpt-gemini-claude-api-comparison/img/eyecatch.jpg" alt="Featured image of post Perbandingan Lengkap API ChatGPT, Gemini, dan Claude! Mana yang Harus Dipilih?" />&lt;h1 id="perbandingan-lengkap-api-chatgpt-gemini-dan-claude-mana-yang-harus-dipilih">Perbandingan Lengkap API ChatGPT, Gemini, dan Claude! Mana yang Harus Dipilih?
&lt;/h1>&lt;p>Evolusi teknologi AI sangat luar biasa, khususnya di bidang Model Bahasa Besar (LLM: Large Language Model), di mana ChatGPT (seri GPT) dari OpenAI, Gemini dari Google, dan Claude dari Anthropic sedang bersaing sengit untuk supremasi. Pada tahun 2026 ini, setiap perusahaan merilis model dan fitur API baru dalam hitungan bulan, bahkan minggu. Bagi pengembang dan arsitek TI perusahaan, pertanyaan &amp;ldquo;API mana yang harus diintegrasikan ke dalam produk?&amp;rdquo; telah menjadi keputusan krusial yang menentukan kesuksesan sebuah proyek.&lt;/p>
&lt;p>Dalam artikel ini, kita tidak hanya akan menyebutkan spesifikasi dari ketiga API penyedia AI besar ini, tetapi juga akan membandingkan dan menjelaskannya secara komprehensif dari sudut pandang pengembang. Kita akan membahas arsitektur desain, struktur harga yang detail, analisis matematis dari latensi, contoh implementasi konkret menggunakan Python dan Node.js, hingga metode optimasi biaya terbaru seperti prompt caching.&lt;/p>
&lt;p>Kami berharap artikel ini dapat menjadi panduan lengkap bagi para pembaca untuk memilih API LLM yang paling sesuai dengan kasus penggunaan (use case) mereka, serta membangun aplikasi AI yang skalabel dan hemat biaya.&lt;/p>
&lt;hr>
&lt;h2 id="1-filosofi-dan-konsep-desain-masing-masing-api-llm">1. Filosofi dan Konsep Desain Masing-masing API LLM
&lt;/h2>&lt;p>Dalam pemilihan teknologi, sangat penting untuk memahami terlebih dahulu filosofi dasar bagaimana setiap perusahaan membangun model dan API mereka.&lt;/p>
&lt;h3 id="11-openai-chatgpt">1.1 OpenAI (ChatGPT)
&lt;/h3>&lt;p>OpenAI mengusung misi &amp;ldquo;mewujudkan Kecerdasan Buatan Umum (AGI)&amp;rdquo; dan selalu memimpin sebagai standar de facto di industri ini. Mereka menawarkan berbagai macam model yang disesuaikan dengan kasus penggunaan, seperti GPT-4o, GPT-4o-mini, dan model khusus penalaran yaitu o1. Ekosistemnya adalah yang paling matang, dengan pustaka dan dokumentasi terbanyak, baik yang resmi maupun tidak resmi.&lt;/p>
&lt;h3 id="12-google-gemini">1.2 Google (Gemini)
&lt;/h3>&lt;p>Google mengedepankan prinsip &amp;ldquo;AI First&amp;rdquo;, menggunakan skalabilitas infrastruktur mereka sendiri (jaringan TPU) secara maksimal sebagai senjata utamanya. Gemini 1.5 Pro/Flash memiliki context window (panjang konteks) yang luar biasa hingga 2 juta token, menjadikannya sangat unggul dalam memproses dokumen panjang atau video/audio berjam-jam sekaligus. Integrasi yang kuat dengan Google Cloud (Vertex AI) juga sangat menarik bagi kalangan perusahaan (enterprise).&lt;/p>
&lt;h3 id="13-anthropic-claude">1.3 Anthropic (Claude)
&lt;/h3>&lt;p>Anthropic adalah perusahaan yang didirikan oleh mantan anggota OpenAI dan mengadopsi pendekatan keamanan unik yang disebut &amp;ldquo;Constitutional AI&amp;rdquo;. Claude 3.5 Sonnet dan Opus mendapatkan dukungan antusias dari banyak pengembang karena kemampuan penalaran yang tinggi, kemampuan menghasilkan kode, dan yang terpenting, &amp;ldquo;dialog alami layaknya manusia&amp;rdquo; serta &amp;ldquo;minimnya halusinasi&amp;rdquo;.&lt;/p>
&lt;hr>
&lt;h2 id="2-perbandingan-spesifikasi-keluarga-model-secara-komprehensif">2. Perbandingan Spesifikasi Keluarga Model secara Komprehensif
&lt;/h2>&lt;p>Berikut adalah perbandingan spesifikasi dari model-model andalan per tahun 2026.&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Penyedia&lt;/th>
&lt;th>Model Andalan&lt;/th>
&lt;th>Panjang Konteks Maksimal&lt;/th>
&lt;th>Keunggulan Utama&lt;/th>
&lt;th>Rekomendasi Kasus Penggunaan&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;strong>OpenAI&lt;/strong>&lt;/td>
&lt;td>GPT-4o&lt;/td>
&lt;td>128K&lt;/td>
&lt;td>Kecepatan, pengenalan visual, dukungan suara&lt;/td>
&lt;td>Aplikasi interaktif, tugas umum&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>OpenAI&lt;/strong>&lt;/td>
&lt;td>o1-preview&lt;/td>
&lt;td>128K&lt;/td>
&lt;td>Penalaran logis tingkat tinggi, matematika, pengkodean (coding)&lt;/td>
&lt;td>Pembuatan algoritma kompleks, tujuan penelitian&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Google&lt;/strong>&lt;/td>
&lt;td>Gemini 1.5 Pro&lt;/td>
&lt;td>2.000K&lt;/td>
&lt;td>Pemrosesan teks super panjang, multimodal (video/audio)&lt;/td>
&lt;td>Analisis basis kode (codebase) raksasa, ringkasan video&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Google&lt;/strong>&lt;/td>
&lt;td>Gemini 1.5 Flash&lt;/td>
&lt;td>2.000K&lt;/td>
&lt;td>Latensi rendah, throughput tinggi, biaya sangat murah&lt;/td>
&lt;td>Pemrosesan real-time, pemrosesan batch data dalam jumlah besar&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Anthropic&lt;/strong>&lt;/td>
&lt;td>Claude 3.5 Sonnet&lt;/td>
&lt;td>200K&lt;/td>
&lt;td>Kemampuan coding, pembuatan teks alami&lt;/td>
&lt;td>Bantuan pengembangan perangkat lunak, dukungan pelanggan tingkat lanjut&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Anthropic&lt;/strong>&lt;/td>
&lt;td>Claude 3.5 Haiku&lt;/td>
&lt;td>200K&lt;/td>
&lt;td>Respons super cepat, efektivitas biaya&lt;/td>
&lt;td>Edge AI, chatbot real-time&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="3-mendalami-arsitektur-di-balik-layar-permintaan-api">3. Mendalami Arsitektur: Di Balik Layar Permintaan API
&lt;/h2>&lt;p>Saat kita memanggil API LLM, proses apa yang sebenarnya terjadi di backend? Untuk mengoptimalkan performa, kita perlu memahami arsitektur ini.&lt;/p>
&lt;p>Diagram Mermaid berikut menunjukkan gambaran keseluruhan mulai dari permintaan API dikirim oleh klien, hingga token dikembalikan secara streaming.&lt;/p>
&lt;div class="mermaid">graph TD
A["Aplikasi Klien"] -->|HTTP/REST atau gRPC| B["API Gateway"]
B --> C["Load Balancer"]
C --> D["Klaster Inferensi"]
D --> E["Tokenizer (BPE / SentencePiece)"]
E --> F["KV Cache &amp; Mekanisme Perhatian (Attention)"]
F --> G["Blok Transformer (Forward Pass)"]
G --> H["Lapisan Output (Logits)"]
H --> I["Sampler (Temperature, Top-p, Top-k)"]
I --> J["Detokenizer"]
J -->|Respons Streaming (Chunk)| A&lt;/div>
&lt;h3 id="31-algoritma-tokenization-tokenisasi">3.1 Algoritma Tokenization (Tokenisasi)
&lt;/h3>&lt;p>Teks yang dimasukkan ke dalam API secara internal dibagi menjadi unit-unit yang disebut &amp;ldquo;token&amp;rdquo;.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>OpenAI (tiktoken)&lt;/strong>: Mengadopsi Byte-Pair Encoding (BPE). Ini sangat efisien dalam mengompresi bahasa Inggris, tetapi jumlah token cenderung membengkak untuk bahasa non-alfabet seperti bahasa Jepang.&lt;/li>
&lt;li>&lt;strong>Google (Gemini)&lt;/strong>: Mengadopsi SentencePiece (Unigram Language Model). Kuat dalam berbagai bahasa, dan cenderung mampu merepresentasikan teks dengan jumlah token yang relatif sedikit bahkan dalam teks bahasa Jepang.&lt;/li>
&lt;li>&lt;strong>Anthropic (Claude)&lt;/strong>: Menggunakan versi kustom dari BPE. Dukungan multibahasa telah ditingkatkan, dan mulai Claude 3 ke atas, efisiensi token untuk bahasa Jepang juga telah diperbaiki secara signifikan.&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="4-analisis-matematis-tentang-latensi-dan-performa">4. Analisis Matematis tentang Latensi dan Performa
&lt;/h2>&lt;p>Dalam aplikasi real-time, latensi berdampak langsung pada pengalaman pengguna (UX). Latensi API LLM $T_{total}$ dapat dimodelkan secara matematis sebagai berikut.&lt;/p>
$$ T_{total} = T_{network} + T_{TTFT} + (N \times T_{TPOT}) $$
&lt;p>Di sini, masing-masing variabel memiliki arti sebagai berikut:&lt;/p>
&lt;ul>
&lt;li>$T_{network}$: Round Trip Time (RTT) jaringan.&lt;/li>
&lt;li>$T_{TTFT}$ (Time To First Token): Waktu yang dibutuhkan hingga karakter pertama dihasilkan. Sangat bergantung pada biaya komputasi attention yang proporsional dengan kuadrat dari panjang prompt (jumlah token input).&lt;/li>
&lt;li>$N$: Jumlah total token yang dihasilkan (output).&lt;/li>
&lt;li>$T_{TPOT}$ (Time Per Output Token): Waktu pembuatan per token. Karena merupakan model autoregresif, token dihitung secara seri dengan bergantung pada output sebelumnya.&lt;/li>
&lt;/ul>
&lt;h3 id="41-kompleksitas-komputasi-dari-mekanisme-self-attention">4.1 Kompleksitas Komputasi dari Mekanisme Self-Attention
&lt;/h3>&lt;p>Kompleksitas komputasi dari Self-Attention dalam arsitektur Transformer meningkat secara kuadratik terhadap panjang urutan input $L$.&lt;/p>
$$ \text{Complexity} = O(L^2 \cdot d) $$
&lt;p>Di mana $d$ adalah jumlah dimensi dari vektor embedding. Karena batasan ini, biasanya $T_{TTFT}$ akan memburuk secara drastis saat prompt menjadi lebih panjang.
Namun, Gemini 1.5 dari Google mengadopsi arsitektur optimasi inovatif seperti &amp;ldquo;Ring Attention&amp;rdquo; dan &amp;ldquo;Block-wise Compute&amp;rdquo;, yang berhasil menghasilkan token pertama dalam waktu yang realistis (beberapa detik hingga puluhan detik) meskipun diberikan input teks panjang sebesar 2 juta token.&lt;/p>
&lt;hr>
&lt;h2 id="5-struktur-harga-dan-strategi-optimasi-biaya">5. Struktur Harga dan Strategi Optimasi Biaya
&lt;/h2>&lt;p>Biaya API pada dasarnya dihitung berdasarkan jumlah token input dan jumlah token output.&lt;/p>
$$ Cost = (Tokens_{in} \times Rate_{in}) + (Tokens_{out} \times Rate_{out}) $$
&lt;p>Namun, API terbaru telah memperkenalkan mekanisme baru untuk menekan biaya secara drastis.&lt;/p>
&lt;h3 id="51-prompt-caching-cache-prompt">5.1 Prompt Caching (Cache Prompt)
&lt;/h3>&lt;p>Mengirimkan sistem prompt yang panjang atau sejumlah besar dokumen hasil pencarian RAG setiap kali permintaan dibuat akan memakan biaya yang sangat besar. Untuk mengatasinya, masing-masing perusahaan menyediakan fitur caching.&lt;/p>
&lt;p>Di Anthropic (Claude) dan Google (Gemini), biaya input dapat dikurangi secara signifikan (hingga 90%) dengan melakukan caching pada blok teks tertentu.&lt;/p>
&lt;p>Model biaya saat menggunakan cache adalah sebagai berikut:&lt;/p>
$$ Cost_{cached} = (Tokens_{cache\_write} \times Rate_{cache\_write}) + (Tokens_{cache\_read} \times Rate_{cache\_read}) + (Tokens_{out} \times Rate_{out}) $$
&lt;p>Di sini, $Rate_{cache\_read}$ biasanya ditetapkan sekitar 10% hingga 25% dari $Rate_{in}$ normal. Hal ini memungkinkan pengoperasian chatbot dengan biaya rendah, sambil terus menyimpan puluhan ribu baris basis kode sebagai latar belakang pengetahuan.&lt;/p>
&lt;h3 id="52-batch-api-api-batch">5.2 Batch API (API Batch)
&lt;/h3>&lt;p>Untuk tugas-tugas yang tidak memerlukan respons real-time (analisis log, klasifikasi data dalam jumlah besar, dll.), OpenAI dan Anthropic menyediakan Batch API. Ini adalah mekanisme luar biasa di mana Anda dapat mengirimkan permintaan sekaligus dan menerima hasilnya dalam waktu 24 jam dengan setengah harga (diskon 50%) dari tarif API normal.&lt;/p>
&lt;hr>
&lt;h2 id="6-pengalaman-pengembang-dx-dan-perbandingan-sdk">6. Pengalaman Pengembang (DX) dan Perbandingan SDK
&lt;/h2>&lt;p>Dari perspektif efisiensi pengembangan, mari kita bandingkan SDK (Software Development Kit) yang disediakan oleh setiap perusahaan.&lt;/p>
&lt;h3 id="61-openai-api">6.1 OpenAI API
&lt;/h3>&lt;p>Paling banyak digunakan, dan dukungan dari pustaka pihak ketiga (seperti LangChain, LlamaIndex) adalah yang tercepat. Selain itu, dengan fitur Structured Outputs, ia menjamin pengembalian respons yang mematuhi skema JSON dengan akurasi 100%, sehingga integrasi sistem menjadi sangat mudah.&lt;/p>
&lt;h3 id="62-anthropic-api-claude">6.2 Anthropic API (Claude)
&lt;/h3>&lt;p>Antarmuka SDK-nya dirancang dengan rapi, dan definisi tipe TypeScript-nya dikenal sangat mudah digunakan. Secara khusus, struktur Message API-nya sangat intuitif, sehingga permintaan multimodal yang mencakup banyak gambar dapat ditulis dengan sederhana.&lt;/p>
&lt;h3 id="63-google-gemini-api">6.3 Google Gemini API
&lt;/h3>&lt;p>Terdapat dua jenis akses: melalui Google Cloud Vertex AI dan melalui AI Studio (Google Gen AI SDK), yang mungkin sedikit membingungkan bagi pemula. Namun, Vertex AI SDK yang ditujukan untuk enterprise terintegrasi penuh dengan IAM (Sistem Otentikasi dan Otorisasi) GCP, sehingga memungkinkan Anda membangun lingkungan pengembangan yang aman.&lt;/p>
&lt;hr>
&lt;h2 id="7-praktik-implementasi-pengujian-terpadu-berbagai-api-menggunakan-python">7. Praktik! Implementasi Pengujian Terpadu Berbagai API Menggunakan Python
&lt;/h2>&lt;p>Di sini, kita akan mencoba mengimplementasikan skrip menggunakan Python untuk mengirim permintaan asinkron secara bersamaan ke ketiga API (OpenAI, Anthropic, Gemini) guna membandingkan latensinya.&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;/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">asyncio&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">time&lt;/span>
&lt;/span>&lt;/span>&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">openai&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">AsyncOpenAI&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">anthropic&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">AsyncAnthropic&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">google.generativeai&lt;/span> &lt;span class="k">as&lt;/span> &lt;span class="nn">genai&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"># Inisialisasi Klien&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">openai_client&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">AsyncOpenAI&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">api_key&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">os&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">environ&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;OPENAI_API_KEY&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">anthropic_client&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">AsyncAnthropic&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">api_key&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">os&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">environ&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;ANTHROPIC_API_KEY&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">genai&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">configure&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">api_key&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">os&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">environ&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;GEMINI_API_KEY&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">prompt&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;Tolong jelaskan dasar-dasar komputer kuantum dan dampaknya terhadap teknologi kriptografi saat ini dengan cara yang mudah dipahami oleh pemula.&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="k">async&lt;/span> &lt;span class="k">def&lt;/span> &lt;span class="nf">fetch_openai&lt;/span>&lt;span class="p">():&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">start_time&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">time&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">time&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">response&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">await&lt;/span> &lt;span class="n">openai_client&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">chat&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">completions&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">create&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="s2">&amp;#34;gpt-4o&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">messages&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">[{&lt;/span>&lt;span class="s2">&amp;#34;role&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;user&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;content&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="n">max_tokens&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">1024&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">elapsed&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">time&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">time&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">start_time&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="s2">&amp;#34;OpenAI (GPT-4o)&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">elapsed&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">response&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">choices&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">message&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">content&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">async&lt;/span> &lt;span class="k">def&lt;/span> &lt;span class="nf">fetch_anthropic&lt;/span>&lt;span class="p">():&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">start_time&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">time&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">time&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">response&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">await&lt;/span> &lt;span class="n">anthropic_client&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">messages&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">create&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="s2">&amp;#34;claude-3-5-sonnet-20240620&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">messages&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">[{&lt;/span>&lt;span class="s2">&amp;#34;role&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;user&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;content&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="n">max_tokens&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">1024&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">elapsed&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">time&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">time&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">start_time&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="s2">&amp;#34;Anthropic (Claude 3.5 Sonnet)&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">elapsed&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">response&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">content&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">text&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">async&lt;/span> &lt;span class="k">def&lt;/span> &lt;span class="nf">fetch_gemini&lt;/span>&lt;span class="p">():&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">start_time&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">time&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">time&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">genai&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">GenerativeModel&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;gemini-1.5-pro&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="c1"># Menggunakan metode asinkron dari Gemini Python SDK&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">response&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">await&lt;/span> &lt;span class="n">model&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">generate_content_async&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="n">elapsed&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">time&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">time&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">start_time&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="s2">&amp;#34;Google (Gemini 1.5 Pro)&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">elapsed&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">response&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">text&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">async&lt;/span> &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="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Mengirim permintaan ke masing-masing API LLM...&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"># Menjalankan ke-3 API secara paralel&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">results&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">await&lt;/span> &lt;span class="n">asyncio&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">gather&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">fetch_openai&lt;/span>&lt;span class="p">(),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">fetch_anthropic&lt;/span>&lt;span class="p">(),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">fetch_gemini&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="k">for&lt;/span> &lt;span class="n">provider&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">latency&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">text&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">results&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;--- &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">provider&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 class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;Latency: &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">latency&lt;/span>&lt;span class="si">:&lt;/span>&lt;span class="s2">.2f&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2"> detik&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="sa">f&lt;/span>&lt;span class="s2">&amp;#34;Response (Kutipan): &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">text&lt;/span>&lt;span class="p">[:&lt;/span>&lt;span class="mi">100&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">...&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="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">asyncio&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">run&lt;/span>&lt;span class="p">(&lt;/span>&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;p>Dengan menjalankan skrip ini, Anda dapat dengan mudah mengukur model mana yang merespons paling cepat (meminimalkan $T_{total}$) di lingkungan jaringan nyata.&lt;/p>
&lt;hr>
&lt;h2 id="8-implementasi-tool-calling-function-calling-menggunakan-nodejs">8. Implementasi Tool Calling (Function Calling) Menggunakan Node.js
&lt;/h2>&lt;p>Untuk membuat LLM berfungsi sebagai &amp;ldquo;Agen AI&amp;rdquo; yang berintegrasi dengan sistem eksternal (bukan sekadar chatbot), Tool Calling (atau Function Calling) sangatlah penting. Berikut adalah contoh penggunaan Node.js (TypeScript) agar API OpenAI dapat memanggil API cuaca.&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;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-typescript" data-lang="typescript">&lt;span class="line">&lt;span class="cl">&lt;span class="kr">import&lt;/span> &lt;span class="nx">OpenAI&lt;/span> &lt;span class="kr">from&lt;/span> &lt;span class="s2">&amp;#34;openai&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="kr">const&lt;/span> &lt;span class="nx">openai&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">new&lt;/span> &lt;span class="nx">OpenAI&lt;/span>&lt;span class="p">({&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">apiKey&lt;/span>: &lt;span class="kt">process.env.OPENAI_API_KEY&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="kr">async&lt;/span> &lt;span class="kd">function&lt;/span> &lt;span class="nx">runAgent() {&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">tools&lt;/span> &lt;span class="o">=&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="kr">type&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;function&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="kd">function&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">name&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;get_weather&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="nx">description&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;Mendapatkan cuaca saat ini untuk kota yang ditentukan.&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="nx">parameters&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">type&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;object&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="nx">properties&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">location&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">type&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;string&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="nx">description&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;Nama kota (contoh: Tokyo, New York)&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="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">required&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;location&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="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="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="kr">const&lt;/span> &lt;span class="nx">response&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">await&lt;/span> &lt;span class="nx">openai&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">chat&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">completions&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">create&lt;/span>&lt;span class="p">({&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">model&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;gpt-4o&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="nx">messages&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">[{&lt;/span> &lt;span class="nx">role&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;user&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;content&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;Bagaimana cuaca di Tokyo hari ini? Apakah saya perlu membawa payung?&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="nx">tools&lt;/span>: &lt;span class="kt">tools&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">tool_choice&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="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="kr">const&lt;/span> &lt;span class="nx">message&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">response&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">choices&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">].&lt;/span>&lt;span class="nx">message&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="p">(&lt;/span>&lt;span class="nx">message&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">tool_calls&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">toolCall&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">message&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">tool_calls&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">];&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sb">`LLM meminta pemanggilan tool: Nama Fungsi = &lt;/span>&lt;span class="si">${&lt;/span>&lt;span class="nx">toolCall&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="kd">function&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">name&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="sb">`&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="kr">const&lt;/span> &lt;span class="nx">args&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">JSON&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">parse&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">toolCall&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="kd">function&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">arguments&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sb">`Argumen: &lt;/span>&lt;span class="si">${&lt;/span>&lt;span class="nx">args&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">location&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="sb">`&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">// Di sini implementasikan proses untuk memanggil API cuaca yang sebenarnya (contoh: OpenWeatherMap)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// const weather = await fetchWeatherFromAPI(args.location);
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Setelah mendapatkan hasil, berikan kembali ke LLM untuk menghasilkan jawaban akhir
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&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="nx">runAgent&lt;/span>&lt;span class="p">().&lt;/span>&lt;span class="k">catch&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">error&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;p>Claude 3.5 Sonnet dan Gemini 1.5 Pro juga memiliki fitur Tool Calling yang setara. Meskipun ada sedikit perbedaan dalam cara mendefinisikan skema, alur dasarnya tetap sama.&lt;/p>
&lt;hr>
&lt;h2 id="9-rag-vs-long-context-window-mana-yang-harus-diadopsi">9. RAG vs Long Context Window: Mana yang Harus Diadopsi?
&lt;/h2>&lt;p>Saat ini, salah satu perdebatan terbesar dalam arsitektur AI perusahaan adalah: &amp;ldquo;Untuk memasukkan pengetahuan eksternal, haruskah kita menggunakan RAG (Retrieval-Augmented Generation), atau haruskah kita melemparkan semuanya ke dalam Context Window yang sangat besar (Long Context)?&amp;rdquo;&lt;/p>
&lt;h3 id="kelebihan-dan-tantangan-rag-retrieval-augmented-generation">Kelebihan dan Tantangan RAG (Retrieval-Augmented Generation)
&lt;/h3>&lt;ul>
&lt;li>&lt;strong>Kelebihan&lt;/strong>: Biaya lebih murah (karena hanya memasukkan bagian/chunk yang diperlukan ke dalam prompt), lebih mudah mengidentifikasi sumber (dasar) dari jawaban.&lt;/li>
&lt;li>&lt;strong>Tantangan&lt;/strong>: Karena bergantung pada akurasi pencarian semantik, ini tidak cocok untuk tugas penalaran tingkat lanjut di mana konteksnya tersebar di beberapa dokumen (Contoh: &amp;ldquo;Berdasarkan seluruh notulen rapat tahun lalu, tolong analisis akar penyebab keterlambatan proyek A secara kronologis.&amp;rdquo;).&lt;/li>
&lt;/ul>
&lt;h3 id="long-context-seperti-2-juta-token-pada-gemini-15-pro">Long Context (seperti 2 juta token pada Gemini 1.5 Pro)
&lt;/h3>&lt;ul>
&lt;li>&lt;strong>Kelebihan&lt;/strong>: Tidak ada informasi yang terlewat akibat proses pencarian. Bahkan dalam uji &amp;ldquo;mencari jarum di tumpukan jerami&amp;rdquo; (Needle In A Haystack: NIAH), Gemini 1.5 Pro dan Claude 3.5 Sonnet mampu mengekstraksi informasi dengan akurasi di atas 99%.&lt;/li>
&lt;li>&lt;strong>Tantangan&lt;/strong>: Menghabiskan jumlah token yang sangat besar sehingga biayanya membengkak, serta latensi ($T_{TTFT}$) meningkat.&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Kesimpulan&lt;/strong>: Praktik terbaik (best practice) di tahun 2026 adalah &lt;strong>&amp;ldquo;Pendekatan Hibrida&amp;rdquo;&lt;/strong>. Desain utama (mainstream) saat ini menggunakan RAG dengan basis data vektor untuk Q&amp;amp;A sehari-hari, dan menggunakan Long Context dengan fitur prompt caching untuk tugas khusus yang memerlukan analisis kompleks atau peninjauan keseluruhan kode.&lt;/p>
&lt;hr>
&lt;h2 id="10-perbandingan-kemampuan-pemrosesan-multimodal">10. Perbandingan Kemampuan Pemrosesan Multimodal
&lt;/h2>&lt;p>Dalam aplikasi AI generasi berikutnya, kemampuan untuk memahami tidak hanya teks, tetapi secara langsung juga memahami gambar, audio, dan video akan sangat dibutuhkan.&lt;/p>
&lt;div class="mermaid">sequenceDiagram
participant User as "Pengguna"
participant Client as "Aplikasi Frontend"
participant API as "API LLM (Multimodal)"
User->>Client: Unggah Video &amp; Prompt Teks
Client->>API: Kirim Byte/URI Video + Teks
Note over API: Pemisahan Audio &amp; Pemotongan Video
Note over API: Model Embedding Multimodal
API-->>Client: Kembalikan Ringkasan Teks &amp; Stempel Waktu
Client-->>User: Tampilkan Wawasan&lt;/div>
&lt;ul>
&lt;li>&lt;strong>OpenAI (GPT-4o)&lt;/strong>: Memiliki akurasi pengenalan gambar yang sangat tinggi, unggul dalam membaca gambar tulisan tangan atau grafik yang rumit. Selain itu, percakapan suara asli (native) dengan latensi sangat rendah (ratusan milidetik) menggunakan Realtime API juga sangat kuat.&lt;/li>
&lt;li>&lt;strong>Google (Gemini 1.5 Pro)&lt;/strong>: &lt;strong>Sangat mendominasi dalam analisis video.&lt;/strong> Anda dapat memasukkan file video berdurasi 1 jam (kumpulan frame + audio) apa adanya, dan menanyakan pertanyaan spesifik seperti &amp;ldquo;Apa judul dokumen yang dipegang oleh orang di sisi kanan layar pada menit 12:45?&amp;rdquo;, lalu mendapatkan jawabannya.&lt;/li>
&lt;li>&lt;strong>Anthropic (Claude 3.5 Sonnet)&lt;/strong>: Kemampuan pengenalan gambar (Vision)-nya setara dengan GPT-4o dan sangat luar biasa. Model ini menunjukkan kekuatan tak tertandingi dalam mendukung pengembangan frontend, seperti ketika diberikan tangkapan layar UI lalu diminta &amp;ldquo;Tolong buatkan kode komponen React untuk layar ini.&amp;rdquo;&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="11-keamanan-dan-kepatuhan-tingkat-perusahaan-enterprise">11. Keamanan dan Kepatuhan Tingkat Perusahaan (Enterprise)
&lt;/h2>&lt;p>Saat perusahaan menggunakan API LLM di lingkungan produksi (production), kekhawatiran terbesar adalah &amp;ldquo;Apakah data kami akan digunakan untuk melatih AI?&amp;rdquo; dan &amp;ldquo;Apakah ini memenuhi persyaratan kepatuhan (compliance)?&amp;rdquo;&lt;/p>
&lt;p>Ketiga penyedia secara tegas menyatakan bahwa data yang dikirim melalui API (prompt dan respons) &lt;strong>tidak digunakan untuk pelatihan model (Zero Data Retention / No Training on Customer Data)&lt;/strong> (*Hal ini berbeda dari UI obrolan web gratis yang ditujukan untuk konsumen).&lt;/p>
&lt;p>Jika tingkat keamanan yang lebih tinggi diperlukan:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>OpenAI&lt;/strong>: Melalui Azure OpenAI Service, Anda dapat memanfaatkan koneksi jaringan tertutup (private network) via Azure Private Link, tingkat SLA (Service Level Agreement), dan keamanan tingkat perusahaan dari Microsoft.&lt;/li>
&lt;li>&lt;strong>Google&lt;/strong>: Melalui Google Cloud Vertex AI, Anda dapat mengaktifkan perlindungan data via CMEK (Customer-Managed Encryption Keys) dan pemisahan jaringan secara ketat menggunakan VPC Service Controls.&lt;/li>
&lt;li>&lt;strong>Anthropic&lt;/strong>: Dengan menggunakannya melalui AWS Bedrock atau Google Cloud Vertex AI, Anda dapat memanfaatkan infrastruktur keamanan yang kokoh dari penyedia cloud tersebut.&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="12-kesimpulan-panduan-pilihan-utama-berdasarkan-kasus-penggunaan">12. Kesimpulan: Panduan Pilihan Utama Berdasarkan Kasus Penggunaan
&lt;/h2>&lt;p>Sejauh ini kita telah membandingkan dari berbagai sudut, tetapi pada akhirnya, jawaban untuk &amp;ldquo;Mana yang harus dipilih?&amp;rdquo; akan bergantung pada kasus penggunaan Anda.&lt;/p>
&lt;ol>
&lt;li>
&lt;p>&lt;strong>Pengembangan Perangkat Lunak Kompleks, Pembuatan Kode, dan Penalaran Tingkat Lanjut&lt;/strong>:
&lt;strong>👑 Pemenang: Claude 3.5 Sonnet (Anthropic)&lt;/strong>
Saat ini, model ini memberikan performa terbaik dalam pemahaman konteks kode, refactoring, dan penulisan teks yang alami layaknya manusia. Kemudahan penggunaan API dan efisiensi biayanya berkat prompt caching juga sangat luar biasa.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Analisis Dokumen Super Panjang, Pemrosesan Batch Video/Audio&lt;/strong>:
&lt;strong>👑 Pemenang: Gemini 1.5 Pro (Google)&lt;/strong>
Context window sebesar 2 juta token adalah senjata unik yang tak tertandingi. Untuk tugas-tugas yang memerlukan pemahaman keseluruhan data, seperti menganalisis panduan PDF setebal ratusan halaman atau merangkum rekaman rapat berdurasi panjang, tidak ada yang bisa mengalahkan Gemini.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Fleksibilitas, Kecepatan Eksekusi, dan Output Terstruktur yang Stabil (JSON)&lt;/strong>:
&lt;strong>👑 Pemenang: GPT-4o / GPT-4o-mini (OpenAI)&lt;/strong>
Model ini menangani hampir semua tugas dengan baik dan memiliki dukungan alat (tool) pihak ketiga yang paling banyak. Jika Anda memerlukan parsing JSON yang andal menggunakan Structured Outputs, atau penalaran logis tingkat sangat tinggi menggunakan model o1, maka ekosistem OpenAI sangat diperlukan.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h3 id="rekomendasi-routing-multi-model">Rekomendasi Routing Multi-Model
&lt;/h3>&lt;p>Tren masa depan bukanlah bergantung pada API tunggal (vendor lock-in), melainkan arsitektur &lt;strong>&amp;ldquo;LLM Routing&amp;rdquo;&lt;/strong> di mana Anda dapat secara dinamis mengganti model tergantung pada tingkat kesulitan dan pentingnya tugas.
Misalnya, untuk merespons pertanyaan sederhana dari pengguna, Anda dapat menggunakan &lt;code>GPT-4o-mini&lt;/code> atau &lt;code>Gemini 1.5 Flash&lt;/code> yang murah dan cepat. Namun, jika dinilai memerlukan pemrosesan yang lebih kompleks, barulah tugas tersebut diserahkan ke &lt;code>Claude 3.5 Sonnet&lt;/code>. Dengan cara ini, keseimbangan optimal antara biaya dan performa dapat tercapai.&lt;/p>
&lt;p>Evolusi AI tidak akan berhenti. Pahami secara mendalam kelebihan dan kekurangan dari masing-masing API, serta karakteristik arsitekturnya, agar Anda dapat membangun aplikasi AI yang fleksibel dan skalabel.&lt;/p></description></item><item><title>Panduan Menggunakan llama.cpp dan Pengenalan Kustomisasi dengan C++</title><link>http://kenji.blog/id/p/llama-cpp-cxx-customization/</link><pubDate>Fri, 11 Sep 2026 11:00:00 +0900</pubDate><guid>http://kenji.blog/id/p/llama-cpp-cxx-customization/</guid><description>&lt;img src="http://kenji.blog/p/llama-cpp-cxx-customization/img/eyecatch.jpg" alt="Featured image of post Panduan Menggunakan llama.cpp dan Pengenalan Kustomisasi dengan C++" />&lt;p>Dalam beberapa tahun terakhir, evolusi Large Language Models (LLM) sangat luar biasa, dan jangkauan aplikasinya meluas dari hari ke hari. Namun, menjalankan model dengan miliaran atau puluhan miliar parameter di lingkungan lokal biasanya membutuhkan GPU &lt;em>high-end&lt;/em> dengan VRAM yang sangat besar. &lt;strong>llama.cpp&lt;/strong> hadir untuk menerobos &amp;ldquo;dinding perangkat keras&amp;rdquo; ini, memungkinkan inferensi LLM secara praktis pada PC umum, Mac, dan bahkan perangkat seperti Raspberry Pi.&lt;/p>
&lt;p>Pada artikel ini, kita tidak hanya membahas cara menggunakan alat baris perintah (CLI), tetapi juga menjelaskan secara sangat rinci bagi para &lt;em>engineer&lt;/em> mengenai arsitektur &lt;code>ggml&lt;/code> yang menjadi teknologi dasarnya, latar belakang matematis dari Transformer dan kuantisasi, serta cara menggunakan API C++ untuk mengintegrasikan dan menyesuaikan LLM ke dalam aplikasi Anda sendiri.&lt;/p>
&lt;hr>
&lt;h2 id="1-ikhtisar-llamacpp-dan-ggml">1. Ikhtisar llama.cpp dan ggml
&lt;/h2>&lt;p>&lt;code>llama.cpp&lt;/code> adalah mesin inferensi LLM ringan yang ditulis dalam bahasa C/C++, dikembangkan oleh Georgi Gerganov. Awalnya dibuat dengan tujuan agar model LLaMA dari Meta dapat berjalan cepat di Apple Silicon (Mac M1/M2), tetapi kini telah mendukung berbagai arsitektur dan model.&lt;/p>
&lt;p>Fitur terbesarnya adalah merupakan &lt;strong>implementasi murni C/C++ tanpa dependensi eksternal&lt;/strong>. Ia tidak membutuhkan ekosistem besar seperti Python atau PyTorch, dan karena dapat dikompilasi menjadi satu file &lt;em>executable&lt;/em>, proses &lt;em>deployment&lt;/em> menjadi sangat mudah.&lt;/p>
&lt;p>Jantung dari &lt;code>llama.cpp&lt;/code> ini adalah &lt;em>library&lt;/em> komputasi tensor bernama &lt;strong>ggml&lt;/strong>. ggml dirancang dari nol untuk mengoptimalkan operasi matriks dalam &lt;em>machine learning&lt;/em> ke batas maksimal di CPU (dan sebagian GPU).&lt;/p>
&lt;h3 id="11-mengapa-llamacpp-cepat">1.1 Mengapa llama.cpp Cepat?
&lt;/h3>&lt;ol>
&lt;li>&lt;strong>Pemanfaatan Memory Mapping (mmap)&lt;/strong>: Saat memuat bobot (weights) model ke memori, penggunaan &lt;code>mmap&lt;/code> dari OS menghindari pemuatan penuh ke RAM, sehingga menghasilkan &lt;em>startup&lt;/em> yang cepat dan hemat memori.&lt;/li>
&lt;li>&lt;strong>Optimasi Ekstensif Instruksi SIMD&lt;/strong>: Memanfaatkan set instruksi khusus CPU seperti AVX2, AVX-512, ARM NEON, dan Apple AMX untuk sangat mempercepat perkalian matriks.&lt;/li>
&lt;li>&lt;strong>Kuantisasi (Quantization)&lt;/strong>: Mengompresi bobot &lt;em>floating-point&lt;/em> 16-bit (FP16) menjadi bilangan bulat 4-bit, 5-bit, dan 8-bit untuk mengatasi &lt;em>bottleneck&lt;/em> pada &lt;em>bandwidth&lt;/em> memori (detail lebih lanjut akan dijelaskan nanti).&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="2-latar-belakang-matematis-transformer-dan-kuantisasi-quantization">2. Latar Belakang Matematis: Transformer dan Kuantisasi (Quantization)
&lt;/h2>&lt;p>Untuk memahami llama.cpp secara mendalam, kita perlu mengetahui rumus matematika yang dihitungnya dan bagaimana komputasi tersebut diaproksimasi.&lt;/p>
&lt;h3 id="21-proses-inferensi-transformer">2.1 Proses Inferensi Transformer
&lt;/h3>&lt;p>Model seperti LLaMA menggunakan arsitektur Transformer decoder yang bersifat &lt;em>auto-regressive&lt;/em>. Inti dari pembuatan teks adalah mekanisme &lt;strong>Self-Attention&lt;/strong>.&lt;/p>
&lt;p>Untuk matriks keadaan tersembunyi (hidden state) $X \in \mathbb{R}^{N \times d}$ sebagai &lt;em>input&lt;/em>, Query $Q$, Key $K$, dan Value $V$ dihitung dengan perkalian bersama matriks bobot (weights matrix):&lt;/p>
$$
Q = X W_Q, \quad K = X W_K, \quad V = X W_V
$$
&lt;p>Di sini, keluaran dari Attention didefinisikan sebagai berikut:&lt;/p>
$$
\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V
$$
&lt;p>Dalam &lt;em>loop&lt;/em> inferensi llama.cpp, yang menjadi hambatan (bottleneck) adalah perkalian antara matriks bobot raksasa $W_Q, W_K, W_V$ atau matriks bobot Feed Forward Network (FFN) dengan vektor $X$ (pada fase generasi teks, vektor diproses token demi token sehingga $N=1$), yang juga dikenal sebagai &lt;strong>GEMV (General Matrix-Vector Multiplication)&lt;/strong>.&lt;/p>
&lt;h3 id="22-dasar-matematis-kuantisasi-quantization">2.2 Dasar Matematis Kuantisasi (Quantization)
&lt;/h3>&lt;p>Dalam inferensi di mana &lt;em>bandwidth&lt;/em> akses memori menjadi hambatan, kuantisasi yang merepresentasikan parameter bobot dengan jumlah bit kecil sangatlah penting. Berikut adalah penjelasan prinsip dasar dari kuantisasi berbasis blok (seperti &lt;code>Q4_K&lt;/code> atau &lt;code>Q4_0&lt;/code>) yang banyak digunakan di llama.cpp.&lt;/p>
&lt;p>Misalkan kita memiliki blok $w = [w_1, w_2, \dots, w_B]$ dengan panjang $B$ (biasanya 32 atau 64) yang merupakan bagian dari matriks bobot FP16 $W$. Blok ini diaproksimasikan menjadi bilangan bulat 4-bit $q_i \in [-8, 7]$ dan sebuah faktor penskalaan (scaling factor) tunggal $\Delta$ (FP16 atau FP32).&lt;/p>
$$
w_i \approx \Delta \times q_i
$$
&lt;p>Nilai $\Delta$ ditentukan berdasarkan nilai absolut maksimum di dalam blok tersebut:&lt;/p>
$$
\Delta = \frac{\max_i |w_i|}{7}
$$
&lt;p>Ketika menghitung perkalian titik (dot product) $y = w \cdot x$ menggunakan bobot yang telah dikuantisasi, jika vektor masukan $x$ juga dikuantisasi menjadi $x_i \approx \Delta_x \times q_{x, i}$, maka:&lt;/p>
$$
y = \sum_{i=1}^{B} w_i x_i \approx \Delta \Delta_x \sum_{i=1}^{B} q_i q_{x, i}
$$
&lt;p>Bagian $\sum q_i q_{x, i}$ ini sepenuhnya merupakan &lt;strong>operasi bilangan bulat murni&lt;/strong> (pure integer arithmetic), yang dapat dikomputasi secara paralel dengan sangat cepat menggunakan instruksi SIMD. Inilah rahasia matematis di balik kecepatan llama.cpp yang luar biasa di CPU.&lt;/p>
&lt;hr>
&lt;h2 id="3-arsitektur-dan-alur-inferensi">3. Arsitektur dan Alur Inferensi
&lt;/h2>&lt;p>Untuk memahami operasi internal llama.cpp, diagram Mermaid berikut menunjukkan arsitektur keseluruhan sistem dan aliran datanya.&lt;/p>
&lt;div class="mermaid">graph TD
A["Input Pengguna (String)"] --> B["Tokenizer llama.cpp"]
B --> C["Token ID (array int32)"]
C --> D["Buffer Konteks (KV Cache)"]
D --> E["Grafik Komputasi ggml"]
E --> F["Lapisan Transformer"]
subgraph "Mesin ggml"
F --> G["Self-Attention (RoPE)"]
G --> H["Jaringan Feed Forward"]
H --> F
end
F --> I["Logits (Ukuran Kosakata)"]
I --> J["Sampler (Suhu, Top-K, Top-P)"]
J --> K["ID Token Terpilih"]
K --> L["Detokenizer llama.cpp"]
L --> M["String Output"]
K -. "Loop Auto-regressive" .-> D&lt;/div>
&lt;p>Generasi teks adalah &lt;em>loop auto-regressive&lt;/em> di mana setiap kali satu token dihasilkan, token tersebut ditambahkan ke &lt;em>KV Cache&lt;/em> sebagai &lt;em>input&lt;/em> berikutnya, lalu melewati grafik komputasi lagi.&lt;/p>
&lt;hr>
&lt;h2 id="4-pengaturan-lingkungan-dan-cara-build">4. Pengaturan Lingkungan dan Cara Build
&lt;/h2>&lt;p>Sebelum mengintegrasikan llama.cpp ke dalam proyek C++, mari kita mulai dengan mem-&lt;em>build&lt;/em> kode sumbernya.&lt;/p>
&lt;h3 id="41-kloning-repositori">4.1 Kloning Repositori
&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;/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">git clone https://github.com/ggerganov/llama.cpp.git
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">cd&lt;/span> llama.cpp
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="42-build-menggunakan-cmake">4.2 Build Menggunakan CMake
&lt;/h3>&lt;p>Ketika mengintegrasikannya ke aplikasi lain sebagai proyek C++, menggunakan CMake adalah pendekatan yang paling standar. Anda dapat mempercepat komputasi dengan mengaktifkan akselerator (backend) yang sesuai dengan platform masing-masing.&lt;/p>
&lt;p>&lt;strong>Hanya CPU (Build Dasar):&lt;/strong>&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;/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">mkdir build &lt;span class="o">&amp;amp;&amp;amp;&lt;/span> &lt;span class="nb">cd&lt;/span> build
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">cmake ..
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">cmake --build . --config Release -j &lt;span class="m">8&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;strong>Jika Menggunakan NVIDIA GPU (CUDA):&lt;/strong>&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;/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">mkdir build &lt;span class="o">&amp;amp;&amp;amp;&lt;/span> &lt;span class="nb">cd&lt;/span> build
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">cmake .. -DGGML_CUDA&lt;span class="o">=&lt;/span>ON
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">cmake --build . --config Release -j &lt;span class="m">8&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;strong>Jika Menggunakan Apple Silicon (Metal):&lt;/strong>&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;/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">mkdir build &lt;span class="o">&amp;amp;&amp;amp;&lt;/span> &lt;span class="nb">cd&lt;/span> build
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">cmake .. -DGGML_METAL&lt;span class="o">=&lt;/span>ON
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">cmake --build . --config Release -j &lt;span class="m">8&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Jika proses &lt;em>build&lt;/em> berhasil, file eksekusi seperti &lt;code>llama-cli&lt;/code> dan pustaka &lt;code>llama&lt;/code> (serta pustaka &lt;code>ggml&lt;/code>) yang akan di-link melalui API C++ yang dijelaskan nanti, akan dibuat di direktori &lt;code>build/bin/&lt;/code>.&lt;/p>
&lt;hr>
&lt;h2 id="5-pengenalan-kustomisasi-dengan-c-menggunakan-api-llamacpp">5. Pengenalan Kustomisasi dengan C++: Menggunakan API llama.cpp
&lt;/h2>&lt;p>Mulai dari sini, kita akan membahas topik utama yaitu mengendalikan llama.cpp dari kode C++.
Untuk tidak sekadar menggunakan alat baris perintah (CLI), melainkan mengintegrasikan LLM ke dalam aplikasi Anda sendiri (seperti &lt;em>game engine&lt;/em>, aplikasi &lt;em>desktop&lt;/em>, sistem &lt;em>embedded&lt;/em>, dll.), Anda perlu memanggil langsung API C++.&lt;/p>
&lt;p>llama.cpp menyediakan antarmuka bahasa C terutama melalui &lt;em>header file&lt;/em> bernama &lt;code>llama.h&lt;/code>. Antarmuka ini juga digunakan ketika dipanggil dari C++.&lt;/p>
&lt;h3 id="51-include-dan-pengaturan-minimal-yang-diperlukan">5.1 Include dan Pengaturan Minimal yang Diperlukan
&lt;/h3>&lt;p>Jika Anda menggunakan llama.cpp di proyek Anda sendiri, masukkan pustaka 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;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;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;#34;llama.h&amp;#34;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;iostream&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;vector&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;string&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;stdexcept&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Makro untuk error handling
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="cp">#define LLAMA_ASSERT(x) \
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp"> do { \
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp"> if (!(x)) { \
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp"> std::cerr &amp;lt;&amp;lt; &amp;#34;Assertion failed: &amp;#34; &amp;lt;&amp;lt; #x &amp;lt;&amp;lt; std::endl; \
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp"> std::terminate(); \
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp"> } \
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp"> } while (0)
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="52-memuat-model-dan-inisialisasi-konteks">5.2 Memuat Model dan Inisialisasi Konteks
&lt;/h3>&lt;p>Pertama, kita muat file model berformat &lt;code>.gguf&lt;/code> dan menyiapkan konteks (ruang memori dan KV Cache) untuk inferensi.&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;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="kt">int&lt;/span> &lt;span class="nf">main&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">argc&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kt">char&lt;/span> &lt;span class="o">**&lt;/span> &lt;span class="n">argv&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">argc&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cerr&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;Usage: &amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">argv&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34; &amp;lt;model.gguf&amp;gt;&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="mi">1&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">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">string&lt;/span> &lt;span class="n">model_path&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">argv&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">1&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">// 1. Inisialisasi backend (Pengaturan lingkungan seperti CPU/GPU)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">llama_backend_init&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. Mendapatkan pengaturan default parameter model
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">llama_model_params&lt;/span> &lt;span class="n">model_params&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">llama_model_default_params&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_params&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">n_gpu_layers&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">35&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">// Jumlah layer yang dialihkan ke GPU
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 3. Memuat model
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">llama_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">llama_load_model_from_file&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">model_path&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">c_str&lt;/span>&lt;span class="p">(),&lt;/span> &lt;span class="n">model_params&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">model&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="k">nullptr&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cerr&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;Failed to load model&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="mi">1&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">// 4. Pengaturan parameter konteks
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">llama_context_params&lt;/span> &lt;span class="n">ctx_params&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">llama_context_default_params&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">ctx_params&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">n_ctx&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">2048&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">// Ukuran konteks maksimum (jumlah token)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">ctx_params&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">n_threads&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">// Jumlah thread CPU yang digunakan untuk inferensi
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 5. Membuat konteks
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">llama_context&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">ctx&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">llama_new_context_with_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">ctx_params&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">ctx&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="k">nullptr&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cerr&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;Failed to create context&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">llama_free_model&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 class="k">return&lt;/span> &lt;span class="mi">1&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="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;Model and context loaded successfully!&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// ... Pemrosesan selanjutnya
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="53-tokenisasi-prompt-tokenization">5.3 Tokenisasi Prompt (Tokenization)
&lt;/h3>&lt;p>LLM tidak secara langsung memahami teks, melainkan memprosesnya sebagai urutan ID integer (token). String &lt;em>input&lt;/em> perlu dikonversi ke token.&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;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">string&lt;/span> &lt;span class="n">prompt&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s">&amp;#34;Q: Apa ibu kota Jepang?&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s">A:&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">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">llama_token&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">tokens_list&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">tokens_list&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">resize&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">prompt&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">length&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="mi">4&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="c1">// Ukuran buffer dengan ruang ekstra
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Apakah akan menambahkan token khusus (seperti BOS: Begin of Sequence) di awal
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kt">bool&lt;/span> &lt;span class="n">add_special&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nb">true&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Mengonversi string menjadi array ID token
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kt">int&lt;/span> &lt;span class="n">n_tokens&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">llama_tokenize&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="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="p">.&lt;/span>&lt;span class="n">c_str&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="p">.&lt;/span>&lt;span class="n">length&lt;/span>&lt;span class="p">(),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">tokens_list&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">data&lt;/span>&lt;span class="p">(),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">tokens_list&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">size&lt;/span>&lt;span class="p">(),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">add_special&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">false&lt;/span> &lt;span class="c1">// parse_special
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&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="p">(&lt;/span>&lt;span class="n">n_tokens&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Jika buffer tidak cukup, diperlukan proses untuk realokasi dan mencoba ulang (dihilangkan untuk penyederhanaan)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cerr&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;Failed to tokenize prompt&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="mi">1&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">tokens_list&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">resize&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n_tokens&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="54-loop-inferensi-dan-sampling">5.4 Loop Inferensi dan Sampling
&lt;/h3>&lt;p>Kita membangun sebuah &lt;em>loop&lt;/em> di mana token dimasukkan ke model untuk mendapatkan distribusi probabilitas (Logits) token berikutnya, lalu melakukan &lt;em>sampling&lt;/em> dari sana untuk menentukan token selanjutnya.&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;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Jumlah token maksimum yang dihasilkan
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">const&lt;/span> &lt;span class="kt">int&lt;/span> &lt;span class="n">max_gen_tokens&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>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Inisialisasi struktur untuk evaluasi batch
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">llama_batch&lt;/span> &lt;span class="n">batch&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">llama_batch_init&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">512&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">1&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">// Menambahkan token prompt ke dalam batch
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">size_t&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="n">tokens_list&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">size&lt;/span>&lt;span class="p">();&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="o">++&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">llama_batch_add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">batch&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">tokens_list&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">],&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="mi">0&lt;/span> &lt;span class="p">},&lt;/span> &lt;span class="nb">false&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="c1">// Diatur agar hanya mengeluarkan logit (hasil prediksi) di token terakhir prompt
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">batch&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">logits&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">batch&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">n_tokens&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nb">true&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">// Evaluasi awal (memasukkan prompt ke model)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">llama_decode&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">ctx&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">batch&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cerr&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;llama_decode() failed&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="mi">1&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="kt">int&lt;/span> &lt;span class="n">n_cur&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">batch&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">n_tokens&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">// Panjang konteks saat ini
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kt">int&lt;/span> &lt;span class="n">n_decode&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&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">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s">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>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Inisialisasi konteks sampler (Pengaturan Temperature, Top-K, Top-P, dll.)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">llama_sampler&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">smpl&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">llama_sampler_chain_init&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">llama_sampler_chain_default_params&lt;/span>&lt;span class="p">());&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">llama_sampler_chain_add_top_k&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">smpl&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">40&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">llama_sampler_chain_add_top_p&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">smpl&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mf">0.9f&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">llama_sampler_chain_add_temp&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">smpl&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mf">0.7f&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">llama_sampler_chain_add_dist&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">smpl&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">1234&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="c1">// Nilai seed
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">while&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">n_decode&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="n">max_gen_tokens&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 1. Sampling: memprediksi token berikutnya berdasarkan konteks saat ini
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">llama_token&lt;/span> &lt;span class="n">new_token_id&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">llama_sampler_sample&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">smpl&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">ctx&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="o">-&lt;/span>&lt;span class="mi">1&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. Jika token adalah EOS (End of Sequence), hentikan loop
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">llama_token_is_eog&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">new_token_id&lt;/span>&lt;span class="p">))&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">break&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">// 3. Dekode token menjadi string (teks) untuk ditampilkan
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kt">char&lt;/span> &lt;span class="n">buf&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">128&lt;/span>&lt;span class="p">];&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">int&lt;/span> &lt;span class="n">n_chars&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">llama_token_to_piece&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">new_token_id&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">buf&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="k">sizeof&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">buf&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nb">false&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">n_chars&lt;/span> &lt;span class="o">&amp;gt;&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">string&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">buf&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">n_chars&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">flush&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">// 4. Persiapkan token baru yang dihasilkan sebagai batch berikutnya
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">llama_batch_clear&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">batch&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">llama_batch_add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">batch&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">new_token_id&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">n_cur&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="mi">0&lt;/span> &lt;span class="p">},&lt;/span> &lt;span class="nb">true&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. Evaluasi model (memperbarui KV Cache dan memprediksi selanjutnya)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">llama_decode&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">ctx&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">batch&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cerr&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;Failed to evaluate&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">break&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="n">n_cur&lt;/span> &lt;span class="o">+=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">n_decode&lt;/span> &lt;span class="o">+=&lt;/span> &lt;span class="mi">1&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="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&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">// Bersihkan
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">llama_sampler_free&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">smpl&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">llama_batch_free&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">batch&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">llama_free&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">ctx&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">llama_free_model&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 class="n">llama_backend_free&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">return&lt;/span> &lt;span class="mi">0&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;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Kode ini merupakan implementasi dari &lt;em>loop&lt;/em> inferensi kustom yang menggunakan API dasar llama.cpp.
Kode ini menggunakan struktur &lt;code>llama_batch&lt;/code> untuk mengelola sekumpulan token, dan menggunakan &lt;code>llama_decode&lt;/code> untuk menjalankan &lt;em>forward pass&lt;/em> dari jaringan saraf.&lt;/p>
&lt;hr>
&lt;h2 id="6-contoh-kustomisasi-lanjutan-manipulasi-logit-dan-kontrol-penalti-dengan-c">6. Contoh Kustomisasi Lanjutan: Manipulasi Logit dan Kontrol Penalti dengan C++
&lt;/h2>&lt;p>Jika kita tidak hanya melakukan pembuatan teks sederhana, tetapi ingin memaksakan format &lt;em>output&lt;/em> tertentu (seperti hanya JSON), atau mencegah dihasilkannya kata-kata terlarang tertentu, kita bisa secara langsung memanipulasi &lt;strong>Logit&lt;/strong> dari sisi C++ sebelum &lt;em>sampling&lt;/em> dilakukan.&lt;/p>
&lt;p>Anda bisa mendapatkan array dari skor mentah (nilai sebelum dikonversi menjadi probabilitas) yang dihasilkan model tepat sebelum setiap token dikeluarkan.&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;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Dapatkan array logit mentah tepat setelah inferensi, sebelum sampling dilakukan
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="kt">float&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">logits&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">llama_get_logits_ith&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">ctx&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">batch&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">n_tokens&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kt">int&lt;/span> &lt;span class="n">n_vocab&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">llama_n_vocab&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">// Daftar ID token terlarang (sebagai contoh 1234, 5678)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">llama_token&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">forbidden_tokens&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="mi">1234&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">5678&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">// Mengatur probabilitas kemunculan token terlarang menjadi 0 (Logit menjadi minus tak terhingga)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">llama_token&lt;/span> &lt;span class="nl">bad_tok&lt;/span> &lt;span class="p">:&lt;/span> &lt;span class="n">forbidden_tokens&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">logits&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">bad_tok&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="o">-&lt;/span>&lt;span class="n">INFINITY&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;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Dengan mengelola API C++ secara langsung, &lt;strong>&amp;ldquo;intervensi berskala mikromilidetik pada setiap siklus inferensi&amp;rdquo;&lt;/strong> bisa dilakukan, sesuatu yang mungkin sulit dicapai atau memakan &lt;em>overhead&lt;/em> yang terlalu besar jika dilakukan melalui LangChain atau Python.&lt;/p>
&lt;hr>
&lt;h2 id="7-rahasia-penyetelan-kinerja-performance-tuning">7. Rahasia Penyetelan Kinerja (Performance Tuning)
&lt;/h2>&lt;p>Setelah implementasi di C++ selesai, berikut adalah beberapa poin untuk diperiksa guna meningkatkan kecepatan hingga batas maksimal untuk produksi yang sebenarnya.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Optimasi Pemrosesan Batch:&lt;/strong> Jika Anda memproses permintaan dari beberapa pengguna secara bersamaan, sertakan beberapa &lt;em>sequence&lt;/em> dalam &lt;code>llama_batch&lt;/code> dan panggil &lt;code>llama_decode&lt;/code> sekaligus (Continuous Batching). Hal ini memungkinkan akses memori untuk dibagikan sehingga dapat meningkatkan &lt;em>throughput&lt;/em> secara dramatis.&lt;/li>
&lt;li>&lt;strong>Mengaktifkan Flash Attention:&lt;/strong>
Dengan menetapkan &lt;code>ctx_params.flash_attn = true;&lt;/code> pada parameter konteks, komputasi Attention bisa dipercepat sembari mengurangi penggunaan memori. Ini merupakan pengaturan yang diwajibkan bila menangani konteks yang panjang (puluhan ribu token).&lt;/li>
&lt;li>&lt;strong>Dukungan NUMA:&lt;/strong>
Di lingkungan server multi-socket, konfigurasi NUMA yang tepat sebelum memanggil &lt;code>llama_backend_init()&lt;/code> dapat mengurangi latensi dari akses memori.&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="8-kesimpulan">8. Kesimpulan
&lt;/h2>&lt;p>Pada artikel ini, kita telah membahas secara mendalam mulai dari latar belakang matematis &lt;code>llama.cpp&lt;/code>, penjelasan arsitektur, hingga cara membangun mesin inferensi kustom menggunakan API C++.&lt;/p>
&lt;p>Ekosistem Python sangat berguna untuk pembuatan &lt;em>prototype&lt;/em>, namun untuk &lt;em>deployment&lt;/em> di perangkat &lt;em>edge&lt;/em>, integrasi ke dalam &lt;em>game&lt;/em>, atau dalam lingkungan produksi yang menuntut pemrosesan secara &lt;em>real-time&lt;/em>, pengontrolan langsung &lt;code>llama.cpp&lt;/code> berbasis C/C++ menunjukkan kekuatan yang luar biasa.&lt;/p>
&lt;p>Kami sangat menyarankan Anda untuk mencoba menulis kode C++ dengan tangan Anda sendiri dan merasakan serunya mengendalikan LLM secara bebas di lingkungan lokal.&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>Tautan Referensi&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;a class="link" href="https://github.com/ggerganov/llama.cpp" target="_blank" rel="noopener"
>Repositori Resmi llama.cpp&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="https://github.com/ggerganov/ggml" target="_blank" rel="noopener"
>ggml - Tensor Library&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="https://arxiv.org/abs/1706.03762" target="_blank" rel="noopener"
>Attention Is All You Need (Vaswani et al., 2017)&lt;/a>&lt;/li>
&lt;/ul>
&lt;/blockquote></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>